diff --git a/src/App.js b/src/App.js
index 729e3f2..48ddfb0 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate, Link, useLocation, useNavigate } from 'react-router-dom';
import { DateRange } from 'react-date-range';
-import { format, parseISO, isValid } from 'date-fns';
+import { format, parseISO, isValid, startOfDay } from 'date-fns';
import { de } from 'date-fns/locale';
import './App.css';
import 'react-date-range/dist/styles.css';
@@ -40,9 +40,16 @@ const formatRangeLabel = (start, end) => {
return 'Zeitraum auswählen';
};
-const buildSelectionRange = (start, end) => {
- const startDate = parseDateValue(start) || parseDateValue(end) || new Date();
- const endDate = parseDateValue(end) || parseDateValue(start) || startDate;
+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,
@@ -76,6 +83,7 @@ function App() {
const [dirtyDialogSaving, setDirtyDialogSaving] = useState(false);
const [confirmDialog, setConfirmDialog] = useState({ open: false, resolve: null });
const [activeRangePicker, setActiveRangePicker] = useState(null);
+ const minSelectableDate = useMemo(() => startOfDay(new Date()), []);
const weekdays = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'];
@@ -866,7 +874,7 @@ function App() {
return updated;
})
);
- }, [setConfig, setIsDirty]);
+ }, [setConfig]);
const configMap = useMemo(() => {
const map = new Map();
@@ -880,15 +888,21 @@ function App() {
const visibleConfig = useMemo(() => config.filter((item) => !item.hidden), [config]);
+ const activeRangeEntry = useMemo(() => {
+ if (!activeRangePicker) {
+ return null;
+ }
+ return config.find((item) => item.id === activeRangePicker) || null;
+ }, [activeRangePicker, config]);
+
useEffect(() => {
if (!activeRangePicker) {
return;
}
- const stillExists = config.some((item) => item.id === activeRangePicker);
- if (!stillExists) {
+ if (!activeRangeEntry || activeRangeEntry.desiredWeekday) {
setActiveRangePicker(null);
}
- }, [activeRangePicker, config]);
+ }, [activeRangePicker, activeRangeEntry]);
const handleStoreSelection = async (store) => {
const storeId = String(store.id);
@@ -1343,62 +1357,24 @@ function App() {
-
-
- {activeRangePicker === item.id && !item.desiredWeekday && (
-
- {
- const { startDate, endDate } = ranges.selection;
- handleDateRangeSelection(item.id, startDate, endDate);
- }}
- moveRangeOnFirstSelection={false}
- ranges={[buildSelectionRange(rangeStart, rangeEnd)]}
- rangeColors={['#2563EB']}
- months={1}
- direction="horizontal"
- showDateDisplay={false}
- locale={de}
- />
-
-
-
-
-
- )}
-
+
|
@@ -1437,6 +1413,75 @@ function App() {
Konfiguration speichern
+
+ {activeRangeEntry && !activeRangeEntry.desiredWeekday && (
+ setActiveRangePicker(null)}
+ >
+ event.stopPropagation()}
+ >
+
+ Zeitraum auswählen für
+
+ {activeRangeEntry.label || `Store ${activeRangeEntry.id}`}
+
+
+
+ {
+ const { startDate, endDate } = ranges.selection;
+ handleDateRangeSelection(activeRangeEntry.id, startDate, endDate);
+ }}
+ moveRangeOnFirstSelection={false}
+ ranges={[
+ buildSelectionRange(
+ activeRangeEntry.desiredDateRange?.start,
+ activeRangeEntry.desiredDateRange?.end,
+ minSelectableDate
+ )
+ ]}
+ rangeColors={['#2563EB']}
+ months={1}
+ direction="horizontal"
+ showDateDisplay={false}
+ locale={de}
+ minDate={minSelectableDate}
+ />
+
+
+
+
+
+
+
+
+
+
+ )}
);
diff --git a/src/PickupConfigEditor.js b/src/PickupConfigEditor.js
index 4d1826c..4c3130a 100644
--- a/src/PickupConfigEditor.js
+++ b/src/PickupConfigEditor.js
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import { DateRange } from 'react-date-range';
-import { format, parseISO, isValid } from 'date-fns';
+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';
@@ -37,9 +37,16 @@ const formatRangeLabel = (start, end) => {
return 'Zeitraum auswählen';
};
-const buildSelectionRange = (start, end) => {
- const startDate = parseDateValue(start) || parseDateValue(end) || new Date();
- const endDate = parseDateValue(end) || parseDateValue(start) || startDate;
+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,
@@ -53,6 +60,7 @@ const PickupConfigEditor = () => {
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';
@@ -62,6 +70,16 @@ const PickupConfigEditor = () => {
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('');
@@ -155,27 +173,38 @@ const PickupConfigEditor = () => {
}
};
- const handleDateRangeSelection = (index, startDate, endDate) => {
- const newConfig = [...config];
+ const handleDateRangeSelection = (entryId, startDate, endDate) => {
const startValue = formatDateValue(startDate);
const endValue = formatDateValue(endDate);
- if (startValue || endValue) {
- newConfig[index].desiredDateRange = {
- start: startValue || endValue,
- end: endValue || startValue
- };
- if (newConfig[index].desiredWeekday) {
- delete newConfig[index].desiredWeekday;
- }
- } else if (newConfig[index].desiredDateRange) {
- delete newConfig[index].desiredDateRange;
- }
- if (newConfig[index].desiredDate) {
- delete newConfig[index].desiredDate;
- }
- setConfig(newConfig);
+ 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 Lade Konfiguration... ;
}
@@ -265,62 +294,24 @@ const PickupConfigEditor = () => {
|
-
-
- {activeRangePicker === item.id && !item.desiredWeekday && (
-
- {
- const { startDate, endDate } = ranges.selection;
- handleDateRangeSelection(index, startDate, endDate);
- }}
- moveRangeOnFirstSelection={false}
- ranges={[buildSelectionRange(rangeStart, rangeEnd)]}
- rangeColors={['#2563EB']}
- months={1}
- direction="horizontal"
- showDateDisplay={false}
- locale={de}
- />
-
-
-
-
-
- )}
-
+
|
);
@@ -350,6 +341,75 @@ const PickupConfigEditor = () => {
{JSON.stringify(config, null, 2)}
+
+ {activeRangeEntry && !activeRangeEntry.desiredWeekday && (
+ setActiveRangePicker(null)}
+ >
+
event.stopPropagation()}
+ >
+
+
Zeitraum auswählen für
+
+ {activeRangeEntry.label || `Store ${activeRangeEntry.id}`}
+
+
+
+ {
+ const { startDate, endDate } = ranges.selection;
+ handleDateRangeSelection(activeRangeEntry.id, startDate, endDate);
+ }}
+ moveRangeOnFirstSelection={false}
+ ranges={[
+ buildSelectionRange(
+ activeRangeEntry.desiredDateRange?.start,
+ activeRangeEntry.desiredDateRange?.end,
+ minSelectableDate
+ )
+ ]}
+ rangeColors={['#2563EB']}
+ months={1}
+ direction="horizontal"
+ showDateDisplay={false}
+ locale={de}
+ minDate={minSelectableDate}
+ />
+
+
+
+
+
+
+
+
+
+
+ )}
);
};