diff --git a/PHASE_9_PLAN.md b/PHASE_9_PLAN.md new file mode 100644 index 0000000..e2504b8 --- /dev/null +++ b/PHASE_9_PLAN.md @@ -0,0 +1,923 @@ +# SimpleShop Theme - Phase 9 Implementation Plan + +## Overview + +This plan covers **Phase 9: Storefront Integration** - applying the theme system to the actual public-facing shop. Based on my analysis, Phases 1-8 are complete, with a fully functional theme editor at `/admin/theme`. Phase 9 will create the public storefront that uses the saved theme settings. + +## Current State Summary + +✅ **Completed (Phases 1-8):** +- Settings and Media contexts with SQLite storage +- CSS three-layer architecture (primitives, attributes, semantic) +- Theme editor LiveView with 8 presets +- All 7 preview pages (home, collection, pdp, cart, about, contact, error) +- Full customization controls (mood, typography, shape, density, colors, layout, toggles) +- Logo and header image uploads with BLOB storage +- SVG recoloring functionality +- CSS generation system +- Preview data system (mock products, testimonials, categories) + +❌ **Not Started (Phase 9):** +- Public storefront routes +- Storefront LiveViews +- Theme CSS injection for public pages +- Plug to load theme settings +- CSS cache warming +- Real product integration + +## Architecture Decisions + +### 1. Routing Strategy +- **Public routes**: Use root-level paths (`/`, `/products/:slug`, `/cart`, etc.) +- **No shop slug**: Since this app IS the shop (not multi-tenant), no slug needed +- **Future-proof**: Structure allows adding multi-shop support later if needed + +### 2. LiveView Structure +- **Reuse preview templates**: The preview pages are already production-ready +- **Extract to shared components**: Move reusable pieces from preview_pages/ to components/ +- **Storefront-specific LiveViews**: Create dedicated LiveViews that handle real data + +### 3. CSS Application +- **Same three-layer system**: Use identical CSS as theme editor +- **Root element**: Use `.shop-root` class with data attributes +- **Inline CSS injection**: Inject generated CSS into layout via assign +- **ETS caching**: Use CSSCache for production performance +- **Cache invalidation**: Invalidate on theme settings save + +### 4. Data Handling +- **Smart degradation**: Show empty states when no products exist +- **Graceful fallback**: Use preview data patterns for missing content +- **Real products**: When Products context exists, use real data + +## Implementation Steps + +### Step 1: Extract Shared Components + +**Goal**: Move reusable preview components to shared location for use in both admin and storefront + +**Files to create:** +- `lib/simpleshop_theme_web/components/shop/announcement_bar.ex` +- `lib/simpleshop_theme_web/components/shop/header.ex` +- `lib/simpleshop_theme_web/components/shop/footer.ex` +- `lib/simpleshop_theme_web/components/shop/search_modal.ex` +- `lib/simpleshop_theme_web/components/shop/product_card.ex` + +**Files to modify:** +- `lib/simpleshop_theme_web/live/theme_live/preview_pages.ex` - Import and use new components +- All preview templates - Update to use new component modules + +**Actions:** +1. Create `lib/simpleshop_theme_web/components/shop/` directory +2. Extract `announcement_bar/1` from preview_pages.ex to `shop/announcement_bar.ex` +3. Extract `shop_header/1` to `shop/header.ex` +4. Extract `shop_footer/1` to `shop/footer.ex` +5. Extract `search_modal/1` to `shop/search_modal.ex` +6. Create new `product_card/1` component (used in multiple places) +7. Update preview_pages.ex to import and use new components +8. Update all 7 preview templates to use new component paths +9. Test theme editor still works correctly + +**Validation:** +- Run `mix test test/simpleshop_theme_web/live/theme_live_test.exs` +- Visit `/admin/theme` and verify all 7 preview pages still render correctly +- No visual regressions + +--- + +### Step 2: Create LoadTheme Plug + +**Goal**: Create a plug that loads theme settings and generated CSS for every public request + +**Files to create:** +- `lib/simpleshop_theme_web/plugs/load_theme.ex` +- `test/simpleshop_theme_web/plugs/load_theme_test.exs` + +**Plug functionality:** +```elixir +defmodule SimpleshopThemeWeb.Plugs.LoadTheme do + import Plug.Conn + alias SimpleshopTheme.Settings + alias SimpleshopTheme.Theme.{CSSGenerator, CSSCache} + + def init(opts), do: opts + + def call(conn, _opts) do + # Try cache first + {theme_settings, generated_css} = + case CSSCache.get() do + {:ok, css} -> + {Settings.get_theme_settings(), css} + :miss -> + settings = Settings.get_theme_settings() + css = CSSGenerator.generate(settings) + CSSCache.put(css) + {settings, css} + end + + conn + |> assign(:theme_settings, theme_settings) + |> assign(:generated_css, generated_css) + end +end +``` + +**Files to modify:** +- `lib/simpleshop_theme_web/router.ex` - Add plug to public pipeline + +**Actions:** +1. Create plug file with init/1 and call/2 functions +2. Implement cache-first CSS loading strategy +3. Assign both `:theme_settings` and `:generated_css` to conn +4. Add plug to `:browser` pipeline in router (before routes) +5. Write tests for plug behavior +6. Test cache hit and cache miss scenarios + +**Validation:** +- Run `mix test test/simpleshop_theme_web/plugs/load_theme_test.exs` +- Verify assigns are available in subsequent requests +- Verify CSS is cached and reused + +--- + +### Step 3: Create Storefront Layout + +**Goal**: Create a dedicated layout for the public storefront with theme CSS injection + +**Files to create:** +- `lib/simpleshop_theme_web/components/layouts/shop.html.heex` + +**Layout structure:** +```heex + + + + + + + <.live_title><%= assigns[:page_title] || @theme_settings.site_name %> + + + + + + + +
+ <%= @inner_content %> +
+ + +``` + +**Files to modify:** +- `lib/simpleshop_theme_web/components/layouts.ex` - Add `shop/1` layout function + +**Actions:** +1. Create new shop.html.heex layout file +2. Add `.shop-root` wrapper with all theme data attributes +3. Inject `@generated_css` into `