# 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