diff --git a/client/src/pages/account.tsx b/client/src/pages/account.tsx
new file mode 100644
index 0000000..858bdd2
--- /dev/null
+++ b/client/src/pages/account.tsx
@@ -0,0 +1,197 @@
+import { useState, useEffect } from "react";
+import { useSearch, Link } from "wouter";
+import { useQuery, useMutation } from "@tanstack/react-query";
+import { queryClient, apiRequest } from "../lib/queryClient";
+import { toast } from "../hooks/use-toast";
+import { Package, User, LogOut, Mail } from "lucide-react";
+
+interface Customer {
+ id: number;
+ email: string;
+ firstName?: string;
+ lastName?: string;
+ phone?: string;
+}
+
+interface Order {
+ id: number;
+ orderNumber: string;
+ status: string;
+ paymentStatus: string;
+ fulfillmentStatus: string;
+ total: string;
+ createdAt: string;
+ trackingNumber?: string;
+ trackingCarrier?: string;
+}
+
+function LoginForm() {
+ const [email, setEmail] = useState("");
+ const [sent, setSent] = useState(false);
+ const [loading, setLoading] = useState(false);
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setLoading(true);
+ try {
+ await apiRequest("POST", "/api/auth/magic-link", { email });
+ setSent(true);
+ } catch (err: any) {
+ toast({ title: "Error", description: err.message, variant: "destructive" });
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ if (sent) {
+ return (
+
+
+
Check your email
+
We sent a sign-in link to {email}. Click it to sign in.
+
Link expires in 15 minutes.
+
+ );
+ }
+
+ return (
+
+
Sign in
+
We'll send a magic link to your email — no password needed.
+
+
+ );
+}
+
+function AccountDashboard({ customer }: { customer: Customer }) {
+ const { data: orders, isLoading } = useQuery({
+ queryKey: ["/api/account/orders"],
+ queryFn: async () => { const r = await fetch("/api/account/orders", { credentials: "include" }); return r.json(); },
+ });
+
+ const logoutMutation = useMutation({
+ mutationFn: () => apiRequest("POST", "/api/auth/logout"),
+ onSuccess: () => queryClient.invalidateQueries({ queryKey: ["/api/auth/me"] }),
+ });
+
+ const statusBadge = (status: string) => {
+ const colors: Record = {
+ confirmed: "bg-blue-100 text-blue-700",
+ pending: "bg-yellow-100 text-yellow-700",
+ cancelled: "bg-red-100 text-red-700",
+ fulfilled: "bg-green-100 text-green-700",
+ };
+ return colors[status] || "bg-muted text-muted-foreground";
+ };
+
+ return (
+
+
+
+
My Account
+
{customer.email}
+
+
+
+
+
+ Orders
+ {isLoading ? (
+
+ {[1, 2, 3].map((i) =>
)}
+
+ ) : !orders?.length ? (
+
+
+
No orders yet
+
Start shopping
+
+ ) : (
+
+ {orders.map((order) => (
+
+
+
+
#{order.orderNumber}
+
{new Date(order.createdAt).toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" })}
+
+
+ {order.status}
+ ${parseFloat(order.total).toFixed(2)}
+
+
+ {order.trackingNumber && (
+
Tracking: {order.trackingNumber}{order.trackingCarrier && ` (${order.trackingCarrier})`}
+ )}
+
+ ))}
+
+ )}
+
+
+ );
+}
+
+export default function AccountPage() {
+ const search = useSearch();
+ const token = new URLSearchParams(search).get("token");
+ const [verifying, setVerifying] = useState(!!token);
+
+ const { data, isLoading } = useQuery<{ customer: Customer | null }>({
+ queryKey: ["/api/auth/me"],
+ queryFn: async () => { const r = await fetch("/api/auth/me", { credentials: "include" }); return r.json(); },
+ });
+
+ useEffect(() => {
+ if (!token) return;
+ (async () => {
+ try {
+ const res = await fetch(`/api/auth/verify?token=${token}`, { credentials: "include" });
+ if (res.ok) {
+ await queryClient.invalidateQueries({ queryKey: ["/api/auth/me"] });
+ toast({ title: "Signed in!", description: "Welcome back." });
+ } else {
+ toast({ title: "Link expired", description: "Please request a new sign-in link.", variant: "destructive" });
+ }
+ } finally {
+ setVerifying(false);
+ window.history.replaceState({}, "", "/account");
+ }
+ })();
+ }, [token]);
+
+ if (isLoading || verifying) {
+ return Loading...
;
+ }
+
+ return (
+
+ {data?.customer ? (
+
+ ) : (
+
+ )}
+
+ );
+}