diff --git a/CAROUSEL_DASHBOARD_PLAN.md b/CAROUSEL_DASHBOARD_PLAN.md index e6bc33d..b8e0d4d 100644 --- a/CAROUSEL_DASHBOARD_PLAN.md +++ b/CAROUSEL_DASHBOARD_PLAN.md @@ -1,6 +1,7 @@ # 🎬 Carousel-Style Dashboard Redesign Plan ## Overview + Transform the current dashboard into a **production-ready** horizontal carousel layout like Audiobookshelf/Kavita, with: - Smart sections (Continue Reading, Recently Added, etc.) - User collections as sections @@ -11,6 +12,27 @@ Transform the current dashboard into a **production-ready** horizontal carousel --- +## ⚠️ Prerequisites: TypeScript Conversion First + +**IMPORTANT:** This plan assumes the **TypeScript Conversion Plan** has been completed first. + +**Required Infrastructure from TypeScript Conversion Plan:** +- ✅ `web/ts/core/api.ts` - Centralized API client with auth +- ✅ `web/ts/core/toast.ts` - Toast notification system +- ✅ `web/ts/shared/events.ts` - Event delegation utilities +- ✅ `web/ts/core/storage.ts` - localStorage wrapper +- ✅ `web/ts/core/dom.ts` - DOM utilities (escapeHtml, etc.) +- ✅ Event delegation pattern established (data attributes) +- ✅ TypeScript compilation pipeline in place (`npm run build:ts`) + +**Execution Order:** +1. Complete TypeScript Conversion Plan (16-21 days) +2. Execute this updated Carousel Dashboard Plan (3-4 days) + +**Timeline:** 19-25 days total (no rework, consistent patterns) + +--- + ## 🏗️ Architecture Compliance ### Project Guidelines Alignment @@ -25,18 +47,20 @@ This plan **adheres to** all PROJECT_GUIDELINES.md requirements with explicit us - New API endpoints for mobile app compatibility - Bruno tests already created in `bruno/dashboard/` -✅ **Frontend Standards**: +✅ **Frontend Standards** (Updated for Post-TypeScript Conversion): - **TailwindCSS classes ONLY** - no custom CSS -- **Inline JavaScript** - matches existing dashboard.templ pattern +- **TypeScript** in `web/ts/features/dashboard/` (no inline JavaScript) - **Procedural/imperative style** - no OOP (classes, inheritance, this-capture) - **SSR for initial data** - no AJAX on page load - **Progressive enhancement** - works without JavaScript - **HTMX for CRUD operations** (library switching, settings updates) +- **Event delegation pattern** - `data-action` attributes (no inline `onclick`) +- **Shared API client** - `apiClient` from `web/ts/core/api.ts` ✅ **Code Organization**: - **Template types in templates/types.go** - SectionData, BookCardData - **All business logic in services** - reusable for SSR/API/mobile -- **Minimal project structure changes** - contextually appropriate directories +- **TypeScript in web/ts/features/dashboard/** - follows TypeScript Conversion Plan structure ✅ **Database Operations**: - **Merge into existing schema.sql** - no migration files @@ -46,9 +70,9 @@ This plan **adheres to** all PROJECT_GUIDELINES.md requirements with explicit us ✅ **API Documentation**: - **Bruno tests** already created in `bruno/dashboard/` -- **Three-context testing** (no user, user, admin) -- **Backward compatibility** for mobile apps -- **docs/developer/api/** documentation updates +- - Three-context testing (no user, user, admin) +- - Backward compatibility for mobile apps +- - `docs/developer/api/** documentation updates --- @@ -403,29 +427,29 @@ frontendProtected.POST("/settings", func(c echo.Context) error { // Update user info _, err = cfg.Queries.UpdateUser(c.Request().Context(), database.UpdateUserParams{ ID: uuidToPGType(userUUID), - Email: pgtype.Text{String: req.Email, Valid: true}, - Username: req.Username, - Theme: pgtype.Text{String: req.Theme, Valid: true}, - FirstName: pgtype.Text{String: req.FirstName, Valid: true}, - LastName: pgtype.Text{String: req.LastName, Valid: true}, -}) + Email: pgtype.Text{String: req.Email, Valid: true}, + Username: req.Username, + Theme: pgtype.Text{String: req.Theme, Valid: true}, + FirstName: pgtype.Text{String: req.FirstName, Valid: true}, + LastName: pgtype.Text{String: req.LastName, Valid: true}, + }) -if err != nil { - return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to update settings"}) -} + if err != nil { + return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to update settings"}) + } // Save dashboard preferences _, err = cfg.DashboardService.UpsertDashboardPreferences(c.Request().Context(), database.UpsertDashboardPreferencesParams{ - UserID: uuidToPGType(userUUID), - LibraryID: uuidToPGType(libUUID), - HiddenSections: req.HiddenSections, - SectionOrder: req.SectionOrder, - ItemsPerSection: pgtype.Int4{Int32: int32(req.ItemsPerSection), Valid: true}, -}) + UserID: uuidToPGType(userUUID), + LibraryID: uuidToPGType(libUUID), + HiddenSections: req.HiddenSections, + SectionOrder: req.SectionOrder, + ItemsPerSection: pgtype.Int4{Int32: int32(req.ItemsPerSection), Valid: true}, + }) -if err != nil { - return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to save preferences"}) -} + if err != nil { + return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to save preferences"}) + } // Return updated user data updatedUser, _ := getTemplateUserWithTheme(c, cfg) @@ -549,7 +573,7 @@ type BookCardData struct { ### **Phase 5: Settings Template** (2 hours) -**COMPLIANCE**: Use template types, TailwindCSS, SSR +**COMPLIANCE**: Use template types, TailwindSSR, SSR **File: `templates/settings.templ`** (new file) @@ -568,7 +592,7 @@ templ Settings(user User, userDB database.Users, dashPrefs database.UserDashboar