From 6a3069f854619e848755d7c82fcb89afc1e9e1dd Mon Sep 17 00:00:00 2001 From: Jamey Greenwood Date: Tue, 30 Dec 2025 22:06:04 +0000 Subject: [PATCH] feat: add preview page templates with theme styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement all 7 preview pages showcasing theme customization: - Home page: hero, featured products, testimonials, categories - Collection page: product grid with filters and sorting - Product detail page (PDP): gallery, variants, add to cart - Cart page: cart items with quantity controls and order summary - About page: company story and values - Contact page: contact form and business information - 404 error page: error message with product suggestions Features: - All pages use CSS custom properties for theming - Preview data from PreviewData module (mock products, testimonials, categories) - Responsive layouts with Tailwind utilities - Grid columns respect theme settings - Colors, typography, shapes, and spacing all theme-aware - Components created as embed_templates for clean separation Technical implementation: - Created PreviewPages component module with embed_templates - Wired up preview_data in LiveView mount - Updated index.html.heex to render preview pages based on @preview_page - All pages styled with inline styles using CSS variables - Scrollable preview frame with max-height All tests passing (197 total). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../live/theme_live/index.ex | 9 +- .../live/theme_live/index.html.heex | 63 ++----- .../live/theme_live/preview_pages.ex | 5 + .../theme_live/preview_pages/about.html.heex | 67 +++++++ .../theme_live/preview_pages/cart.html.heex | 109 ++++++++++++ .../preview_pages/collection.html.heex | 159 +++++++++++++++++ .../preview_pages/contact.html.heex | 124 +++++++++++++ .../theme_live/preview_pages/error.html.heex | 56 ++++++ .../theme_live/preview_pages/home.html.heex | 134 ++++++++++++++ .../theme_live/preview_pages/pdp.html.heex | 168 ++++++++++++++++++ .../live/theme_live_test.exs | 2 +- 11 files changed, 848 insertions(+), 48 deletions(-) create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages.ex create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages/about.html.heex create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages/cart.html.heex create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages/collection.html.heex create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages/contact.html.heex create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages/error.html.heex create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages/home.html.heex create mode 100644 lib/simpleshop_theme_web/live/theme_live/preview_pages/pdp.html.heex diff --git a/lib/simpleshop_theme_web/live/theme_live/index.ex b/lib/simpleshop_theme_web/live/theme_live/index.ex index ee1fad9..6c31f98 100644 --- a/lib/simpleshop_theme_web/live/theme_live/index.ex +++ b/lib/simpleshop_theme_web/live/theme_live/index.ex @@ -2,12 +2,18 @@ defmodule SimpleshopThemeWeb.ThemeLive.Index do use SimpleshopThemeWeb, :live_view alias SimpleshopTheme.Settings - alias SimpleshopTheme.Theme.{CSSGenerator, Presets} + alias SimpleshopTheme.Theme.{CSSGenerator, Presets, PreviewData} @impl true def mount(_params, _session, socket) do theme_settings = Settings.get_theme_settings() generated_css = CSSGenerator.generate(theme_settings) + preview_data = %{ + products: PreviewData.products(), + cart_items: PreviewData.cart_items(), + testimonials: PreviewData.testimonials(), + categories: PreviewData.categories() + } socket = socket @@ -15,6 +21,7 @@ defmodule SimpleshopThemeWeb.ThemeLive.Index do |> assign(:generated_css, generated_css) |> assign(:preview_page, :home) |> assign(:preset_names, Presets.list_names()) + |> assign(:preview_data, preview_data) {:ok, socket} end diff --git a/lib/simpleshop_theme_web/live/theme_live/index.html.heex b/lib/simpleshop_theme_web/live/theme_live/index.html.heex index 8d8775a..bab748d 100644 --- a/lib/simpleshop_theme_web/live/theme_live/index.html.heex +++ b/lib/simpleshop_theme_web/live/theme_live/index.html.heex @@ -103,56 +103,27 @@ -
+
-
-

- Preview: <%= String.capitalize(to_string(@preview_page)) %> -

- -
-

- This is a preview of the <%= @preview_page %> page with your current theme settings. -

- -
- - -
- -
-

- Card Example -

-

- This card demonstrates the current surface, border, and text colors with the selected shape style. -

-
- -
- Detailed preview pages coming in Phase 5 -
-
-
+ <%= case @preview_page do %> + <% :home -> %> + + <% :collection -> %> + + <% :pdp -> %> + + <% :cart -> %> + + <% :about -> %> + + <% :contact -> %> + + <% :error -> %> + + <% end %>
diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages.ex b/lib/simpleshop_theme_web/live/theme_live/preview_pages.ex new file mode 100644 index 0000000..a2af6b1 --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages.ex @@ -0,0 +1,5 @@ +defmodule SimpleshopThemeWeb.ThemeLive.PreviewPages do + use Phoenix.Component + + embed_templates "preview_pages/*" +end diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages/about.html.heex b/lib/simpleshop_theme_web/live/theme_live/preview_pages/about.html.heex new file mode 100644 index 0000000..3cb7fc0 --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages/about.html.heex @@ -0,0 +1,67 @@ +
+
+

