Müll-Erinnerung gemeinschaftlich abhakbar machen
Jeder Mieter kann eine Mülltonne als rausgestellt markieren; danach verschwindet die Erinnerung für alle Mieter, nicht nur für den, der sie abgehakt hat.
This commit is contained in:
parent
b15ba77336
commit
778cb94b3a
@ -105,7 +105,13 @@ storageRouter.delete(
|
|||||||
// MÜLL-KALENDER
|
// MÜLL-KALENDER
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
const TRASH_SELECT = { id: true, type: true, date: true };
|
const TRASH_SELECT = {
|
||||||
|
id: true,
|
||||||
|
type: true,
|
||||||
|
date: true,
|
||||||
|
completedAt: true,
|
||||||
|
completedBy: { select: { id: true, fullName: true } },
|
||||||
|
};
|
||||||
|
|
||||||
storageRouter.post(
|
storageRouter.post(
|
||||||
'/trash-schedule',
|
'/trash-schedule',
|
||||||
@ -146,6 +152,26 @@ storageRouter.get('/trash-schedule', requireAuth, async (req: AuthedRequest, res
|
|||||||
res.status(200).json({ entries });
|
res.status(200).json({ entries });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Jeder Mieter (nicht nur der Vermieter) kann eine Mülltonne als
|
||||||
|
// "rausgestellt" markieren — das ist eine gemeinschaftliche Aufgabe, keine
|
||||||
|
// pro Person. Danach verschwindet die Erinnerung für alle.
|
||||||
|
storageRouter.post(
|
||||||
|
'/trash-schedule/:id/complete',
|
||||||
|
requireAuth,
|
||||||
|
async (req: AuthedRequest, res: Response) => {
|
||||||
|
try {
|
||||||
|
const entry = await prisma.trashSchedule.update({
|
||||||
|
where: { id: req.params.id },
|
||||||
|
data: { completedAt: new Date(), completedById: req.user!.id },
|
||||||
|
select: TRASH_SELECT,
|
||||||
|
});
|
||||||
|
res.status(200).json({ entry });
|
||||||
|
} catch {
|
||||||
|
res.status(404).json({ error: 'Eintrag nicht gefunden' });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
storageRouter.delete(
|
storageRouter.delete(
|
||||||
'/trash-schedule/:id',
|
'/trash-schedule/:id',
|
||||||
requireAuth,
|
requireAuth,
|
||||||
|
|||||||
@ -189,6 +189,7 @@ model User {
|
|||||||
accessCodeAssigned AccessCode[] @relation("AccessCodeUser")
|
accessCodeAssigned AccessCode[] @relation("AccessCodeUser")
|
||||||
accessCodesGiven AccessCode[] @relation("AccessCodeAssignedBy")
|
accessCodesGiven AccessCode[] @relation("AccessCodeAssignedBy")
|
||||||
announcementsMade Announcement[]
|
announcementsMade Announcement[]
|
||||||
|
trashCompleted TrashSchedule[]
|
||||||
notifications Notification[]
|
notifications Notification[]
|
||||||
invitationsSent Invitation[] @relation("InvitationsSent")
|
invitationsSent Invitation[] @relation("InvitationsSent")
|
||||||
storageSlots StorageSlot[]
|
storageSlots StorageSlot[]
|
||||||
@ -640,6 +641,13 @@ model TrashSchedule {
|
|||||||
date DateTime
|
date DateTime
|
||||||
reminderSentAt DateTime? @map("reminder_sent_at")
|
reminderSentAt DateTime? @map("reminder_sent_at")
|
||||||
|
|
||||||
|
// Wird gesetzt, sobald irgendein Mieter die Tonne rausgestellt hat — dann
|
||||||
|
// verschwindet die Erinnerung für ALLE Mieter (gemeinschaftliche Aufgabe,
|
||||||
|
// keine Erledigung pro Person).
|
||||||
|
completedAt DateTime? @map("completed_at")
|
||||||
|
completedById String? @map("completed_by_id")
|
||||||
|
completedBy User? @relation(fields: [completedById], references: [id])
|
||||||
|
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
|
|
||||||
@@unique([type, date])
|
@@unique([type, date])
|
||||||
|
|||||||
@ -3283,8 +3283,14 @@
|
|||||||
const from = today.toISOString().slice(0, 10);
|
const from = today.toISOString().slice(0, 10);
|
||||||
const to = weekAhead.toISOString().slice(0, 10);
|
const to = weekAhead.toISOString().slice(0, 10);
|
||||||
const data = await apiFetch(`/trash-schedule?from=${from}&to=${to}`);
|
const data = await apiFetch(`/trash-schedule?from=${from}&to=${to}`);
|
||||||
data.entries.forEach(e => {
|
data.entries.filter(e => !e.completedAt).forEach(e => {
|
||||||
items.push({ date: new Date(e.date), icon: '🗑️', text: `Müll rausstellen: ${TRASH_TYPE_LABEL[e.type] || e.type} am ${new Date(e.date).toLocaleDateString('de-DE')}` });
|
items.push({
|
||||||
|
date: new Date(e.date),
|
||||||
|
icon: '🗑️',
|
||||||
|
text: `Müll rausstellen: ${TRASH_TYPE_LABEL[e.type] || e.type} am ${new Date(e.date).toLocaleDateString('de-DE')}`,
|
||||||
|
actionLabel: 'Erledigt',
|
||||||
|
onAction: () => completeTrashEntry(e.id),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[notifications] Müllkalender laden fehlgeschlagen:', err.message);
|
console.error('[notifications] Müllkalender laden fehlgeschlagen:', err.message);
|
||||||
@ -3316,10 +3322,26 @@
|
|||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
const row = el('div', 'ticket-row');
|
const row = el('div', 'ticket-row');
|
||||||
row.appendChild(el('div', 'title', `${item.icon} ${item.text}`));
|
row.appendChild(el('div', 'title', `${item.icon} ${item.text}`));
|
||||||
|
if (item.onAction) {
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.className = 'btn-secondary';
|
||||||
|
btn.textContent = item.actionLabel;
|
||||||
|
btn.onclick = item.onAction;
|
||||||
|
row.appendChild(btn);
|
||||||
|
}
|
||||||
list.appendChild(row);
|
list.appendChild(row);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function completeTrashEntry(id) {
|
||||||
|
try {
|
||||||
|
await apiFetch(`/trash-schedule/${id}/complete`, { method: 'POST' });
|
||||||
|
loadNotifications();
|
||||||
|
} catch (err) {
|
||||||
|
alert(err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function buildProfileCompletenessBadge(user) {
|
function buildProfileCompletenessBadge(user) {
|
||||||
const missing = [];
|
const missing = [];
|
||||||
if (!user.phoneNumber) missing.push('Telefonnummer');
|
if (!user.phoneNumber) missing.push('Telefonnummer');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user