feat: support pickup booking date ranges

This commit is contained in:
root
2025-11-09 19:11:26 +01:00
parent 1a7aa0e1b3
commit 3f8f1f24eb
4 changed files with 186 additions and 19 deletions

View File

@@ -748,6 +748,9 @@ function App() {
if (value && updated.desiredDate) {
delete updated.desiredDate;
}
if (value && updated.desiredDateRange) {
delete updated.desiredDateRange;
}
return updated;
})
);
@@ -764,6 +767,49 @@ function App() {
if (value && updated.desiredWeekday) {
delete updated.desiredWeekday;
}
if (value && updated.desiredDateRange) {
delete updated.desiredDateRange;
}
return updated;
})
);
};
const handleDateRangeChange = (entryId, field, value) => {
setIsDirty(true);
setConfig((prev) =>
prev.map((item) => {
if (item.id !== entryId) {
return item;
}
const nextRange = {
start: item.desiredDateRange?.start || null,
end: item.desiredDateRange?.end || null
};
if (field === 'start') {
nextRange.start = value || null;
if (nextRange.end && value && value > nextRange.end) {
nextRange.end = value;
}
} else if (field === 'end') {
nextRange.end = value || null;
if (nextRange.start && value && value < nextRange.start) {
nextRange.start = value;
}
}
const hasRange = Boolean(nextRange.start || nextRange.end);
const updated = { ...item };
if (hasRange) {
updated.desiredDateRange = nextRange;
if (updated.desiredWeekday) {
delete updated.desiredWeekday;
}
if (updated.desiredDate) {
delete updated.desiredDate;
}
} else if (updated.desiredDateRange) {
delete updated.desiredDateRange;
}
return updated;
})
);
@@ -1165,19 +1211,22 @@ function App() {
<th className="px-4 py-2 border-b">Nur benachrichtigen</th>
<th className="px-4 py-2 border-b">Wochentag</th>
<th className="px-4 py-2 border-b">Spezifisches Datum</th>
<th className="px-4 py-2 border-b">Datumsbereich</th>
<th className="px-4 py-2 border-b">Aktionen</th>
</tr>
</thead>
<tbody>
{visibleConfig.length === 0 && (
<tr>
<td colSpan="7" className="px-4 py-6 text-center text-sm text-gray-500">
<td colSpan="8" className="px-4 py-6 text-center text-sm text-gray-500">
Keine sichtbaren Einträge. Nutze Verfügbare Betriebe, um Betriebe hinzuzufügen oder ausgeblendete Einträge zurückzuholen.
</td>
</tr>
)}
{visibleConfig.map((item, index) => (
<tr key={`${item.id}-${index}`} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
{visibleConfig.map((item, index) => {
const hasDateRange = Boolean(item.desiredDateRange?.start || item.desiredDateRange?.end);
return (
<tr key={`${item.id}-${index}`} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
<td className="px-4 py-2 border-b text-center">
<input
type="checkbox"
@@ -1214,7 +1263,7 @@ function App() {
value={item.desiredWeekday || ''}
onChange={(e) => handleWeekdayChange(item.id, e.target.value)}
className="border rounded p-2 w-full bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
disabled={item.desiredDate}
disabled={item.desiredDate || hasDateRange}
>
<option value="">Kein Wochentag</option>
{weekdays.map((day) => (
@@ -1230,9 +1279,34 @@ function App() {
value={item.desiredDate || ''}
onChange={(e) => handleDateChange(item.id, e.target.value)}
className="border rounded p-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
disabled={item.desiredWeekday}
disabled={item.desiredWeekday || hasDateRange}
/>
</td>
<td className="px-4 py-2 border-b">
<div className="grid grid-cols-1 gap-2">
<div>
<label className="block text-xs text-gray-500 mb-1">Von</label>
<input
type="date"
value={item.desiredDateRange?.start || ''}
onChange={(e) => handleDateRangeChange(item.id, 'start', e.target.value)}
className="border rounded p-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
disabled={item.desiredWeekday || item.desiredDate}
/>
</div>
<div>
<label className="block text-xs text-gray-500 mb-1">Bis</label>
<input
type="date"
value={item.desiredDateRange?.end || ''}
onChange={(e) => handleDateRangeChange(item.id, 'end', e.target.value)}
className="border rounded p-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
disabled={item.desiredWeekday || item.desiredDate}
min={item.desiredDateRange?.start || undefined}
/>
</div>
</div>
</td>
<td className="px-4 py-2 border-b">
<div className="flex items-center justify-center gap-2">
<button
@@ -1256,7 +1330,8 @@ function App() {
</div>
</td>
</tr>
))}
);
})}
</tbody>
</table>
</div>

View File

@@ -94,6 +94,9 @@ const PickupConfigEditor = () => {
if (newConfig[index].desiredDate) {
delete newConfig[index].desiredDate;
}
if (newConfig[index].desiredDateRange) {
delete newConfig[index].desiredDateRange;
}
setConfig(newConfig);
};
@@ -104,6 +107,41 @@ const PickupConfigEditor = () => {
if (newConfig[index].desiredWeekday) {
delete newConfig[index].desiredWeekday;
}
if (newConfig[index].desiredDateRange) {
delete newConfig[index].desiredDateRange;
}
setConfig(newConfig);
};
const handleDateRangeChange = (index, field, value) => {
const newConfig = [...config];
const nextRange = {
start: newConfig[index].desiredDateRange?.start || null,
end: newConfig[index].desiredDateRange?.end || null
};
if (field === 'start') {
nextRange.start = value || null;
if (nextRange.end && value && value > nextRange.end) {
nextRange.end = value;
}
} else if (field === 'end') {
nextRange.end = value || null;
if (nextRange.start && value && value < nextRange.start) {
nextRange.start = value;
}
}
const hasRange = Boolean(nextRange.start || nextRange.end);
if (hasRange) {
newConfig[index].desiredDateRange = nextRange;
if (newConfig[index].desiredWeekday) {
delete newConfig[index].desiredWeekday;
}
if (newConfig[index].desiredDate) {
delete newConfig[index].desiredDate;
}
} else if (newConfig[index].desiredDateRange) {
delete newConfig[index].desiredDateRange;
}
setConfig(newConfig);
};
@@ -139,10 +177,13 @@ const PickupConfigEditor = () => {
<th className="px-4 py-2">Nur benachrichtigen</th>
<th className="px-4 py-2">Wochentag</th>
<th className="px-4 py-2">Spezifisches Datum</th>
<th className="px-4 py-2">Datumsbereich</th>
</tr>
</thead>
<tbody>
{config.map((item, index) => (
{config.map((item, index) => {
const hasDateRange = Boolean(item.desiredDateRange?.start || item.desiredDateRange?.end);
return (
<tr key={index} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
<td className="px-4 py-2 text-center">
<input
@@ -178,7 +219,7 @@ const PickupConfigEditor = () => {
value={item.desiredWeekday || ''}
onChange={(e) => handleWeekdayChange(index, e.target.value)}
className="border rounded p-1 w-full"
disabled={item.desiredDate}
disabled={item.desiredDate || hasDateRange}
>
<option value="">Kein Wochentag</option>
{weekdays.map((day) => (
@@ -192,11 +233,37 @@ const PickupConfigEditor = () => {
value={item.desiredDate || ''}
onChange={(e) => handleDateChange(index, e.target.value)}
className="border rounded p-1 w-full"
disabled={item.desiredWeekday}
disabled={item.desiredWeekday || hasDateRange}
/>
</td>
<td className="px-4 py-2">
<div className="grid grid-cols-1 gap-2">
<div>
<label className="block text-xs text-gray-500 mb-1">Von</label>
<input
type="date"
value={item.desiredDateRange?.start || ''}
onChange={(e) => handleDateRangeChange(index, 'start', e.target.value)}
className="border rounded p-1 w-full"
disabled={item.desiredWeekday || item.desiredDate}
/>
</div>
<div>
<label className="block text-xs text-gray-500 mb-1">Bis</label>
<input
type="date"
value={item.desiredDateRange?.end || ''}
onChange={(e) => handleDateRangeChange(index, 'end', e.target.value)}
className="border rounded p-1 w-full"
disabled={item.desiredWeekday || item.desiredDate}
min={item.desiredDateRange?.start || undefined}
/>
</div>
</div>
</td>
</tr>
))}
);
})}
</tbody>
</table>
</div>