+ About Us +

+ +

+ We're passionate about bringing you the finest products, handpicked with care and attention to detail. +

+ +
+ Our Story +
+ +
+

+ Our Story +

+

+ Founded in 2020, our journey began with a simple mission: to curate and deliver exceptional products that enhance everyday life. We believe that quality shouldn't be compromised, and that's why every item in our collection is carefully selected for its craftsmanship, sustainability, and timeless appeal. +

+

+ What started as a small passion project has grown into a community of like-minded individuals who appreciate the finer things in life. We work directly with artisans and makers who share our values of quality, authenticity, and ethical production. +

+ +

+ Our Values +

+
+
+

Quality First

+

+ Every product is vetted for exceptional quality and durability. +

+
+
+

Sustainability

+

+ We prioritize eco-friendly materials and ethical production methods. +

+
+
+

Community

+

+ Supporting local artisans and building lasting relationships. +

+
+
+
+ +
+

+ Ready to Explore? +

+ +
+
+
diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages/cart.html.heex b/lib/simpleshop_theme_web/live/theme_live/preview_pages/cart.html.heex new file mode 100644 index 0000000..e9169f8 --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages/cart.html.heex @@ -0,0 +1,109 @@ +
+
+

+ Shopping Cart +

+ +
+ +
+
+ <%= for item <- @preview_data.cart_items do %> +
+
+ {item.product.name} +
+ +
+

+ <%= item.product.name %> +

+

+ <%= item.variant %> +

+ +
+
+ + + <%= item.quantity %> + + +
+ + +
+
+ +
+

+ $<%= item.product.price / 100 * item.quantity %> +

+
+
+ <% end %> +
+
+ + +
+
+

+ Order Summary +

+ +
+
+ Subtotal + + $<%= Enum.reduce(@preview_data.cart_items, 0, fn item, acc -> acc + item.product.price * item.quantity end) / 100 %> + +
+
+ Shipping + $10.00 +
+
+ Tax + $8.50 +
+
+
+ Total + + $<%= (Enum.reduce(@preview_data.cart_items, 0, fn item, acc -> acc + item.product.price * item.quantity end) / 100 + 10.00 + 8.50) |> Float.round(2) %> + +
+
+
+ + + + +
+
+
+
+
diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages/collection.html.heex b/lib/simpleshop_theme_web/live/theme_live/preview_pages/collection.html.heex new file mode 100644 index 0000000..9d108b1 --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages/collection.html.heex @@ -0,0 +1,159 @@ +
+ +
+
+

+ All Products +

+

+ <%= length(@preview_data.products) %> products +

+
+
+ +
+
+ +
+
+

+ Filter by Category +

+
+ <%= for category <- @preview_data.categories do %> + + <% end %> +
+ +
+

+ Price Range +

+
+ + + + +
+
+
+
+ + +
+
+

+ Showing all <%= length(@preview_data.products) %> products +

+ +
+ +
+ <%= for product <- @preview_data.products do %> +
+
+ <%= if product.on_sale do %> +
+ SALE +
+ <% end %> + <%= if not product.in_stock do %> +
+ Out of Stock +
+ <% end %> + {product.name} +
+
+

+ <%= product.category %> +

+

+ <%= product.name %> +

+
+
+ <%= if product.on_sale do %> + + $<%= product.price / 100 %> + + + $<%= product.compare_at_price / 100 %> + + <% else %> + + $<%= product.price / 100 %> + + <% end %> +
+ <%= if product.in_stock do %> + + <% end %> +
+
+
+ <% end %> +
+
+
+
+
diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages/contact.html.heex b/lib/simpleshop_theme_web/live/theme_live/preview_pages/contact.html.heex new file mode 100644 index 0000000..80b504b --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages/contact.html.heex @@ -0,0 +1,124 @@ +
+
+

+ Contact Us +

+ +

+ Have a question or comment? We'd love to hear from you. Send us a message and we'll respond as soon as possible. +

+ +
+ +
+

+ Send us a message +

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
+ + +
+
+

Email

+

hello@example.com

+
+ +
+

Phone

+

(555) 123-4567

+
+ +
+

Address

+

+ 123 Main Street
+ San Francisco, CA 94102
+ United States +

+
+ +
+

Hours

+

+ Monday - Friday: 9am - 6pm
+ Saturday: 10am - 4pm
+ Sunday: Closed +

