From 457cd407a8ae415346de760a18e13f32c1c51516 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Thu, 29 Jan 2026 05:27:31 +0100 Subject: [PATCH] docs(02): create phase plan Phase 02: Core CRUD - 4 plans in 4 waves - 3 parallel-ready (Wave 1-3 sequential), 1 checkpoint - Ready for execution --- .planning/ROADMAP.md | 10 +- .planning/phases/02-core-crud/02-01-PLAN.md | 218 ++++++++++ .planning/phases/02-core-crud/02-02-PLAN.md | 368 +++++++++++++++++ .planning/phases/02-core-crud/02-03-PLAN.md | 417 ++++++++++++++++++++ .planning/phases/02-core-crud/02-04-PLAN.md | 255 ++++++++++++ 5 files changed, 1263 insertions(+), 5 deletions(-) create mode 100644 .planning/phases/02-core-crud/02-01-PLAN.md create mode 100644 .planning/phases/02-core-crud/02-02-PLAN.md create mode 100644 .planning/phases/02-core-crud/02-03-PLAN.md create mode 100644 .planning/phases/02-core-crud/02-04-PLAN.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 5f0b3fe..0bc3b79 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -50,13 +50,13 @@ Plans: 6. Quick capture input is visible on main view with one-click submission 7. UI is usable on mobile devices with adequate touch targets 8. Text is readable for older eyes (minimum 16px base font) -**Plans**: TBD +**Plans**: 4 plans Plans: -- [ ] 02-01: TBD -- [ ] 02-02: TBD -- [ ] 02-03: TBD -- [ ] 02-04: TBD +- [ ] 02-01-PLAN.md — Form actions for CRUD operations and accessible base styling +- [ ] 02-02-PLAN.md — Entry list, entry cards, and quick capture components +- [ ] 02-03-PLAN.md — Inline editing with expand/collapse, auto-save, and completed toggle +- [ ] 02-04-PLAN.md — Swipe-to-delete gesture and mobile UX verification ### Phase 3: Images **Goal**: Users can attach, view, and manage images on entries from any device diff --git a/.planning/phases/02-core-crud/02-01-PLAN.md b/.planning/phases/02-core-crud/02-01-PLAN.md new file mode 100644 index 0000000..7bf90f9 --- /dev/null +++ b/.planning/phases/02-core-crud/02-01-PLAN.md @@ -0,0 +1,218 @@ +--- +phase: 02-core-crud +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - src/routes/+page.server.ts + - src/lib/server/db/repository.ts + - src/app.css +autonomous: true + +must_haves: + truths: + - "Form actions accept POST requests for create, update, delete, toggleComplete" + - "Repository has getOrdered method returning tasks-first, newest-within-type" + - "Base font size is 16px (1rem) respecting browser settings" + artifacts: + - path: "src/routes/+page.server.ts" + provides: "SvelteKit form actions for CRUD operations" + exports: ["actions", "load"] + - path: "src/lib/server/db/repository.ts" + provides: "Extended repository with getOrdered method" + contains: "getOrdered" + - path: "src/app.css" + provides: "Base styling for accessibility" + contains: "font-size: 100%" + key_links: + - from: "src/routes/+page.server.ts" + to: "src/lib/server/db/repository.ts" + via: "entryRepository import" + pattern: "import.*entryRepository.*from.*repository" +--- + + +Create SvelteKit form actions for all CRUD operations and establish base styling for accessibility. + +Purpose: Provides the server-side API that all UI components will use, ensuring progressive enhancement (forms work without JavaScript) and establishing accessible typography. + +Output: Form actions (create, update, delete, toggleComplete), extended repository with ordering, base CSS with 16px minimum font. + + + +@/home/tho/.claude/get-shit-done/workflows/execute-plan.md +@/home/tho/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/02-core-crud/02-CONTEXT.md +@.planning/phases/02-core-crud/02-RESEARCH.md +@src/lib/server/db/repository.ts +@src/lib/server/db/schema.ts +@src/routes/+page.server.ts + + + + + + Task 1: Extend repository with getOrdered method + src/lib/server/db/repository.ts + +Add a `getOrdered` method to EntryRepository interface and SQLiteEntryRepository implementation: + +```typescript +getOrdered(options?: { showCompleted?: boolean }): Entry[] +``` + +Behavior: +- If showCompleted is false (default), exclude entries where status='done' +- Order by: type ASC (task before thought alphabetically), then createdAt DESC (newest first) +- Use drizzle-orm operators: `asc`, `ne` (import from drizzle-orm) + +Implementation pattern from research: +```typescript +import { eq, desc, asc, ne } from 'drizzle-orm'; + +getOrdered(options: { showCompleted?: boolean } = {}): Entry[] { + const { showCompleted = false } = options; + + let query = db.select().from(entries); + + if (!showCompleted) { + query = query.where(ne(entries.status, 'done')); + } + + return query + .orderBy(asc(entries.type), desc(entries.createdAt)) + .all(); +} +``` + + +Run TypeScript check: `npm run check` passes without errors. +Test manually: Start dev server, database should still work with existing getAll method. + + Repository has getOrdered method that filters completed entries and orders tasks-first, newest-within-type + + + + Task 2: Create form actions for CRUD operations + src/routes/+page.server.ts + +Replace current page.server.ts with full CRUD form actions. Keep the existing load function but modify to use getOrdered. + +Actions to implement: + +1. **create**: Accept title (optional), content (required), type (task|thought, default thought) + - Validate content not empty + - Return { success: true, entryId } on success + - Return fail(400, { error, title, content, type }) on validation failure + +2. **update**: Accept id (required), plus any of: title, content, type, status + - Return fail(400) if no id + - Return fail(404) if entry not found + - Return { success: true } on success + +3. **delete**: Accept id (required) + - Return fail(400) if no id + - Return fail(404) if entry not found + - Return { success: true } on success + +4. **toggleComplete**: Accept id (required) + - Toggle status between 'open' and 'done' + - Return fail(400) if no id + - Return { success: true } on success + +Import `fail` from '@sveltejs/kit'. +Import `entryRepository` from '$lib/server/db/repository'. + +Update load function: +- Use getOrdered() instead of getAll() +- Pass showCompleted: false for now (will be dynamic later) + + +Run `npm run check` - TypeScript passes. +Test with curl: +```bash +# Create +curl -X POST http://localhost:5173/?/create -d "content=Test entry&type=task" +# Should return redirect (SvelteKit form action behavior) +``` + + All four form actions (create, update, delete, toggleComplete) exist and handle validation/errors correctly + + + + Task 3: Establish accessible base styling + src/app.css + +Update app.css to establish accessible base typography: + +```css +@import 'tailwindcss'; + +/* Ensure minimum 16px base for accessibility (UX-02) */ +html { + font-size: 100%; /* 16px default, respects user browser settings */ +} + +body { + font-size: 1rem; /* 16px minimum */ + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Safe area padding for mobile devices with notches */ +.safe-bottom { + padding-bottom: env(safe-area-inset-bottom, 0px); +} + +/* Utility for adequate touch targets (44x44px minimum per WCAG) */ +.touch-target { + min-height: 44px; + min-width: 44px; +} +``` + +This ensures: +- Base font respects user's browser zoom settings (100% = 16px default) +- All text uses rem, so user scaling works +- Mobile safe areas handled for bottom capture bar +- Touch target utility class available + + +Start dev server: `npm run dev` +Open in browser, inspect html element - font-size should be 100%. +Inspect body - font-size should be 1rem (16px computed). + + Base CSS establishes 16px minimum font, safe area insets, and touch target utility + + + + + +After all tasks complete: + +1. **TypeScript**: `npm run check` passes +2. **Dev server**: `npm run dev` starts without errors +3. **Repository**: getOrdered method exists and returns entries in correct order +4. **Form actions**: All four actions exist in +page.server.ts +5. **CSS**: Base font is 16px (1rem), safe-bottom and touch-target classes defined + + + +- Repository has getOrdered(options?) method with showCompleted filter and tasks-first ordering +- Form actions handle create (with validation), update, delete, and toggleComplete +- Base CSS ensures 16px minimum font and provides mobile-friendly utilities +- TypeScript compilation passes +- All requirements groundwork laid: CORE-01 through CORE-06, UX-02 + + + +After completion, create `.planning/phases/02-core-crud/02-01-SUMMARY.md` + diff --git a/.planning/phases/02-core-crud/02-02-PLAN.md b/.planning/phases/02-core-crud/02-02-PLAN.md new file mode 100644 index 0000000..855303b --- /dev/null +++ b/.planning/phases/02-core-crud/02-02-PLAN.md @@ -0,0 +1,368 @@ +--- +phase: 02-core-crud +plan: 02 +type: execute +wave: 2 +depends_on: [02-01] +files_modified: + - src/lib/components/EntryList.svelte + - src/lib/components/EntryCard.svelte + - src/lib/components/QuickCapture.svelte + - src/lib/stores/preferences.svelte.ts + - src/routes/+page.svelte + - package.json +autonomous: true + +must_haves: + truths: + - "User sees a list of entries on the main page" + - "User can type in quick capture bar and create an entry" + - "Entries show type indicator (task vs thought)" + - "Quick capture bar is fixed at bottom of screen" + artifacts: + - path: "src/lib/components/EntryList.svelte" + provides: "Entry list rendering with ordering" + min_lines: 20 + - path: "src/lib/components/EntryCard.svelte" + provides: "Single entry display with type indicator" + min_lines: 30 + - path: "src/lib/components/QuickCapture.svelte" + provides: "Bottom capture bar with form" + min_lines: 40 + - path: "src/lib/stores/preferences.svelte.ts" + provides: "Persisted user preferences store" + contains: "lastEntryType" + - path: "src/routes/+page.svelte" + provides: "Main page composing components" + contains: "EntryList" + key_links: + - from: "src/routes/+page.svelte" + to: "src/lib/components/EntryList.svelte" + via: "component import" + pattern: "import EntryList" + - from: "src/lib/components/QuickCapture.svelte" + to: "src/routes/+page.server.ts" + via: "form action ?/create" + pattern: "action=.*\\?/create" +--- + + +Build the main UI components: entry list, entry cards, and quick capture bar. + +Purpose: Users can see their entries and create new ones via the quick capture bar fixed at the bottom of the screen. + +Output: EntryList, EntryCard, QuickCapture components plus preferences store. Main page renders all entries with quick capture. + + + +@/home/tho/.claude/get-shit-done/workflows/execute-plan.md +@/home/tho/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/02-core-crud/02-CONTEXT.md +@.planning/phases/02-core-crud/02-RESEARCH.md +@.planning/phases/02-core-crud/02-01-SUMMARY.md +@src/routes/+page.server.ts +@src/lib/server/db/schema.ts + + + + + + Task 1: Install dependencies and create preferences store + package.json, src/lib/stores/preferences.svelte.ts + +Install svelte-persisted-store for sticky preferences: + +```bash +npm install svelte-persisted-store +``` + +Create preferences store at src/lib/stores/preferences.svelte.ts: + +```typescript +import { persisted } from 'svelte-persisted-store'; + +export const preferences = persisted('taskplaner-preferences', { + lastEntryType: 'thought' as 'task' | 'thought', + showCompleted: false +}); +``` + +This store: +- Persists to localStorage automatically +- Remembers last used entry type for quick capture +- Tracks show/hide completed preference + +Create the stores directory if it doesn't exist. + + +npm install completes without errors. +TypeScript check: `npm run check` passes. + + svelte-persisted-store installed, preferences store created with lastEntryType and showCompleted + + + + Task 2: Create EntryCard and EntryList components + src/lib/components/EntryCard.svelte, src/lib/components/EntryList.svelte + +Create src/lib/components directory if needed. + +**EntryCard.svelte** - Single entry display: + +```svelte + + +
+
+ {#if entry.type === 'task'} +
+ + +
+ {:else} + + T + + {/if} + +
+

+ {entry.title || 'Untitled'} +

+

+ {entry.content} +

+
+ + + {entry.type} + +
+
+``` + +**EntryList.svelte** - List of entries: + +```svelte + + +{#if entries.length === 0} +
+

No entries yet

+

Use the capture bar below to add your first entry

+
+{:else} +
+ {#each entries as entry (entry.id)} + + {/each} +
+{/if} +``` + +Key features: +- Type indicator: checkbox for tasks, purple "T" badge for thoughts +- Type badge in corner (blue for task, purple for thought) +- Completed tasks have strikethrough +- Mobile compact (border-b), desktop cards (rounded, shadow) +- Touch-friendly checkbox (44px touch target via touch-target class) +
+ +TypeScript check: `npm run check` passes. +Files exist: src/lib/components/EntryCard.svelte, src/lib/components/EntryList.svelte + + EntryCard shows entry with type indicator and completion toggle. EntryList renders all entries. +
+ + + Task 3: Create QuickCapture component and integrate into main page + src/lib/components/QuickCapture.svelte, src/routes/+page.svelte + +**QuickCapture.svelte** - Bottom capture bar: + +```svelte + + +
{ + return async ({ result, update }) => { + if (result.type === 'success') { + // Update preference + $preferences.lastEntryType = type; + // Clear form + title = ''; + content = ''; + // Let SvelteKit refresh data + } + await update(); + }; + }} + class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 shadow-lg safe-bottom" +> +
+
+ +
+ +
+ + +
+
+
+
+
+``` + +**+page.svelte** - Main page: + +```svelte + + + + TaskPlaner + + +
+
+
+

TaskPlaner

+
+
+ +
+ +
+ + +
+``` + +Key features: +- Fixed bottom capture bar with safe area insets +- Type selector remembers last used type +- Clear form on successful submit +- Adequate padding at bottom (pb-40) so entries aren't hidden by capture bar +- Progressive enhancement: works without JS, enhanced with use:enhance +
+ +Start dev server: `npm run dev` +Open http://localhost:5173 +- Entry list should display (may be empty) +- Quick capture bar should be fixed at bottom +- Creating an entry should work and appear in list +- Type preference should stick across page refreshes + + Quick capture bar creates entries. Main page shows entry list with proper bottom padding. Type preference persists. +
+ +
+ + +After all tasks complete: + +1. **TypeScript**: `npm run check` passes +2. **Dev server**: `npm run dev` starts without errors +3. **UI visible**: Entry list renders, quick capture bar at bottom +4. **Create entry**: Fill in content, click Add - entry appears in list +5. **Type indicator**: Tasks show checkbox, thoughts show purple badge +6. **Task toggle**: Clicking checkbox marks task complete (strikethrough) +7. **Type preference**: Select "task", create entry, refresh page - type selector still shows "task" + +Requirements satisfied: +- CORE-01: Can create entry ✓ +- CORE-04: Can specify type ✓ +- CORE-05: Can mark task complete ✓ +- CAPT-01, CAPT-02, CAPT-03: Quick capture works ✓ + + + +- EntryList and EntryCard components render entries with type indicators +- QuickCapture component creates entries via form action +- Type preference persists in localStorage +- Main page composes all components with proper layout +- TypeScript compilation passes + + + +After completion, create `.planning/phases/02-core-crud/02-02-SUMMARY.md` + diff --git a/.planning/phases/02-core-crud/02-03-PLAN.md b/.planning/phases/02-core-crud/02-03-PLAN.md new file mode 100644 index 0000000..57a237a --- /dev/null +++ b/.planning/phases/02-core-crud/02-03-PLAN.md @@ -0,0 +1,417 @@ +--- +phase: 02-core-crud +plan: 03 +type: execute +wave: 3 +depends_on: [02-02] +files_modified: + - src/lib/components/EntryCard.svelte + - src/lib/components/CompletedToggle.svelte + - src/routes/+page.svelte + - src/routes/+page.server.ts +autonomous: true + +must_haves: + truths: + - "Clicking an entry expands it to show edit fields" + - "Editing title or content auto-saves after typing stops" + - "User can toggle show/hide completed tasks" + - "User can change entry type after creation" + artifacts: + - path: "src/lib/components/EntryCard.svelte" + provides: "Expandable entry with inline editing" + contains: "expanded" + - path: "src/lib/components/CompletedToggle.svelte" + provides: "Toggle for showing completed tasks" + min_lines: 15 + - path: "src/routes/+page.svelte" + provides: "Main page with completed toggle" + contains: "CompletedToggle" + key_links: + - from: "src/lib/components/EntryCard.svelte" + to: "src/routes/+page.server.ts" + via: "form action ?/update" + pattern: "action=.*\\?/update" +--- + + +Implement inline editing with expand/collapse and auto-save, plus completed tasks toggle. + +Purpose: Users can click an entry to expand and edit it in place. Changes save automatically as they type (debounced). Completed tasks can be shown/hidden. + +Output: Expandable EntryCard with auto-save, CompletedToggle component, updated page with toggle integration. + + + +@/home/tho/.claude/get-shit-done/workflows/execute-plan.md +@/home/tho/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/02-core-crud/02-CONTEXT.md +@.planning/phases/02-core-crud/02-RESEARCH.md +@.planning/phases/02-core-crud/02-02-SUMMARY.md +@src/lib/components/EntryCard.svelte +@src/routes/+page.svelte +@src/routes/+page.server.ts + + + + + + Task 1: Add expand/collapse and inline editing to EntryCard + src/lib/components/EntryCard.svelte + +Update EntryCard to support expand/collapse with inline editing and debounced auto-save. + +Key changes: +1. Add `expanded` state variable +2. When collapsed, show title + truncated content (current behavior) +3. When expanded, show editable fields: title input, content textarea, type selector +4. Auto-save changes with 400ms debounce using fetch to ?/update +5. Use Svelte's slide transition for smooth expand/collapse + +```svelte + + +
+ + + + {:else} + + T + + {/if} + +
+

+ {entry.title || 'Untitled'} +

+ {#if !expanded} +

+ {entry.content} +

+ {/if} +
+ +
+ {#if isSaving} + Saving... + {/if} + + {entry.type} + + + + +
+ + + + {#if expanded} +
+
+ + +
+ +
+ + +
+ +
+
+ + +
+ +
+ + +
+
+
+ {/if} +
+``` + +Features: +- Click anywhere on header to expand/collapse +- Checkbox click doesn't trigger expand (stopPropagation) +- Smooth slide transition +- 400ms debounce on input changes +- "Saving..." indicator during save +- Delete with confirmation dialog +- Type can be changed after creation +
+ +Start dev server: `npm run dev` +- Click an entry - should expand +- Edit title or content - should see "Saving..." briefly +- Click again - should collapse +- Change type - should save +- Delete - should prompt for confirmation + + EntryCard expands/collapses with inline editing and 400ms debounced auto-save +
+ + + Task 2: Create CompletedToggle component and wire up showCompleted + src/lib/components/CompletedToggle.svelte, src/routes/+page.svelte, src/routes/+page.server.ts + +**CompletedToggle.svelte** - Toggle for showing/hiding completed tasks: + +```svelte + + + +``` + +**Update +page.server.ts** - Accept showCompleted parameter: + +Modify the load function to accept a URL search param: + +```typescript +export const load: PageServerLoad = async ({ url }) => { + const showCompleted = url.searchParams.get('showCompleted') === 'true'; + const entries = entryRepository.getOrdered({ showCompleted }); + return { entries, showCompleted }; +}; +``` + +**Update +page.svelte** - Add toggle and use invalidateAll for refresh: + +```svelte + + + + TaskPlaner + + +
+
+
+

TaskPlaner

+ +
+
+ +
+ +
+ + +
+``` + +Note: The preference syncs with URL so the server can filter correctly. When toggle changes, URL updates and data reloads. +
+ +Start dev server: `npm run dev` +- Create a task, mark it complete +- Should disappear from list +- Check "Show completed" - completed task should appear +- Refresh page - toggle state should persist + + CompletedToggle shows/hides completed tasks, state persists in preferences and URL +
+ +
+ + +After all tasks complete: + +1. **TypeScript**: `npm run check` passes +2. **Expand/collapse**: Click entry to expand, click again to collapse +3. **Inline editing**: Title, content, type can be edited in expanded view +4. **Auto-save**: Editing shows "Saving..." then saves (no need to click save) +5. **Delete**: Delete button in expanded view with confirmation +6. **Completed toggle**: Checkbox in header shows/hides completed tasks +7. **Persistence**: Toggle state persists across page refreshes + +Requirements satisfied: +- CORE-02: Edit entry ✓ +- CORE-03: Delete entry ✓ (with confirmation) +- CORE-06: Add notes (append to content) ✓ + + + +- EntryCard expands on click to show edit fields +- Changes auto-save with 400ms debounce +- Delete button with confirmation dialog +- CompletedToggle shows/hides completed tasks +- Toggle state persists in localStorage +- TypeScript compilation passes + + + +After completion, create `.planning/phases/02-core-crud/02-03-SUMMARY.md` + diff --git a/.planning/phases/02-core-crud/02-04-PLAN.md b/.planning/phases/02-core-crud/02-04-PLAN.md new file mode 100644 index 0000000..8d9b4ce --- /dev/null +++ b/.planning/phases/02-core-crud/02-04-PLAN.md @@ -0,0 +1,255 @@ +--- +phase: 02-core-crud +plan: 04 +type: execute +wave: 4 +depends_on: [02-03] +files_modified: + - src/lib/components/EntryCard.svelte + - package.json +autonomous: false + +must_haves: + truths: + - "User can swipe left on mobile to delete an entry" + - "Touch targets are at least 44x44px" + - "UI is usable on mobile devices (tested)" + - "Delete via swipe shows confirmation before deleting" + artifacts: + - path: "src/lib/components/EntryCard.svelte" + provides: "Swipe-to-delete functionality" + contains: "svelte-gestures" + - path: "package.json" + provides: "svelte-gestures dependency" + contains: "svelte-gestures" + key_links: + - from: "src/lib/components/EntryCard.svelte" + to: "src/routes/+page.server.ts" + via: "form action ?/delete" + pattern: "action=.*\\?/delete" +--- + + +Implement swipe-to-delete gesture for mobile and verify overall mobile UX. + +Purpose: Mobile users can swipe left to delete entries (common mobile pattern). Final verification ensures all touch targets meet WCAG guidelines and UI works well on mobile. + +Output: Swipe-to-delete on EntryCard, verified mobile-friendly UI. + + + +@/home/tho/.claude/get-shit-done/workflows/execute-plan.md +@/home/tho/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/02-core-crud/02-CONTEXT.md +@.planning/phases/02-core-crud/02-RESEARCH.md +@.planning/phases/02-core-crud/02-03-SUMMARY.md +@src/lib/components/EntryCard.svelte + + + + + + Task 1: Install svelte-gestures and implement swipe-to-delete + package.json, src/lib/components/EntryCard.svelte + +Install svelte-gestures: + +```bash +npm install svelte-gestures +``` + +Update EntryCard.svelte to add swipe-to-delete functionality: + +1. Import the swipe action from svelte-gestures +2. Wrap the entry in a swipeable container +3. On left swipe, show confirmation then delete +4. Add visual feedback (red background revealing during swipe) +5. On desktop, keep the delete button in expanded view (swipe is touch-only) + +Add to the script section: + +```typescript +import { swipe } from 'svelte-gestures'; + +// Swipe state +let swipeOffset = $state(0); +let isConfirmingDelete = $state(false); + +function handleSwipe(event: CustomEvent) { + const { direction } = event.detail; + if (direction === 'left') { + // Show confirmation + isConfirmingDelete = true; + } +} + +function handleSwipeMove(event: CustomEvent) { + // Visual feedback during swipe + const { offsetX } = event.detail; + if (offsetX < 0) { + swipeOffset = Math.max(offsetX, -100); // Cap at -100px + } +} + +function handleSwipeEnd() { + if (!isConfirmingDelete) { + swipeOffset = 0; + } +} + +function cancelDelete() { + isConfirmingDelete = false; + swipeOffset = 0; +} + +async function confirmDelete() { + const formData = new FormData(); + formData.append('id', entry.id); + + await fetch('?/delete', { + method: 'POST', + body: formData + }); + + // Refresh page to show updated list + window.location.reload(); +} +``` + +Update the template to wrap in a swipeable container: + +```svelte +
+ +
+ + + +
+ + +
+ +
+ + + {#if isConfirmingDelete} +
+ + +
+ {/if} +
+``` + +Key behaviors: +- Swipe left reveals red delete icon +- If swipe distance > 60px, show confirmation overlay +- Confirmation has Cancel and Delete buttons +- On desktop, swipe doesn't trigger (touch-only) +- Delete button in expanded view still works for desktop users +
+ +npm install completes. +TypeScript check: `npm run check` passes. +Start dev server: `npm run dev` +Open in browser dev tools mobile view: +- Swipe left on an entry +- Red background should reveal +- Release after 60px+ swipe shows confirmation +- Cancel returns to normal, Delete removes entry + + Swipe-to-delete works on mobile with confirmation overlay +
+ + + +Complete Phase 2 UI with: +- Entry list showing tasks and thoughts +- Quick capture bar at bottom +- Inline editing with auto-save +- Swipe-to-delete on mobile +- Show/hide completed toggle +- Mobile-responsive layout + + +1. **Desktop verification** (http://localhost:5173): + - Create a task via quick capture - should appear in list + - Create a thought - should appear with purple indicator + - Click an entry - should expand with edit fields + - Edit title/content - should auto-save (see "Saving...") + - Mark a task complete - checkbox should fill, task may disappear + - Check "Show completed" - completed task reappears + - Delete an entry via expanded view - should prompt then remove + +2. **Mobile verification** (use browser dev tools mobile mode OR actual phone): + - Quick capture bar should be at bottom, thumb-friendly + - Type selector and Add button should be reachable + - Entries should be tappable to expand + - Swipe left on an entry - red trash icon reveals + - Complete swipe - confirmation appears + - Tap Delete - entry removed + - Touch targets feel adequately sized (not too small) + - Text is readable (not tiny) + +3. **Font/Accessibility**: + - Base text should be at least 16px + - No text smaller than 14px anywhere + - Buttons and checkboxes are easy to tap + + Type "approved" if all checks pass, or describe any issues found + + +
+ + +After all tasks complete: + +1. **TypeScript**: `npm run check` passes +2. **Swipe gesture**: Works on mobile/touch devices +3. **Touch targets**: All interactive elements >= 44x44px +4. **Font sizes**: Base 16px, no text under 14px +5. **Mobile layout**: Compact list, bottom capture bar +6. **Desktop layout**: Card style entries, adequate spacing + +Requirements satisfied: +- UX-01: Mobile-friendly ✓ +- UX-02: Readable fonts ✓ +- UX-03: Cross-browser (SvelteKit handles) ✓ + + + +- Swipe-to-delete works on mobile with confirmation +- All touch targets meet WCAG 44x44px minimum +- UI verified working on both desktop and mobile +- User approves the UI at checkpoint +- All Phase 2 requirements complete + + + +After completion, create `.planning/phases/02-core-crud/02-04-SUMMARY.md` +