aktueller Stand
This commit is contained in:
@@ -7,7 +7,7 @@ services:
|
|||||||
- .env # Lädt Umgebungsvariablen aus der .env-Datei
|
- .env # Lädt Umgebungsvariablen aus der .env-Datei
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./config:/app/config # Für persistente Konfiguration
|
- /opt/docker/foodsharing/config:/app/config # Für persistente Konfiguration
|
||||||
networks:
|
networks:
|
||||||
- nginx-proxy-manager_default
|
- nginx-proxy-manager_default
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -59,13 +59,14 @@ function mergeStoresIntoConfig(config = [], stores = []) {
|
|||||||
}
|
}
|
||||||
const id = String(store.id);
|
const id = String(store.id);
|
||||||
if (!map.has(id)) {
|
if (!map.has(id)) {
|
||||||
|
const hideByDefault = store.hasPickupSlots === false;
|
||||||
map.set(id, {
|
map.set(id, {
|
||||||
id,
|
id,
|
||||||
label: store.name || `Store ${id}`,
|
label: store.name || `Store ${id}`,
|
||||||
active: false,
|
active: false,
|
||||||
checkProfileId: true,
|
checkProfileId: true,
|
||||||
onlyNotify: false,
|
onlyNotify: false,
|
||||||
hidden: false
|
hidden: hideByDefault
|
||||||
});
|
});
|
||||||
changed = true;
|
changed = true;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -124,11 +124,8 @@ async function fetchStores(cookieHeader, profileId) {
|
|||||||
headers: buildHeaders(cookieHeader),
|
headers: buildHeaders(cookieHeader),
|
||||||
params: { activeStores: 1 }
|
params: { activeStores: 1 }
|
||||||
});
|
});
|
||||||
const stores = response.data || [];
|
const stores = Array.isArray(response.data) ? response.data : [];
|
||||||
if (!Array.isArray(stores)) {
|
const normalized = stores.map((store) => ({
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return stores.map((store) => ({
|
|
||||||
id: String(store.id),
|
id: String(store.id),
|
||||||
name: store.name || `Store ${store.id}`,
|
name: store.name || `Store ${store.id}`,
|
||||||
pickupStatus: store.pickupStatus,
|
pickupStatus: store.pickupStatus,
|
||||||
@@ -138,12 +135,45 @@ async function fetchStores(cookieHeader, profileId) {
|
|||||||
street: store.street || '',
|
street: store.street || '',
|
||||||
zip: store.zip || ''
|
zip: store.zip || ''
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
return annotateStoresWithPickupSlots(normalized, cookieHeader);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Stores konnten nicht geladen werden:', error.message);
|
console.warn('Stores konnten nicht geladen werden:', error.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function annotateStoresWithPickupSlots(stores, cookieHeader, concurrency = 5) {
|
||||||
|
if (!Array.isArray(stores) || stores.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cappedConcurrency = Math.max(1, Math.min(concurrency, stores.length));
|
||||||
|
const results = new Array(stores.length);
|
||||||
|
let pointer = 0;
|
||||||
|
|
||||||
|
async function worker() {
|
||||||
|
while (true) {
|
||||||
|
const currentIndex = pointer++;
|
||||||
|
if (currentIndex >= stores.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const store = stores[currentIndex];
|
||||||
|
let hasPickupSlots = null;
|
||||||
|
try {
|
||||||
|
const pickups = await fetchPickups(store.id, cookieHeader);
|
||||||
|
hasPickupSlots = Array.isArray(pickups) && pickups.length > 0;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`Pickups für Store ${store.id} konnten nicht geprüft werden:`, error.message);
|
||||||
|
}
|
||||||
|
results[currentIndex] = { ...store, hasPickupSlots };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(Array.from({ length: cappedConcurrency }, () => worker()));
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchPickups(storeId, cookieHeader) {
|
async function fetchPickups(storeId, cookieHeader) {
|
||||||
const response = await client.get(`/api/stores/${storeId}/pickups`, {
|
const response = await client.get(`/api/stores/${storeId}/pickups`, {
|
||||||
headers: buildHeaders(cookieHeader)
|
headers: buildHeaders(cookieHeader)
|
||||||
|
|||||||
@@ -713,12 +713,19 @@ function App() {
|
|||||||
const entry = configMap.get(storeId);
|
const entry = configMap.get(storeId);
|
||||||
const isVisible = entry && !entry.hidden;
|
const isVisible = entry && !entry.hidden;
|
||||||
const needsRestore = entry && entry.hidden;
|
const needsRestore = entry && entry.hidden;
|
||||||
|
const blockedByNoPickups = store.hasPickupSlots === false;
|
||||||
let statusLabel = 'Hinzufügen';
|
let statusLabel = 'Hinzufügen';
|
||||||
|
let statusClass = 'text-blue-600';
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
statusLabel = 'Bereits in Konfiguration';
|
statusLabel = 'Bereits in Konfiguration';
|
||||||
|
statusClass = 'text-gray-500';
|
||||||
} else if (needsRestore) {
|
} else if (needsRestore) {
|
||||||
statusLabel = 'Ausgeblendet – erneut hinzufügen';
|
statusLabel = 'Ausgeblendet – erneut hinzufügen';
|
||||||
}
|
}
|
||||||
|
if (blockedByNoPickups) {
|
||||||
|
statusLabel = 'Keine Pickups – automatisch verborgen';
|
||||||
|
statusClass = 'text-amber-600';
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={storeId}
|
key={storeId}
|
||||||
@@ -735,7 +742,7 @@ function App() {
|
|||||||
{store.zip || ''} {store.city}
|
{store.zip || ''} {store.city}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<p className={`text-xs mt-2 ${isVisible ? 'text-gray-500' : 'text-blue-600'}`}>{statusLabel}</p>
|
<p className={`text-xs mt-2 ${statusClass}`}>{statusLabel}</p>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in New Issue
Block a user