diff --git a/src/routes/api/tasks/completions/[id]/+server.ts b/src/routes/api/tasks/completions/[id]/+server.ts new file mode 100644 index 0000000..13e3433 --- /dev/null +++ b/src/routes/api/tasks/completions/[id]/+server.ts @@ -0,0 +1,22 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import { TaskCompletion } from '$models/TaskCompletion'; +import { dbConnect } from '$utils/db'; +import { error, json } from '@sveltejs/kit'; + +export const DELETE: RequestHandler = async ({ params, locals }) => { + const auth = await locals.auth(); + if (!auth?.user?.nickname) throw error(401, 'Not logged in'); + + await dbConnect(); + + const completion = await TaskCompletion.findById(params.id); + if (!completion) throw error(404, 'Completion not found'); + + if (completion.completedBy !== auth.user.nickname) { + throw error(403, 'You can only delete your own completions'); + } + + await completion.deleteOne(); + + return json({ success: true }); +}; diff --git a/src/routes/tasks/rewards/+page.svelte b/src/routes/tasks/rewards/+page.svelte index 4d1e52c..8263e3b 100644 --- a/src/routes/tasks/rewards/+page.svelte +++ b/src/routes/tasks/rewards/+page.svelte @@ -62,6 +62,15 @@ .slice(0, 20) ); + /** @param {string} id */ + async function deleteCompletion(id) { + const res = await fetch(`/api/tasks/completions/${id}`, { method: 'DELETE' }); + if (res.ok) { + const statsRes = await fetch('/api/tasks/stats'); + if (statsRes.ok) stats = await statsRes.json(); + } + } + async function clearHistory() { if (!confirm('Deinen gesamten Verlauf und alle Sticker wirklich löschen? Das kann nicht rückgängig gemacht werden.')) return; const res = await fetch('/api/tasks/stats', { method: 'DELETE' }); @@ -135,6 +144,11 @@ {completion.completedBy} · {formatDistanceToNow(new Date(completion.completedAt), { locale: de, addSuffix: true })} + {#if completion.completedBy === currentUser} + + {/if} {/if} {/each} @@ -306,6 +320,27 @@ border: 1px solid var(--color-border, #e8e4dd); border-radius: 10px; } + .btn-delete-completion { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + margin-left: auto; + flex-shrink: 0; + border: none; + background: transparent; + color: var(--color-text-secondary, #ccc); + border-radius: 6px; + cursor: pointer; + opacity: 0; + transition: all 150ms; + } + .recent-item:hover .btn-delete-completion { opacity: 1; } + .btn-delete-completion:hover { + color: var(--nord11); + background: rgba(191, 97, 106, 0.08); + } .recent-img { width: 36px; height: 36px;