From 5b7540be99f07a528adddea80f4aad38c4823ebf Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Fri, 13 Mar 2026 12:50:47 -0400 Subject: [PATCH] docs: update Alpine.js migration guide and project guidelines - Fix incorrect function references in ALPINE_COMPLETION_GUIDE.md - header.changeThemeTo -> changeTheme - header.logout -> logout - woodPaneling.change -> changeWoodPaneling - Add SSR-first principles section to PROJECT_GUIDELINES.md - Add page type classifications (Type 1, 2, 3) - Fix extra asterisks on line 43 - Update to reference TypeScript instead of JavaScript --- ALPINE_COMPLETION_GUIDE.md | 978 +++++++++++++++++++++++-------------- PROJECT_GUIDELINES.md | 80 ++- 2 files changed, 678 insertions(+), 380 deletions(-) diff --git a/ALPINE_COMPLETION_GUIDE.md b/ALPINE_COMPLETION_GUIDE.md index 221ab92..f39bb92 100644 --- a/ALPINE_COMPLETION_GUIDE.md +++ b/ALPINE_COMPLETION_GUIDE.md @@ -10,6 +10,7 @@ This guide completes the migration from **hybrid onclick/@click with manual DOM **Impact**: Cleaner code, better maintainability, smoother UX **References:** + - **`SSR_FIRST_ALPINE_GUIDE.md`** - SSR-first architecture principles (READ THIS FIRST) --- @@ -65,6 +66,7 @@ This guide completes the migration from **hybrid onclick/@click with manual DOM **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"); @@ -79,6 +81,7 @@ const toggleThemeDropdown = (): void => { ``` **Templates still using:** + - `id="theme-dropdown"` + `class="hidden"` for show/hide - No reactive state variables - No `x-show` directives @@ -90,7 +93,7 @@ const toggleThemeDropdown = (): void => { **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 +2. 🔄 **collection_modal.templ** - Create/edit collection modal (needs work - see 2.1) 3. ✅ **collections.templ** - Add books modal + navigation 4. ✅ **conflicts.templ** - Conflict resolution modal 5. ✅ **queue.templ** - Queue actions modal @@ -107,6 +110,7 @@ const toggleThemeDropdown = (): void => { ### The Pattern Every migration follows the same 5-step pattern: + 1. **Prerequisites** (Phase 0): Remove dead exports that cause console errors 2. **Template Changes**: Add `x-data` state, replace `class="hidden"` with `x-show`, add transitions 3. **TypeScript Cleanup**: Remove manual DOM manipulation functions @@ -116,12 +120,14 @@ Every migration follows the same 5-step pattern: ### Key Principles **SSR-First (see `SSR_FIRST_ALPINE_GUIDE.md`):** + - ❌ **NEVER fetch data in x-init** if data is already SSR'd - ✅ x-init ONLY for setup (event listeners, modals) - ✅ Data fetch ONLY after user actions (create/delete/update) - ✅ State lives in template (`x-data`), not in TypeScript **Alpine.js Best Practices:** + - **State lives in template** (`x-data="{ open: false }"`) - **UI updates automatically** (`x-show="open"`) - **No manual DOM manipulation** in TypeScript @@ -136,11 +142,14 @@ Every migration follows the same 5-step pattern: ### Why This Phase? When functions are deleted from TypeScript but remain in `Alpine.data()` exports, the browser console shows errors like: -- `addbooksToAdd is not defined` -- `removebooksToAdd is not defined` -- `toggleBookSelection is not defined` -These must be fixed before attempting full migration. +- `addbooksToAdd is not defined` +- `removebooksToAdd is not defined` +- `showAllIcons is not defined` + +**Important**: For the Add Books functionality, these functions should be RESTORED with the proper Alpine/HTMX pattern (see Section 2.2), not just removed. The backend API still exists and should work. + +For other dead exports, they can be removed from Alpine.data if truly not needed. --- @@ -180,7 +189,7 @@ You'll see something like: ```typescript Alpine.data("collections", () => ({ - addbooksToAdd, // ❌ Does NOT exist - deleted + addbooksToAdd, // ❌ Does NOT exist - deleted backToCollections, closeCollectionModal, createRule, @@ -188,24 +197,24 @@ Alpine.data("collections", () => ({ filterCollectionBooks, filterIcons, hideAddBooksModal, - initCollectionDetail, // ❌ Does NOT exist - deleted - initColorSelection, // ❌ Does NOT exist - deleted - initIconSelection, // ❌ Does NOT exist - deleted + initCollectionDetail, // ❌ Does NOT exist - deleted + initColorSelection, // ❌ Does NOT exist - deleted + initIconSelection, // ❌ Does NOT exist - deleted loadCollectionRules, loadCollections, navigateToCollection, populateIconGrid, removeBook, - removebooksToAdd, // ❌ Does NOT exist - deleted + removebooksToAdd, // ❌ Does NOT exist - deleted searchBooksForCollections, selectColor, selectIcon, showAddBooksModal, - showAllIcons, // ❌ Does NOT exist - deleted + showAllIcons, // ❌ Does NOT exist - deleted setupHTMXAuth, testRule, - toggleBookForRemoval, // ❌ Does NOT exist - deleted - toggleBookSelection, // ❌ Does NOT exist - deleted + toggleBookForRemoval, // ❌ Does NOT exist - deleted + toggleBookSelection, // ❌ Does NOT exist - deleted updateSelectedCount, })); ``` @@ -231,6 +240,7 @@ grep -n "^function\|^async function" web/src/collections.ts ``` Expected output (actual existing functions): + - `backToCollections` ✓ - `closeCollectionModal` ✓ - `createRule` ✓ @@ -324,44 +334,19 @@ npm run build:ts **Problem:** Template calls functions that no longer exist. -#### Step 0.3.1: Remove Dead Function Calls from Collection Detail Page +#### Step 0.3.1: Restore Add Books Functionality (Not Remove!) -**Line ~226:** Remove the `removebooksToAdd` call: +**IMPORTANT**: These functions were accidentally deleted in commit 93710a1. The buttons were disabled but the backend API still exists. Instead of removing these, we need to RESTORE them with the proper Alpine/HTMX pattern. -```html - - +**See Section 2.2 for complete instructions on restoring Add Books functionality.** - - -``` +The new pattern uses: +1. Alpine.store for modal visibility +2. HTMX for book search (server-side) +3. HTMX form submission for adding books +4. On success: close modal + refresh books list -**Line ~229:** Remove `addbooksToAdd` call: - -```html - - - - - -``` +**Do NOT disable these buttons - restore the functionality!** #### Step 0.3.2: Regenerate Templates @@ -377,12 +362,14 @@ templ generate ### Step 0.4: Check Other Files for Similar Issues Based on commit 93710a1 and current errors: + - ✅ `web/src/collections.ts` - Fixed above - Check other files for similar issues as you encounter them **General process for any file:** 1. **Identify dead exports:** + ```bash # Check what's exported grep -A25 "Alpine.data" web/src/FILENAME.ts @@ -391,13 +378,13 @@ grep -A25 "Alpine.data" web/src/FILENAME.ts grep -n "^function\|^async function" web/src/FILENAME.ts ``` -2. **Update export statement** to remove dead functions +1. **Update export statement** to remove dead functions -3. **Update Alpine.data registration** to remove dead functions +2. **Update Alpine.data registration** to remove dead functions -4. **Update templates** to remove dead function calls +3. **Update templates** to remove dead function calls -5. **Verify:** `npm run build:ts` and `templ generate` +4. **Verify:** `npm run build:ts` and `templ generate` --- @@ -413,6 +400,7 @@ grep -n "^function\|^async function" web/src/FILENAME.ts **Lines to modify**: 46-191 **Current Structure (lines 46-53):** + ```templ
-
+**Step 1: Add Alpine.store for modal state** + +In `web/src/collections.ts`, add at the top: + +```typescript +// Alpine.store for modal state +Alpine.store("modals", { + addBooks: false, + showAddBooks() { + this.addBooks = true; + }, + hideAddBooks() { + this.addBooks = false; + }, +}); ``` -**Replace with:** -```templ -
- - +**Step 2: Add missing icon picker functions** - - -
- - - + + } ``` @@ -1999,11 +2254,12 @@ Alpine.global("header", { ### A.3: Alpine.store Pattern for Modals **TypeScript (web/src/collections.ts):** + ```typescript import { Alpine } from "./alpine"; // Create global modal store -Alpine.store('modals', { +Alpine.store("modals", { addBooks: false, editCollection: false, @@ -2021,7 +2277,7 @@ Alpine.store('modals', { hideEditCollection() { this.editCollection = false; - } + }, }); // Business logic functions (no DOM manipulation) @@ -2038,6 +2294,7 @@ export { addSelectedBooks, searchBooksForCollections }; ``` **Template (templates/collections.templ):** + ```templ