diff --git a/web/src/routes/[workspace]/[collection]/[slug]/+page.svelte b/web/src/routes/[workspace]/[collection]/[slug]/+page.svelte index 1a719392..4ee5579c 100644 --- a/web/src/routes/[workspace]/[collection]/[slug]/+page.svelte +++ b/web/src/routes/[workspace]/[collection]/[slug]/+page.svelte @@ -7,14 +7,15 @@ import VersionHistory from '$lib/components/versions/VersionHistory.svelte'; import CommentThread from '$lib/components/comments/CommentThread.svelte'; import PhaseTasks from '$lib/components/phases/PhaseTasks.svelte'; + import { goto } from '$app/navigation'; import { relativeTime, wikiLinksToMarkdown, markdownToWikiLinks, cleanBrokenLinks } from '$lib/utils/markdown'; import { toastStore } from '$lib/stores/toast.svelte'; import type { Item, Collection, CollectionSettings } from '$lib/types'; import { parseFields, parseSchema, parseSettings, formatItemRef } from '$lib/types'; - let wsSlug = $derived(page.params.workspace); - let collSlug = $derived(page.params.collection); - let itemSlug = $derived(page.params.slug); + let wsSlug = $derived(page.params.workspace ?? ''); + let collSlug = $derived(page.params.collection ?? ''); + let itemSlug = $derived(page.params.slug ?? ''); let item = $state(null); let collection = $state(null); @@ -45,6 +46,8 @@ let saveStatus = $state<'idle' | 'saving' | 'saved'>('idle'); let saveStatusTimer: ReturnType | undefined; let showHistory = $state(false); + let confirmDelete = $state(false); + let deleting = $state(false); $effect(() => { if (wsSlug && collSlug && itemSlug) { @@ -193,6 +196,20 @@ item = updatedItem; showHistory = false; } + + async function handleDelete() { + if (!item) return; + deleting = true; + try { + await api.items.delete(wsSlug, item.slug); + toastStore.show('Item deleted', 'success'); + goto(`/${wsSlug}/${collSlug}`); + } catch { + toastStore.show('Failed to delete item', 'error'); + deleting = false; + confirmDelete = false; + } + } {#if loading} @@ -240,13 +257,30 @@ {:else if saveStatus === 'saved'} ✓ Saved {/if} - +
+ + {#if confirmDelete} + + Delete this item? + + + + {:else} + + {/if} +
@@ -549,8 +583,13 @@ } /* History */ - .history-btn { + .meta-actions { margin-left: auto; + display: flex; + align-items: center; + gap: var(--space-2); + } + .history-btn { padding: 2px var(--space-3); background: var(--bg-secondary); border: 1px solid var(--border); @@ -569,6 +608,43 @@ border-color: var(--accent-blue); color: #fff; } + .delete-btn:hover { + color: var(--accent-orange); + border-color: var(--accent-orange); + } + .delete-confirm { + display: flex; + align-items: center; + gap: var(--space-2); + font-size: 0.85em; + color: var(--accent-orange); + font-weight: 500; + } + .delete-confirm-btn { + padding: 2px var(--space-2); + border-radius: var(--radius); + font-size: 0.85em; + cursor: pointer; + border: 1px solid var(--border); + background: var(--bg-secondary); + color: var(--text-secondary); + } + .delete-confirm-btn.yes { + color: var(--accent-orange); + border-color: var(--accent-orange); + } + .delete-confirm-btn.yes:hover { + background: var(--accent-orange); + color: #fff; + } + .delete-confirm-btn.no:hover { + background: var(--bg-tertiary); + color: var(--text-primary); + } + .delete-confirm-btn:disabled { + opacity: 0.5; + cursor: not-allowed; + } .modal-backdrop { position: fixed; inset: 0;