import { useState, useEffect } from 'react'; import { DateRange } from 'react-date-range'; import { format, parseISO, isValid, startOfDay } from 'date-fns'; import { de } from 'date-fns/locale'; import 'react-date-range/dist/styles.css'; import 'react-date-range/dist/theme/default.css'; const parseDateValue = (value) => { if (!value) { return null; } const parsed = parseISO(value); return isValid(parsed) ? parsed : null; }; const formatDateValue = (date) => { if (!(date instanceof Date) || !isValid(date)) { return null; } return format(date, 'yyyy-MM-dd'); }; const formatRangeLabel = (start, end) => { const startDate = parseDateValue(start); const endDate = parseDateValue(end); if (startDate && endDate) { const startLabel = format(startDate, 'dd.MM.yyyy', { locale: de }); const endLabel = format(endDate, 'dd.MM.yyyy', { locale: de }); if (startLabel === endLabel) { return startLabel; } return `${startLabel} – ${endLabel}`; } if (startDate) { return format(startDate, 'dd.MM.yyyy', { locale: de }); } return 'Zeitraum auswählen'; }; const buildSelectionRange = (start, end, minDate) => { const minimum = minDate || startOfDay(new Date()); let startDate = parseDateValue(start) || parseDateValue(end) || minimum; let endDate = parseDateValue(end) || parseDateValue(start) || startDate; if (startDate < minimum) { startDate = minimum; } if (endDate < minimum) { endDate = startDate; } return { startDate, endDate, key: 'selection' }; }; const sortEntriesByLabel = (entries = []) => { return [...entries].sort((a, b) => (a.label || '').localeCompare(b.label || '', 'de', { sensitivity: 'base' }) ); }; const PickupConfigEditor = () => { const [config, setConfig] = useState([]); const [loading, setLoading] = useState(true); const [status, setStatus] = useState(''); const [error, setError] = useState(''); const [activeRangePicker, setActiveRangePicker] = useState(null); const minSelectableDate = startOfDay(new Date()); // Simulierte API-Endpunkte - diese müssen in Ihrer tatsächlichen Implementierung angepasst werden const API_URL = '/api/iobroker/pickup-config'; useEffect(() => { // Beim Laden der Komponente die aktuelle Konfiguration abrufen fetchConfig(); }, []); useEffect(() => { if (!activeRangePicker) { return; } const entry = config.find((item) => item.id === activeRangePicker); if (!entry || entry.desiredWeekday) { setActiveRangePicker(null); } }, [activeRangePicker, config]); const fetchConfig = async () => { setLoading(true); setError(''); try { // In einer echten Implementierung würden Sie Ihre API aufrufen // Hier wird die statische Konfiguration verwendet // const response = await fetch(API_URL); // const data = await response.json(); // Simulierte Verzögerung und Antwort mit der statischen Konfiguration setTimeout(() => { const staticConfig = [ { id: "63448", active: false, checkProfileId: true, onlyNotify: true, label: "Penny Baden-Oos" }, { id: "44975", active: false, checkProfileId: true, onlyNotify: false, label: "Aldi Kuppenheim", desiredWeekday: "Samstag" }, { id: "44972", active: false, checkProfileId: true, onlyNotify: false, label: "Aldi Biblisweg", desiredWeekday: "Dienstag" }, { id: "44975", active: false, checkProfileId: true, onlyNotify: false, label: "Aldi Kuppenheim", desiredDateRange: { start: "2025-05-18", end: "2025-05-18" } }, { id: "33875", active: false, checkProfileId: true, onlyNotify: false, label: "Cap Markt", desiredWeekday: "Donnerstag" }, { id: "42322", active: false, checkProfileId: false, onlyNotify: false, label: "Edeka Haueneberstein" }, { id: "51450", active: false, checkProfileId: true, onlyNotify: false, label: "Hornbach Grünwinkel" } ]; setConfig(sortEntriesByLabel(staticConfig)); setLoading(false); }, 500); } catch (err) { setError('Fehler beim Laden der Konfiguration: ' + err.message); setLoading(false); } }; const saveConfig = async () => { setStatus('Speichere...'); setError(''); try { // API-Aufruf zum Speichern der Konfiguration in ioBroker // In einer echten Implementierung würden Sie Ihre API aufrufen // const response = await fetch(API_URL, { // method: 'POST', // headers: { // 'Content-Type': 'application/json', // }, // body: JSON.stringify(config), // }); // Simulierte Verzögerung zum Darstellen des Speichervorgangs setTimeout(() => { setStatus('Konfiguration erfolgreich gespeichert!'); setTimeout(() => setStatus(''), 3000); }, 1000); } catch (err) { setError('Fehler beim Speichern: ' + err.message); } }; const handleToggleActive = (index) => { const newConfig = [...config]; newConfig[index].active = !newConfig[index].active; setConfig(newConfig); }; const handleToggleProfileCheck = (index) => { const newConfig = [...config]; newConfig[index].checkProfileId = !newConfig[index].checkProfileId; setConfig(newConfig); }; const handleToggleOnlyNotify = (index) => { const newConfig = [...config]; newConfig[index].onlyNotify = !newConfig[index].onlyNotify; setConfig(newConfig); }; const handleWeekdayChange = (index, value) => { const newConfig = [...config]; const entryId = newConfig[index]?.id; newConfig[index].desiredWeekday = value; if (newConfig[index].desiredDateRange) { delete newConfig[index].desiredDateRange; } setConfig(newConfig); if (value && entryId) { setActiveRangePicker((prev) => (prev === entryId ? null : prev)); } }; const handleDateRangeSelection = (entryId, startDate, endDate) => { const startValue = formatDateValue(startDate); const endValue = formatDateValue(endDate); setConfig((prev) => prev.map((item) => { if (item.id !== entryId) { return item; } const updated = { ...item }; if (startValue || endValue) { updated.desiredDateRange = { start: startValue || endValue, end: endValue || startValue }; if (updated.desiredWeekday) { delete updated.desiredWeekday; } } else if (updated.desiredDateRange) { delete updated.desiredDateRange; } if (updated.desiredDate) { delete updated.desiredDate; } return updated; }) ); }; const activeRangeEntry = activeRangePicker ? config.find((item) => item.id === activeRangePicker) || null : null; if (loading) { return
| Aktiv | Geschäft | Profil prüfen | Nur benachrichtigen | Wochentag | Datum / Zeitraum |
|---|---|---|---|---|---|
| handleToggleActive(index)} className="h-5 w-5" /> | {item.label} | handleToggleProfileCheck(index)} className="h-5 w-5" /> | handleToggleOnlyNotify(index)} className="h-5 w-5" /> |
{JSON.stringify(config, null, 2)}
Zeitraum auswählen für
{activeRangeEntry.label || `Store ${activeRangeEntry.id}`}