improve cart recovery: product links in email, persistent session cookie
All checks were successful
deploy / deploy (push) Successful in 3m32s
All checks were successful
deploy / deploy (push) Successful in 3m32s
- add product_id to order_items (migration + schema + create_order) - cart recovery email now includes a direct product link per item - extend session cookie max_age to 7 days so carts survive browser restarts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,7 @@ defmodule Berrypod.Orders do
|
||||
%{
|
||||
order_id: order.id,
|
||||
variant_id: item.variant_id,
|
||||
product_id: item[:product_id],
|
||||
product_name: item.name,
|
||||
variant_title: item.variant,
|
||||
quantity: item.quantity,
|
||||
|
||||
@@ -7,6 +7,7 @@ defmodule Berrypod.Orders.OrderItem do
|
||||
|
||||
schema "order_items" do
|
||||
field :variant_id, :string
|
||||
field :product_id, :string
|
||||
field :product_name, :string
|
||||
field :variant_title, :string
|
||||
field :quantity, :integer
|
||||
@@ -19,7 +20,15 @@ defmodule Berrypod.Orders.OrderItem do
|
||||
|
||||
def changeset(item, attrs) do
|
||||
item
|
||||
|> cast(attrs, [:variant_id, :product_name, :variant_title, :quantity, :unit_price, :order_id])
|
||||
|> cast(attrs, [
|
||||
:variant_id,
|
||||
:product_id,
|
||||
:product_name,
|
||||
:variant_title,
|
||||
:quantity,
|
||||
:unit_price,
|
||||
:order_id
|
||||
])
|
||||
|> validate_required([:variant_id, :product_name, :quantity, :unit_price])
|
||||
|> validate_number(:quantity, greater_than: 0)
|
||||
|> validate_number(:unit_price, greater_than_or_equal_to: 0)
|
||||
|
||||
@@ -100,6 +100,7 @@ defmodule Berrypod.Orders.OrderNotifier do
|
||||
def deliver_cart_recovery(cart, order, unsubscribe_url) do
|
||||
from_address = Berrypod.Settings.get_setting("email_from_address", "contact@example.com")
|
||||
subject = "You left something behind"
|
||||
base_url = BerrypodWeb.Endpoint.url()
|
||||
|
||||
body = """
|
||||
==============================
|
||||
@@ -107,11 +108,9 @@ defmodule Berrypod.Orders.OrderNotifier do
|
||||
You recently started a checkout but didn't complete it.
|
||||
|
||||
Your cart had:
|
||||
#{format_items(order.items)}
|
||||
#{format_cart_items(order.items, base_url)}
|
||||
Total: #{Cart.format_price(cart.cart_total)}
|
||||
|
||||
If you'd like to complete your order, head to our shop and add these items again.
|
||||
|
||||
We're only sending this once.
|
||||
|
||||
Don't want to hear from us? Unsubscribe: #{unsubscribe_url}
|
||||
@@ -169,6 +168,22 @@ defmodule Berrypod.Orders.OrderNotifier do
|
||||
|
||||
defp format_items(_), do: ""
|
||||
|
||||
defp format_cart_items(items, base_url) when is_list(items) do
|
||||
items
|
||||
|> Enum.map_join("\n", fn item ->
|
||||
price = Cart.format_price(item.unit_price * item.quantity)
|
||||
line = " #{item.quantity}x #{item.product_name} (#{item.variant_title}) - #{price}"
|
||||
|
||||
if item.product_id do
|
||||
line <> "\n #{base_url}/products/#{item.product_id}"
|
||||
else
|
||||
line
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp format_cart_items(_, _), do: ""
|
||||
|
||||
defp format_shipping_address(address) when is_map(address) and map_size(address) > 0 do
|
||||
lines =
|
||||
[
|
||||
|
||||
@@ -8,7 +8,8 @@ defmodule BerrypodWeb.Endpoint do
|
||||
store: :cookie,
|
||||
key: "_berrypod_key",
|
||||
signing_salt: "JNwRcD7y",
|
||||
same_site: "Lax"
|
||||
same_site: "Lax",
|
||||
max_age: 604_800
|
||||
]
|
||||
|
||||
socket "/live", Phoenix.LiveView.Socket,
|
||||
|
||||
Reference in New Issue
Block a user