fix navigation links, footer categories, product card structure, and social icons
- add missing cta_href to hero section and error page CTAs - replace hardcoded footer shop links with real product categories - restructure product cards with stretched-link pattern so category badges link to their collection page - unify social icons: footer and contact page share the same default links from a single source in content.ex - add search implementation plan (docs/plans/search.md, deferred) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ac46c1504f
commit
209ae7aee7
12
PROGRESS.md
12
PROGRESS.md
@ -53,11 +53,10 @@ Issues found during hands-on testing of the deployed prod site on mobile and des
|
||||
- [ ] Shipping costs: add Stripe shipping options or query Printify for dynamic rates
|
||||
|
||||
### Navigation & links
|
||||
- [ ] Search doesn't work (modal opens but no results/functionality)
|
||||
- [ ] "Shop the collection" button/link does nothing
|
||||
- [ ] Footer "New arrivals" and "Best sellers" links don't go anywhere
|
||||
- [ ] Should be able to tap a category badge on product cards to go to that category
|
||||
- [ ] Footer social icons should match the "Find me on" icons from the contact page
|
||||
- [x] "Shop the collection" button/link does nothing
|
||||
- [x] Footer "New arrivals" and "Best sellers" links don't go anywhere
|
||||
- [x] Should be able to tap a category badge on product cards to go to that category
|
||||
- [x] Footer social icons should match the "Find me on" icons from the contact page
|
||||
|
||||
### Collections / all products
|
||||
- [ ] Categories on all-products page are too spaced out
|
||||
@ -71,6 +70,9 @@ Issues found during hands-on testing of the deployed prod site on mobile and des
|
||||
### Errors
|
||||
- [ ] 404 page is broken
|
||||
|
||||
### Search (deferred — after usability fixes)
|
||||
- [ ] Search doesn't work (modal opens but no results/functionality) — see [docs/plans/search.md](docs/plans/search.md)
|
||||
|
||||
## Roadmap
|
||||
|
||||
### Tier 1 — MVP (can take real orders and fulfil them)
|
||||
|
||||
@ -229,6 +229,14 @@
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Stretched link: makes a parent container fully clickable via ::after overlay */
|
||||
.stretched-link::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Nav link styling with active state indicator */
|
||||
.shop-nav a,
|
||||
.shop-nav span {
|
||||
|
||||
61
docs/plans/search.md
Normal file
61
docs/plans/search.md
Normal file
@ -0,0 +1,61 @@
|
||||
# Plan: Implement product search in search modal
|
||||
|
||||
Status: Pending (after usability fixes)
|
||||
|
||||
## Overview
|
||||
|
||||
The search modal UI shell exists but has zero functionality — no event bindings, no backend search, no results rendering. This plan adds live search across all products.
|
||||
|
||||
## Approach
|
||||
|
||||
Small catalog (print-on-demand, < 100 products) — search `PreviewData.products()` in memory. No DB full-text search needed.
|
||||
|
||||
Product maps have: `.name`, `.category`, `.description`, `.slug`, `.price`, `.image_url`, `.image_id`
|
||||
|
||||
## Changes
|
||||
|
||||
### 1. CartHook — add search assigns + event handler
|
||||
**File:** `lib/simpleshop_theme_web/cart_hook.ex`
|
||||
|
||||
- Init assigns in `on_mount`: `search_results: []`, `search_query: ""`
|
||||
- Handle `"search"` event (from `phx-keyup`):
|
||||
- Empty/blank query → assign `search_results: []`, `search_query: ""`
|
||||
- Non-empty → filter `PreviewData.products()` by name/category/description (case-insensitive substring match), take 6, assign results
|
||||
- Handle `"close_search"` event → clear query + results + hide modal via JS
|
||||
|
||||
### 2. shop_layout + search_modal — add search attrs and UI
|
||||
**File:** `lib/simpleshop_theme_web/components/shop_components/layout.ex`
|
||||
|
||||
**shop_layout:**
|
||||
- Add optional attrs: `search_results` (default `[]`), `search_query` (default `""`)
|
||||
- Pass them to `<.search_modal>`
|
||||
|
||||
**search_modal:**
|
||||
- Add `search_results` (list, default `[]`) and `search_query` (string, default `""`) attrs
|
||||
- Add `name="query"`, `phx-keyup="search"`, `phx-debounce="200"`, `value={@search_query}` to the input
|
||||
- On close button + backdrop click: also push `"close_search"` event
|
||||
- Results section below input:
|
||||
- Each result: link to `/products/{slug}` with product name, category, formatted price
|
||||
- "No results found" when query non-empty but no matches
|
||||
- Hint text only shown when no query
|
||||
- Click on result: navigate to product, close modal (JS.hide + close_search event)
|
||||
|
||||
### 3. Page templates — thread search assigns
|
||||
**All 8 files in** `lib/simpleshop_theme_web/components/page_templates/`
|
||||
|
||||
Add two lines to each `<.shop_layout>` call:
|
||||
```
|
||||
search_results={assigns[:search_results] || []}
|
||||
search_query={assigns[:search_query] || ""}
|
||||
```
|
||||
|
||||
Same pattern as `cart_drawer_open` and `cart_status`.
|
||||
|
||||
## Files to modify
|
||||
1. `lib/simpleshop_theme_web/cart_hook.ex`
|
||||
2. `lib/simpleshop_theme_web/components/shop_components/layout.ex` (shop_layout + search_modal)
|
||||
3. All 8 page templates in `lib/simpleshop_theme_web/components/page_templates/`
|
||||
|
||||
## Verification
|
||||
- Browser: open search modal on multiple pages, type queries, verify results appear and link correctly
|
||||
- `mix test` — all existing tests pass
|
||||
@ -19,6 +19,7 @@ defmodule SimpleshopThemeWeb.CartHook do
|
||||
import Phoenix.LiveView, only: [attach_hook: 4, connected?: 1, push_event: 3]
|
||||
|
||||
alias SimpleshopTheme.Cart
|
||||
alias SimpleshopTheme.Theme.PreviewData
|
||||
|
||||
def on_mount(:mount_cart, _params, session, socket) do
|
||||
cart_items = Cart.get_from_session(session)
|
||||
@ -28,6 +29,7 @@ defmodule SimpleshopThemeWeb.CartHook do
|
||||
|> update_cart_assigns(cart_items)
|
||||
|> assign(:cart_drawer_open, false)
|
||||
|> assign(:cart_status, nil)
|
||||
|> assign(:categories, PreviewData.categories())
|
||||
|> attach_hook(:cart_events, :handle_event, &handle_cart_event/3)
|
||||
|> attach_hook(:cart_info, :handle_info, &handle_cart_info/2)
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page="cart"
|
||||
>
|
||||
<main id="main-content" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page="checkout"
|
||||
>
|
||||
<main id="main-content" class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page="collection"
|
||||
>
|
||||
<main id="main-content">
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page="contact"
|
||||
>
|
||||
<main id="main-content" class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||
@ -34,13 +35,7 @@
|
||||
|
||||
<.newsletter_card />
|
||||
|
||||
<.social_links_card links={[
|
||||
%{platform: :instagram, url: "https://instagram.com", label: "Instagram"},
|
||||
%{platform: :bluesky, url: "https://bsky.app", label: "Bluesky"},
|
||||
%{platform: :mastodon, url: "https://mastodon.social", label: "Mastodon"},
|
||||
%{platform: :kofi, url: "https://ko-fi.com", label: "Ko-fi"},
|
||||
%{platform: :github, url: "https://github.com", label: "GitHub"}
|
||||
]} />
|
||||
<.social_links_card />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page={@active_page}
|
||||
>
|
||||
<main id="main-content" class="content-page" style="background-color: var(--t-surface-base);">
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page="error"
|
||||
error_page
|
||||
>
|
||||
@ -24,8 +25,10 @@
|
||||
description={@error_description}
|
||||
cta_text="Go to Homepage"
|
||||
cta_page="home"
|
||||
cta_href="/"
|
||||
secondary_cta_text="Browse Products"
|
||||
secondary_cta_page="collection"
|
||||
secondary_cta_href="/collections/all"
|
||||
mode={@mode}
|
||||
/>
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page="home"
|
||||
>
|
||||
<main id="main-content">
|
||||
@ -16,6 +17,7 @@
|
||||
description="Welcome to the SimpleShop demo store. This is where your hero text goes – something short and punchy about what makes your shop worth a browse."
|
||||
cta_text="Shop the collection"
|
||||
cta_page="collection"
|
||||
cta_href="/collections/all"
|
||||
mode={@mode}
|
||||
/>
|
||||
|
||||
@ -34,6 +36,7 @@
|
||||
image_url="/mockups/mountain-sunrise-print-3-800.webp"
|
||||
link_text="Learn more about the studio →"
|
||||
link_page="about"
|
||||
link_href="/about"
|
||||
mode={@mode}
|
||||
/>
|
||||
</main>
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
cart_subtotal={@cart_subtotal}
|
||||
cart_drawer_open={assigns[:cart_drawer_open] || false}
|
||||
cart_status={assigns[:cart_status]}
|
||||
categories={assigns[:categories] || []}
|
||||
active_page="pdp"
|
||||
>
|
||||
<main id="main-content" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
|
||||
@ -5,6 +5,14 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
import SimpleshopThemeWeb.ShopComponents.Base
|
||||
|
||||
@default_social_links [
|
||||
%{platform: :instagram, url: "https://instagram.com", label: "Instagram"},
|
||||
%{platform: :bluesky, url: "https://bsky.app", label: "Bluesky"},
|
||||
%{platform: :mastodon, url: "https://mastodon.social", label: "Mastodon"},
|
||||
%{platform: :kofi, url: "https://ko-fi.com", label: "Ko-fi"},
|
||||
%{platform: :github, url: "https://github.com", label: "GitHub"}
|
||||
]
|
||||
|
||||
@doc """
|
||||
Renders a content body container for long-form content pages (about, etc.).
|
||||
|
||||
@ -338,11 +346,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
"""
|
||||
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: @default_social_links
|
||||
|
||||
def social_links_card(assigns) do
|
||||
~H"""
|
||||
@ -381,11 +385,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
<.social_links />
|
||||
<.social_links links={[%{platform: :instagram, url: "https://instagram.com/example", label: "Instagram"}]} />
|
||||
"""
|
||||
attr :links, :list,
|
||||
default: [
|
||||
%{platform: :instagram, url: "https://instagram.com", label: "Instagram"},
|
||||
%{platform: :pinterest, url: "https://pinterest.com", label: "Pinterest"}
|
||||
]
|
||||
attr :links, :list, default: @default_social_links
|
||||
|
||||
def social_links(assigns) do
|
||||
~H"""
|
||||
|
||||
@ -65,6 +65,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Layout do
|
||||
attr :cart_subtotal, :string, required: true
|
||||
attr :cart_drawer_open, :boolean, default: false
|
||||
attr :cart_status, :string, default: nil
|
||||
attr :categories, :list, default: []
|
||||
attr :active_page, :string, required: true
|
||||
attr :error_page, :boolean, default: false
|
||||
|
||||
@ -95,7 +96,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Layout do
|
||||
|
||||
{render_slot(@inner_block)}
|
||||
|
||||
<.shop_footer theme_settings={@theme_settings} mode={@mode} />
|
||||
<.shop_footer theme_settings={@theme_settings} mode={@mode} categories={@categories} />
|
||||
|
||||
<.cart_drawer
|
||||
cart_items={@cart_items}
|
||||
@ -405,6 +406,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Layout do
|
||||
"""
|
||||
attr :theme_settings, :map, required: true
|
||||
attr :mode, :atom, default: :live
|
||||
attr :categories, :list, default: []
|
||||
|
||||
def shop_footer(assigns) do
|
||||
assigns = assign(assigns, :current_year, Date.utc_today().year)
|
||||
@ -437,28 +439,19 @@ defmodule SimpleshopThemeWeb.ShopComponents.Layout do
|
||||
All products
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
phx-click="change_preview_page"
|
||||
phx-value-page="collection"
|
||||
class="transition-colors hover:opacity-80"
|
||||
style="color: var(--t-text-secondary); cursor: pointer;"
|
||||
>
|
||||
New arrivals
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
phx-click="change_preview_page"
|
||||
phx-value-page="collection"
|
||||
class="transition-colors hover:opacity-80"
|
||||
style="color: var(--t-text-secondary); cursor: pointer;"
|
||||
>
|
||||
Best sellers
|
||||
</a>
|
||||
</li>
|
||||
<%= for category <- @categories do %>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
phx-click="change_preview_page"
|
||||
phx-value-page="collection"
|
||||
class="transition-colors hover:opacity-80"
|
||||
style="color: var(--t-text-secondary); cursor: pointer;"
|
||||
>
|
||||
{category.name}
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<li>
|
||||
<a
|
||||
@ -469,24 +462,17 @@ defmodule SimpleshopThemeWeb.ShopComponents.Layout do
|
||||
All products
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/collections/all"
|
||||
class="transition-colors hover:opacity-80"
|
||||
style="color: var(--t-text-secondary);"
|
||||
>
|
||||
New arrivals
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/collections/all"
|
||||
class="transition-colors hover:opacity-80"
|
||||
style="color: var(--t-text-secondary);"
|
||||
>
|
||||
Best sellers
|
||||
</a>
|
||||
</li>
|
||||
<%= for category <- @categories do %>
|
||||
<li>
|
||||
<a
|
||||
href={"/collections/#{category.slug}"}
|
||||
class="transition-colors hover:opacity-80"
|
||||
style="color: var(--t-text-secondary);"
|
||||
>
|
||||
{category.name}
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
@ -594,48 +580,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Layout do
|
||||
<p class="text-xs" style="color: var(--t-text-tertiary);">
|
||||
© {@current_year} {@theme_settings.site_name}
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<a
|
||||
href="https://instagram.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="social-link w-9 h-9 flex items-center justify-center transition-all"
|
||||
style="color: var(--t-text-secondary); border-radius: var(--t-radius-button);"
|
||||
aria-label="Instagram"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect>
|
||||
<path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path>
|
||||
<line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://pinterest.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="social-link w-9 h-9 flex items-center justify-center transition-all"
|
||||
style="color: var(--t-text-secondary); border-radius: var(--t-radius-button);"
|
||||
aria-label="Pinterest"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<path d="M8 12c0-2.2 1.8-4 4-4s4 1.8 4 4-1.8 4-4 4"></path>
|
||||
<line x1="12" y1="16" x2="9" y2="21"></line>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<.social_links />
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@ -59,58 +59,22 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
|
||||
end)
|
||||
|
||||
~H"""
|
||||
<%= if @clickable_resolved do %>
|
||||
<%= if @mode == :preview do %>
|
||||
<a
|
||||
href="#"
|
||||
phx-click="change_preview_page"
|
||||
phx-value-page="pdp"
|
||||
class={card_classes(@variant)}
|
||||
style={card_style(@variant)}
|
||||
>
|
||||
<.product_card_inner
|
||||
product={@product}
|
||||
theme_settings={@theme_settings}
|
||||
variant={@variant}
|
||||
priority={@priority}
|
||||
show_category={@show_category_resolved}
|
||||
show_badges={@show_badges_resolved}
|
||||
show_delivery_text={@show_delivery_text_resolved}
|
||||
/>
|
||||
</a>
|
||||
<% else %>
|
||||
<a
|
||||
href={"/products/#{@product[:slug] || @product[:id]}"}
|
||||
class={card_classes(@variant)}
|
||||
style={card_style(@variant)}
|
||||
>
|
||||
<.product_card_inner
|
||||
product={@product}
|
||||
theme_settings={@theme_settings}
|
||||
variant={@variant}
|
||||
priority={@priority}
|
||||
show_category={@show_category_resolved}
|
||||
show_badges={@show_badges_resolved}
|
||||
show_delivery_text={@show_delivery_text_resolved}
|
||||
/>
|
||||
</a>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div
|
||||
class={card_classes(@variant)}
|
||||
style={card_style(@variant)}
|
||||
>
|
||||
<.product_card_inner
|
||||
product={@product}
|
||||
theme_settings={@theme_settings}
|
||||
variant={@variant}
|
||||
priority={@priority}
|
||||
show_category={@show_category_resolved}
|
||||
show_badges={@show_badges_resolved}
|
||||
show_delivery_text={@show_delivery_text_resolved}
|
||||
/>
|
||||
</div>
|
||||
<% end %>
|
||||
<article
|
||||
class={card_classes(@variant)}
|
||||
style={card_style(@variant) <> if(@clickable_resolved, do: " position: relative;", else: "")}
|
||||
>
|
||||
<.product_card_inner
|
||||
product={@product}
|
||||
theme_settings={@theme_settings}
|
||||
variant={@variant}
|
||||
priority={@priority}
|
||||
show_category={@show_category_resolved}
|
||||
show_badges={@show_badges_resolved}
|
||||
show_delivery_text={@show_delivery_text_resolved}
|
||||
clickable={@clickable_resolved}
|
||||
mode={@mode}
|
||||
/>
|
||||
</article>
|
||||
"""
|
||||
end
|
||||
|
||||
@ -121,6 +85,8 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
|
||||
attr :show_category, :boolean, required: true
|
||||
attr :show_badges, :boolean, required: true
|
||||
attr :show_delivery_text, :boolean, required: true
|
||||
attr :clickable, :boolean, default: true
|
||||
attr :mode, :atom, default: :live
|
||||
|
||||
defp product_card_inner(assigns) do
|
||||
assigns =
|
||||
@ -171,12 +137,47 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
|
||||
</div>
|
||||
<div class={content_padding_class(@variant)}>
|
||||
<%= if @show_category && @product[:category] do %>
|
||||
<p class="text-xs mb-1" style="color: var(--t-text-tertiary);">
|
||||
{@product.category}
|
||||
</p>
|
||||
<%= if @mode == :preview do %>
|
||||
<p
|
||||
class="text-xs mb-1"
|
||||
style="color: var(--t-text-tertiary); position: relative; z-index: 1;"
|
||||
>
|
||||
{@product.category}
|
||||
</p>
|
||||
<% else %>
|
||||
<a
|
||||
href={"/collections/#{Slug.slugify(@product.category)}"}
|
||||
class="text-xs mb-1 block hover:underline"
|
||||
style="color: var(--t-text-tertiary); text-decoration: none; position: relative; z-index: 1;"
|
||||
>
|
||||
{@product.category}
|
||||
</a>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<h3 class={title_classes(@variant)} style={title_style(@variant)}>
|
||||
{@product.name}
|
||||
<%= if @clickable do %>
|
||||
<%= if @mode == :preview do %>
|
||||
<a
|
||||
href="#"
|
||||
phx-click="change_preview_page"
|
||||
phx-value-page="pdp"
|
||||
class="stretched-link"
|
||||
style="color: inherit; text-decoration: none;"
|
||||
>
|
||||
{@product.name}
|
||||
</a>
|
||||
<% else %>
|
||||
<a
|
||||
href={"/products/#{@product[:slug] || @product[:id]}"}
|
||||
class="stretched-link"
|
||||
style="color: inherit; text-decoration: none;"
|
||||
>
|
||||
{@product.name}
|
||||
</a>
|
||||
<% end %>
|
||||
<% else %>
|
||||
{@product.name}
|
||||
<% end %>
|
||||
</h3>
|
||||
<%= if @theme_settings.show_prices do %>
|
||||
<.product_price product={@product} variant={@variant} />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user