29 KiB
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-rootclass 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.exlib/simpleshop_theme_web/components/shop/header.exlib/simpleshop_theme_web/components/shop/footer.exlib/simpleshop_theme_web/components/shop/search_modal.exlib/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:
- Create
lib/simpleshop_theme_web/components/shop/directory - Extract
announcement_bar/1from preview_pages.ex toshop/announcement_bar.ex - Extract
shop_header/1toshop/header.ex - Extract
shop_footer/1toshop/footer.ex - Extract
search_modal/1toshop/search_modal.ex - Create new
product_card/1component (used in multiple places) - Update preview_pages.ex to import and use new components
- Update all 7 preview templates to use new component paths
- Test theme editor still works correctly
Validation:
- Run
mix test test/simpleshop_theme_web/live/theme_live_test.exs - Visit
/admin/themeand 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.extest/simpleshop_theme_web/plugs/load_theme_test.exs
Plug functionality:
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:
- Create plug file with init/1 and call/2 functions
- Implement cache-first CSS loading strategy
- Assign both
:theme_settingsand:generated_cssto conn - Add plug to
:browserpipeline in router (before routes) - Write tests for plug behavior
- 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:
<!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- Addshop/1layout function
Actions:
- Create new shop.html.heex layout file
- Add
.shop-rootwrapper with all theme data attributes - Inject
@generated_cssinto<style>tag - Use
@theme_settings.site_namefor page title default - Add shop layout function to layouts.ex module
- 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.exlib/simpleshop_theme_web/live/shop_live/home.html.heextest/simpleshop_theme_web/live/shop_live/home_test.exs
LiveView structure:
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:
- Create home LiveView module with mount function
- Load preview data (real products when available)
- Create home template based on preview version
- Use shared components for header, footer, announcement bar
- Add route:
live "/", ShopLive.Home, :indexin public scope - Set layout to
:shopfor route - Write tests for home page rendering
- Test with and without products
Router changes:
# 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.exlib/simpleshop_theme_web/live/shop_live/collection.html.heextest/simpleshop_theme_web/live/shop_live/collection_test.exs
LiveView structure:
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:
- Create collection LiveView module
- Implement filtering and sorting logic
- Create collection template based on preview
- Add route:
live "/collections/:slug", ShopLive.Collection, :show - Handle empty state (no products)
- Write tests for filtering and sorting
- Test grid columns respect theme setting
Router changes:
live "/collections/:slug", ShopLive.Collection, :show
live "/collections", ShopLive.Collection, :index # "All Products"
Validation:
- Visit
/collectionsand/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.exlib/simpleshop_theme_web/live/shop_live/product.html.heextest/simpleshop_theme_web/live/shop_live/product_test.exs
LiveView structure:
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_positionsetting
Files to modify:
lib/simpleshop_theme_web/router.ex- Add product route
Actions:
- Create product LiveView module
- Implement variant selection logic
- Implement image gallery navigation
- Create product template based on preview
- Add route:
live "/products/:slug", ShopLive.Product, :show - Handle toggle features (reviews, badges, related)
- Write tests for variant selection and cart add
- Test gallery position setting
Router changes:
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.exlib/simpleshop_theme_web/live/shop_live/cart.html.heextest/simpleshop_theme_web/live/shop_live/cart_test.exs
LiveView structure:
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:
- Create cart LiveView module
- Implement quantity update logic
- Implement remove item logic
- Create cart template based on preview
- Add route:
live "/cart", ShopLive.Cart, :show - Handle empty cart state
- Write tests for cart operations
- Test price calculations
Router changes:
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.exlib/simpleshop_theme_web/live/shop_live/about.html.heexlib/simpleshop_theme_web/live/shop_live/contact.exlib/simpleshop_theme_web/live/shop_live/contact.html.heexlib/simpleshop_theme_web/controllers/error_html/404.html.heextest/simpleshop_theme_web/live/shop_live/about_test.exstest/simpleshop_theme_web/live/shop_live/contact_test.exs
About Page:
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:
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 routeslib/simpleshop_theme_web/controllers/error_html.ex- Add 404 template
Actions:
- Create about LiveView and template (copy from preview)
- Create contact LiveView and template (copy from preview)
- Add contact form submission handler
- Create 404 error template (copy from preview_pages/error.html.heex)
- Add routes:
live "/about"andlive "/contact" - Write tests for static pages
- Test contact form submission
Router changes:
live "/about", ShopLive.About, :show
live "/contact", ShopLive.Contact, :show
Validation:
- Visit
/aboutand verify page renders - Visit
/contactand 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/1lib/simpleshop_theme_web/live/theme_live/index.ex- Ensure save_theme calls invalidation
Actions:
- Update
Settings.update_theme_settings/1to callCSSCache.invalidate()after save - Update
ThemeLive.Index.handle_event("save_theme")to trigger cache refresh - Optionally warm cache after invalidation for first request performance
- Test cache invalidation works correctly
Code changes in Settings context:
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:
- Add cache warming function to Application module
- Call after supervisor starts successfully
- Handle case where no theme settings exist yet
- Add logging for cache warming
Code changes:
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 authenticatedlib/simpleshop_theme_web/live/theme_live/index.html.heex- Add "View Shop" link
Actions:
- In shop header component, add conditional admin link for authenticated users
- In theme editor, add "View Shop" button in controls area
- Ensure links use proper route helpers
- Test navigation between admin and storefront
Shop header changes:
<%= if @current_user do %>
<a href={~p"/admin/theme"} class="admin-link">
Edit Theme
</a>
<% end %>
Theme editor changes (add near "Save Theme" button):
<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:
-
Write comprehensive tests:
- Test all storefront LiveViews
- Test plug behavior
- Test cache invalidation flow
- Test theme application across all pages
- Test responsive behavior
-
Add loading states:
- Product loading skeletons
- Cart update feedback
- Form submission states
-
Error handling:
- Handle missing products gracefully
- Handle invalid routes
- Handle network errors
-
Performance optimization:
- Verify CSS cache is working
- Check database query counts
- Test with many products (when available)
-
Accessibility:
- Check color contrast ratios
- Verify keyboard navigation
- Add ARIA labels where needed
-
Mobile testing:
- Test all pages on mobile viewport
- Verify touch interactions work
- Check responsive grid layouts
-
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.exlib/simpleshop_theme_web/components/shop/header.exlib/simpleshop_theme_web/components/shop/footer.exlib/simpleshop_theme_web/components/shop/search_modal.exlib/simpleshop_theme_web/components/shop/product_card.ex
Infrastructure (2 files):
lib/simpleshop_theme_web/plugs/load_theme.exlib/simpleshop_theme_web/components/layouts/shop.html.heex
Storefront LiveViews (10 files):
lib/simpleshop_theme_web/live/shop_live/home.exlib/simpleshop_theme_web/live/shop_live/home.html.heexlib/simpleshop_theme_web/live/shop_live/collection.exlib/simpleshop_theme_web/live/shop_live/collection.html.heexlib/simpleshop_theme_web/live/shop_live/product.exlib/simpleshop_theme_web/live/shop_live/product.html.heexlib/simpleshop_theme_web/live/shop_live/cart.exlib/simpleshop_theme_web/live/shop_live/cart.html.heexlib/simpleshop_theme_web/live/shop_live/about.exlib/simpleshop_theme_web/live/shop_live/about.html.heexlib/simpleshop_theme_web/live/shop_live/contact.exlib/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.exstest/simpleshop_theme_web/live/shop_live/home_test.exstest/simpleshop_theme_web/live/shop_live/collection_test.exstest/simpleshop_theme_web/live/shop_live/product_test.exstest/simpleshop_theme_web/live/shop_live/cart_test.exstest/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 layoutlib/simpleshop_theme_web/components/layouts.ex- Add shop layout functionlib/simpleshop_theme/settings.ex- Add cache invalidationlib/simpleshop_theme/application.ex- Add cache warminglib/simpleshop_theme_web/live/theme_live/index.ex- Add "View Shop" linklib/simpleshop_theme_web/live/theme_live/index.html.heex- Update to use shared componentslib/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
- CSS Application: Always use
.shop-rootclass with data attributes on root element - Component Reuse: Use shared components from
components/shop/directory - Preview Data: Use
PreviewDatamodule for mock content until real Products context exists - Cache Strategy: Always check
CSSCachebefore generating CSS - Theme Settings: Access via
@theme_settingsassign (provided by LoadTheme plug) - Layout: Use
:shoplayout for all public pages - Testing: Write tests alongside each LiveView
- 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)
- Products Context - Add real product management
- Orders & Checkout - Implement cart persistence and checkout flow
- Custom Domain Support - Allow users to use their own domain
- SEO Optimization - Meta tags, structured data, sitemaps
- Analytics Integration - Track visitor behavior
- Email Templates - Order confirmations, shipping notifications
- Multi-currency Support - International selling
- Advanced Shipping - Shipping rates, zones, carriers
- Discount Codes - Promotional codes and sales
- 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