+
+
+
+
+
diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages/error.html.heex b/lib/simpleshop_theme_web/live/theme_live/preview_pages/error.html.heex new file mode 100644 index 0000000..9198482 --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages/error.html.heex @@ -0,0 +1,56 @@ +
+
+

+ 404 +

+ +

+ Page Not Found +

+ +

+ Sorry, we couldn't find the page you're looking for. Perhaps you've mistyped the URL or the page has been moved. +

+ +
+ + + +
+ +
+ <%= for product <- Enum.take(@preview_data.products, 4) do %> +
+
+ {product.name} +
+
+

+ <%= product.name %> +

+

+ $<%= product.price / 100 %> +

+
+
+ <% end %> +
+
+
diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages/home.html.heex b/lib/simpleshop_theme_web/live/theme_live/preview_pages/home.html.heex new file mode 100644 index 0000000..7cfeea4 --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages/home.html.heex @@ -0,0 +1,134 @@ +
+ +
+
+
+

+ Welcome to Our Store +

+

+ Discover our curated collection of handpicked products crafted with care +

+ +
+
+
+ + +
+

+ Featured Products +

+ +
+ <%= for product <- Enum.take(@preview_data.products, 6) do %> +
+
+ {product.name} +
+
+

+ <%= product.name %> +

+

+ <%= product.description %> +

+
+
+ <%= if product.on_sale do %> + + $<%= product.price / 100 %> + + + $<%= product.compare_at_price / 100 %> + + <% else %> + + $<%= product.price / 100 %> + + <% end %> +
+ +
+
+
+ <% end %> +
+
+ + +
+
+

+ What Our Customers Say +

+ +
+ <%= for testimonial <- Enum.take(@preview_data.testimonials, 3) do %> +
+
+ <%= for _ <- 1..testimonial.rating do %> + + + + <% end %> +
+

+ "<%= testimonial.content %>" +

+

+ — <%= testimonial.author %> +

+
+ <% end %> +
+
+
+ + +
+

+ Shop by Category +

+ +
+ <%= for category <- @preview_data.categories do %> +
+
+ {category.name} +
+

+ <%= category.name %> +

+

+ <%= category.product_count %> products +

+
+ <% end %> +
+
+
diff --git a/lib/simpleshop_theme_web/live/theme_live/preview_pages/pdp.html.heex b/lib/simpleshop_theme_web/live/theme_live/preview_pages/pdp.html.heex new file mode 100644 index 0000000..7b2ef94 --- /dev/null +++ b/lib/simpleshop_theme_web/live/theme_live/preview_pages/pdp.html.heex @@ -0,0 +1,168 @@ +<% + product = List.first(@preview_data.products) +%> +
+
+ +
+ Home + / + <%= product.category %> + / + <%= product.name %> +
+ +
+ +
+
+ {product.name} +
+
+ <%= for img_url <- [product.image_url, product.hover_image_url, product.image_url, product.hover_image_url] do %> +
+ {product.name} +
+ <% end %> +
+
+ + +
+

+ <%= product.name %> +

+ +
+ <%= if product.on_sale do %> + + $<%= product.price / 100 %> + + + $<%= product.compare_at_price / 100 %> + + + SAVE <%= round((product.compare_at_price - product.price) / product.compare_at_price * 100) %>% + + <% else %> + + $<%= product.price / 100 %> + + <% end %> +
+ +

+ <%= product.description %>. Crafted with attention to detail and quality materials, this product is designed to last. Perfect for everyday use or special occasions. +

+ + +
+ +
+ <%= for size <- ["S", "M", "L", "XL"] do %> + + <% end %> +
+
+ + +
+ +
+
+ + + 1 + + +
+ <%= if product.in_stock do %> + In stock + <% else %> + Out of stock + <% end %> +
+
+ + + + + +
+
+ + + +
+

Free Shipping

+

On orders over $50

+
+
+
+ + + +
+

Easy Returns

+

30-day return policy

+
+
+
+
+
+ + +
+

+ You May Also Like +

+ +
+ <%= for related_product <- Enum.slice(@preview_data.products, 1, 4) do %> +
+
+ {related_product.name} +
+
+

+ <%= related_product.name %> +

+

+ $<%= related_product.price / 100 %> +

+
+
+ <% end %> +
+
+
+
diff --git a/test/simpleshop_theme_web/live/theme_live_test.exs b/test/simpleshop_theme_web/live/theme_live_test.exs index bb839c0..b17428f 100644 --- a/test/simpleshop_theme_web/live/theme_live_test.exs +++ b/test/simpleshop_theme_web/live/theme_live_test.exs @@ -90,7 +90,7 @@ defmodule SimpleshopThemeWeb.ThemeLiveTest do |> element("button", "Collection") |> render_click() - assert html =~ "Preview: Collection" + assert html =~ "All Products" end test "save theme button works", %{conn: conn} do