Journal für abholungen
This commit is contained in:
@@ -95,6 +95,60 @@ const JournalPage = ({ authorizedFetch, stores }) => {
|
||||
return parsed.getTime();
|
||||
}, []);
|
||||
|
||||
const getIntervalMonths = useCallback((interval) => {
|
||||
if (interval === 'monthly') {
|
||||
return 1;
|
||||
}
|
||||
if (interval === 'quarterly') {
|
||||
return 3;
|
||||
}
|
||||
return 12;
|
||||
}, []);
|
||||
|
||||
const addMonths = useCallback((date, months) => {
|
||||
const copy = new Date(date.getTime());
|
||||
copy.setMonth(copy.getMonth() + months);
|
||||
return copy;
|
||||
}, []);
|
||||
|
||||
const startOfDay = useCallback((date) => {
|
||||
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
}, []);
|
||||
|
||||
const getNextReminderTimestamp = useCallback(
|
||||
(entry) => {
|
||||
if (!entry?.reminder?.enabled || !entry.pickupDate) {
|
||||
return null;
|
||||
}
|
||||
const baseDate = new Date(`${entry.pickupDate}T00:00:00`);
|
||||
if (Number.isNaN(baseDate.getTime())) {
|
||||
return null;
|
||||
}
|
||||
const intervalMonths = getIntervalMonths(entry.reminder.interval);
|
||||
const daysBefore = Number.isFinite(entry.reminder.daysBefore)
|
||||
? Math.max(0, entry.reminder.daysBefore)
|
||||
: 42;
|
||||
const todayStart = startOfDay(new Date());
|
||||
let occurrence = startOfDay(baseDate);
|
||||
const guardYear = todayStart.getFullYear() + 200;
|
||||
while (occurrence < todayStart && occurrence.getFullYear() < guardYear) {
|
||||
occurrence = startOfDay(addMonths(occurrence, intervalMonths));
|
||||
}
|
||||
if (occurrence.getFullYear() >= guardYear) {
|
||||
return null;
|
||||
}
|
||||
let reminderDate = new Date(occurrence.getTime());
|
||||
reminderDate.setDate(reminderDate.getDate() - daysBefore);
|
||||
if (reminderDate < todayStart) {
|
||||
occurrence = startOfDay(addMonths(occurrence, intervalMonths));
|
||||
reminderDate = new Date(occurrence.getTime());
|
||||
reminderDate.setDate(reminderDate.getDate() - daysBefore);
|
||||
}
|
||||
return reminderDate.getTime();
|
||||
},
|
||||
[addMonths, getIntervalMonths, startOfDay]
|
||||
);
|
||||
|
||||
const filteredEntries = useMemo(() => {
|
||||
const query = filters.query.trim().toLowerCase();
|
||||
const fromValue = parseDateValue(filters.dateFrom);
|
||||
@@ -142,11 +196,25 @@ const JournalPage = ({ authorizedFetch, stores }) => {
|
||||
const aLabel = a.storeName || storeLabelMap.get(String(a.storeId)) || '';
|
||||
const bLabel = b.storeName || storeLabelMap.get(String(b.storeId)) || '';
|
||||
return bLabel.localeCompare(aLabel);
|
||||
},
|
||||
nextReminderAsc: (a, b) => {
|
||||
const aNext = getNextReminderTimestamp(a);
|
||||
const bNext = getNextReminderTimestamp(b);
|
||||
if (aNext === null && bNext === null) {
|
||||
return 0;
|
||||
}
|
||||
if (aNext === null) {
|
||||
return 1;
|
||||
}
|
||||
if (bNext === null) {
|
||||
return -1;
|
||||
}
|
||||
return aNext - bNext;
|
||||
}
|
||||
};
|
||||
const sorter = sorters[sortBy] || sorters.pickupDateDesc;
|
||||
return [...results].sort(sorter);
|
||||
}, [entries, filters, parseDateValue, sortBy, storeLabelMap]);
|
||||
}, [entries, filters, getNextReminderTimestamp, parseDateValue, sortBy, storeLabelMap]);
|
||||
|
||||
const releaseEntryImageUrls = useCallback((entryList) => {
|
||||
if (!Array.isArray(entryList)) {
|
||||
@@ -538,6 +606,7 @@ const JournalPage = ({ authorizedFetch, stores }) => {
|
||||
<option value="createdAtAsc">Erstellt ↑</option>
|
||||
<option value="storeNameAsc">Betrieb A–Z</option>
|
||||
<option value="storeNameDesc">Betrieb Z–A</option>
|
||||
<option value="nextReminderAsc">Nächste Erinnerung</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
|
||||
Reference in New Issue
Block a user