F14: add per-activity delete (DELETE /api/activity/{id} + drawer button)
Server endpoint removes the activity JSON, GeoJSON, timeseries, sidecar edit, and images directory. Also purges the dedup cache entry so the file can be re-uploaded if needed. Runs merge_all + rebuild afterwards. EditDrawer: two-click delete button (click once → "Confirm delete?", click again → deletes). On success, dispatches 'deleted' event. ActivityDetail navigates back to the feed on delete.
This commit is contained in:
@@ -112,7 +112,7 @@
|
||||
<svelte:window on:keydown={onKeydown} />
|
||||
|
||||
{#if editOpen && editEnabled}
|
||||
<EditDrawer activityId={activity.id} {editUrl} on:saved={onSaved} on:close={() => editOpen = false} />
|
||||
<EditDrawer activityId={activity.id} {editUrl} on:saved={onSaved} on:close={() => editOpen = false} on:deleted={() => { window.location.href = base; }} />
|
||||
{/if}
|
||||
|
||||
<!-- Lightbox -->
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
export let activityId: string;
|
||||
export let editUrl: string;
|
||||
|
||||
const dispatch = createEventDispatcher<{ saved: { title: string; description: string }; close: void }>();
|
||||
const dispatch = createEventDispatcher<{ saved: { title: string; description: string }; close: void; deleted: void }>();
|
||||
|
||||
const SPORTS: Sport[] = ['cycling', 'running', 'hiking', 'walking', 'swimming', 'skiing', 'other'];
|
||||
const STAT_PANELS = [
|
||||
@@ -21,6 +21,8 @@
|
||||
let saving = false;
|
||||
let saveStatus = '';
|
||||
let saveOk = false;
|
||||
let confirmDelete = false;
|
||||
let deleting = false;
|
||||
|
||||
// Form state
|
||||
let title = '';
|
||||
@@ -120,6 +122,22 @@
|
||||
: [...hideStats, key];
|
||||
}
|
||||
|
||||
async function deleteActivity() {
|
||||
if (!confirmDelete) { confirmDelete = true; return; }
|
||||
deleting = true;
|
||||
try {
|
||||
const res = await fetch(api, { method: 'DELETE' });
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
dispatch('deleted');
|
||||
} catch (e: any) {
|
||||
saveStatus = `Delete failed: ${e.message}`;
|
||||
saveOk = false;
|
||||
confirmDelete = false;
|
||||
} finally {
|
||||
deleting = false;
|
||||
}
|
||||
}
|
||||
|
||||
load();
|
||||
</script>
|
||||
|
||||
@@ -284,11 +302,26 @@
|
||||
<div class="px-5 py-4 border-t border-zinc-800 flex items-center gap-3 shrink-0">
|
||||
<button
|
||||
class="px-4 py-2 bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white text-sm font-medium rounded-lg transition-colors"
|
||||
disabled={saving}
|
||||
disabled={saving || deleting}
|
||||
on:click={save}
|
||||
>
|
||||
{saving ? 'Saving…' : 'Save'}
|
||||
</button>
|
||||
<button
|
||||
class="px-3 py-2 text-sm font-medium rounded-lg border transition-colors disabled:opacity-40 ml-auto"
|
||||
class:border-zinc-700={!confirmDelete}
|
||||
class:text-zinc-500={!confirmDelete}
|
||||
class:hover:border-red-600={!confirmDelete}
|
||||
class:hover:text-red-400={!confirmDelete}
|
||||
class:border-red-500={confirmDelete}
|
||||
class:text-red-400={confirmDelete}
|
||||
class:bg-red-950={confirmDelete}
|
||||
disabled={deleting}
|
||||
on:click={deleteActivity}
|
||||
on:blur={() => confirmDelete = false}
|
||||
>
|
||||
{deleting ? 'Deleting…' : confirmDelete ? 'Confirm delete?' : 'Delete'}
|
||||
</button>
|
||||
{#if saveStatus}
|
||||
<span class="text-xs" class:text-green-400={saveOk} class:text-red-400={!saveOk}>
|
||||
{saveStatus}
|
||||
|
||||
Reference in New Issue
Block a user