refactor: extract hero_section to shared ShopComponents module
Create a centered hero section component with: - Title (h1) and description (p) - Optional CTA button with preview/live mode support - Configurable background (:base or :sunken) Used in: home page (with CTA), about page (without CTA) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b2869514cb
commit
f5b7693b96
@ -859,4 +859,79 @@ defmodule SimpleshopThemeWeb.ShopComponents do
|
||||
|> Enum.reject(&(&1 == ""))
|
||||
|> Enum.join(" ")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Renders a centered hero section with title, description, and optional CTA.
|
||||
|
||||
## Attributes
|
||||
|
||||
* `title` - Required. The main heading text.
|
||||
* `description` - Required. The description paragraph text.
|
||||
* `background` - Background style. Either `:base` (default) or `:sunken`.
|
||||
* `cta_text` - Optional. Text for the CTA button.
|
||||
* `cta_page` - Optional. Page to navigate to on click (for preview mode).
|
||||
* `mode` - Either `:live` (default) or `:preview`.
|
||||
|
||||
## Examples
|
||||
|
||||
<.hero_section
|
||||
title="Original designs, printed on demand"
|
||||
description="From art prints to apparel – unique products created by independent artists."
|
||||
cta_text="Shop the collection"
|
||||
cta_page="collection"
|
||||
mode={:preview}
|
||||
/>
|
||||
|
||||
<.hero_section
|
||||
title="About the studio"
|
||||
description="Nature photography, printed with care"
|
||||
background={:sunken}
|
||||
/>
|
||||
"""
|
||||
attr :title, :string, required: true
|
||||
attr :description, :string, required: true
|
||||
attr :background, :atom, default: :base
|
||||
attr :cta_text, :string, default: nil
|
||||
attr :cta_page, :string, default: nil
|
||||
attr :cta_href, :string, default: nil
|
||||
attr :mode, :atom, default: :live
|
||||
|
||||
def hero_section(assigns) do
|
||||
~H"""
|
||||
<section
|
||||
class="text-center"
|
||||
style={"padding: var(--space-2xl) var(--space-lg); background-color: var(--t-surface-#{@background});"}
|
||||
>
|
||||
<h1
|
||||
class="text-3xl md:text-4xl mb-4"
|
||||
style="font-family: var(--t-font-heading); font-weight: var(--t-heading-weight); letter-spacing: var(--t-heading-tracking); color: var(--t-text-primary);"
|
||||
>
|
||||
<%= @title %>
|
||||
</h1>
|
||||
<p class="text-lg max-w-lg mx-auto mb-8" style="color: var(--t-text-secondary); line-height: 1.6;">
|
||||
<%= @description %>
|
||||
</p>
|
||||
<%= if @cta_text do %>
|
||||
<%= if @mode == :preview do %>
|
||||
<button
|
||||
phx-click="change_preview_page"
|
||||
phx-value-page={@cta_page}
|
||||
class="px-6 py-3 font-medium transition-all"
|
||||
style="background-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l)); color: var(--t-text-inverse); border-radius: var(--t-radius-button); cursor: pointer; border: none;"
|
||||
>
|
||||
<%= @cta_text %>
|
||||
</button>
|
||||
<% else %>
|
||||
<a
|
||||
href={@cta_href || "/products"}
|
||||
class="inline-block px-6 py-3 font-medium transition-all"
|
||||
style="background-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l)); color: var(--t-text-inverse); border-radius: var(--t-radius-button); text-decoration: none;"
|
||||
>
|
||||
<%= @cta_text %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</section>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
@ -13,14 +13,11 @@
|
||||
<!-- Content Page -->
|
||||
<main id="main-content" class="content-page" style="background-color: var(--t-surface-base);">
|
||||
<!-- Hero Section -->
|
||||
<div class="content-hero text-center" style="padding: var(--space-2xl) var(--space-lg); background-color: var(--t-surface-sunken);">
|
||||
<h1 class="text-3xl md:text-4xl mb-3" style="font-family: var(--t-font-heading); font-weight: var(--t-heading-weight); letter-spacing: var(--t-heading-tracking); color: var(--t-text-primary);">
|
||||
About the studio
|
||||
</h1>
|
||||
<p class="text-lg" style="color: var(--t-text-secondary);">
|
||||
Nature photography, printed with care
|
||||
</p>
|
||||
</div>
|
||||
<.hero_section
|
||||
title="About the studio"
|
||||
description="Nature photography, printed with care"
|
||||
background={:sunken}
|
||||
/>
|
||||
|
||||
<!-- Content Body -->
|
||||
<div class="content-body" style="padding: var(--space-xl) var(--space-lg); max-width: 800px; margin: 0 auto;">
|
||||
|
||||
@ -12,22 +12,13 @@
|
||||
|
||||
<!-- Hero Section -->
|
||||
<main id="main-content">
|
||||
<section class="text-center" style="padding: var(--space-2xl) var(--space-lg); background-color: var(--t-surface-base);">
|
||||
<h1 class="text-3xl md:text-4xl mb-4" style="font-family: var(--t-font-heading); font-weight: var(--t-heading-weight); letter-spacing: var(--t-heading-tracking); color: var(--t-text-primary);">
|
||||
Original designs, printed on demand
|
||||
</h1>
|
||||
<p class="text-lg max-w-lg mx-auto mb-8" style="color: var(--t-text-secondary); line-height: 1.6;">
|
||||
From art prints to apparel – unique products created by independent artists and delivered straight to your door.
|
||||
</p>
|
||||
<button
|
||||
phx-click="change_preview_page"
|
||||
phx-value-page="collection"
|
||||
class="px-6 py-3 font-medium transition-all"
|
||||
style="background-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l)); color: var(--t-text-inverse); border-radius: var(--t-radius-button); cursor: pointer; border: none;"
|
||||
>
|
||||
Shop the collection
|
||||
</button>
|
||||
</section>
|
||||
<.hero_section
|
||||
title="Original designs, printed on demand"
|
||||
description="From art prints to apparel – unique products created by independent artists and delivered straight to your door."
|
||||
cta_text="Shop the collection"
|
||||
cta_page="collection"
|
||||
mode={:preview}
|
||||
/>
|
||||
|
||||
<!-- Categories -->
|
||||
<section style="padding: var(--space-xl) var(--space-lg); background-color: var(--t-surface-base);">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user