diff --git a/lib/simpleshop_theme_web/live/shop_live/product_show.ex b/lib/simpleshop_theme_web/live/shop_live/product_show.ex new file mode 100644 index 0000000..4046279 --- /dev/null +++ b/lib/simpleshop_theme_web/live/shop_live/product_show.ex @@ -0,0 +1,58 @@ +defmodule SimpleshopThemeWeb.ShopLive.ProductShow do + use SimpleshopThemeWeb, :live_view + + alias SimpleshopTheme.Settings + alias SimpleshopTheme.Media + alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData} + + @impl true + def mount(%{"id" => id}, _session, socket) do + theme_settings = Settings.get_theme_settings() + + generated_css = + case CSSCache.get() do + {:ok, css} -> css + :miss -> + css = CSSGenerator.generate(theme_settings) + CSSCache.put(css) + css + end + + logo_image = Media.get_logo() + header_image = Media.get_header() + + products = PreviewData.products() + + # Find product by ID (preview data uses integer IDs) + product_id = String.to_integer(id) + product = Enum.find(products, List.first(products), fn p -> p.id == product_id end) + + # Get related products (exclude current product, take 4) + related_products = + products + |> Enum.reject(fn p -> p.id == product_id end) + |> Enum.take(4) + + # Build gallery images + gallery_images = [ + product.image_url, + product.hover_image_url, + product.image_url, + product.hover_image_url + ] + + socket = + socket + |> assign(:page_title, product.name) + |> assign(:theme_settings, theme_settings) + |> assign(:generated_css, generated_css) + |> assign(:logo_image, logo_image) + |> assign(:header_image, header_image) + |> assign(:product, product) + |> assign(:gallery_images, gallery_images) + |> assign(:related_products, related_products) + |> assign(:quantity, 1) + + {:ok, socket} + end +end diff --git a/lib/simpleshop_theme_web/live/shop_live/product_show.html.heex b/lib/simpleshop_theme_web/live/shop_live/product_show.html.heex new file mode 100644 index 0000000..5b78c58 --- /dev/null +++ b/lib/simpleshop_theme_web/live/shop_live/product_show.html.heex @@ -0,0 +1,44 @@ +
+ <.skip_link /> + + <%= if @theme_settings.announcement_bar do %> + <.announcement_bar theme_settings={@theme_settings} /> + <% end %> + + <.shop_header theme_settings={@theme_settings} logo_image={@logo_image} header_image={@header_image} active_page="pdp" mode={:shop} cart_count={0} /> + +
+ <.breadcrumb items={[ + %{label: "Home", page: "home", href: "/"}, + %{label: @product.category, page: "collection", href: "/products"}, + %{label: @product.name, current: true} + ]} mode={:shop} /> + +
+ <.product_gallery images={@gallery_images} product_name={@product.name} /> + +
+ <.product_info product={@product} /> + <.variant_selector label="Size" options={["S", "M", "L", "XL"]} /> + <.quantity_selector quantity={@quantity} in_stock={@product.in_stock} /> + <.add_to_cart_button /> + <.trust_badges :if={@theme_settings.pdp_trust_badges} /> + <.product_details product={@product} /> +
+
+ + <.reviews_section :if={@theme_settings.pdp_reviews} reviews={SimpleshopTheme.Theme.PreviewData.reviews()} average_rating={5} total_count={24} /> + + <.related_products_section + :if={@theme_settings.pdp_related_products} + products={@related_products} + theme_settings={@theme_settings} + mode={:shop} + /> +
+ + <.shop_footer theme_settings={@theme_settings} mode={:shop} /> + + <.cart_drawer cart_items={[]} subtotal="£0.00" mode={:shop} /> + <.search_modal hint_text={~s(Try searching for "mountain", "forest", or "ocean")} /> +
diff --git a/lib/simpleshop_theme_web/router.ex b/lib/simpleshop_theme_web/router.ex index a4d79c0..84bed60 100644 --- a/lib/simpleshop_theme_web/router.ex +++ b/lib/simpleshop_theme_web/router.ex @@ -30,6 +30,7 @@ defmodule SimpleshopThemeWeb.Router do live "/about", ShopLive.About, :index live "/contact", ShopLive.Contact, :index live "/products", ShopLive.Products, :index + live "/products/:id", ShopLive.ProductShow, :show end end