Bring in plan for phase 9
This commit is contained in:
parent
6d66d56b62
commit
48b1e0bc96
923
PHASE_9_PLAN.md
Normal file
923
PHASE_9_PLAN.md
Normal file
@ -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
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-full">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="csrf-token" content={get_csrf_token()} />
|
||||||
|
<.live_title><%= assigns[:page_title] || @theme_settings.site_name %></.live_title>
|
||||||
|
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
|
||||||
|
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}></script>
|
||||||
|
|
||||||
|
<!-- Inject theme CSS -->
|
||||||
|
<style id="theme-css">
|
||||||
|
<%= Phoenix.HTML.raw(@generated_css) %>
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="h-full">
|
||||||
|
<div class="shop-root h-full"
|
||||||
|
data-mood={@theme_settings.mood}
|
||||||
|
data-typography={@theme_settings.typography}
|
||||||
|
data-shape={@theme_settings.shape}
|
||||||
|
data-density={@theme_settings.density}
|
||||||
|
data-grid={@theme_settings.grid_columns}
|
||||||
|
data-header={@theme_settings.header_layout}
|
||||||
|
data-sticky={to_string(@theme_settings.sticky_header)}
|
||||||
|
data-layout={@theme_settings.layout_width}
|
||||||
|
data-shadow={@theme_settings.card_shadow}>
|
||||||
|
<%= @inner_content %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
**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 `<style>` tag
|
||||||
|
4. Use `@theme_settings.site_name` for page title default
|
||||||
|
5. Add shop layout function to layouts.ex module
|
||||||
|
6. Ensure Google Fonts are loaded (already in root.html.heex)
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Inspect HTML output to verify data attributes present
|
||||||
|
- Verify CSS injection works
|
||||||
|
- Check that layout compiles without errors
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 4: Create Home Page LiveView
|
||||||
|
|
||||||
|
**Goal**: Create the public homepage LiveView using real/mock data
|
||||||
|
|
||||||
|
**Files to create:**
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/home.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/home.html.heex`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/home_test.exs`
|
||||||
|
|
||||||
|
**LiveView structure:**
|
||||||
|
```elixir
|
||||||
|
defmodule SimpleshopThemeWeb.ShopLive.Home do
|
||||||
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
|
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
# Use real products when available, else preview data
|
||||||
|
products = PreviewData.products()
|
||||||
|
categories = PreviewData.categories()
|
||||||
|
testimonials = PreviewData.testimonials()
|
||||||
|
|
||||||
|
{:ok, assign(socket,
|
||||||
|
page_title: "Home",
|
||||||
|
products: products,
|
||||||
|
categories: categories,
|
||||||
|
testimonials: testimonials
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Template approach:**
|
||||||
|
- Copy structure from `preview_pages/home.html.heex`
|
||||||
|
- Use new shared components (header, footer, announcement_bar)
|
||||||
|
- Remove preview-specific wrapper divs
|
||||||
|
- Ensure data-driven rendering from assigns
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme_web/router.ex` - Add home route
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. Create home LiveView module with mount function
|
||||||
|
2. Load preview data (real products when available)
|
||||||
|
3. Create home template based on preview version
|
||||||
|
4. Use shared components for header, footer, announcement bar
|
||||||
|
5. Add route: `live "/", ShopLive.Home, :index` in public scope
|
||||||
|
6. Set layout to `:shop` for route
|
||||||
|
7. Write tests for home page rendering
|
||||||
|
8. Test with and without products
|
||||||
|
|
||||||
|
**Router changes:**
|
||||||
|
```elixir
|
||||||
|
# Public storefront
|
||||||
|
scope "/", SimpleshopThemeWeb do
|
||||||
|
pipe_through :browser
|
||||||
|
|
||||||
|
live_session :public_shop, layout: {SimpleshopThemeWeb.Layouts, :shop} do
|
||||||
|
live "/", ShopLive.Home, :index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Visit `/` and verify homepage renders
|
||||||
|
- Check theme styles are applied
|
||||||
|
- Test announcement bar toggle works
|
||||||
|
- Verify header layout variations work
|
||||||
|
- Test sticky header toggle
|
||||||
|
- Confirm products display (mock data)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 5: Create Collection Page LiveView
|
||||||
|
|
||||||
|
**Goal**: Create product collection/grid page
|
||||||
|
|
||||||
|
**Files to create:**
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/collection.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/collection.html.heex`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/collection_test.exs`
|
||||||
|
|
||||||
|
**LiveView structure:**
|
||||||
|
```elixir
|
||||||
|
defmodule SimpleshopThemeWeb.ShopLive.Collection do
|
||||||
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
|
|
||||||
|
def mount(%{"slug" => slug}, _session, socket) do
|
||||||
|
# Future: Load real collection by slug
|
||||||
|
# For now: Use preview products filtered by category
|
||||||
|
products = PreviewData.products()
|
||||||
|
|
||||||
|
{:ok, assign(socket,
|
||||||
|
page_title: "Shop All Products",
|
||||||
|
collection_name: "All Products",
|
||||||
|
products: products,
|
||||||
|
filter: nil,
|
||||||
|
sort: "featured"
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("filter", %{"category" => category}, socket) do
|
||||||
|
# Filter products by category
|
||||||
|
{:noreply, assign(socket, filter: category)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("sort", %{"by" => sort_by}, socket) do
|
||||||
|
# Sort products
|
||||||
|
{:noreply, assign(socket, sort: sort_by)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Template approach:**
|
||||||
|
- Copy from `preview_pages/collection.html.heex`
|
||||||
|
- Implement filter sidebar (responds to filter events)
|
||||||
|
- Implement sort dropdown (price, name, featured)
|
||||||
|
- Use product_card component
|
||||||
|
- Respect grid_columns setting (2/3/4)
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme_web/router.ex` - Add collection route
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. Create collection LiveView module
|
||||||
|
2. Implement filtering and sorting logic
|
||||||
|
3. Create collection template based on preview
|
||||||
|
4. Add route: `live "/collections/:slug", ShopLive.Collection, :show`
|
||||||
|
5. Handle empty state (no products)
|
||||||
|
6. Write tests for filtering and sorting
|
||||||
|
7. Test grid columns respect theme setting
|
||||||
|
|
||||||
|
**Router changes:**
|
||||||
|
```elixir
|
||||||
|
live "/collections/:slug", ShopLive.Collection, :show
|
||||||
|
live "/collections", ShopLive.Collection, :index # "All Products"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Visit `/collections` and `/collections/tshirts`
|
||||||
|
- Test filter sidebar works
|
||||||
|
- Test sort dropdown changes order
|
||||||
|
- Verify grid columns (2, 3, 4) work correctly
|
||||||
|
- Check card shadow setting is respected
|
||||||
|
- Test hover image toggle works
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 6: Create Product Detail Page (PDP) LiveView
|
||||||
|
|
||||||
|
**Goal**: Create individual product page with gallery, details, add to cart
|
||||||
|
|
||||||
|
**Files to create:**
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/product.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/product.html.heex`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/product_test.exs`
|
||||||
|
|
||||||
|
**LiveView structure:**
|
||||||
|
```elixir
|
||||||
|
defmodule SimpleshopThemeWeb.ShopLive.Product do
|
||||||
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
|
|
||||||
|
def mount(%{"slug" => slug}, _session, socket) do
|
||||||
|
# Future: Load real product by slug
|
||||||
|
# For now: Use first preview product
|
||||||
|
[product | _] = PreviewData.products()
|
||||||
|
|
||||||
|
{:ok, assign(socket,
|
||||||
|
page_title: product.name,
|
||||||
|
product: product,
|
||||||
|
selected_variant: nil,
|
||||||
|
quantity: 1,
|
||||||
|
selected_image: 0
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("select_variant", %{"variant_id" => id}, socket) do
|
||||||
|
{:noreply, assign(socket, selected_variant: id)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("select_image", %{"index" => index}, socket) do
|
||||||
|
{:noreply, assign(socket, selected_image: String.to_integer(index))}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("add_to_cart", _params, socket) do
|
||||||
|
# Future: Add to cart functionality
|
||||||
|
{:noreply, put_flash(socket, :info, "Added to cart")}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Template approach:**
|
||||||
|
- Copy from `preview_pages/pdp.html.heex`
|
||||||
|
- Image gallery with thumbnails
|
||||||
|
- Variant selector (size, color)
|
||||||
|
- Quantity selector
|
||||||
|
- Add to cart button
|
||||||
|
- Respect toggle settings: `pdp_trust_badges`, `pdp_reviews`, `pdp_related_products`
|
||||||
|
- Gallery position: left/right based on `gallery_position` setting
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme_web/router.ex` - Add product route
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. Create product LiveView module
|
||||||
|
2. Implement variant selection logic
|
||||||
|
3. Implement image gallery navigation
|
||||||
|
4. Create product template based on preview
|
||||||
|
5. Add route: `live "/products/:slug", ShopLive.Product, :show`
|
||||||
|
6. Handle toggle features (reviews, badges, related)
|
||||||
|
7. Write tests for variant selection and cart add
|
||||||
|
8. Test gallery position setting
|
||||||
|
|
||||||
|
**Router changes:**
|
||||||
|
```elixir
|
||||||
|
live "/products/:slug", ShopLive.Product, :show
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Visit `/products/example-tshirt`
|
||||||
|
- Test variant selection updates UI
|
||||||
|
- Test image gallery thumbnail clicks
|
||||||
|
- Verify trust badges show/hide based on setting
|
||||||
|
- Verify reviews show/hide based on setting
|
||||||
|
- Verify related products show/hide based on setting
|
||||||
|
- Test "Add to cart" button (shows flash for now)
|
||||||
|
- Test gallery position (left/right) setting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 7: Create Cart Page LiveView
|
||||||
|
|
||||||
|
**Goal**: Create shopping cart page with line items and checkout
|
||||||
|
|
||||||
|
**Files to create:**
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/cart.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/cart.html.heex`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/cart_test.exs`
|
||||||
|
|
||||||
|
**LiveView structure:**
|
||||||
|
```elixir
|
||||||
|
defmodule SimpleshopThemeWeb.ShopLive.Cart do
|
||||||
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
|
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
# Future: Load real cart from session
|
||||||
|
# For now: Use preview cart items
|
||||||
|
cart_items = PreviewData.cart_items()
|
||||||
|
|
||||||
|
{:ok, assign(socket,
|
||||||
|
page_title: "Shopping Cart",
|
||||||
|
cart_items: cart_items,
|
||||||
|
subtotal: calculate_subtotal(cart_items),
|
||||||
|
shipping: 0,
|
||||||
|
tax: 0
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("update_quantity", %{"id" => id, "quantity" => qty}, socket) do
|
||||||
|
# Update item quantity
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("remove_item", %{"id" => id}, socket) do
|
||||||
|
# Remove item from cart
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("checkout", _params, socket) do
|
||||||
|
# Future: Proceed to checkout
|
||||||
|
{:noreply, put_flash(socket, :info, "Checkout coming soon")}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp calculate_subtotal(items) do
|
||||||
|
Enum.reduce(items, 0, fn item, acc ->
|
||||||
|
acc + (item.price * item.quantity)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Template approach:**
|
||||||
|
- Copy from `preview_pages/cart.html.heex`
|
||||||
|
- Line items with product image, name, variant, price, quantity
|
||||||
|
- Quantity update controls
|
||||||
|
- Remove item button
|
||||||
|
- Cart summary (subtotal, shipping, tax, total)
|
||||||
|
- Checkout button
|
||||||
|
- Empty cart state
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme_web/router.ex` - Add cart route
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. Create cart LiveView module
|
||||||
|
2. Implement quantity update logic
|
||||||
|
3. Implement remove item logic
|
||||||
|
4. Create cart template based on preview
|
||||||
|
5. Add route: `live "/cart", ShopLive.Cart, :show`
|
||||||
|
6. Handle empty cart state
|
||||||
|
7. Write tests for cart operations
|
||||||
|
8. Test price calculations
|
||||||
|
|
||||||
|
**Router changes:**
|
||||||
|
```elixir
|
||||||
|
live "/cart", ShopLive.Cart, :show
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Visit `/cart`
|
||||||
|
- Test quantity update buttons
|
||||||
|
- Test remove item button
|
||||||
|
- Verify price calculations correct
|
||||||
|
- Test empty cart state
|
||||||
|
- Verify checkout button shows flash
|
||||||
|
- Check button style setting is respected
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 8: Create Static Pages (About, Contact, Error)
|
||||||
|
|
||||||
|
**Goal**: Create remaining static pages
|
||||||
|
|
||||||
|
**Files to create:**
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/about.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/about.html.heex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/contact.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/contact.html.heex`
|
||||||
|
- `lib/simpleshop_theme_web/controllers/error_html/404.html.heex`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/about_test.exs`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/contact_test.exs`
|
||||||
|
|
||||||
|
**About Page:**
|
||||||
|
```elixir
|
||||||
|
defmodule SimpleshopThemeWeb.ShopLive.About do
|
||||||
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
{:ok, assign(socket, page_title: "About Us")}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Contact Page:**
|
||||||
|
```elixir
|
||||||
|
defmodule SimpleshopThemeWeb.ShopLive.Contact do
|
||||||
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
{:ok, assign(socket,
|
||||||
|
page_title: "Contact Us",
|
||||||
|
form: to_form(%{})
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("submit_contact", %{"contact" => params}, socket) do
|
||||||
|
# Future: Send contact email
|
||||||
|
{:noreply, put_flash(socket, :info, "Message sent successfully")}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme_web/router.ex` - Add routes
|
||||||
|
- `lib/simpleshop_theme_web/controllers/error_html.ex` - Add 404 template
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. Create about LiveView and template (copy from preview)
|
||||||
|
2. Create contact LiveView and template (copy from preview)
|
||||||
|
3. Add contact form submission handler
|
||||||
|
4. Create 404 error template (copy from preview_pages/error.html.heex)
|
||||||
|
5. Add routes: `live "/about"` and `live "/contact"`
|
||||||
|
6. Write tests for static pages
|
||||||
|
7. Test contact form submission
|
||||||
|
|
||||||
|
**Router changes:**
|
||||||
|
```elixir
|
||||||
|
live "/about", ShopLive.About, :show
|
||||||
|
live "/contact", ShopLive.Contact, :show
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Visit `/about` and verify page renders
|
||||||
|
- Visit `/contact` and test form submission
|
||||||
|
- Visit invalid URL and verify 404 page shows with theme
|
||||||
|
- Check all pages respect theme settings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 9: Wire Up CSS Cache Invalidation
|
||||||
|
|
||||||
|
**Goal**: Ensure CSS cache is invalidated when theme settings are saved
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme/settings.ex` - Add cache invalidation to update_theme_settings/1
|
||||||
|
- `lib/simpleshop_theme_web/live/theme_live/index.ex` - Ensure save_theme calls invalidation
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. Update `Settings.update_theme_settings/1` to call `CSSCache.invalidate()` after save
|
||||||
|
2. Update `ThemeLive.Index.handle_event("save_theme")` to trigger cache refresh
|
||||||
|
3. Optionally warm cache after invalidation for first request performance
|
||||||
|
4. Test cache invalidation works correctly
|
||||||
|
|
||||||
|
**Code changes in Settings context:**
|
||||||
|
```elixir
|
||||||
|
def update_theme_settings(attrs) do
|
||||||
|
current = get_theme_settings()
|
||||||
|
changeset = ThemeSettings.changeset(current, attrs)
|
||||||
|
|
||||||
|
case changeset.valid? do
|
||||||
|
true ->
|
||||||
|
updated = Ecto.Changeset.apply_changes(changeset)
|
||||||
|
put_setting("theme_settings", updated, :json)
|
||||||
|
|
||||||
|
# Invalidate CSS cache
|
||||||
|
SimpleshopTheme.Theme.CSSCache.invalidate()
|
||||||
|
|
||||||
|
# Optionally warm cache immediately
|
||||||
|
css = SimpleshopTheme.Theme.CSSGenerator.generate(updated)
|
||||||
|
SimpleshopTheme.Theme.CSSCache.put(css)
|
||||||
|
|
||||||
|
{:ok, updated}
|
||||||
|
false ->
|
||||||
|
{:error, changeset}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Change theme settings in admin
|
||||||
|
- Save theme
|
||||||
|
- Visit public storefront
|
||||||
|
- Verify changes are reflected immediately
|
||||||
|
- Check cache is being used (add logging if needed)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 10: Add Cache Warming on Application Start
|
||||||
|
|
||||||
|
**Goal**: Pre-generate and cache theme CSS when application starts
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme/application.ex` - Add cache warming after supervisor start
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. Add cache warming function to Application module
|
||||||
|
2. Call after supervisor starts successfully
|
||||||
|
3. Handle case where no theme settings exist yet
|
||||||
|
4. Add logging for cache warming
|
||||||
|
|
||||||
|
**Code changes:**
|
||||||
|
```elixir
|
||||||
|
defmodule SimpleshopTheme.Application do
|
||||||
|
def start(_type, _args) do
|
||||||
|
children = [
|
||||||
|
# ... existing children ...
|
||||||
|
SimpleshopTheme.Theme.CSSCache,
|
||||||
|
# ... more children ...
|
||||||
|
]
|
||||||
|
|
||||||
|
opts = [strategy: :one_for_one, name: SimpleshopTheme.Supervisor]
|
||||||
|
result = Supervisor.start_link(children, opts)
|
||||||
|
|
||||||
|
# Warm CSS cache on startup
|
||||||
|
Task.start(fn -> warm_theme_cache() end)
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
defp warm_theme_cache do
|
||||||
|
try do
|
||||||
|
settings = SimpleshopTheme.Settings.get_theme_settings()
|
||||||
|
css = SimpleshopTheme.Theme.CSSGenerator.generate(settings)
|
||||||
|
SimpleshopTheme.Theme.CSSCache.put(css)
|
||||||
|
Logger.info("Theme CSS cache warmed successfully")
|
||||||
|
rescue
|
||||||
|
e -> Logger.warning("Failed to warm theme cache: #{inspect(e)}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Restart application
|
||||||
|
- Check logs for "Theme CSS cache warmed successfully"
|
||||||
|
- Visit storefront immediately (should be fast)
|
||||||
|
- Verify no database queries for CSS generation on first request
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 11: Update Navigation Links
|
||||||
|
|
||||||
|
**Goal**: Connect theme editor to storefront and vice versa
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- `lib/simpleshop_theme_web/components/shop/header.ex` - Add admin link when authenticated
|
||||||
|
- `lib/simpleshop_theme_web/live/theme_live/index.html.heex` - Add "View Shop" link
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
1. In shop header component, add conditional admin link for authenticated users
|
||||||
|
2. In theme editor, add "View Shop" button in controls area
|
||||||
|
3. Ensure links use proper route helpers
|
||||||
|
4. Test navigation between admin and storefront
|
||||||
|
|
||||||
|
**Shop header changes:**
|
||||||
|
```heex
|
||||||
|
<%= if @current_user do %>
|
||||||
|
<a href={~p"/admin/theme"} class="admin-link">
|
||||||
|
Edit Theme
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Theme editor changes (add near "Save Theme" button):**
|
||||||
|
```heex
|
||||||
|
<a href={~p"/"} target="_blank" class="btn btn-outline">
|
||||||
|
View Shop
|
||||||
|
</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- When logged in on storefront, verify "Edit Theme" link appears
|
||||||
|
- Click link and verify navigates to theme editor
|
||||||
|
- In theme editor, click "View Shop" link
|
||||||
|
- Verify opens storefront in new tab
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 12: Testing and Polish
|
||||||
|
|
||||||
|
**Goal**: Comprehensive testing and UX improvements
|
||||||
|
|
||||||
|
**Files to modify:**
|
||||||
|
- All test files - Add comprehensive coverage
|
||||||
|
- Various LiveViews - Add loading states, error handling
|
||||||
|
|
||||||
|
**Actions:**
|
||||||
|
|
||||||
|
1. **Write comprehensive tests:**
|
||||||
|
- Test all storefront LiveViews
|
||||||
|
- Test plug behavior
|
||||||
|
- Test cache invalidation flow
|
||||||
|
- Test theme application across all pages
|
||||||
|
- Test responsive behavior
|
||||||
|
|
||||||
|
2. **Add loading states:**
|
||||||
|
- Product loading skeletons
|
||||||
|
- Cart update feedback
|
||||||
|
- Form submission states
|
||||||
|
|
||||||
|
3. **Error handling:**
|
||||||
|
- Handle missing products gracefully
|
||||||
|
- Handle invalid routes
|
||||||
|
- Handle network errors
|
||||||
|
|
||||||
|
4. **Performance optimization:**
|
||||||
|
- Verify CSS cache is working
|
||||||
|
- Check database query counts
|
||||||
|
- Test with many products (when available)
|
||||||
|
|
||||||
|
5. **Accessibility:**
|
||||||
|
- Check color contrast ratios
|
||||||
|
- Verify keyboard navigation
|
||||||
|
- Add ARIA labels where needed
|
||||||
|
|
||||||
|
6. **Mobile testing:**
|
||||||
|
- Test all pages on mobile viewport
|
||||||
|
- Verify touch interactions work
|
||||||
|
- Check responsive grid layouts
|
||||||
|
|
||||||
|
7. **Cross-browser testing:**
|
||||||
|
- Test in Chrome, Firefox, Safari
|
||||||
|
- Verify CSS variables work correctly
|
||||||
|
- Check font loading
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- Run full test suite: `mix test`
|
||||||
|
- All tests pass
|
||||||
|
- No console errors
|
||||||
|
- Good Lighthouse scores
|
||||||
|
- Responsive on all devices
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary of Files
|
||||||
|
|
||||||
|
### Files to Create (23 files)
|
||||||
|
|
||||||
|
**Shared Components (5 files):**
|
||||||
|
- `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`
|
||||||
|
|
||||||
|
**Infrastructure (2 files):**
|
||||||
|
- `lib/simpleshop_theme_web/plugs/load_theme.ex`
|
||||||
|
- `lib/simpleshop_theme_web/components/layouts/shop.html.heex`
|
||||||
|
|
||||||
|
**Storefront LiveViews (10 files):**
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/home.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/home.html.heex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/collection.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/collection.html.heex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/product.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/product.html.heex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/cart.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/cart.html.heex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/about.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/about.html.heex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/contact.ex`
|
||||||
|
- `lib/simpleshop_theme_web/live/shop_live/contact.html.heex`
|
||||||
|
|
||||||
|
**Error Pages (1 file):**
|
||||||
|
- `lib/simpleshop_theme_web/controllers/error_html/404.html.heex`
|
||||||
|
|
||||||
|
**Tests (6 files):**
|
||||||
|
- `test/simpleshop_theme_web/plugs/load_theme_test.exs`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/home_test.exs`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/collection_test.exs`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/product_test.exs`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/cart_test.exs`
|
||||||
|
- `test/simpleshop_theme_web/live/shop_live/about_test.exs`
|
||||||
|
|
||||||
|
### Files to Modify (9 files)
|
||||||
|
|
||||||
|
- `lib/simpleshop_theme_web/router.ex` - Add plug, public routes, shop layout
|
||||||
|
- `lib/simpleshop_theme_web/components/layouts.ex` - Add shop layout function
|
||||||
|
- `lib/simpleshop_theme/settings.ex` - Add cache invalidation
|
||||||
|
- `lib/simpleshop_theme/application.ex` - Add cache warming
|
||||||
|
- `lib/simpleshop_theme_web/live/theme_live/index.ex` - Add "View Shop" link
|
||||||
|
- `lib/simpleshop_theme_web/live/theme_live/index.html.heex` - Update to use shared components
|
||||||
|
- `lib/simpleshop_theme_web/live/theme_live/preview_pages.ex` - Remove extracted components
|
||||||
|
- All 7 preview page templates - Update component paths
|
||||||
|
- `lib/simpleshop_theme_web/components/shop/header.ex` - Add admin link
|
||||||
|
|
||||||
|
## Key Patterns to Follow
|
||||||
|
|
||||||
|
1. **CSS Application**: Always use `.shop-root` class with data attributes on root element
|
||||||
|
2. **Component Reuse**: Use shared components from `components/shop/` directory
|
||||||
|
3. **Preview Data**: Use `PreviewData` module for mock content until real Products context exists
|
||||||
|
4. **Cache Strategy**: Always check `CSSCache` before generating CSS
|
||||||
|
5. **Theme Settings**: Access via `@theme_settings` assign (provided by LoadTheme plug)
|
||||||
|
6. **Layout**: Use `:shop` layout for all public pages
|
||||||
|
7. **Testing**: Write tests alongside each LiveView
|
||||||
|
8. **Validation**: Test each step before moving to next
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
✅ Public storefront accessible at `/`
|
||||||
|
✅ All pages (home, collection, product, cart, about, contact) render correctly
|
||||||
|
✅ Theme settings from admin are applied to storefront
|
||||||
|
✅ CSS is cached for performance
|
||||||
|
✅ Cache invalidates when theme is saved
|
||||||
|
✅ Data attributes drive theme styling
|
||||||
|
✅ All toggle features work (announcement bar, sticky header, etc.)
|
||||||
|
✅ Grid columns, layout width, and other layout settings work
|
||||||
|
✅ Logo and header image display correctly
|
||||||
|
✅ Navigation between admin and storefront works
|
||||||
|
✅ Empty states handle gracefully (no products)
|
||||||
|
✅ All tests pass
|
||||||
|
✅ Mobile responsive
|
||||||
|
✅ No console errors
|
||||||
|
|
||||||
|
## Future Enhancements (After Phase 9)
|
||||||
|
|
||||||
|
1. **Products Context** - Add real product management
|
||||||
|
2. **Orders & Checkout** - Implement cart persistence and checkout flow
|
||||||
|
3. **Custom Domain Support** - Allow users to use their own domain
|
||||||
|
4. **SEO Optimization** - Meta tags, structured data, sitemaps
|
||||||
|
5. **Analytics Integration** - Track visitor behavior
|
||||||
|
6. **Email Templates** - Order confirmations, shipping notifications
|
||||||
|
7. **Multi-currency Support** - International selling
|
||||||
|
8. **Advanced Shipping** - Shipping rates, zones, carriers
|
||||||
|
9. **Discount Codes** - Promotional codes and sales
|
||||||
|
10. **Customer Accounts** - Registration, order history, wishlists
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- This implementation maintains perfect parity with the theme editor preview
|
||||||
|
- No JavaScript required for theming - purely CSS-based
|
||||||
|
- Self-contained in SQLite database (no external dependencies)
|
||||||
|
- Performance optimized with ETS caching
|
||||||
|
- Ready for multi-shop support in future (architecture supports it)
|
||||||
|
- Follows Phoenix/LiveView best practices throughout
|
||||||
|
- Mobile-first, accessible, performant
|
||||||
|
|
||||||
|
## Estimated Complexity
|
||||||
|
|
||||||
|
- **Step 1** (Extract Components): Medium - Refactoring existing code
|
||||||
|
- **Step 2** (LoadTheme Plug): Easy - Simple plug implementation
|
||||||
|
- **Step 3** (Storefront Layout): Easy - Template creation
|
||||||
|
- **Step 4** (Home Page): Medium - First full LiveView
|
||||||
|
- **Step 5** (Collection Page): Medium - Filtering/sorting logic
|
||||||
|
- **Step 6** (Product Page): Medium - Variant selection, gallery
|
||||||
|
- **Step 7** (Cart Page): Medium - Cart operations
|
||||||
|
- **Step 8** (Static Pages): Easy - Simple templates
|
||||||
|
- **Step 9** (Cache Invalidation): Easy - Add function calls
|
||||||
|
- **Step 10** (Cache Warming): Easy - Application startup hook
|
||||||
|
- **Step 11** (Navigation Links): Easy - Add links
|
||||||
|
- **Step 12** (Testing & Polish): Large - Comprehensive testing
|
||||||
|
|
||||||
|
**Total Effort**: ~2-3 days for experienced Phoenix developer
|
||||||
|
|
||||||
|
## Risk Assessment
|
||||||
|
|
||||||
|
**Low Risk:**
|
||||||
|
- CSS system is proven in preview pages
|
||||||
|
- No database schema changes needed
|
||||||
|
- No breaking changes to existing code
|
||||||
|
- Can test each step independently
|
||||||
|
|
||||||
|
**Medium Risk:**
|
||||||
|
- Component extraction might miss edge cases
|
||||||
|
- Cache invalidation timing could cause brief inconsistencies
|
||||||
|
|
||||||
|
**Mitigation:**
|
||||||
|
- Comprehensive testing after each step
|
||||||
|
- Keep preview pages working during refactor
|
||||||
|
- Add logging for cache operations
|
||||||
|
- Test cache invalidation thoroughly
|
||||||
419
PHASE_9_PROGRESS.md
Normal file
419
PHASE_9_PROGRESS.md
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
# Phase 9: Storefront Integration - Progress Tracker
|
||||||
|
|
||||||
|
**Last Updated:** 2026-01-01
|
||||||
|
**Status:** Not Started
|
||||||
|
**Current Step:** Step 0 (Preparation)
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
- **Detailed Plan:** `.claude/plans/snuggly-forging-cat.md`
|
||||||
|
- **Main Plan:** `PLAN.md` (lines 643-690)
|
||||||
|
- **Spec:** `SPEC.md`
|
||||||
|
|
||||||
|
## Progress Overview
|
||||||
|
|
||||||
|
- [ ] Step 1: Extract Shared Components
|
||||||
|
- [ ] Step 2: Create LoadTheme Plug
|
||||||
|
- [ ] Step 3: Create Storefront Layout
|
||||||
|
- [ ] Step 4: Create Home Page LiveView
|
||||||
|
- [ ] Step 5: Create Collection Page LiveView
|
||||||
|
- [ ] Step 6: Create Product Detail Page (PDP) LiveView
|
||||||
|
- [ ] Step 7: Create Cart Page LiveView
|
||||||
|
- [ ] Step 8: Create Static Pages (About, Contact, Error)
|
||||||
|
- [ ] Step 9: Wire Up CSS Cache Invalidation
|
||||||
|
- [ ] Step 10: Add Cache Warming on Application Start
|
||||||
|
- [ ] Step 11: Update Navigation Links
|
||||||
|
- [ ] Step 12: Testing and Polish
|
||||||
|
|
||||||
|
**Completion:** 0/12 steps (0%)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step-by-Step Progress
|
||||||
|
|
||||||
|
### Step 1: Extract Shared Components
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `refactor: extract shared shop components from preview pages`
|
||||||
|
|
||||||
|
**Goal:** Move reusable preview components to `components/shop/` for use in both admin and storefront
|
||||||
|
|
||||||
|
**Files to Create (5):**
|
||||||
|
- [ ] `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 (8):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages.ex` - Import new components
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages/home.html.heex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages/collection.html.heex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages/pdp.html.heex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages/cart.html.heex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages/about.html.heex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages/contact.html.heex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/preview_pages/error.html.heex`
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Run `mix test test/simpleshop_theme_web/live/theme_live_test.exs`
|
||||||
|
- [ ] Visit `/admin/theme` - verify all 7 preview pages still render
|
||||||
|
- [ ] No visual regressions
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 2: Create LoadTheme Plug
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add LoadTheme plug for public storefront`
|
||||||
|
|
||||||
|
**Goal:** Create plug that loads theme settings and CSS for every public request
|
||||||
|
|
||||||
|
**Files to Create (2):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/plugs/load_theme.ex`
|
||||||
|
- [ ] `test/simpleshop_theme_web/plugs/load_theme_test.exs`
|
||||||
|
|
||||||
|
**Files to Modify (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/router.ex` - Add plug to `:browser` pipeline
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Run `mix test test/simpleshop_theme_web/plugs/load_theme_test.exs`
|
||||||
|
- [ ] Verify assigns available in requests
|
||||||
|
- [ ] Verify CSS cached and reused
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 3: Create Storefront Layout
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add shop layout with theme CSS injection`
|
||||||
|
|
||||||
|
**Goal:** Create dedicated layout for public storefront with theme CSS injection
|
||||||
|
|
||||||
|
**Files to Create (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/components/layouts/shop.html.heex`
|
||||||
|
|
||||||
|
**Files to Modify (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/components/layouts.ex` - Add `shop/1` function
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Inspect HTML - verify data attributes present
|
||||||
|
- [ ] Verify CSS injection works
|
||||||
|
- [ ] Layout compiles without errors
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 4: Create Home Page LiveView
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add public home page with theme support`
|
||||||
|
|
||||||
|
**Goal:** Create public homepage LiveView using real/mock data
|
||||||
|
|
||||||
|
**Files to Create (3):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/home.ex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/home.html.heex`
|
||||||
|
- [ ] `test/simpleshop_theme_web/live/shop_live/home_test.exs`
|
||||||
|
|
||||||
|
**Files to Modify (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/router.ex` - Add route: `live "/", ShopLive.Home, :index`
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Visit `/` - verify homepage renders
|
||||||
|
- [ ] Theme styles applied correctly
|
||||||
|
- [ ] Announcement bar toggle works
|
||||||
|
- [ ] Header layout variations work
|
||||||
|
- [ ] Sticky header toggle works
|
||||||
|
- [ ] Products display (mock data)
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 5: Create Collection Page LiveView
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add collection/product grid page with filtering`
|
||||||
|
|
||||||
|
**Goal:** Create product collection/grid page with filtering and sorting
|
||||||
|
|
||||||
|
**Files to Create (3):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/collection.ex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/collection.html.heex`
|
||||||
|
- [ ] `test/simpleshop_theme_web/live/shop_live/collection_test.exs`
|
||||||
|
|
||||||
|
**Files to Modify (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/router.ex` - Add routes for collections
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Visit `/collections` and `/collections/:slug`
|
||||||
|
- [ ] Filter sidebar works
|
||||||
|
- [ ] Sort dropdown works
|
||||||
|
- [ ] Grid columns (2, 3, 4) work
|
||||||
|
- [ ] Card shadow setting respected
|
||||||
|
- [ ] Hover image toggle works
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 6: Create Product Detail Page (PDP) LiveView
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add product detail page with gallery and variants`
|
||||||
|
|
||||||
|
**Goal:** Create individual product page with gallery, details, add to cart
|
||||||
|
|
||||||
|
**Files to Create (3):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/product.ex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/product.html.heex`
|
||||||
|
- [ ] `test/simpleshop_theme_web/live/shop_live/product_test.exs`
|
||||||
|
|
||||||
|
**Files to Modify (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/router.ex` - Add route: `live "/products/:slug"`
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Visit `/products/:slug`
|
||||||
|
- [ ] Variant selection works
|
||||||
|
- [ ] Image gallery works
|
||||||
|
- [ ] Trust badges show/hide based on setting
|
||||||
|
- [ ] Reviews show/hide based on setting
|
||||||
|
- [ ] Related products show/hide based on setting
|
||||||
|
- [ ] Add to cart shows flash
|
||||||
|
- [ ] Gallery position (left/right) works
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 7: Create Cart Page LiveView
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add shopping cart page with line items`
|
||||||
|
|
||||||
|
**Goal:** Create shopping cart page with line items and checkout
|
||||||
|
|
||||||
|
**Files to Create (3):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/cart.ex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/cart.html.heex`
|
||||||
|
- [ ] `test/simpleshop_theme_web/live/shop_live/cart_test.exs`
|
||||||
|
|
||||||
|
**Files to Modify (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/router.ex` - Add route: `live "/cart"`
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Visit `/cart`
|
||||||
|
- [ ] Quantity update works
|
||||||
|
- [ ] Remove item works
|
||||||
|
- [ ] Price calculations correct
|
||||||
|
- [ ] Empty cart state works
|
||||||
|
- [ ] Checkout button shows flash
|
||||||
|
- [ ] Button style setting respected
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 8: Create Static Pages (About, Contact, Error)
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add static pages (about, contact, 404) with theme support`
|
||||||
|
|
||||||
|
**Goal:** Create remaining static pages
|
||||||
|
|
||||||
|
**Files to Create (6):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/about.ex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/about.html.heex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/contact.ex`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/shop_live/contact.html.heex`
|
||||||
|
- [ ] `test/simpleshop_theme_web/live/shop_live/about_test.exs`
|
||||||
|
- [ ] `test/simpleshop_theme_web/live/shop_live/contact_test.exs`
|
||||||
|
|
||||||
|
**Files to Modify (2):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/router.ex` - Add routes
|
||||||
|
- [ ] `lib/simpleshop_theme_web/controllers/error_html.ex` - Add 404 template (or create if missing)
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Visit `/about` - page renders
|
||||||
|
- [ ] Visit `/contact` - form works
|
||||||
|
- [ ] Visit invalid URL - 404 shows with theme
|
||||||
|
- [ ] All pages respect theme settings
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 9: Wire Up CSS Cache Invalidation
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add CSS cache invalidation on theme save`
|
||||||
|
|
||||||
|
**Goal:** Ensure CSS cache invalidates when theme settings saved
|
||||||
|
|
||||||
|
**Files to Modify (2):**
|
||||||
|
- [ ] `lib/simpleshop_theme/settings.ex` - Add cache invalidation to `update_theme_settings/1`
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/index.ex` - Ensure save triggers invalidation
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Change theme in admin
|
||||||
|
- [ ] Save theme
|
||||||
|
- [ ] Visit storefront
|
||||||
|
- [ ] Verify changes reflected immediately
|
||||||
|
- [ ] Check cache being used
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 10: Add Cache Warming on Application Start
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add CSS cache warming on application startup`
|
||||||
|
|
||||||
|
**Goal:** Pre-generate and cache theme CSS when app starts
|
||||||
|
|
||||||
|
**Files to Modify (1):**
|
||||||
|
- [ ] `lib/simpleshop_theme/application.ex` - Add cache warming after supervisor start
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Restart application
|
||||||
|
- [ ] Check logs for "Theme CSS cache warmed successfully"
|
||||||
|
- [ ] Visit storefront immediately (should be fast)
|
||||||
|
- [ ] No DB queries for CSS on first request
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 11: Update Navigation Links
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `feat: add navigation between admin and storefront`
|
||||||
|
|
||||||
|
**Goal:** Connect theme editor to storefront and vice versa
|
||||||
|
|
||||||
|
**Files to Modify (2):**
|
||||||
|
- [ ] `lib/simpleshop_theme_web/components/shop/header.ex` - Add admin link when authenticated
|
||||||
|
- [ ] `lib/simpleshop_theme_web/live/theme_live/index.html.heex` - Add "View Shop" link
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] When logged in on storefront, "Edit Theme" link appears
|
||||||
|
- [ ] Click link - navigates to theme editor
|
||||||
|
- [ ] In theme editor, click "View Shop" link
|
||||||
|
- [ ] Opens storefront in new tab
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 12: Testing and Polish
|
||||||
|
|
||||||
|
**Status:** ❌ Not Started
|
||||||
|
**Git Commit:** `test: add comprehensive tests and polish for Phase 9`
|
||||||
|
|
||||||
|
**Goal:** Comprehensive testing and UX improvements
|
||||||
|
|
||||||
|
**Testing Areas:**
|
||||||
|
- [ ] All storefront LiveViews tested
|
||||||
|
- [ ] Plug behavior tested
|
||||||
|
- [ ] Cache invalidation flow tested
|
||||||
|
- [ ] Theme application across all pages tested
|
||||||
|
- [ ] Responsive behavior tested
|
||||||
|
|
||||||
|
**Polish Areas:**
|
||||||
|
- [ ] Loading states added
|
||||||
|
- [ ] Error handling complete
|
||||||
|
- [ ] Performance optimized
|
||||||
|
- [ ] Accessibility checked
|
||||||
|
- [ ] Mobile tested
|
||||||
|
- [ ] Cross-browser tested
|
||||||
|
|
||||||
|
**Validation:**
|
||||||
|
- [ ] Run `mix test` - all tests pass
|
||||||
|
- [ ] No console errors
|
||||||
|
- [ ] Good Lighthouse scores
|
||||||
|
- [ ] Responsive on all devices
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Git Commit Log
|
||||||
|
|
||||||
|
Track all commits made during Phase 9 implementation:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Commits will be added here as we progress
|
||||||
|
# Format: [YYYY-MM-DD HH:MM] <commit-hash> <commit-message>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Issues / Blockers
|
||||||
|
|
||||||
|
Track any issues encountered:
|
||||||
|
|
||||||
|
- None yet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Enhancements (Post-Phase 9)
|
||||||
|
|
||||||
|
1. Products Context - Add real product management
|
||||||
|
2. Orders & Checkout - Cart persistence and checkout flow
|
||||||
|
3. Custom Domain Support
|
||||||
|
4. SEO Optimization
|
||||||
|
5. Analytics Integration
|
||||||
|
6. Email Templates
|
||||||
|
7. Multi-currency Support
|
||||||
|
8. Advanced Shipping
|
||||||
|
9. Discount Codes
|
||||||
|
10. Customer Accounts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Context Preservation
|
||||||
|
|
||||||
|
**Key Architectural Decisions:**
|
||||||
|
- CSS applied via `.shop-root` class with data attributes
|
||||||
|
- Same three-layer CSS system as theme editor
|
||||||
|
- LoadTheme plug provides `@theme_settings` and `@generated_css` assigns
|
||||||
|
- CSS cached in ETS via `CSSCache` GenServer
|
||||||
|
- Preview data used until real Products context exists
|
||||||
|
- Shared components in `components/shop/` directory
|
||||||
|
|
||||||
|
**Critical Files:**
|
||||||
|
- Theme editor: `lib/simpleshop_theme_web/live/theme_live/index.ex`
|
||||||
|
- CSS generator: `lib/simpleshop_theme/theme/css_generator.ex`
|
||||||
|
- Settings context: `lib/simpleshop_theme/settings.ex`
|
||||||
|
- Preview data: `lib/simpleshop_theme/theme/preview_data.ex`
|
||||||
|
|
||||||
|
**Current State (as of last update):**
|
||||||
|
- Theme editor fully functional at `/admin/theme`
|
||||||
|
- 8 presets working with real-time preview
|
||||||
|
- All customization options implemented
|
||||||
|
- Logo/header uploads with BLOB storage working
|
||||||
|
- SVG recoloring functional
|
||||||
|
- No public storefront routes yet (Phase 9 not started)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to Use This File
|
||||||
|
|
||||||
|
1. **Starting a new step:** Update the step status to "🚧 In Progress"
|
||||||
|
2. **Completing files:** Check off files as created/modified
|
||||||
|
3. **Finishing a step:**
|
||||||
|
- Mark step as "✅ Complete"
|
||||||
|
- Update completion percentage
|
||||||
|
- Make git commit with specified message
|
||||||
|
- Add commit to Git Commit Log section
|
||||||
|
4. **Encountering issues:** Add to Issues/Blockers section
|
||||||
|
5. **Taking notes:** Add to Notes field for each step
|
||||||
|
|
||||||
|
**For new conversations:** Read this file first to understand current progress and context.
|
||||||
107
PLAN.md
107
PLAN.md
@ -170,9 +170,38 @@ test/simpleshop_theme_web/
|
|||||||
└── theme_live_test.exs # LiveView integration tests
|
└── theme_live_test.exs # LiveView integration tests
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation Phases
|
## Implementation Status
|
||||||
|
|
||||||
### Phase 1: Database Foundation ✓
|
### Completed Phases (1-8): ✅
|
||||||
|
- ✅ Phase 1: Database Foundation
|
||||||
|
- ✅ Phase 2: CSS Architecture
|
||||||
|
- ✅ Phase 3: Smart Preview Data
|
||||||
|
- ✅ Phase 4: Theme LiveView (Basic)
|
||||||
|
- ✅ Phase 5: Preview Pages
|
||||||
|
- ✅ Phase 6: Customization Options
|
||||||
|
- ✅ Phase 6.5: Fix Theme Visual Application
|
||||||
|
- ✅ Phase 7: File Uploads (Logo & Header)
|
||||||
|
- ✅ Phase 8: Persistence & Polish
|
||||||
|
|
||||||
|
### Current Phase: Phase 9 - Storefront Integration 🚧
|
||||||
|
|
||||||
|
**See detailed Phase 9 plan at:** `.claude/plans/snuggly-forging-cat.md`
|
||||||
|
|
||||||
|
**Phase 9 Goal:** Apply the theme system to the actual public-facing storefront
|
||||||
|
|
||||||
|
**Key deliverables:**
|
||||||
|
- Public storefront routes (`/`, `/products/:slug`, `/collections`, `/cart`, etc.)
|
||||||
|
- Storefront LiveViews using real/mock data
|
||||||
|
- LoadTheme plug to inject theme settings and CSS
|
||||||
|
- CSS cache integration for performance
|
||||||
|
- Navigation between admin theme editor and public shop
|
||||||
|
- All 7 pages working on storefront (home, collection, product, cart, about, contact, error)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Phases (Details)
|
||||||
|
|
||||||
|
### Phase 1: Database Foundation ✅
|
||||||
**Goal:** Set up Settings and Media models for site-wide configuration
|
**Goal:** Set up Settings and Media models for site-wide configuration
|
||||||
|
|
||||||
**Steps:**
|
**Steps:**
|
||||||
@ -611,45 +640,53 @@ The demo HTML uses data attributes (`data-mood="warm"`, `data-typography="editor
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 9: Storefront Integration ✓
|
### Phase 9: Storefront Integration 🚧
|
||||||
**Goal:** Apply theme to actual public-facing shop
|
**Goal:** Apply theme to actual public-facing shop
|
||||||
|
|
||||||
**Steps:**
|
**Status:** Ready to implement - See detailed plan in `.claude/plans/snuggly-forging-cat.md`
|
||||||
1. Create public shop routes in router:
|
|
||||||
- `get "/:shop_slug", ShopController, :show` (shop homepage)
|
|
||||||
- Or use domain-based routing for custom domains
|
|
||||||
2. Create `lib/simpleshop_theme_web/live/shop_live/` directory for storefront LiveViews
|
|
||||||
3. Create storefront page templates that respect theme settings:
|
|
||||||
- Use same CSS system as preview
|
|
||||||
- Load theme CSS from cache
|
|
||||||
- Render actual products (when they exist) or empty states
|
|
||||||
4. Create `lib/simpleshop_theme_web/plugs/load_shop_theme.ex`:
|
|
||||||
- Load shop by domain/slug
|
|
||||||
- Load theme CSS from cache
|
|
||||||
- Assign to `conn.assigns.theme_css`
|
|
||||||
5. Add theme CSS to root layout for storefront
|
|
||||||
6. Implement proper caching headers for theme CSS
|
|
||||||
7. Handle theme CSS cache warming on app startup
|
|
||||||
|
|
||||||
**Files to create:**
|
**High-level overview:**
|
||||||
- `lib/simpleshop_theme_web/live/shop_live/*` (storefront pages)
|
1. Extract shared components from preview pages (header, footer, product card, etc.)
|
||||||
- `lib/simpleshop_theme_web/plugs/load_theme.ex`
|
2. Create LoadTheme plug to inject theme settings and CSS into all public requests
|
||||||
- `test/simpleshop_theme_web/live/shop_live_test.exs`
|
3. Create dedicated shop layout with `.shop-root` class and data attributes
|
||||||
- `test/simpleshop_theme_web/plugs/load_theme_test.exs`
|
4. Build storefront LiveViews for all pages:
|
||||||
|
- Home (`/`)
|
||||||
|
- Collection (`/collections/:slug`)
|
||||||
|
- Product Detail (`/products/:slug`)
|
||||||
|
- Cart (`/cart`)
|
||||||
|
- About (`/about`)
|
||||||
|
- Contact (`/contact`)
|
||||||
|
- Error (404 page)
|
||||||
|
5. Wire up CSS cache invalidation when theme is saved
|
||||||
|
6. Add cache warming on application startup
|
||||||
|
7. Add navigation links between admin and storefront
|
||||||
|
8. Comprehensive testing and polish
|
||||||
|
|
||||||
**Files to modify:**
|
**Key files to create (23 files):**
|
||||||
- `lib/simpleshop_theme_web/router.ex` - Public shop routes
|
- 5 shared component modules in `components/shop/`
|
||||||
- `lib/simpleshop_theme_web/components/layouts.ex` - Theme CSS injection
|
- 1 LoadTheme plug
|
||||||
- Root layout template
|
- 1 shop layout template
|
||||||
|
- 6 storefront LiveView modules + templates
|
||||||
|
- 1 error page template
|
||||||
|
- 6 test files
|
||||||
|
|
||||||
**Git commit:** `feat: integrate theme system with public storefront`
|
**Key files to modify (9 files):**
|
||||||
|
- Router (add public routes and plug)
|
||||||
|
- Settings context (add cache invalidation)
|
||||||
|
- Application (add cache warming)
|
||||||
|
- Theme editor (add "View Shop" link)
|
||||||
|
- Preview pages (use shared components)
|
||||||
|
|
||||||
**Validation:**
|
**Detailed implementation plan:** See `.claude/plans/snuggly-forging-cat.md` for 12-step implementation guide with code examples, validation steps, and architectural decisions.
|
||||||
- Run tests: `mix test`
|
|
||||||
- Visit public shop URL, verify theme applies correctly
|
**Git commit strategy:** Commit after each major step (components extraction, plug creation, each LiveView, etc.)
|
||||||
- Change theme in admin, verify storefront updates
|
|
||||||
- Test CSS cache invalidation
|
**Validation approach:**
|
||||||
- Verify performance with caching headers
|
- Test theme editor still works after component extraction
|
||||||
|
- Test each storefront page individually as built
|
||||||
|
- Verify CSS cache invalidation flow
|
||||||
|
- Test navigation between admin and storefront
|
||||||
|
- Comprehensive testing in Step 12
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user