feat: add default content pages for delivery, privacy and terms
Replace one-off ShopLive.About with generic ShopLive.Content that handles all static content pages via live_action. Add delivery & returns, privacy policy, and terms of service pages with sample content. Update footer help links and theme editor preview. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0af8997623
commit
5a43cfc761
@ -133,6 +133,171 @@ defmodule SimpleshopTheme.Theme.PreviewData do
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns delivery & returns page content for preview.
|
||||||
|
"""
|
||||||
|
def delivery_content do
|
||||||
|
[
|
||||||
|
%{
|
||||||
|
type: :lead,
|
||||||
|
text:
|
||||||
|
"This is sample content for the demo shop. Replace it with your own delivery and returns information."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Shipping"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"All products are printed on demand and shipped directly from the print facility. Typical delivery times depend on your location:"
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
type: :list,
|
||||||
|
items: [
|
||||||
|
"United Kingdom: 5–8 business days",
|
||||||
|
"Europe: 8–12 business days",
|
||||||
|
"United States & Canada: 8–14 business days",
|
||||||
|
"Rest of world: 10–20 business days"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"You'll receive a shipping confirmation email with tracking details once your order has been dispatched."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Returns & exchanges"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"Because every item is made to order, we can't accept returns for change of mind. However, if your order arrives damaged or with a printing defect, we'll sort it out — just get in touch within 14 days of delivery."
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"Please include your order number and a photo of the issue so we can resolve things quickly."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Cancellations"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"Orders can be cancelled within 2 hours of being placed. After that, production will have started and we won't be able to make changes. Contact us as soon as possible if you need to cancel."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns privacy policy page content for preview.
|
||||||
|
"""
|
||||||
|
def privacy_content do
|
||||||
|
[
|
||||||
|
%{
|
||||||
|
type: :lead,
|
||||||
|
text: "This is sample content for the demo shop. Replace it with your own privacy policy."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "What we collect"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"When you place an order, we collect the information needed to fulfil it — your name, email address, shipping address, and payment details. Payment is processed securely by Stripe; we never see or store your card number."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "How we use it"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text: "We use your information to:"
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
type: :list,
|
||||||
|
items: [
|
||||||
|
"Process and deliver your order",
|
||||||
|
"Send order confirmation and shipping updates",
|
||||||
|
"Respond to any queries or issues you raise"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"We won't send you marketing emails unless you've opted in, and we'll never sell your data to third parties."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Third parties"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"To fulfil orders, we share your shipping details with our print-on-demand provider. Payment is handled by Stripe. Both process data in accordance with their own privacy policies."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Your rights"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"You can request a copy of your data, ask us to correct it, or ask us to delete it at any time. Just get in touch and we'll sort it out."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Cookies"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"We use essential cookies to keep your session and cart working. We don't use tracking cookies or third-party analytics that follow you around the web."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns terms of service page content for preview.
|
||||||
|
"""
|
||||||
|
def terms_content do
|
||||||
|
[
|
||||||
|
%{
|
||||||
|
type: :lead,
|
||||||
|
text:
|
||||||
|
"This is sample content for the demo shop. Replace it with your own terms of service."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Overview"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"By placing an order through this shop, you agree to the following terms. Please read them before making a purchase."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Products"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"All products are made to order using print-on-demand services. Colours may vary slightly between screens and the finished product. We do our best to represent products accurately, but minor differences are normal."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Orders & payment"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"Payment is taken at the time of purchase via Stripe. Once an order is confirmed and production has started, it cannot be modified. Prices include VAT where applicable."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Delivery"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"Delivery times are estimates and may vary. We're not responsible for delays caused by postal services or customs. See our delivery page for current timeframes."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Returns"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"As items are made to order, we don't accept returns for change of mind. If an item arrives damaged or defective, contact us within 14 days for a replacement. See our delivery & returns page for full details."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Intellectual property"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"All designs, images, and content on this site are owned by the shop owner and may not be reproduced without permission."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Liability"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"We do our best to keep the shop running smoothly, but we can't guarantee uninterrupted service. Our liability is limited to the value of your order."
|
||||||
|
},
|
||||||
|
%{type: :heading, text: "Changes"},
|
||||||
|
%{
|
||||||
|
type: :paragraph,
|
||||||
|
text:
|
||||||
|
"We may update these terms from time to time. Any changes apply to orders placed after the update."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns categories for preview.
|
Returns categories for preview.
|
||||||
|
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
<div
|
|
||||||
id="shop-container"
|
|
||||||
phx-hook="CartPersist"
|
|
||||||
class="shop-container min-h-screen pb-20 md:pb-0"
|
|
||||||
style="background-color: var(--t-surface-base); font-family: var(--t-font-body); color: var(--t-text-primary);"
|
|
||||||
>
|
|
||||||
<.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}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<main id="main-content" class="content-page" style="background-color: var(--t-surface-base);">
|
|
||||||
<.hero_section
|
|
||||||
title="About the studio"
|
|
||||||
description="Your story goes here – this is sample content for the demo shop"
|
|
||||||
background={:sunken}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<.content_body
|
|
||||||
image_src="/mockups/night-sky-blanket-3"
|
|
||||||
image_alt="Night sky blanket draped over a chair"
|
|
||||||
>
|
|
||||||
<.rich_text blocks={SimpleshopTheme.Theme.PreviewData.about_content()} />
|
|
||||||
</.content_body>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<.shop_footer theme_settings={@theme_settings} mode={@mode} />
|
|
||||||
|
|
||||||
<.cart_drawer
|
|
||||||
cart_items={@cart_items}
|
|
||||||
subtotal={@cart_subtotal}
|
|
||||||
cart_count={@cart_count}
|
|
||||||
mode={@mode}
|
|
||||||
open={assigns[:cart_drawer_open] || false}
|
|
||||||
cart_status={assigns[:cart_status]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} />
|
|
||||||
|
|
||||||
<.mobile_bottom_nav active_page="about" mode={@mode} />
|
|
||||||
</div>
|
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
<div
|
||||||
|
id="shop-container"
|
||||||
|
phx-hook="CartPersist"
|
||||||
|
class="shop-container min-h-screen pb-20 md:pb-0"
|
||||||
|
style="background-color: var(--t-surface-base); font-family: var(--t-font-body); color: var(--t-text-primary);"
|
||||||
|
>
|
||||||
|
<.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={@active_page}
|
||||||
|
mode={@mode}
|
||||||
|
cart_count={@cart_count}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<main id="main-content" class="content-page" style="background-color: var(--t-surface-base);">
|
||||||
|
<%= if assigns[:hero_background] do %>
|
||||||
|
<.hero_section
|
||||||
|
title={@hero_title}
|
||||||
|
description={@hero_description}
|
||||||
|
background={@hero_background}
|
||||||
|
/>
|
||||||
|
<% else %>
|
||||||
|
<.hero_section
|
||||||
|
variant={:page}
|
||||||
|
title={@hero_title}
|
||||||
|
description={@hero_description}
|
||||||
|
/>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div style="padding: var(--space-xl) var(--space-lg); max-width: 800px; margin: 0 auto;">
|
||||||
|
<%= if assigns[:image_src] do %>
|
||||||
|
<div
|
||||||
|
class="content-image"
|
||||||
|
style="margin-bottom: var(--space-lg); border-radius: var(--t-radius-image); overflow: hidden;"
|
||||||
|
>
|
||||||
|
<.responsive_image
|
||||||
|
src={@image_src}
|
||||||
|
source_width={1200}
|
||||||
|
alt={@image_alt}
|
||||||
|
sizes="(max-width: 800px) 100vw, 800px"
|
||||||
|
class="w-full h-[300px] object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<.rich_text blocks={@content_blocks} />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<.shop_footer theme_settings={@theme_settings} mode={@mode} />
|
||||||
|
|
||||||
|
<.cart_drawer
|
||||||
|
cart_items={@cart_items}
|
||||||
|
subtotal={@cart_subtotal}
|
||||||
|
cart_count={@cart_count}
|
||||||
|
mode={@mode}
|
||||||
|
open={assigns[:cart_drawer_open] || false}
|
||||||
|
cart_status={assigns[:cart_status]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} />
|
||||||
|
|
||||||
|
<.mobile_bottom_nav active_page={@active_page} mode={@mode} />
|
||||||
|
</div>
|
||||||
@ -691,22 +691,33 @@ defmodule SimpleshopThemeWeb.ShopComponents do
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
phx-click="change_preview_page"
|
phx-click="change_preview_page"
|
||||||
phx-value-page="about"
|
phx-value-page="delivery"
|
||||||
class="transition-colors hover:opacity-80"
|
class="transition-colors hover:opacity-80"
|
||||||
style="color: var(--t-text-secondary); cursor: pointer;"
|
style="color: var(--t-text-secondary); cursor: pointer;"
|
||||||
>
|
>
|
||||||
Delivery
|
Delivery & returns
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
phx-click="change_preview_page"
|
phx-click="change_preview_page"
|
||||||
phx-value-page="about"
|
phx-value-page="privacy"
|
||||||
class="transition-colors hover:opacity-80"
|
class="transition-colors hover:opacity-80"
|
||||||
style="color: var(--t-text-secondary); cursor: pointer;"
|
style="color: var(--t-text-secondary); cursor: pointer;"
|
||||||
>
|
>
|
||||||
Returns
|
Privacy policy
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
phx-click="change_preview_page"
|
||||||
|
phx-value-page="terms"
|
||||||
|
class="transition-colors hover:opacity-80"
|
||||||
|
style="color: var(--t-text-secondary); cursor: pointer;"
|
||||||
|
>
|
||||||
|
Terms of service
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -723,20 +734,29 @@ defmodule SimpleshopThemeWeb.ShopComponents do
|
|||||||
<% else %>
|
<% else %>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="/contact"
|
href="/delivery"
|
||||||
class="transition-colors hover:opacity-80"
|
class="transition-colors hover:opacity-80"
|
||||||
style="color: var(--t-text-secondary);"
|
style="color: var(--t-text-secondary);"
|
||||||
>
|
>
|
||||||
Delivery
|
Delivery & returns
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="/contact"
|
href="/privacy"
|
||||||
class="transition-colors hover:opacity-80"
|
class="transition-colors hover:opacity-80"
|
||||||
style="color: var(--t-text-secondary);"
|
style="color: var(--t-text-secondary);"
|
||||||
>
|
>
|
||||||
Returns
|
Privacy policy
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="/terms"
|
||||||
|
class="transition-colors hover:opacity-80"
|
||||||
|
style="color: var(--t-text-secondary);"
|
||||||
|
>
|
||||||
|
Terms of service
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -4205,6 +4225,16 @@ defmodule SimpleshopThemeWeb.ShopComponents do
|
|||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp rich_text_block(%{block: %{type: :list}} = assigns) do
|
||||||
|
~H"""
|
||||||
|
<ul class="mb-4 ml-6 list-disc" style="color: var(--t-text-secondary);">
|
||||||
|
<%= for item <- @block.items do %>
|
||||||
|
<li class="mb-1">{item}</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
defp rich_text_block(assigns) do
|
defp rich_text_block(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<p class="mb-4" style="color: var(--t-text-secondary);">
|
<p class="mb-4" style="color: var(--t-text-secondary);">
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
defmodule SimpleshopThemeWeb.ShopLive.About do
|
|
||||||
use SimpleshopThemeWeb, :live_view
|
|
||||||
|
|
||||||
alias SimpleshopTheme.Settings
|
|
||||||
alias SimpleshopTheme.Media
|
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def mount(_params, _session, socket) do
|
|
||||||
theme_settings = Settings.get_theme_settings()
|
|
||||||
|
|
||||||
generated_css =
|
|
||||||
case CSSCache.get() do
|
|
||||||
{:ok, css} ->
|
|
||||||
css
|
|
||||||
|
|
||||||
:miss ->
|
|
||||||
css = CSSGenerator.generate(theme_settings)
|
|
||||||
CSSCache.put(css)
|
|
||||||
css
|
|
||||||
end
|
|
||||||
|
|
||||||
logo_image = Media.get_logo()
|
|
||||||
header_image = Media.get_header()
|
|
||||||
|
|
||||||
socket =
|
|
||||||
socket
|
|
||||||
|> assign(:page_title, "About")
|
|
||||||
|> assign(:theme_settings, theme_settings)
|
|
||||||
|> assign(:generated_css, generated_css)
|
|
||||||
|> assign(:logo_image, logo_image)
|
|
||||||
|> assign(:header_image, header_image)
|
|
||||||
|> assign(:mode, :shop)
|
|
||||||
|
|
||||||
{:ok, socket}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def render(assigns) do
|
|
||||||
~H"""
|
|
||||||
<SimpleshopThemeWeb.PageTemplates.about
|
|
||||||
theme_settings={@theme_settings}
|
|
||||||
logo_image={@logo_image}
|
|
||||||
header_image={@header_image}
|
|
||||||
mode={@mode}
|
|
||||||
cart_items={@cart_items}
|
|
||||||
cart_count={@cart_count}
|
|
||||||
cart_subtotal={@cart_subtotal}
|
|
||||||
cart_drawer_open={@cart_drawer_open}
|
|
||||||
cart_status={@cart_status}
|
|
||||||
/>
|
|
||||||
"""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
88
lib/simpleshop_theme_web/live/shop_live/content.ex
Normal file
88
lib/simpleshop_theme_web/live/shop_live/content.ex
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
defmodule SimpleshopThemeWeb.ShopLive.Content do
|
||||||
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
|
alias SimpleshopTheme.{Settings, Media}
|
||||||
|
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
theme_settings = Settings.get_theme_settings()
|
||||||
|
|
||||||
|
generated_css =
|
||||||
|
case CSSCache.get() do
|
||||||
|
{:ok, css} ->
|
||||||
|
css
|
||||||
|
|
||||||
|
:miss ->
|
||||||
|
css = CSSGenerator.generate(theme_settings)
|
||||||
|
CSSCache.put(css)
|
||||||
|
css
|
||||||
|
end
|
||||||
|
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> assign(:theme_settings, theme_settings)
|
||||||
|
|> assign(:generated_css, generated_css)
|
||||||
|
|> assign(:logo_image, Media.get_logo())
|
||||||
|
|> assign(:header_image, Media.get_header())
|
||||||
|
|> assign(:mode, :shop)
|
||||||
|
|
||||||
|
{:ok, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_params(_params, _uri, socket) do
|
||||||
|
config = page_config(socket.assigns.live_action)
|
||||||
|
{:noreply, assign(socket, config)}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def render(assigns) do
|
||||||
|
~H"""
|
||||||
|
<SimpleshopThemeWeb.PageTemplates.content {assigns} />
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp page_config(:about) do
|
||||||
|
%{
|
||||||
|
page_title: "About",
|
||||||
|
active_page: "about",
|
||||||
|
hero_title: "About the studio",
|
||||||
|
hero_description: "Your story goes here – this is sample content for the demo shop",
|
||||||
|
hero_background: :sunken,
|
||||||
|
image_src: "/mockups/night-sky-blanket-3",
|
||||||
|
image_alt: "Night sky blanket draped over a chair",
|
||||||
|
content_blocks: PreviewData.about_content()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp page_config(:delivery) do
|
||||||
|
%{
|
||||||
|
page_title: "Delivery & returns",
|
||||||
|
active_page: "delivery",
|
||||||
|
hero_title: "Delivery & returns",
|
||||||
|
hero_description: "Everything you need to know about shipping and returns",
|
||||||
|
content_blocks: PreviewData.delivery_content()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp page_config(:privacy) do
|
||||||
|
%{
|
||||||
|
page_title: "Privacy policy",
|
||||||
|
active_page: "privacy",
|
||||||
|
hero_title: "Privacy policy",
|
||||||
|
hero_description: "How we handle your personal information",
|
||||||
|
content_blocks: PreviewData.privacy_content()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp page_config(:terms) do
|
||||||
|
%{
|
||||||
|
page_title: "Terms of service",
|
||||||
|
active_page: "terms",
|
||||||
|
hero_title: "Terms of service",
|
||||||
|
hero_description: "The legal bits",
|
||||||
|
content_blocks: PreviewData.terms_content()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -431,11 +431,75 @@ defmodule SimpleshopThemeWeb.ThemeLive.Index do
|
|||||||
|
|
||||||
defp preview_page(%{page: :about} = assigns) do
|
defp preview_page(%{page: :about} = assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<SimpleshopThemeWeb.PageTemplates.about
|
<SimpleshopThemeWeb.PageTemplates.content
|
||||||
theme_settings={@theme_settings}
|
theme_settings={@theme_settings}
|
||||||
logo_image={@logo_image}
|
logo_image={@logo_image}
|
||||||
header_image={@header_image}
|
header_image={@header_image}
|
||||||
mode={:preview}
|
mode={:preview}
|
||||||
|
active_page="about"
|
||||||
|
hero_title="About the studio"
|
||||||
|
hero_description="Your story goes here – this is sample content for the demo shop"
|
||||||
|
hero_background={:sunken}
|
||||||
|
image_src="/mockups/night-sky-blanket-3"
|
||||||
|
image_alt="Night sky blanket draped over a chair"
|
||||||
|
content_blocks={PreviewData.about_content()}
|
||||||
|
cart_items={PreviewData.cart_drawer_items()}
|
||||||
|
cart_count={2}
|
||||||
|
cart_subtotal="£72.00"
|
||||||
|
cart_drawer_open={@cart_drawer_open}
|
||||||
|
/>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp preview_page(%{page: :delivery} = assigns) do
|
||||||
|
~H"""
|
||||||
|
<SimpleshopThemeWeb.PageTemplates.content
|
||||||
|
theme_settings={@theme_settings}
|
||||||
|
logo_image={@logo_image}
|
||||||
|
header_image={@header_image}
|
||||||
|
mode={:preview}
|
||||||
|
active_page="delivery"
|
||||||
|
hero_title="Delivery & returns"
|
||||||
|
hero_description="Everything you need to know about shipping and returns"
|
||||||
|
content_blocks={PreviewData.delivery_content()}
|
||||||
|
cart_items={PreviewData.cart_drawer_items()}
|
||||||
|
cart_count={2}
|
||||||
|
cart_subtotal="£72.00"
|
||||||
|
cart_drawer_open={@cart_drawer_open}
|
||||||
|
/>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp preview_page(%{page: :privacy} = assigns) do
|
||||||
|
~H"""
|
||||||
|
<SimpleshopThemeWeb.PageTemplates.content
|
||||||
|
theme_settings={@theme_settings}
|
||||||
|
logo_image={@logo_image}
|
||||||
|
header_image={@header_image}
|
||||||
|
mode={:preview}
|
||||||
|
active_page="privacy"
|
||||||
|
hero_title="Privacy policy"
|
||||||
|
hero_description="How we handle your personal information"
|
||||||
|
content_blocks={PreviewData.privacy_content()}
|
||||||
|
cart_items={PreviewData.cart_drawer_items()}
|
||||||
|
cart_count={2}
|
||||||
|
cart_subtotal="£72.00"
|
||||||
|
cart_drawer_open={@cart_drawer_open}
|
||||||
|
/>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp preview_page(%{page: :terms} = assigns) do
|
||||||
|
~H"""
|
||||||
|
<SimpleshopThemeWeb.PageTemplates.content
|
||||||
|
theme_settings={@theme_settings}
|
||||||
|
logo_image={@logo_image}
|
||||||
|
header_image={@header_image}
|
||||||
|
mode={:preview}
|
||||||
|
active_page="terms"
|
||||||
|
hero_title="Terms of service"
|
||||||
|
hero_description="The legal bits"
|
||||||
|
content_blocks={PreviewData.terms_content()}
|
||||||
cart_items={PreviewData.cart_drawer_items()}
|
cart_items={PreviewData.cart_drawer_items()}
|
||||||
cart_count={2}
|
cart_count={2}
|
||||||
cart_subtotal="£72.00"
|
cart_subtotal="£72.00"
|
||||||
|
|||||||
@ -1091,6 +1091,9 @@
|
|||||||
{:pdp, "Product"},
|
{:pdp, "Product"},
|
||||||
{:cart, "Cart"},
|
{:cart, "Cart"},
|
||||||
{:about, "About"},
|
{:about, "About"},
|
||||||
|
{:delivery, "Delivery"},
|
||||||
|
{:privacy, "Privacy"},
|
||||||
|
{:terms, "Terms"},
|
||||||
{:contact, "Contact"},
|
{:contact, "Contact"},
|
||||||
{:error, "404"}
|
{:error, "404"}
|
||||||
] do %>
|
] do %>
|
||||||
|
|||||||
@ -34,7 +34,10 @@ defmodule SimpleshopThemeWeb.Router do
|
|||||||
layout: {SimpleshopThemeWeb.Layouts, :shop},
|
layout: {SimpleshopThemeWeb.Layouts, :shop},
|
||||||
on_mount: [{SimpleshopThemeWeb.CartHook, :mount_cart}] do
|
on_mount: [{SimpleshopThemeWeb.CartHook, :mount_cart}] do
|
||||||
live "/", ShopLive.Home, :index
|
live "/", ShopLive.Home, :index
|
||||||
live "/about", ShopLive.About, :index
|
live "/about", ShopLive.Content, :about
|
||||||
|
live "/delivery", ShopLive.Content, :delivery
|
||||||
|
live "/privacy", ShopLive.Content, :privacy
|
||||||
|
live "/terms", ShopLive.Content, :terms
|
||||||
live "/contact", ShopLive.Contact, :index
|
live "/contact", ShopLive.Contact, :index
|
||||||
live "/collections/:slug", ShopLive.Collection, :show
|
live "/collections/:slug", ShopLive.Collection, :show
|
||||||
live "/products/:id", ShopLive.ProductShow, :show
|
live "/products/:id", ShopLive.ProductShow, :show
|
||||||
|
|||||||
89
test/simpleshop_theme_web/live/shop_live/content_test.exs
Normal file
89
test/simpleshop_theme_web/live/shop_live/content_test.exs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
defmodule SimpleshopThemeWeb.ShopLive.ContentTest do
|
||||||
|
use SimpleshopThemeWeb.ConnCase, async: false
|
||||||
|
|
||||||
|
import Phoenix.LiveViewTest
|
||||||
|
|
||||||
|
describe "About page" do
|
||||||
|
test "renders about page", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/about")
|
||||||
|
|
||||||
|
assert html =~ "About the studio"
|
||||||
|
assert html =~ "sample about page"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "displays about image", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/about")
|
||||||
|
|
||||||
|
assert html =~ "night-sky-blanket"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Delivery page" do
|
||||||
|
test "renders delivery page", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/delivery")
|
||||||
|
|
||||||
|
assert html =~ "Delivery & returns"
|
||||||
|
assert html =~ "shipping and returns"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "displays delivery content", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/delivery")
|
||||||
|
|
||||||
|
assert html =~ "Shipping"
|
||||||
|
assert html =~ "Returns & exchanges"
|
||||||
|
assert html =~ "Cancellations"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "displays list items", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/delivery")
|
||||||
|
|
||||||
|
assert html =~ "United Kingdom"
|
||||||
|
assert html =~ "5–8 business days"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Privacy page" do
|
||||||
|
test "renders privacy page", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/privacy")
|
||||||
|
|
||||||
|
assert html =~ "Privacy policy"
|
||||||
|
assert html =~ "personal information"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "displays privacy content", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/privacy")
|
||||||
|
|
||||||
|
assert html =~ "What we collect"
|
||||||
|
assert html =~ "Cookies"
|
||||||
|
assert html =~ "Your rights"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Terms page" do
|
||||||
|
test "renders terms page", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/terms")
|
||||||
|
|
||||||
|
assert html =~ "Terms of service"
|
||||||
|
assert html =~ "The legal bits"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "displays terms content", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/terms")
|
||||||
|
|
||||||
|
assert html =~ "Products"
|
||||||
|
assert html =~ "Orders & payment"
|
||||||
|
assert html =~ "Intellectual property"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Footer links" do
|
||||||
|
test "footer contains policy page links", %{conn: conn} do
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/about")
|
||||||
|
|
||||||
|
assert html =~ ~s(href="/delivery")
|
||||||
|
assert html =~ ~s(href="/privacy")
|
||||||
|
assert html =~ ~s(href="/terms")
|
||||||
|
assert html =~ ~s(href="/contact")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user