diff --git a/ALPINE_COMPLETION_GUIDE.md b/ALPINE_COMPLETION_GUIDE.md new file mode 100644 index 0000000..5424437 --- /dev/null +++ b/ALPINE_COMPLETION_GUIDE.md @@ -0,0 +1,1354 @@ +# Alpine.js Integration Completion Guide + +## Executive Summary + +This guide completes the migration from **hybrid onclick/@click with manual DOM manipulation** to **full reactive Alpine.js** with state-driven UI. + +**Current State**: Hybrid approach with 121 manual DOM manipulations +**Target State**: Full reactive Alpine.js with zero manual DOM manipulation +**Estimated Time**: 10-12 hours +**Impact**: Cleaner code, better maintainability, smoother UX + +--- + +## Table of Contents + +1. [Current State Analysis](#current-state-analysis) +2. [Migration Strategy](#migration-strategy) +3. [Phase 1: Header Template (Reference Implementation)](#phase-1-header-template-reference-implementation) +4. [Phase 2: Modal Templates](#phase-2-modal-templates) +5. [Phase 3: Verification & Testing](#phase-3-verification--testing) +6. [Phase 4: Cleanup](#phase-4-cleanup) +7. [Troubleshooting](#troubleshooting) +8. [Success Criteria](#success-criteria) + +--- + +## Current State Analysis + +### What's Already Done ✅ + +- All `onclick` handlers converted to `@click` directives +- Functions registered with `Alpine.global()` in TypeScript +- 18 templates have `x-data="namespace"` attributes +- HTMX integration working for forms + +### What's Still Missing ❌ + +**Problem**: 121 instances of manual DOM manipulation in TypeScript files + +**Example from header.ts:7-17:** +```typescript +const toggleThemeDropdown = (): void => { + const dropdown = document.getElementById("theme-dropdown"); + if (dropdown) { + dropdown.classList.toggle("hidden"); // ← Manual DOM manipulation! + const userMenu = document.getElementById("user-menu"); + if (userMenu && !dropdown.classList.contains("hidden")) { + userMenu.classList.add("hidden"); // ← Manual DOM manipulation! + } + } +}; +``` + +**Templates still using:** +- `id="theme-dropdown"` + `class="hidden"` for show/hide +- No reactive state variables +- No `x-show` directives +- No `@click.outside` for closing dropdowns +- No `x-transition` for animations + +### What Needs Migration + +**8 stateful templates** (modals, dropdowns, wizards): + +1. ✅ **header.templ** - Theme dropdown + user menu (P0 - used in 17 places) +2. ✅ **collection_modal.templ** - Create/edit collection modal +3. ✅ **collections.templ** - Add books modal + navigation +4. ✅ **conflicts.templ** - Conflict resolution modal +5. ✅ **queue.templ** - Queue actions modal +6. ✅ **admin.templ** - Scan progress modal +7. ✅ **devices.templ** - Device token modal +8. ✅ **profile_modal.templ** - Profile edit modal + +**Note**: Simple buttons with `@click` handlers are fine - no migration needed. + +--- + +## Migration Strategy + +### The Pattern + +Every migration follows the same 4-step pattern: + +1. **Template Changes**: Add `x-data` state, replace `class="hidden"` with `x-show`, add transitions +2. **TypeScript Cleanup**: Remove manual DOM manipulation functions +3. **Alpine Registration**: Remove deleted functions from `Alpine.global()` +4. **Testing**: Verify functionality, build, check for regressions + +### Key Principles + +- **State lives in template** (`x-data="{ open: false }"`) +- **UI updates automatically** (`x-show="open"`) +- **No manual DOM manipulation** in TypeScript +- **Pure business logic only** in TypeScript functions + +--- + +## Phase 1: Header Template (Reference Implementation) + +**Priority**: P0 (highest - used in 17 templates) +**Time**: 2-3 hours +**Complexity**: High (2 dropdowns + theme switching + click-outside) + +### Step 1.1: Update header.templ + +**Location**: `templates/header.templ` +**Lines to modify**: 46-191 + +**Current Structure (lines 46-53):** +```templ +
+ +