tasks: add individual completion deletion API and UI
All checks were successful
CI / update (push) Successful in 2m23s

This commit is contained in:
2026-04-02 07:47:57 +02:00
parent a588b8ee84
commit 4f17ad56fa
2 changed files with 57 additions and 0 deletions

View File

@@ -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 });
};

View File

@@ -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 })}
</span>
</div>
{#if completion.completedBy === currentUser}
<button class="btn-delete-completion" title="Eintrag löschen" onclick={() => deleteCompletion(completion._id)}>
<Trash2 size={14} />
</button>
{/if}
</div>
{/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;