diff --git a/lib/berrypod_web/components/shop_components/content.ex b/lib/berrypod_web/components/shop_components/content.ex index 660786b..aef4734 100644 --- a/lib/berrypod_web/components/shop_components/content.ex +++ b/lib/berrypod_web/components/shop_components/content.ex @@ -167,7 +167,8 @@ defmodule BerrypodWeb.ShopComponents.Content do

No orders found for that address. Make sure you use the same email you checked out with.

-
+ + <.shop_input type="email" name="email" @@ -188,7 +189,8 @@ defmodule BerrypodWeb.ShopComponents.Content do

Enter the email address you used at checkout and we'll send you a link.

- + + <.shop_input type="email" name="email" diff --git a/lib/berrypod_web/controllers/order_lookup_controller.ex b/lib/berrypod_web/controllers/order_lookup_controller.ex index cc82c0d..e79034a 100644 --- a/lib/berrypod_web/controllers/order_lookup_controller.ex +++ b/lib/berrypod_web/controllers/order_lookup_controller.ex @@ -1,9 +1,45 @@ defmodule BerrypodWeb.OrderLookupController do use BerrypodWeb, :controller + alias Berrypod.Orders + alias Berrypod.Orders.OrderNotifier + @salt "order_lookup" @max_age 3_600 + @doc """ + Looks up orders by email and sends a verification link (no-JS fallback). + """ + def lookup(conn, %{"email" => email}) when is_binary(email) and email != "" do + orders = Orders.list_orders_by_email(email) + + if orders == [] do + conn + |> put_flash( + :error, + "No orders found for that address. Make sure you use the same email you checked out with." + ) + |> redirect(to: ~p"/contact") + else + token = generate_token(email) + link = BerrypodWeb.Endpoint.url() <> ~p"/orders/verify/#{token}" + OrderNotifier.deliver_order_lookup(email, link) + + conn + |> put_flash( + :info, + "We've sent a link to your email address. It'll expire after an hour." + ) + |> redirect(to: ~p"/contact") + end + end + + def lookup(conn, _params) do + conn + |> put_flash(:error, "Please enter your email address.") + |> redirect(to: ~p"/contact") + end + def verify(conn, %{"token" => token}) do case Phoenix.Token.verify(BerrypodWeb.Endpoint, @salt, token, max_age: @max_age) do {:ok, email} -> diff --git a/lib/berrypod_web/router.ex b/lib/berrypod_web/router.ex index dfcf9d2..9e99825 100644 --- a/lib/berrypod_web/router.ex +++ b/lib/berrypod_web/router.ex @@ -90,6 +90,9 @@ defmodule BerrypodWeb.Router do # Checkout (POST — creates Stripe session and redirects) post "/checkout", CheckoutController, :create + # Order lookup (no-JS fallback for contact page form) + post "/contact/lookup", OrderLookupController, :lookup + # Cart form actions (no-JS fallbacks for LiveView cart events) post "/cart/add", CartController, :add post "/cart/remove", CartController, :remove diff --git a/test/berrypod_web/controllers/order_lookup_controller_test.exs b/test/berrypod_web/controllers/order_lookup_controller_test.exs new file mode 100644 index 0000000..5f71866 --- /dev/null +++ b/test/berrypod_web/controllers/order_lookup_controller_test.exs @@ -0,0 +1,37 @@ +defmodule BerrypodWeb.OrderLookupControllerTest do + use BerrypodWeb.ConnCase, async: false + + import Berrypod.AccountsFixtures + import Berrypod.OrdersFixtures + + setup do + user_fixture() + {:ok, _} = Berrypod.Settings.set_site_live(true) + :ok + end + + describe "POST /contact/lookup" do + test "sends lookup email and redirects when orders exist", %{conn: conn} do + order_fixture(%{customer_email: "buyer@test.com", payment_status: "paid"}) + + conn = post(conn, ~p"/contact/lookup", %{"email" => "buyer@test.com"}) + + assert redirected_to(conn) == "/contact" + assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "sent a link" + end + + test "shows error when no orders found", %{conn: conn} do + conn = post(conn, ~p"/contact/lookup", %{"email" => "nobody@test.com"}) + + assert redirected_to(conn) == "/contact" + assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "No orders found" + end + + test "shows error when email is missing", %{conn: conn} do + conn = post(conn, ~p"/contact/lookup", %{}) + + assert redirected_to(conn) == "/contact" + assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "enter your email" + end + end +end