Phase 02: Core CRUD - 4 plans in 4 waves - 3 parallel-ready (Wave 1-3 sequential), 1 checkpoint - Ready for execution
7.6 KiB
7.6 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 02-core-crud | 04 | execute | 4 |
|
|
false |
|
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.
<execution_context> @/home/tho/.claude/get-shit-done/workflows/execute-plan.md @/home/tho/.claude/get-shit-done/templates/summary.md </execution_context>
@.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:npm install svelte-gestures
Update EntryCard.svelte to add swipe-to-delete functionality:
- Import the swipe action from svelte-gestures
- Wrap the entry in a swipeable container
- On left swipe, show confirmation then delete
- Add visual feedback (red background revealing during swipe)
- On desktop, keep the delete button in expanded view (swipe is touch-only)
Add to the script section:
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:
<div class="relative overflow-hidden">
<!-- Delete background revealed during swipe -->
<div class="absolute inset-y-0 right-0 w-24 bg-red-500 flex items-center justify-center">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
</div>
<!-- Swipeable entry card -->
<article
use:swipe={{ timeframe: 300, minSwipeDistance: 60, touchAction: 'pan-y' }}
onswipe={handleSwipe}
style="transform: translateX({swipeOffset}px); transition: {swipeOffset === 0 ? 'transform 0.2s' : 'none'}"
class="p-4 border-b border-gray-100 md:border md:rounded-lg md:shadow-sm md:mb-3 bg-white relative"
>
<!-- ... existing entry content ... -->
</article>
<!-- Delete confirmation overlay -->
{#if isConfirmingDelete}
<div
class="absolute inset-0 bg-white/95 flex items-center justify-center gap-4 z-10"
transition:slide={{ duration: 150 }}
>
<button
onclick={cancelDelete}
class="px-4 py-2 text-gray-600 border border-gray-300 rounded-lg touch-target"
>
Cancel
</button>
<button
onclick={confirmDelete}
class="px-4 py-2 bg-red-600 text-white rounded-lg touch-target"
>
Delete
</button>
</div>
{/if}
</div>
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 checkpasses. Start dev server:npm run devOpen 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
-
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)
-
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
- TypeScript:
npm run checkpasses - Swipe gesture: Works on mobile/touch devices
- Touch targets: All interactive elements >= 44x44px
- Font sizes: Base 16px, no text under 14px
- Mobile layout: Compact list, bottom capture bar
- Desktop layout: Card style entries, adequate spacing
Requirements satisfied:
- UX-01: Mobile-friendly ✓
- UX-02: Readable fonts ✓
- UX-03: Cross-browser (SvelteKit handles) ✓
<success_criteria>
- 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 </success_criteria>