From 336b2bb81da072adec0c1747a6015ec6c56be6af Mon Sep 17 00:00:00 2001 From: jamey Date: Sat, 31 Jan 2026 14:24:58 +0000 Subject: [PATCH] chore: apply mix format to codebase Co-Authored-By: Claude Opus 4.5 --- lib/mix/tasks/generate_mockups.ex | 4 +- lib/simpleshop_theme/images/optimizer.ex | 18 +- lib/simpleshop_theme/images/variant_cache.ex | 4 +- lib/simpleshop_theme/media.ex | 14 +- lib/simpleshop_theme/media/image.ex | 3 +- lib/simpleshop_theme/media/svg_recolorer.ex | 3 +- lib/simpleshop_theme/mockups/generator.ex | 55 +- lib/simpleshop_theme/products.ex | 7 +- .../products/product_variant.ex | 3 +- .../settings/theme_settings.ex | 15 +- lib/simpleshop_theme/theme/fonts.ex | 1 - lib/simpleshop_theme/theme/preview_data.ex | 54 +- lib/simpleshop_theme_web.ex | 3 +- .../components/layouts/shop.html.heex | 2 +- .../components/layouts/shop_root.html.heex | 14 +- .../components/page_templates/about.html.heex | 14 +- .../components/page_templates/cart.html.heex | 14 +- .../page_templates/collection.html.heex | 14 +- .../page_templates/contact.html.heex | 27 +- .../components/page_templates/error.html.heex | 20 +- .../components/page_templates/home.html.heex | 14 +- .../components/page_templates/pdp.html.heex | 39 +- .../components/shop_components.ex | 1081 +++++++--- .../controllers/error_html.ex | 46 +- .../live/shop_live/about.ex | 4 +- .../live/shop_live/cart.ex | 12 +- .../live/shop_live/collection.ex | 49 +- .../live/shop_live/contact.ex | 4 +- .../live/shop_live/home.ex | 4 +- .../live/shop_live/product_show.ex | 4 +- .../live/theme_live/index.ex | 5 +- .../live/theme_live/index.html.heex | 1834 +++++++++-------- .../live/user_live/login.ex | 3 +- .../20260128235846_create_products.exs | 5 +- .../20260128235847_create_product_images.exs | 5 +- ...20260128235848_create_product_variants.exs | 5 +- .../media/svg_recolorer_test.exs | 4 + .../products/product_test.exs | 5 +- test/simpleshop_theme/products_test.exs | 4 +- test/simpleshop_theme/settings_test.exs | 6 +- .../sync/product_sync_worker_test.exs | 4 +- .../theme/preview_data_test.exs | 1 + .../controllers/error_json_test.exs | 4 +- 43 files changed, 2227 insertions(+), 1204 deletions(-) diff --git a/lib/mix/tasks/generate_mockups.ex b/lib/mix/tasks/generate_mockups.ex index be22bd0..e4541b0 100644 --- a/lib/mix/tasks/generate_mockups.ex +++ b/lib/mix/tasks/generate_mockups.ex @@ -194,7 +194,9 @@ defmodule Mix.Tasks.GenerateMockups do """) if failed > 0 do - Mix.shell().error("Some products failed to generate. Check the output above for details.") + Mix.shell().error( + "Some products failed to generate. Check the output above for details." + ) end end end diff --git a/lib/simpleshop_theme/images/optimizer.ex b/lib/simpleshop_theme/images/optimizer.ex index 01fd556..79a4b2f 100644 --- a/lib/simpleshop_theme/images/optimizer.ex +++ b/lib/simpleshop_theme/images/optimizer.ex @@ -31,7 +31,8 @@ defmodule SimpleshopTheme.Images.Optimizer do {width, _height, _} <- Image.shape(image), {:ok, resized} <- maybe_resize(image, width), {final_width, final_height, _} <- Image.shape(resized), - {:ok, webp_data} <- Image.write(resized, :memory, suffix: ".webp", quality: @storage_quality) do + {:ok, webp_data} <- + Image.write(resized, :memory, suffix: ".webp", quality: @storage_quality) do {:ok, webp_data, final_width, final_height} end rescue @@ -191,9 +192,20 @@ defmodule SimpleshopTheme.Images.Optimizer do widths = applicable_widths(source_width) tasks = [ - Task.async(fn -> generate_variant_to_dir(vips_image, output_basename, output_dir, "thumb", :jpg, @thumb_size) end) + Task.async(fn -> + generate_variant_to_dir( + vips_image, + output_basename, + output_dir, + "thumb", + :jpg, + @thumb_size + ) + end) | for w <- widths, fmt <- @pregenerated_formats do - Task.async(fn -> generate_variant_to_dir(vips_image, output_basename, output_dir, w, fmt, w) end) + Task.async(fn -> + generate_variant_to_dir(vips_image, output_basename, output_dir, w, fmt, w) + end) end ] diff --git a/lib/simpleshop_theme/images/variant_cache.ex b/lib/simpleshop_theme/images/variant_cache.ex index ee62d33..fc387c0 100644 --- a/lib/simpleshop_theme/images/variant_cache.ex +++ b/lib/simpleshop_theme/images/variant_cache.ex @@ -59,7 +59,9 @@ defmodule SimpleshopTheme.Images.VariantCache do if to_process == [] do Logger.info("[VariantCache] All database image variants up to date") else - Logger.info("[VariantCache] Enqueueing #{length(to_process)} database images for processing") + Logger.info( + "[VariantCache] Enqueueing #{length(to_process)} database images for processing" + ) Enum.each(to_process, fn image -> image diff --git a/lib/simpleshop_theme/media.ex b/lib/simpleshop_theme/media.ex index fd1cb30..16077b2 100644 --- a/lib/simpleshop_theme/media.ex +++ b/lib/simpleshop_theme/media.ex @@ -119,7 +119,12 @@ defmodule SimpleshopTheme.Media do """ def get_logo do - Repo.one(from i in ImageSchema, where: i.image_type == "logo", order_by: [desc: i.inserted_at], limit: 1) + Repo.one( + from i in ImageSchema, + where: i.image_type == "logo", + order_by: [desc: i.inserted_at], + limit: 1 + ) end @doc """ @@ -132,7 +137,12 @@ defmodule SimpleshopTheme.Media do """ def get_header do - Repo.one(from i in ImageSchema, where: i.image_type == "header", order_by: [desc: i.inserted_at], limit: 1) + Repo.one( + from i in ImageSchema, + where: i.image_type == "header", + order_by: [desc: i.inserted_at], + limit: 1 + ) end @doc """ diff --git a/lib/simpleshop_theme/media/image.ex b/lib/simpleshop_theme/media/image.ex index 3e4c965..5529699 100644 --- a/lib/simpleshop_theme/media/image.ex +++ b/lib/simpleshop_theme/media/image.ex @@ -46,7 +46,8 @@ defmodule SimpleshopTheme.Media.Image do defp detect_svg(changeset) do content_type = get_change(changeset, :content_type) - if content_type == "image/svg+xml" or String.ends_with?(get_change(changeset, :filename) || "", ".svg") do + if content_type == "image/svg+xml" or + String.ends_with?(get_change(changeset, :filename) || "", ".svg") do changeset |> put_change(:is_svg, true) |> maybe_store_svg_content() diff --git a/lib/simpleshop_theme/media/svg_recolorer.ex b/lib/simpleshop_theme/media/svg_recolorer.ex index 294018e..d2022e4 100644 --- a/lib/simpleshop_theme/media/svg_recolorer.ex +++ b/lib/simpleshop_theme/media/svg_recolorer.ex @@ -23,7 +23,8 @@ defmodule SimpleshopTheme.Media.SVGRecolorer do """ @spec recolor(String.t(), String.t()) :: String.t() - def recolor(svg_content, target_color) when is_binary(svg_content) and is_binary(target_color) do + def recolor(svg_content, target_color) + when is_binary(svg_content) and is_binary(target_color) do svg_content |> recolor_fill_attributes(target_color) |> recolor_stroke_attributes(target_color) diff --git a/lib/simpleshop_theme/mockups/generator.ex b/lib/simpleshop_theme/mockups/generator.ex index a4bd350..955f68c 100644 --- a/lib/simpleshop_theme/mockups/generator.ex +++ b/lib/simpleshop_theme/mockups/generator.ex @@ -163,9 +163,17 @@ defmodule SimpleshopTheme.Mockups.Generator do hoodie: %{blueprint_id: nil, print_provider_id: nil, search_term: "Pullover Hoodie"}, tote: %{blueprint_id: nil, print_provider_id: nil, search_term: "Cotton Tote Bag"}, mug: %{blueprint_id: nil, print_provider_id: nil, search_term: "Mug 11oz"}, - cushion: %{blueprint_id: nil, print_provider_id: nil, search_term: "Spun Polyester Square Pillow"}, + cushion: %{ + blueprint_id: nil, + print_provider_id: nil, + search_term: "Spun Polyester Square Pillow" + }, blanket: %{blueprint_id: nil, print_provider_id: nil, search_term: "Sherpa Fleece Blanket"}, - notebook: %{blueprint_id: nil, print_provider_id: nil, search_term: "Hardcover Journal Matte"}, + notebook: %{ + blueprint_id: nil, + print_provider_id: nil, + search_term: "Hardcover Journal Matte" + }, phone_case: %{blueprint_id: nil, print_provider_id: nil, search_term: "Tough Phone Cases"}, laptop_sleeve: %{blueprint_id: nil, print_provider_id: nil, search_term: "Laptop Sleeve"} } @@ -253,12 +261,12 @@ defmodule SimpleshopTheme.Mockups.Generator do """ def calculate_cover_scale(artwork_width, artwork_height, placeholder_width, placeholder_height) when is_number(artwork_width) and is_number(artwork_height) and - is_number(placeholder_width) and is_number(placeholder_height) and - artwork_width > 0 and artwork_height > 0 and - placeholder_width > 0 and placeholder_height > 0 do + is_number(placeholder_width) and is_number(placeholder_height) and + artwork_width > 0 and artwork_height > 0 and + placeholder_width > 0 and placeholder_height > 0 do # For cover: use the larger scale to ensure full coverage width_scale = 1.0 - height_scale = (placeholder_height * artwork_width) / (artwork_height * placeholder_width) + height_scale = placeholder_height * artwork_width / (artwork_height * placeholder_width) max(width_scale, height_scale) end @@ -267,21 +275,36 @@ defmodule SimpleshopTheme.Mockups.Generator do @doc """ Create a product with the uploaded artwork. """ - def create_product(shop_id, product_def, image_id, image_width, image_height, blueprint_id, print_provider_id, variants) do + def create_product( + shop_id, + product_def, + image_id, + image_width, + image_height, + blueprint_id, + print_provider_id, + variants + ) do # Get the first variant for simplicity (typically a standard size/color) variant = hd(variants) variant_id = variant["id"] # Get placeholder info placeholders = variant["placeholders"] || [] - front_placeholder = Enum.find(placeholders, fn p -> p["position"] == "front" end) || hd(placeholders) + + front_placeholder = + Enum.find(placeholders, fn p -> p["position"] == "front" end) || hd(placeholders) # Extract placeholder dimensions and calculate cover scale placeholder_width = front_placeholder["width"] placeholder_height = front_placeholder["height"] - scale = calculate_cover_scale(image_width, image_height, placeholder_width, placeholder_height) - IO.puts(" Scale calculation: artwork #{image_width}x#{image_height}, placeholder #{placeholder_width}x#{placeholder_height} -> scale #{Float.round(scale, 3)}") + scale = + calculate_cover_scale(image_width, image_height, placeholder_width, placeholder_height) + + IO.puts( + " Scale calculation: artwork #{image_width}x#{image_height}, placeholder #{placeholder_width}x#{placeholder_height} -> scale #{Float.round(scale, 3)}" + ) product_data = %{ title: product_def.name, @@ -439,7 +462,17 @@ defmodule SimpleshopTheme.Mockups.Generator do image_height = upload["height"], _ = IO.puts(" Artwork uploaded (ID: #{image_id}, #{image_width}x#{image_height})"), _ = IO.puts(" Creating product..."), - {:ok, product} <- create_product(shop_id, product_def, image_id, image_width, image_height, blueprint_id, provider_id, variants), + {:ok, product} <- + create_product( + shop_id, + product_def, + image_id, + image_width, + image_height, + blueprint_id, + provider_id, + variants + ), product_id = product["id"], mockup_urls = extract_mockup_urls(product), _ = IO.puts(" Product created (ID: #{product_id})"), diff --git a/lib/simpleshop_theme/products.ex b/lib/simpleshop_theme/products.ex index c5c3613..2a94e6f 100644 --- a/lib/simpleshop_theme/products.ex +++ b/lib/simpleshop_theme/products.ex @@ -287,14 +287,17 @@ defmodule SimpleshopTheme.Products do if MapSet.size(removed_ids) > 0 do from(v in ProductVariant, - where: v.product_id == ^product_id and v.provider_variant_id in ^MapSet.to_list(removed_ids) + where: + v.product_id == ^product_id and v.provider_variant_id in ^MapSet.to_list(removed_ids) ) |> Repo.delete_all() end # Upsert incoming variants Enum.map(variants, fn variant_data -> - provider_variant_id = variant_data[:provider_variant_id] || variant_data["provider_variant_id"] + provider_variant_id = + variant_data[:provider_variant_id] || variant_data["provider_variant_id"] + attrs = Map.put(variant_data, :product_id, product_id) case get_variant_by_provider(product_id, provider_variant_id) do diff --git a/lib/simpleshop_theme/products/product_variant.ex b/lib/simpleshop_theme/products/product_variant.ex index 144044f..a6353a8 100644 --- a/lib/simpleshop_theme/products/product_variant.ex +++ b/lib/simpleshop_theme/products/product_variant.ex @@ -88,7 +88,8 @@ defmodule SimpleshopTheme.Products.ProductVariant do Formats the options as a human-readable title. E.g., %{"Size" => "Large", "Color" => "Blue"} -> "Large / Blue" """ - def options_title(%__MODULE__{options: options}) when is_map(options) and map_size(options) > 0 do + def options_title(%__MODULE__{options: options}) + when is_map(options) and map_size(options) > 0 do options |> Map.values() |> Enum.join(" / ") diff --git a/lib/simpleshop_theme/settings/theme_settings.ex b/lib/simpleshop_theme/settings/theme_settings.ex index 13f6dd8..c6e098c 100644 --- a/lib/simpleshop_theme/settings/theme_settings.ex +++ b/lib/simpleshop_theme/settings/theme_settings.ex @@ -93,7 +93,10 @@ defmodule SimpleshopTheme.Settings.ThemeSettings do ]) |> validate_required([:mood, :typography, :shape, :density]) |> validate_inclusion(:mood, ~w(neutral warm cool dark)) - |> validate_inclusion(:typography, ~w(clean editorial modern classic friendly minimal impulse)) + |> validate_inclusion( + :typography, + ~w(clean editorial modern classic friendly minimal impulse) + ) |> validate_inclusion(:shape, ~w(sharp soft round pill)) |> validate_inclusion(:density, ~w(spacious balanced compact)) |> validate_inclusion(:grid_columns, ~w(2 3 4)) @@ -101,8 +104,14 @@ defmodule SimpleshopTheme.Settings.ThemeSettings do |> validate_inclusion(:logo_mode, ~w(text-only logo-text logo-only)) |> validate_number(:logo_size, greater_than_or_equal_to: 24, less_than_or_equal_to: 120) |> validate_number(:header_zoom, greater_than_or_equal_to: 100, less_than_or_equal_to: 200) - |> validate_number(:header_position_x, greater_than_or_equal_to: 0, less_than_or_equal_to: 100) - |> validate_number(:header_position_y, greater_than_or_equal_to: 0, less_than_or_equal_to: 100) + |> validate_number(:header_position_x, + greater_than_or_equal_to: 0, + less_than_or_equal_to: 100 + ) + |> validate_number(:header_position_y, + greater_than_or_equal_to: 0, + less_than_or_equal_to: 100 + ) |> validate_inclusion(:layout_width, ~w(contained wide full)) |> validate_inclusion(:card_shadow, ~w(none sm md lg)) |> validate_inclusion(:font_size, ~w(small medium large)) diff --git a/lib/simpleshop_theme/theme/fonts.ex b/lib/simpleshop_theme/theme/fonts.ex index e4680a6..732aaeb 100644 --- a/lib/simpleshop_theme/theme/fonts.ex +++ b/lib/simpleshop_theme/theme/fonts.ex @@ -234,5 +234,4 @@ defmodule SimpleshopTheme.Theme.Fonts do "" end end - end diff --git a/lib/simpleshop_theme/theme/preview_data.ex b/lib/simpleshop_theme/theme/preview_data.ex index 16f224a..7139f16 100644 --- a/lib/simpleshop_theme/theme/preview_data.ex +++ b/lib/simpleshop_theme/theme/preview_data.ex @@ -67,7 +67,8 @@ defmodule SimpleshopTheme.Theme.PreviewData do %{ rating: 5, title: "Absolutely beautiful", - body: "The quality exceeded my expectations. The colours are vibrant and the paper feels premium. It's now pride of place in my living room.", + body: + "The quality exceeded my expectations. The colours are vibrant and the paper feels premium. It's now pride of place in my living room.", author: "Sarah M.", date: "2 weeks ago", verified: true @@ -75,7 +76,8 @@ defmodule SimpleshopTheme.Theme.PreviewData do %{ rating: 4, title: "Great gift", - body: "Bought this as a gift and it arrived beautifully packaged. Fast shipping too. Would definitely order again.", + body: + "Bought this as a gift and it arrived beautifully packaged. Fast shipping too. Would definitely order again.", author: "James T.", date: "1 month ago", verified: true @@ -90,13 +92,33 @@ defmodule SimpleshopTheme.Theme.PreviewData do """ def about_content do [ - %{type: :lead, text: "I'm Emma, a nature photographer based in the UK. What started as weekend walks with my camera has grown into something I never expected – a little shop where I can share my favourite captures with others."}, - %{type: :paragraph, text: "Every design in this shop comes from my own photography. Whether it's early morning mist over the hills, autumn leaves in the local woods, or the quiet beauty of wildflower meadows, I'm drawn to the peaceful moments that nature offers."}, - %{type: :paragraph, text: "I work with quality print partners to bring these images to life on products you can actually use and enjoy – from art prints for your walls to mugs for your morning tea."}, + %{ + type: :lead, + text: + "I'm Emma, a nature photographer based in the UK. What started as weekend walks with my camera has grown into something I never expected – a little shop where I can share my favourite captures with others." + }, + %{ + type: :paragraph, + text: + "Every design in this shop comes from my own photography. Whether it's early morning mist over the hills, autumn leaves in the local woods, or the quiet beauty of wildflower meadows, I'm drawn to the peaceful moments that nature offers." + }, + %{ + type: :paragraph, + text: + "I work with quality print partners to bring these images to life on products you can actually use and enjoy – from art prints for your walls to mugs for your morning tea." + }, %{type: :heading, text: "Quality you can trust"}, - %{type: :paragraph, text: "I've carefully chosen print partners who share my commitment to quality. Every product is made to order using premium materials and printing techniques that ensure vibrant colours and lasting quality."}, + %{ + type: :paragraph, + text: + "I've carefully chosen print partners who share my commitment to quality. Every product is made to order using premium materials and printing techniques that ensure vibrant colours and lasting quality." + }, %{type: :heading, text: "Printed sustainably"}, - %{type: :paragraph, text: "Because each item is printed on demand, there's no waste from unsold stock. My print partners use eco-friendly inks where possible, and products are shipped directly to you to minimise unnecessary handling."}, + %{ + type: :paragraph, + text: + "Because each item is printed on demand, there's no waste from unsold stock. My print partners use eco-friendly inks where possible, and products are shipped directly to you to minimise unnecessary handling." + }, %{type: :closing, text: "Thank you for visiting. It means a lot that you're here."} ] end @@ -427,42 +449,48 @@ defmodule SimpleshopTheme.Theme.PreviewData do %{ id: "1", author: "Sarah M.", - content: "The print quality is absolutely stunning - colours are exactly as shown online. My living room looks so much better now!", + content: + "The print quality is absolutely stunning - colours are exactly as shown online. My living room looks so much better now!", rating: 5, date: "2025-01-15" }, %{ id: "2", author: "James L.", - content: "Bought the forest hoodie as a gift. The packaging was lovely and the quality exceeded expectations. Will order again!", + content: + "Bought the forest hoodie as a gift. The packaging was lovely and the quality exceeded expectations. Will order again!", rating: 5, date: "2025-01-10" }, %{ id: "3", author: "Emily R.", - content: "My new favourite mug! I love sipping my morning tea while looking at that beautiful fern design.", + content: + "My new favourite mug! I love sipping my morning tea while looking at that beautiful fern design.", rating: 5, date: "2025-01-05" }, %{ id: "4", author: "Michael T.", - content: "The tote bag is so sturdy - I use it for everything now. Great print quality that hasn't faded at all.", + content: + "The tote bag is so sturdy - I use it for everything now. Great print quality that hasn't faded at all.", rating: 5, date: "2024-12-28" }, %{ id: "5", author: "Lisa K.", - content: "The night sky blanket is gorgeous and so cosy. Perfect for film nights on the sofa. Highly recommend!", + content: + "The night sky blanket is gorgeous and so cosy. Perfect for film nights on the sofa. Highly recommend!", rating: 5, date: "2024-12-20" }, %{ id: "6", author: "David P.", - content: "Ordered several prints for my new flat. They arrived well packaged and look amazing on the wall.", + content: + "Ordered several prints for my new flat. They arrived well packaged and look amazing on the wall.", rating: 5, date: "2024-12-15" } diff --git a/lib/simpleshop_theme_web.ex b/lib/simpleshop_theme_web.ex index 79921db..eef6873 100644 --- a/lib/simpleshop_theme_web.ex +++ b/lib/simpleshop_theme_web.ex @@ -17,7 +17,8 @@ defmodule SimpleshopThemeWeb do those modules here. """ - def static_paths, do: ~w(assets css fonts images image_cache mockups favicon.ico robots.txt demo.html) + def static_paths, + do: ~w(assets css fonts images image_cache mockups favicon.ico robots.txt demo.html) def router do quote do diff --git a/lib/simpleshop_theme_web/components/layouts/shop.html.heex b/lib/simpleshop_theme_web/components/layouts/shop.html.heex index 0543398..ccdf89c 100644 --- a/lib/simpleshop_theme_web/components/layouts/shop.html.heex +++ b/lib/simpleshop_theme_web/components/layouts/shop.html.heex @@ -1 +1 @@ -<%= @inner_content %> +{@inner_content} diff --git a/lib/simpleshop_theme_web/components/layouts/shop_root.html.heex b/lib/simpleshop_theme_web/components/layouts/shop_root.html.heex index d74eb4e..716a087 100644 --- a/lib/simpleshop_theme_web/components/layouts/shop_root.html.heex +++ b/lib/simpleshop_theme_web/components/layouts/shop_root.html.heex @@ -4,8 +4,14 @@ - - <.live_title><%= assigns[:page_title] || @theme_settings.site_name %> + + <.live_title>{assigns[:page_title] || @theme_settings.site_name} <%= for preload <- SimpleshopTheme.Theme.Fonts.preload_links( @theme_settings.typography, @@ -17,7 +23,9 @@ - +
+
<.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="about" mode={@mode} cart_count={@cart_count} /> + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page="about" + mode={@mode} + cart_count={@cart_count} + />
<.hero_section diff --git a/lib/simpleshop_theme_web/components/page_templates/cart.html.heex b/lib/simpleshop_theme_web/components/page_templates/cart.html.heex index 308d556..7ffb0b1 100644 --- a/lib/simpleshop_theme_web/components/page_templates/cart.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/cart.html.heex @@ -1,11 +1,21 @@ -
+
<.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="cart" mode={@mode} cart_count={@cart_count} /> + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page="cart" + mode={@mode} + cart_count={@cart_count} + />
<.page_title text="Your basket" /> diff --git a/lib/simpleshop_theme_web/components/page_templates/collection.html.heex b/lib/simpleshop_theme_web/components/page_templates/collection.html.heex index c3e6619..2e3a3d2 100644 --- a/lib/simpleshop_theme_web/components/page_templates/collection.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/collection.html.heex @@ -1,11 +1,21 @@ -
+
<.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="collection" mode={@mode} cart_count={@cart_count} /> + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page="collection" + mode={@mode} + cart_count={@cart_count} + />
<.collection_header title="All Products" product_count={length(@preview_data.products)} /> diff --git a/lib/simpleshop_theme_web/components/page_templates/contact.html.heex b/lib/simpleshop_theme_web/components/page_templates/contact.html.heex index 019cf50..5bfcb02 100644 --- a/lib/simpleshop_theme_web/components/page_templates/contact.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/contact.html.heex @@ -1,11 +1,21 @@ -
+
<.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="contact" mode={@mode} cart_count={@cart_count} /> + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page="contact" + mode={@mode} + cart_count={@cart_count} + />
<.hero_section @@ -20,11 +30,14 @@
<.order_tracking_card /> - <.info_card title="Handy to know" items={[ - %{label: "Printing", value: "2-5 business days"}, - %{label: "Delivery", value: "3-7 business days after printing"}, - %{label: "Returns", value: "Happy to help with faulty or damaged items"} - ]} /> + <.info_card + title="Handy to know" + items={[ + %{label: "Printing", value: "2-5 business days"}, + %{label: "Delivery", value: "3-7 business days after printing"}, + %{label: "Returns", value: "Happy to help with faulty or damaged items"} + ]} + /> <.newsletter_card /> diff --git a/lib/simpleshop_theme_web/components/page_templates/error.html.heex b/lib/simpleshop_theme_web/components/page_templates/error.html.heex index 0d07e0c..b48d0d4 100644 --- a/lib/simpleshop_theme_web/components/page_templates/error.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/error.html.heex @@ -1,13 +1,27 @@ -
+
<.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="error" mode={@mode} cart_count={@cart_count} /> + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page="error" + mode={@mode} + cart_count={@cart_count} + /> -
+
<.hero_section variant={:error} diff --git a/lib/simpleshop_theme_web/components/page_templates/home.html.heex b/lib/simpleshop_theme_web/components/page_templates/home.html.heex index 8c5ea0a..af96f16 100644 --- a/lib/simpleshop_theme_web/components/page_templates/home.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/home.html.heex @@ -1,11 +1,21 @@ -
+
<.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="home" mode={@mode} cart_count={@cart_count} /> + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page="home" + mode={@mode} + cart_count={@cart_count} + />
<.hero_section diff --git a/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex b/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex index 6034ed2..24a2916 100644 --- a/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex @@ -1,18 +1,36 @@ -
+
<.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={@mode} cart_count={@cart_count} /> + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page="pdp" + mode={@mode} + cart_count={@cart_count} + />
- <.breadcrumb items={[ - %{label: "Home", page: "home", href: "/"}, - %{label: @product.category, page: "collection", href: "/collections/#{@product.category |> String.downcase() |> String.replace(" ", "-")}"}, - %{label: @product.name, current: true} - ]} mode={@mode} /> + <.breadcrumb + items={[ + %{label: "Home", page: "home", href: "/"}, + %{ + label: @product.category, + page: "collection", + href: + "/collections/#{@product.category |> String.downcase() |> String.replace(" ", "-")}" + }, + %{label: @product.name, current: true} + ]} + mode={@mode} + />
<.product_gallery images={@gallery_images} product_name={@product.name} /> @@ -27,7 +45,12 @@
- <.reviews_section :if={@theme_settings.pdp_reviews} reviews={SimpleshopTheme.Theme.PreviewData.reviews()} average_rating={5} total_count={24} /> + <.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} diff --git a/lib/simpleshop_theme_web/components/shop_components.ex b/lib/simpleshop_theme_web/components/shop_components.ex index 80ad8bd..30dbab8 100644 --- a/lib/simpleshop_theme_web/components/shop_components.ex +++ b/lib/simpleshop_theme_web/components/shop_components.ex @@ -228,7 +228,11 @@ defmodule SimpleshopThemeWeb.ShopComponents do def shop_link_button(assigns) do ~H""" - + {render_slot(@inner_block)} """ @@ -257,7 +261,11 @@ defmodule SimpleshopThemeWeb.ShopComponents do def shop_link_outline(assigns) do ~H""" - + {render_slot(@inner_block)} """ @@ -323,7 +331,10 @@ defmodule SimpleshopThemeWeb.ShopComponents do style="position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; background-color: var(--t-surface-raised); border-top: 1px solid var(--t-border-default); box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); padding-bottom: env(safe-area-inset-bottom, 0px);" aria-label="Main navigation" > -
    + @@ -2043,9 +2393,18 @@ defmodule SimpleshopThemeWeb.ShopComponents do ~H""" <.shop_card class="p-6">

    {@title}

    - + - + {@email} @@ -2073,14 +2432,20 @@ defmodule SimpleshopThemeWeb.ShopComponents do <.newsletter_card variant={:inline} /> """ attr :title, :string, default: "Newsletter" - attr :description, :string, default: "Get new designs and updates in your inbox. No spam, I promise." + + attr :description, :string, + default: "Get new designs and updates in your inbox. No spam, I promise." + attr :button_text, :string, default: "Subscribe" attr :variant, :atom, default: :card def newsletter_card(%{variant: :inline} = assigns) do ~H"""
    -

    +

    {@title}

    @@ -2138,10 +2503,12 @@ defmodule SimpleshopThemeWeb.ShopComponents do <.social_links_card title="Elsewhere" links={[%{platform: :instagram, url: "https://instagram.com/example", label: "Instagram"}]} /> """ attr :title, :string, default: "Find me on" - attr :links, :list, default: [ - %{platform: :instagram, url: "#", label: "Instagram"}, - %{platform: :pinterest, url: "#", label: "Pinterest"} - ] + + attr :links, :list, + default: [ + %{platform: :instagram, url: "#", label: "Instagram"}, + %{platform: :pinterest, url: "#", label: "Pinterest"} + ] def social_links_card(assigns) do ~H""" @@ -2178,10 +2545,11 @@ defmodule SimpleshopThemeWeb.ShopComponents do <.social_links /> <.social_links links={[%{platform: :instagram, url: "https://instagram.com/example", label: "Instagram"}]} /> """ - attr :links, :list, default: [ - %{platform: :instagram, url: "#", label: "Instagram"}, - %{platform: :pinterest, url: "#", label: "Pinterest"} - ] + attr :links, :list, + default: [ + %{platform: :instagram, url: "#", label: "Instagram"}, + %{platform: :pinterest, url: "#", label: "Pinterest"} + ] def social_links(assigns) do ~H""" @@ -2226,7 +2594,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :instagram} = assigns) do ~H""" - + """ end @@ -2234,7 +2602,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :pinterest} = assigns) do ~H""" - + """ end @@ -2242,7 +2610,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :tiktok} = assigns) do ~H""" - + """ end @@ -2250,7 +2618,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :facebook} = assigns) do ~H""" - + """ end @@ -2258,7 +2626,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :twitter} = assigns) do ~H""" - + """ end @@ -2266,7 +2634,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :youtube} = assigns) do ~H""" - + """ end @@ -2274,7 +2642,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :patreon} = assigns) do ~H""" - + """ end @@ -2282,7 +2650,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :kofi} = assigns) do ~H""" - + """ end @@ -2290,7 +2658,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :etsy} = assigns) do ~H""" - + """ end @@ -2298,7 +2666,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :gumroad} = assigns) do ~H""" - + """ end @@ -2306,7 +2674,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :bandcamp} = assigns) do ~H""" - + """ end @@ -2315,7 +2683,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :mastodon} = assigns) do ~H""" - + """ end @@ -2323,7 +2691,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :pixelfed} = assigns) do ~H""" - + """ end @@ -2331,7 +2699,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :bluesky} = assigns) do ~H""" - + """ end @@ -2339,7 +2707,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :peertube} = assigns) do ~H""" - + """ end @@ -2347,7 +2715,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :lemmy} = assigns) do ~H""" - + """ end @@ -2355,7 +2723,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :matrix} = assigns) do ~H""" - + """ end @@ -2364,7 +2732,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :github} = assigns) do ~H""" - + """ end @@ -2372,7 +2740,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :gitlab} = assigns) do ~H""" - + """ end @@ -2380,7 +2748,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :codeberg} = assigns) do ~H""" - + """ end @@ -2388,7 +2756,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :sourcehut} = assigns) do ~H""" - + """ end @@ -2397,7 +2765,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :discord} = assigns) do ~H""" - + """ end @@ -2405,7 +2773,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :telegram} = assigns) do ~H""" - + """ end @@ -2413,7 +2781,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :signal} = assigns) do ~H""" - + """ end @@ -2422,7 +2790,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :substack} = assigns) do ~H""" - + """ end @@ -2430,7 +2798,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :rss} = assigns) do ~H""" - + """ end @@ -2438,7 +2806,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(%{platform: :website} = assigns) do ~H""" - + """ end @@ -2447,7 +2815,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp social_icon(assigns) do ~H""" - + """ end @@ -2470,7 +2838,10 @@ defmodule SimpleshopThemeWeb.ShopComponents do def cart_item(assigns) do ~H""" <.shop_card class="flex gap-4 p-4"> -

    +
    {@item.product.name}
    -

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

    + {@item.product.name}

    - <%= @item.variant %> + {@item.variant}

    -
    +
    - - <%= @item.quantity %> + + {@item.quantity}
    @@ -2541,7 +2921,10 @@ defmodule SimpleshopThemeWeb.ShopComponents do ~H""" <.shop_card class="p-6 sticky top-4"> -

    +

    Order Summary

    @@ -2554,7 +2937,9 @@ defmodule SimpleshopThemeWeb.ShopComponents do
    Delivery - {@currency}{Float.round(@delivery / 100, 2)} + + {@currency}{Float.round(@delivery / 100, 2)} +
    VAT (20%) @@ -2575,11 +2960,18 @@ defmodule SimpleshopThemeWeb.ShopComponents do <%= if @mode == :preview do %> - <.shop_button_outline phx-click="change_preview_page" phx-value-page="collection" class="w-full px-6 py-3 font-semibold transition-all"> + <.shop_button_outline + phx-click="change_preview_page" + phx-value-page="collection" + class="w-full px-6 py-3 font-semibold transition-all" + > Continue Shopping <% else %> - <.shop_link_outline href="/collections/all" class="block w-full px-6 py-3 font-semibold transition-all text-center"> + <.shop_link_outline + href="/collections/all" + class="block w-full px-6 py-3 font-semibold transition-all text-center" + > Continue Shopping <% end %> @@ -2618,12 +3010,19 @@ defmodule SimpleshopThemeWeb.ShopComponents do / <% end %> <%= if item[:current] do %> - <%= item.label %> + {item.label} <% else %> <%= if @mode == :preview do %> - <%= item.label %> + + {item.label} + <% else %> - <%= item.label %> + {item.label} <% end %> <% end %> <% end %> @@ -2659,8 +3058,11 @@ defmodule SimpleshopThemeWeb.ShopComponents do def related_products_section(assigns) do ~H"""
    -

    - <%= @title %> +

    + {@title}

    <.product_grid columns={:fixed_4} gap="gap-6"> @@ -2704,8 +3106,15 @@ defmodule SimpleshopThemeWeb.ShopComponents do ~H"""
    <%= for i <- 1..@max do %> - - + + <% end %>
    @@ -2728,20 +3137,24 @@ defmodule SimpleshopThemeWeb.ShopComponents do <.trust_badges /> <.trust_badges items={[%{icon: :check, title: "Custom", description: "Badge text"}]} /> """ - attr :items, :list, default: [ - %{icon: :check, title: "Free Delivery", description: "On orders over £40"}, - %{icon: :shield, title: "Easy Returns", description: "30-day return policy"} - ] + attr :items, :list, + default: [ + %{icon: :check, title: "Free Delivery", description: "On orders over £40"}, + %{icon: :shield, title: "Easy Returns", description: "30-day return policy"} + ] def trust_badges(assigns) do ~H""" -
    +
    <%= for item <- @items do %>
    <.trust_badge_icon icon={item.icon} />
    -

    <%= item.title %>

    -

    <%= item.description %>

    +

    {item.title}

    +

    {item.description}

    <% end %> @@ -2753,7 +3166,13 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp trust_badge_icon(%{icon: :check} = assigns) do ~H""" - + """ @@ -2761,15 +3180,32 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp trust_badge_icon(%{icon: :shield} = assigns) do ~H""" - - + + """ end defp trust_badge_icon(assigns) do ~H""" - + """ @@ -2801,23 +3237,39 @@ defmodule SimpleshopThemeWeb.ShopComponents do attr :open, :boolean, default: true def reviews_section(assigns) do - assigns = assign_new(assigns, :display_count, fn -> - assigns.total_count || length(assigns.reviews) - end) + assigns = + assign_new(assigns, :display_count, fn -> + assigns.total_count || length(assigns.reviews) + end) ~H""" -
    - +
    +
    -

    +

    Customer reviews

    <.star_rating rating={@average_rating} /> - (<%= @display_count %>) + ({@display_count})
    - + @@ -2855,16 +3307,23 @@ defmodule SimpleshopThemeWeb.ShopComponents do
    <.star_rating rating={@review.rating} /> - <%= @review.date %> + {@review.date}
    -

    <%= @review.title %>

    +

    {@review.title}

    - <%= @review.body %> + {@review.body}

    - <%= @review.author %> + + {@review.author} + <%= if @review.verified do %> - Verified purchase + + Verified purchase + <% end %>
    @@ -2907,7 +3366,12 @@ defmodule SimpleshopThemeWeb.ShopComponents do
    - +
    @@ -2919,10 +3383,14 @@ defmodule SimpleshopThemeWeb.ShopComponents do class={"aspect-square bg-gray-200 cursor-pointer overflow-hidden pdp-thumbnail#{if idx == 0, do: " pdp-thumbnail-active", else: ""}"} style="border-radius: var(--t-radius-image);" data-index={idx} - phx-click={Phoenix.LiveView.JS.set_attribute({"src", img_url}, to: "##{@id_prefix}-main-image") - |> Phoenix.LiveView.JS.set_attribute({"data-current-index", to_string(idx)}, to: "##{@id_prefix}-lightbox") + phx-click={ + Phoenix.LiveView.JS.set_attribute({"src", img_url}, to: "##{@id_prefix}-main-image") + |> Phoenix.LiveView.JS.set_attribute({"data-current-index", to_string(idx)}, + to: "##{@id_prefix}-lightbox" + ) |> Phoenix.LiveView.JS.remove_class("pdp-thumbnail-active", to: ".pdp-thumbnail") - |> Phoenix.LiveView.JS.add_class("pdp-thumbnail-active")} + |> Phoenix.LiveView.JS.add_class("pdp-thumbnail-active") + } > - + - +
    """ @@ -3027,24 +3499,35 @@ defmodule SimpleshopThemeWeb.ShopComponents do def product_info(assigns) do ~H"""
    -

    - <%= @product.name %> +

    + {@product.name}

    <%= if @product.on_sale do %> - - <%= @currency %><%= @product.price / 100 %> + + {@currency}{@product.price / 100} - <%= @currency %><%= @product.compare_at_price / 100 %> + {@currency}{@product.compare_at_price / 100} - - SAVE <%= round((@product.compare_at_price - @product.price) / @product.compare_at_price * 100) %>% + + SAVE {round( + (@product.compare_at_price - @product.price) / @product.compare_at_price * 100 + )}% <% else %> - <%= @currency %><%= @product.price / 100 %> + {@currency}{@product.price / 100} <% end %>
    @@ -3071,14 +3554,15 @@ defmodule SimpleshopThemeWeb.ShopComponents do attr :selected, :string, default: nil def variant_selector(assigns) do - assigns = assign_new(assigns, :selected_value, fn -> - assigns.selected || List.first(assigns.options) - end) + assigns = + assign_new(assigns, :selected_value, fn -> + assigns.selected || List.first(assigns.options) + end) ~H"""
    <%= for option <- @options do %> @@ -3087,7 +3571,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do class="px-4 py-2 font-medium transition-all" style={"border: 2px solid #{if option == @selected_value, do: "hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l))", else: "var(--t-border-default)"}; border-radius: var(--t-radius-button); color: var(--t-text-primary); background: #{if option == @selected_value, do: "hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l) / 0.1)", else: "transparent"};"} > - <%= option %> + {option} <% end %>
    @@ -3122,10 +3606,16 @@ defmodule SimpleshopThemeWeb.ShopComponents do Quantity
    -
    +
    - - <%= @quantity %> + + {@quantity}
    @@ -3159,15 +3649,25 @@ defmodule SimpleshopThemeWeb.ShopComponents do def add_to_cart_button(assigns) do ~H""" -
    +
    """ @@ -3199,14 +3699,22 @@ defmodule SimpleshopThemeWeb.ShopComponents do def accordion_item(assigns) do ~H"""
    - - <%= @title %> - + + {@title} +
    - <%= render_slot(@inner_block) %> + {render_slot(@inner_block)}
    """ @@ -3231,19 +3739,26 @@ defmodule SimpleshopThemeWeb.ShopComponents do attr :size_guide, :list, default: nil def product_details(assigns) do - assigns = assign_new(assigns, :sizes, fn -> - assigns.size_guide || [ - %{size: "S", chest: "86-91", length: "71"}, - %{size: "M", chest: "91-96", length: "73"}, - %{size: "L", chest: "96-101", length: "75"}, - %{size: "XL", chest: "101-106", length: "77"} - ] - end) + assigns = + assign_new(assigns, :sizes, fn -> + assigns.size_guide || + [ + %{size: "S", chest: "86-91", length: "71"}, + %{size: "M", chest: "91-96", length: "73"}, + %{size: "L", chest: "96-101", length: "75"}, + %{size: "XL", chest: "101-106", length: "77"} + ] + end) ~H""" -
    +
    <.accordion_item title="Description" open={true}> -

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

    +

    + {@product.description}. Crafted with attention to detail and quality materials, this product is designed to last. Perfect for everyday use or special occasions. +

    <%= if @show_size_guide do %> @@ -3251,17 +3766,27 @@ defmodule SimpleshopThemeWeb.ShopComponents do - - - + + + <%= for {size_row, idx} <- Enum.with_index(@sizes) do %> - - - - + + + + <% end %> @@ -3273,11 +3798,15 @@ defmodule SimpleshopThemeWeb.ShopComponents do

    Delivery

    -

    Free UK delivery on orders over £40. Standard delivery 3-5 working days. Express delivery available at checkout.

    +

    + Free UK delivery on orders over £40. Standard delivery 3-5 working days. Express delivery available at checkout. +

    Returns

    -

    We offer a 30-day return policy. Items must be unused and in original packaging. Please contact us to arrange a return.

    +

    + We offer a 30-day return policy. Items must be unused and in original packaging. Please contact us to arrange a return. +

    @@ -3303,8 +3832,11 @@ defmodule SimpleshopThemeWeb.ShopComponents do def page_title(assigns) do ~H""" -

    - <%= @text %> +

    + {@text}

    """ end @@ -3385,7 +3917,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp rich_text_block(%{block: %{type: :lead}} = assigns) do ~H"""

    - <%= @block.text %> + {@block.text}

    """ end @@ -3393,15 +3925,18 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp rich_text_block(%{block: %{type: :paragraph}} = assigns) do ~H"""

    - <%= @block.text %> + {@block.text}

    """ end defp rich_text_block(%{block: %{type: :heading}} = assigns) do ~H""" -

    - <%= @block.text %> +

    + {@block.text}

    """ end @@ -3409,7 +3944,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp rich_text_block(%{block: %{type: :closing}} = assigns) do ~H"""

    - <%= @block.text %> + {@block.text}

    """ end @@ -3417,7 +3952,7 @@ defmodule SimpleshopThemeWeb.ShopComponents do defp rich_text_block(assigns) do ~H"""

    - <%= @block.text %> + {@block.text}

    """ end diff --git a/lib/simpleshop_theme_web/controllers/error_html.ex b/lib/simpleshop_theme_web/controllers/error_html.ex index ec00e84..6e185e9 100644 --- a/lib/simpleshop_theme_web/controllers/error_html.ex +++ b/lib/simpleshop_theme_web/controllers/error_html.ex @@ -12,13 +12,21 @@ defmodule SimpleshopThemeWeb.ErrorHTML do alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData} def render("404.html", assigns) do - render_error_page(assigns, "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.") + render_error_page( + assigns, + "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." + ) end def render("500.html", assigns) do - render_error_page(assigns, "500", "Server Error", - "Something went wrong on our end. Please try again later or contact support if the problem persists.") + render_error_page( + assigns, + "500", + "Server Error", + "Something went wrong on our end. Please try again later or contact support if the problem persists." + ) end def render(template, _assigns) do @@ -57,23 +65,25 @@ defmodule SimpleshopThemeWeb.ErrorHTML do - <%= @error_code %> - <%= @error_title %> + {@error_code} - {@error_title} -
    +
    css + {:ok, css} -> + css + :miss -> css = CSSGenerator.generate(theme_settings) CSSCache.put(css) css end + {theme_settings, generated_css} rescue _ -> {%ThemeSettings{}, ""} diff --git a/lib/simpleshop_theme_web/live/shop_live/about.ex b/lib/simpleshop_theme_web/live/shop_live/about.ex index 66678ce..4a42300 100644 --- a/lib/simpleshop_theme_web/live/shop_live/about.ex +++ b/lib/simpleshop_theme_web/live/shop_live/about.ex @@ -11,7 +11,9 @@ defmodule SimpleshopThemeWeb.ShopLive.About do generated_css = case CSSCache.get() do - {:ok, css} -> css + {:ok, css} -> + css + :miss -> css = CSSGenerator.generate(theme_settings) CSSCache.put(css) diff --git a/lib/simpleshop_theme_web/live/shop_live/cart.ex b/lib/simpleshop_theme_web/live/shop_live/cart.ex index d3874c1..37fbee3 100644 --- a/lib/simpleshop_theme_web/live/shop_live/cart.ex +++ b/lib/simpleshop_theme_web/live/shop_live/cart.ex @@ -11,7 +11,9 @@ defmodule SimpleshopThemeWeb.ShopLive.Cart do generated_css = case CSSCache.get() do - {:ok, css} -> css + {:ok, css} -> + css + :miss -> css = CSSGenerator.generate(theme_settings) CSSCache.put(css) @@ -24,9 +26,11 @@ defmodule SimpleshopThemeWeb.ShopLive.Cart do # For now, use preview data for cart items # In a real implementation, this would come from session/database cart_page_items = PreviewData.cart_items() - cart_page_subtotal = Enum.reduce(cart_page_items, 0, fn item, acc -> - acc + item.product.price * item.quantity - end) + + cart_page_subtotal = + Enum.reduce(cart_page_items, 0, fn item, acc -> + acc + item.product.price * item.quantity + end) socket = socket diff --git a/lib/simpleshop_theme_web/live/shop_live/collection.ex b/lib/simpleshop_theme_web/live/shop_live/collection.ex index b91766b..8d0cf37 100644 --- a/lib/simpleshop_theme_web/live/shop_live/collection.ex +++ b/lib/simpleshop_theme_web/live/shop_live/collection.ex @@ -20,7 +20,9 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do generated_css = case CSSCache.get() do - {:ok, css} -> css + {:ok, css} -> + css + :miss -> css = CSSGenerator.generate(theme_settings) CSSCache.put(css) @@ -82,7 +84,9 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do @impl true def handle_event("sort_changed", %{"sort" => sort}, socket) do - slug = if socket.assigns.current_category, do: socket.assigns.current_category.slug, else: "all" + slug = + if socket.assigns.current_category, do: socket.assigns.current_category.slug, else: "all" + {:noreply, push_patch(socket, to: ~p"/collections/#{slug}?sort=#{sort}")} end @@ -100,7 +104,10 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do @impl true def render(assigns) do ~H""" -
    +
    <%= if @theme_settings.announcement_bar do %> @@ -145,7 +152,11 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do <%= if @products == [] do %>

    No products found in this collection.

    - <.link navigate={~p"/collections/all"} class="mt-4 inline-block underline" style="color: var(--t-text-accent);"> + <.link + navigate={~p"/collections/all"} + class="mt-4 inline-block underline" + style="color: var(--t-text-accent);" + > View all products
    @@ -155,9 +166,15 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do - + - +
    @@ -176,10 +193,12 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do "px-4 py-2 rounded-full text-sm transition-colors", if(@current_slug == nil, do: "font-medium", else: "hover:opacity-80") ]} - style={if(@current_slug == nil, - do: "background-color: var(--t-accent); color: var(--t-text-on-accent);", - else: "background-color: var(--t-surface-raised); color: var(--t-text-primary);" - )} + style={ + if(@current_slug == nil, + do: "background-color: var(--t-accent); color: var(--t-text-on-accent);", + else: "background-color: var(--t-surface-raised); color: var(--t-text-primary);" + ) + } > All @@ -192,10 +211,12 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do "px-4 py-2 rounded-full text-sm transition-colors", if(@current_slug == category.slug, do: "font-medium", else: "hover:opacity-80") ]} - style={if(@current_slug == category.slug, - do: "background-color: var(--t-accent); color: var(--t-text-on-accent);", - else: "background-color: var(--t-surface-raised); color: var(--t-text-primary);" - )} + style={ + if(@current_slug == category.slug, + do: "background-color: var(--t-accent); color: var(--t-text-on-accent);", + else: "background-color: var(--t-surface-raised); color: var(--t-text-primary);" + ) + } > {category.name} diff --git a/lib/simpleshop_theme_web/live/shop_live/contact.ex b/lib/simpleshop_theme_web/live/shop_live/contact.ex index af37f1e..607abe8 100644 --- a/lib/simpleshop_theme_web/live/shop_live/contact.ex +++ b/lib/simpleshop_theme_web/live/shop_live/contact.ex @@ -11,7 +11,9 @@ defmodule SimpleshopThemeWeb.ShopLive.Contact do generated_css = case CSSCache.get() do - {:ok, css} -> css + {:ok, css} -> + css + :miss -> css = CSSGenerator.generate(theme_settings) CSSCache.put(css) diff --git a/lib/simpleshop_theme_web/live/shop_live/home.ex b/lib/simpleshop_theme_web/live/shop_live/home.ex index 948d4f1..70af4d9 100644 --- a/lib/simpleshop_theme_web/live/shop_live/home.ex +++ b/lib/simpleshop_theme_web/live/shop_live/home.ex @@ -11,7 +11,9 @@ defmodule SimpleshopThemeWeb.ShopLive.Home do generated_css = case CSSCache.get() do - {:ok, css} -> css + {:ok, css} -> + css + :miss -> css = CSSGenerator.generate(theme_settings) CSSCache.put(css) diff --git a/lib/simpleshop_theme_web/live/shop_live/product_show.ex b/lib/simpleshop_theme_web/live/shop_live/product_show.ex index f90b9cd..b42a623 100644 --- a/lib/simpleshop_theme_web/live/shop_live/product_show.ex +++ b/lib/simpleshop_theme_web/live/shop_live/product_show.ex @@ -11,7 +11,9 @@ defmodule SimpleshopThemeWeb.ShopLive.ProductShow do generated_css = case CSSCache.get() do - {:ok, css} -> css + {:ok, css} -> + css + :miss -> css = CSSGenerator.generate(theme_settings) CSSCache.put(css) diff --git a/lib/simpleshop_theme_web/live/theme_live/index.ex b/lib/simpleshop_theme_web/live/theme_live/index.ex index 8fd3126..6f25b5b 100644 --- a/lib/simpleshop_theme_web/live/theme_live/index.ex +++ b/lib/simpleshop_theme_web/live/theme_live/index.ex @@ -10,6 +10,7 @@ defmodule SimpleshopThemeWeb.ThemeLive.Index do theme_settings = Settings.get_theme_settings() generated_css = CSSGenerator.generate(theme_settings) active_preset = Presets.detect_preset(theme_settings) + preview_data = %{ products: PreviewData.products(), cart_items: PreviewData.cart_items(), @@ -361,7 +362,9 @@ defmodule SimpleshopThemeWeb.ThemeLive.Index do defp preview_page(%{page: :cart} = assigns) do cart_items = assigns.preview_data.cart_items - subtotal = Enum.reduce(cart_items, 0, fn item, acc -> acc + item.product.price * item.quantity end) + + subtotal = + Enum.reduce(cart_items, 0, fn item, acc -> acc + item.product.price * item.quantity end) assigns = assigns 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 dcf6083..b4abf8f 100644 --- a/lib/simpleshop_theme_web/live/theme_live/index.html.heex +++ b/lib/simpleshop_theme_web/live/theme_live/index.html.heex @@ -5,7 +5,10 @@ id="theme-sidebar" class={[ "bg-base-100 border-r border-base-300 lg:h-screen flex-shrink-0 transition-all duration-300", - if(@sidebar_collapsed, do: "w-12 overflow-hidden", else: "w-full lg:w-[380px] overflow-y-auto p-6") + if(@sidebar_collapsed, + do: "w-12 overflow-hidden", + else: "w-full lg:w-[380px] overflow-y-auto p-6" + ) ]} > @@ -19,866 +22,1065 @@ aria-expanded="false" aria-controls="theme-sidebar" > -
    <% else %> - -
    -
    -

    Theme Studio

    -

    One theme, infinite possibilities. Every combination is designed to work beautifully.

    + +
    +
    +

    + Theme Studio +

    +

    + One theme, infinite possibilities. Every combination is designed to work beautifully. +

    +
    +
    - -
    - - -
    - -
    - - -
    - - -
    - - - -
    - <%= for {value, title, desc} <- [ + + +
    + +
    + + +
    + + +
    + + + +
    + <%= for {value, title, desc} <- [ {"text-only", "Shop name only", "Your name in the heading font"}, {"logo-text", "Logo + shop name", "Your logo image with name beside it"}, {"logo-only", "Logo only", "Just your logo (with text built in)"} ] do %> - + <% end %> +
    + + + <%= if @theme_settings.logo_mode in ["logo-text", "logo-only"] do %> +
    + + Upload logo (SVG or PNG) -
    -
    <%= title %>
    -
    <%= desc %>
    +
    +
    + + + <%= if @logo_image do %> +
    + Current logo + +
    + <% end %>
    - - <% end %> -
    - - <%= if @theme_settings.logo_mode in ["logo-text", "logo-only"] do %> -
    - Upload logo (SVG or PNG) -
    -
    - - - <%= if @logo_image do %> -
    - Current logo + <%= for entry <- @uploads.logo_upload.entries do %> +
    +
    +
    +
    +
    + {entry.progress}% + phx-click="cancel_upload" + phx-value-ref={entry.ref} + phx-value-upload="logo_upload" + class="text-base-content/40 hover:text-base-content/70" + > + × +
    + <%= for err <- upload_errors(@uploads.logo_upload, entry) do %> +

    {error_to_string(err)}

    + <% end %> + <% end %> + + <%= for err <- upload_errors(@uploads.logo_upload) do %> +

    {error_to_string(err)}

    + <% end %> + + + <%= if @logo_image do %> +
    +
    + Logo size + + {@theme_settings.logo_size}px + +
    + + + + + <%= if @logo_image.is_svg do %> +
    + + + <%= if @theme_settings.logo_recolor do %> +
    + + + {@theme_settings.logo_color} + + + <% end %> +
    + <% end %> <% end %>
    + <% end %> +
    + + +
    + +
    + + + <%= if @theme_settings.header_background_enabled do %> +
    + + Upload header image + +
    + + - <%= for entry <- @uploads.logo_upload.entries do %> + <%= if @header_image do %> +
    + Current header background + +
    + + +
    +
    +
    + Zoom + + {@theme_settings.header_zoom}% + +
    + + +
    +
    + + Horizontal position + + + {@theme_settings.header_position_x}% + +
    + + +
    +
    + + Vertical position + + + {@theme_settings.header_position_y}% + +
    + + +
    + <% end %> + + <%= for entry <- @uploads.header_upload.entries do %>
    -
    +
    +
    - <%= entry.progress %>% + {entry.progress}% + > + × +
    - <%= for err <- upload_errors(@uploads.logo_upload, entry) do %> -

    <%= error_to_string(err) %>

    + <%= for err <- upload_errors(@uploads.header_upload, entry) do %> +

    {error_to_string(err)}

    <% end %> <% end %> - <%= for err <- upload_errors(@uploads.logo_upload) do %> -

    <%= error_to_string(err) %>

    - <% end %> - - - <%= if @logo_image do %> -
    -
    - Logo size - <%= @theme_settings.logo_size %>px -
    - - - - - <%= if @logo_image.is_svg do %> -
    - - - <%= if @theme_settings.logo_recolor do %> -
    - - <%= @theme_settings.logo_color %> - - <% end %> -
    - <% end %> + <%= for err <- upload_errors(@uploads.header_upload) do %> +

    {error_to_string(err)}

    <% end %>
    <% end %> -
    - - -
    - -
    - - - <%= if @theme_settings.header_background_enabled do %> -
    - Upload header image -
    - - - - <%= if @header_image do %> -
    - Current header background + + +
    + +
    + <%= for {preset_name, description} <- @presets_with_descriptions do %> -
    - - -
    -
    -
    - Zoom - <%= @theme_settings.header_zoom %>% + phx-click="apply_preset" + phx-value-preset={preset_name} + class={[ + "p-3 rounded-lg text-left transition-all border-2", + if(@active_preset == preset_name, + do: "border-base-content bg-base-100", + else: "border-transparent bg-base-200 hover:bg-base-300" + ) + ]} + > +
    + {preset_name}
    - - -
    -
    - Horizontal position - <%= @theme_settings.header_position_x %>% -
    - - -
    -
    - Vertical position - <%= @theme_settings.header_position_y %>% -
    - - -
    - <% end %> - - <%= for entry <- @uploads.header_upload.entries do %> -
    -
    -
    -
    - <%= entry.progress %>% - -
    - <%= for err <- upload_errors(@uploads.header_upload, entry) do %> -

    <%= error_to_string(err) %>

    +
    {description}
    + <% end %> - <% end %> - - <%= for err <- upload_errors(@uploads.header_upload) do %> -

    <%= error_to_string(err) %>

    - <% end %> +
    +
    + + +
    + +
    +
    + + + {@theme_settings.accent_color} + +
    +
    - <% end %> - -
    - -
    - <%= for {preset_name, description} <- @presets_with_descriptions do %> -
    + +
    + +
    +
    + + + {@theme_settings.sale_color} + +
    + +
    + + +
    + + + Customise + + -
    <%= preset_name %>
    -
    <%= description %>
    - - <% end %> -
    -
    + + + - -
    - -
    -
    - - <%= @theme_settings.accent_color %> -
    - -
    +
    + +
    +
    + + + + + + Typography +
    -
    - -
    -
    - - <%= @theme_settings.secondary_accent_color %> -
    - -
    +
    + +
    + <%= for typo <- ["clean", "editorial", "modern", "classic", "friendly", "minimal"] do %> + + <% end %> +
    +
    -
    - -
    -
    - - <%= @theme_settings.sale_color %> -
    - -
    +
    + +
    + <%= for {value, label} <- [{"small", "Small"}, {"medium", "Medium"}, {"large", "Large"}] do %> + + <% end %> +
    +
    - -
    - - Customise - - - - - -
    - -
    -
    - - - - - - Typography -
    - -
    - -
    - <%= for typo <- ["clean", "editorial", "modern", "classic", "friendly", "minimal"] do %> - - <% end %> +
    + +
    + <%= for {value, label} <- [{"regular", "Regular"}, {"medium", "Medium"}, {"bold", "Bold"}] do %> + + <% end %> +
    + + +
    +
    + + + + + Colours +
    -
    - -
    - <%= for {value, label} <- [{"small", "Small"}, {"medium", "Medium"}, {"large", "Large"}] do %> - - <% end %> +
    + +
    + <%= for mood <- ["warm", "neutral", "cool", "dark"] do %> + + <% end %> +
    + + +
    +
    + + + + + + Layout +
    +
    + +
    + <%= for cols <- ["2", "3", "4"] do %> + + <% end %> +
    +
    + +
    + +
    + <%= for density <- ["spacious", "balanced", "compact"] do %> + + <% end %> +
    +
    + +
    + +
    + <%= for layout <- ["standard", "centered", "left"] do %> + + <% end %> +
    +
    + +
    + +
    + +
    + +
    +
    + +
    - -
    - <%= for {value, label} <- [{"regular", "Regular"}, {"medium", "Medium"}, {"bold", "Bold"}] do %> - - <% end %> +
    + + + + Shape +
    + +
    + +
    + <%= for shape <- ["sharp", "soft", "round", "pill"] do %> + + <% end %> +
    +
    + +
    + +
    + <%= for {value, label} <- [{"none", "None"}, {"sm", "Subtle"}, {"md", "Medium"}, {"lg", "Strong"}] do %> + + <% end %> +
    +
    + +
    + +
    + <%= for {value, label} <- [{"filled", "Filled"}, {"outline", "Outline"}, {"soft", "Soft"}] do %> + + <% end %> +
    +
    +
    + + +
    +
    + + + + + + + Products +
    + +
    + +
    + <%= for width <- ["contained", "wide", "full"] do %> + + <% end %> +
    +
    + +
    + +
    + <%= for {value, label} <- [{"square", "Square"}, {"portrait", "Portrait"}, {"landscape", "Landscape"}] do %> + + <% end %> +
    +
    + +
    + +
    + <%= for {value, label} <- [{"left", "Left"}, {"center", "Centre"}] do %> + + <% end %> +
    +
    + +
    + +
    + +
    + +
    +
    + + +
    +
    + + + + + Product page +
    + +
    + +
    + +
    + +
    + +
    +
    - - -
    -
    - - - - - Colours -
    - -
    - -
    - <%= for mood <- ["warm", "neutral", "cool", "dark"] do %> - - <% end %> -
    -
    +
    + + +
    +
    + Current combination
    - - -
    -
    - - - - - - Layout -
    - -
    - -
    - <%= for cols <- ["2", "3", "4"] do %> - - <% end %> -
    -
    - -
    - -
    - <%= for density <- ["spacious", "balanced", "compact"] do %> - - <% end %> -
    -
    - -
    - -
    - <%= for layout <- ["standard", "centered", "left"] do %> - - <% end %> -
    -
    - -
    - -
    - -
    - -
    +
    + {String.capitalize(@theme_settings.mood)} · {String.capitalize( + @theme_settings.typography + )} · {String.capitalize(@theme_settings.shape)} · {String.capitalize( + @theme_settings.density + )} · {@theme_settings.grid_columns}-up · {String.capitalize( + @theme_settings.header_layout + )}
    - - -
    -
    - - - - Shape -
    - -
    - -
    - <%= for shape <- ["sharp", "soft", "round", "pill"] do %> - - <% end %> -
    -
    - -
    - -
    - <%= for {value, label} <- [{"none", "None"}, {"sm", "Subtle"}, {"md", "Medium"}, {"lg", "Strong"}] do %> - - <% end %> -
    -
    - -
    - -
    - <%= for {value, label} <- [{"filled", "Filled"}, {"outline", "Outline"}, {"soft", "Soft"}] do %> - - <% end %> -
    -
    -
    - - -
    -
    - - - - - - - Products -
    - -
    - -
    - <%= for width <- ["contained", "wide", "full"] do %> - - <% end %> -
    -
    - -
    - -
    - <%= for {value, label} <- [{"square", "Square"}, {"portrait", "Portrait"}, {"landscape", "Landscape"}] do %> - - <% end %> -
    -
    - -
    - -
    - <%= for {value, label} <- [{"left", "Left"}, {"center", "Centre"}] do %> - - <% end %> -
    -
    - -
    - -
    - -
    - -
    -
    - - -
    -
    - - - - - Product page -
    - -
    - -
    - -
    - -
    - -
    - -
    +
    + One of 100,000+ possible combinations
    - - - -
    -
    Current combination
    -
    - <%= String.capitalize(@theme_settings.mood) %> · <%= String.capitalize(@theme_settings.typography) %> · <%= String.capitalize(@theme_settings.shape) %> · <%= String.capitalize(@theme_settings.density) %> · <%= @theme_settings.grid_columns %>-up · <%= String.capitalize(@theme_settings.header_layout) %> -
    -
    One of 100,000+ possible combinations
    -
    <% end %>
    - - + +
    @@ -904,12 +1106,12 @@ ) ]} > - <%= label %> + {label} <% end %>
    - - + +
    @@ -917,26 +1119,36 @@
    - + - <%= @theme_settings.site_name |> String.downcase() |> String.replace(" ", "") %>.myshopify.com + + {@theme_settings.site_name |> String.downcase() |> String.replace(" ", "")}.myshopify.com +
    - - -
    + + +
    """ + result = SVGRecolorer.recolor(svg, "#ff6600") assert result =~ "fill:#ff6600" refute result =~ "#FFFFFF" @@ -80,6 +81,7 @@ defmodule SimpleshopTheme.Media.SVGRecolorerTest do svg = """ """ + result = SVGRecolorer.recolor(svg, "#ff6600") assert result =~ "stroke:#ff6600" refute result =~ "#000000" @@ -89,6 +91,7 @@ defmodule SimpleshopTheme.Media.SVGRecolorerTest do svg = """ """ + result = SVGRecolorer.recolor(svg, "#ff6600") assert result =~ "fill:none" assert result =~ "stroke:#ff6600" @@ -98,6 +101,7 @@ defmodule SimpleshopTheme.Media.SVGRecolorerTest do svg = """ """ + result = SVGRecolorer.recolor(svg, "#ff6600") assert result =~ "fill:#ff6600" assert result =~ "stroke:#ff6600" diff --git a/test/simpleshop_theme/products/product_test.exs b/test/simpleshop_theme/products/product_test.exs index e09f646..41d6fdf 100644 --- a/test/simpleshop_theme/products/product_test.exs +++ b/test/simpleshop_theme/products/product_test.exs @@ -96,7 +96,10 @@ defmodule SimpleshopTheme.Products.ProductTest do test "stores provider_data as map", %{conn: conn} do provider_data = %{"blueprint_id" => 145, "print_provider_id" => 29, "extra" => "value"} - attrs = valid_product_attrs(%{provider_connection_id: conn.id, provider_data: provider_data}) + + attrs = + valid_product_attrs(%{provider_connection_id: conn.id, provider_data: provider_data}) + changeset = Product.changeset(%Product{}, attrs) assert changeset.valid? diff --git a/test/simpleshop_theme/products_test.exs b/test/simpleshop_theme/products_test.exs index 9f73bed..5ffacb9 100644 --- a/test/simpleshop_theme/products_test.exs +++ b/test/simpleshop_theme/products_test.exs @@ -437,7 +437,9 @@ defmodule SimpleshopTheme.ProductsTest do test "updates existing variants" do product = product_fixture() - existing = product_variant_fixture(%{product: product, provider_variant_id: "v1", price: 2000}) + + existing = + product_variant_fixture(%{product: product, provider_variant_id: "v1", price: 2000}) variants = [ %{provider_variant_id: "v1", title: "Small Updated", price: 2200} diff --git a/test/simpleshop_theme/settings_test.exs b/test/simpleshop_theme/settings_test.exs index 9dc562c..35e9fe1 100644 --- a/test/simpleshop_theme/settings_test.exs +++ b/test/simpleshop_theme/settings_test.exs @@ -76,13 +76,15 @@ defmodule SimpleshopTheme.SettingsTest do # Cache should now contain new CSS with the red accent color {:ok, updated_css} = CSSCache.get() assert updated_css =~ ".themed {" - assert updated_css =~ "--t-accent-h: 0" # Red = hue 0 + # Red = hue 0 + assert updated_css =~ "--t-accent-h: 0" # Change to blue {:ok, _settings} = Settings.update_theme_settings(%{accent_color: "#0000ff"}) {:ok, blue_css} = CSSCache.get() - assert blue_css =~ "--t-accent-h: 240" # Blue = hue 240 + # Blue = hue 240 + assert blue_css =~ "--t-accent-h: 240" # Restore default CSSCache.warm() diff --git a/test/simpleshop_theme/sync/product_sync_worker_test.exs b/test/simpleshop_theme/sync/product_sync_worker_test.exs index f86019a..a52d2b5 100644 --- a/test/simpleshop_theme/sync/product_sync_worker_test.exs +++ b/test/simpleshop_theme/sync/product_sync_worker_test.exs @@ -61,7 +61,9 @@ defmodule SimpleshopTheme.Sync.ProductSyncWorkerTest do test "new/2 with scheduled_at creates scheduled job" do future = DateTime.add(DateTime.utc_now(), 60, :second) - changeset = ProductSyncWorker.new(%{provider_connection_id: "test-id"}, scheduled_at: future) + + changeset = + ProductSyncWorker.new(%{provider_connection_id: "test-id"}, scheduled_at: future) assert changeset.changes.scheduled_at == future end diff --git a/test/simpleshop_theme/theme/preview_data_test.exs b/test/simpleshop_theme/theme/preview_data_test.exs index 7efc144..95982af 100644 --- a/test/simpleshop_theme/theme/preview_data_test.exs +++ b/test/simpleshop_theme/theme/preview_data_test.exs @@ -51,6 +51,7 @@ defmodule SimpleshopTheme.Theme.PreviewDataTest do if product.hover_image_url do assert is_binary(product.hover_image_url) + assert String.starts_with?(product.hover_image_url, "/") or String.starts_with?(product.hover_image_url, "http") end diff --git a/test/simpleshop_theme_web/controllers/error_json_test.exs b/test/simpleshop_theme_web/controllers/error_json_test.exs index 863cf03..3532c10 100644 --- a/test/simpleshop_theme_web/controllers/error_json_test.exs +++ b/test/simpleshop_theme_web/controllers/error_json_test.exs @@ -2,7 +2,9 @@ defmodule SimpleshopThemeWeb.ErrorJSONTest do use SimpleshopThemeWeb.ConnCase, async: true test "renders 404" do - assert SimpleshopThemeWeb.ErrorJSON.render("404.json", %{}) == %{errors: %{detail: "Not Found"}} + assert SimpleshopThemeWeb.ErrorJSON.render("404.json", %{}) == %{ + errors: %{detail: "Not Found"} + } end test "renders 500" do
    SizeChest (cm)Length (cm) + Size + + Chest (cm) + + Length (cm) +
    <%= size_row.size %><%= size_row.chest %><%= size_row.length %>
    {size_row.size}{size_row.chest}{size_row.length}