Files
kottgard-testing/src/app/account/page.tsx
T

164 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useEffect } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { User, Package, MapPin, Phone, Mail, LogOut, Heart } from 'lucide-react';
import Button from '@/components/ui/Button';
import { useAuth } from '@/presentation/hooks/useAuth';
import { formatPrice, formatDate, getFormatLocale } from '@/lib/utils';
import { useTranslation } from '@/hooks/useTranslation';
import { localizeProduct } from '@/lib/product-i18n';
export default function AccountPage() {
const router = useRouter();
const { user, isAuthenticated, orders, logout } = useAuth();
const { t, locale } = useTranslation();
useEffect(() => {
if (!isAuthenticated) {
router.push('/login');
}
}, [isAuthenticated, router]);
if (!isAuthenticated || !user) {
return null;
}
const handleLogout = () => {
logout();
router.push('/');
};
const fmt = (n: number) => formatPrice(n, getFormatLocale(locale));
return (
<div className="bg-gray-50">
<div className="border-b border-gray-100 bg-white">
<div className="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<h1 className="section-heading">{t('account.title')}</h1>
<p className="text-gray-500">{t('account.welcome', { name: user.name })}</p>
</div>
</div>
<div className="mx-auto max-w-7xl px-4 py-10 sm:px-6 lg:px-8">
<div className="grid gap-8 lg:grid-cols-3">
<div className="space-y-6">
<div className="card-premium p-6">
<div className="mb-4 flex items-center gap-3">
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-brand-100">
<User className="h-6 w-6 text-brand-700" />
</div>
<div>
<h2 className="font-display text-lg font-semibold">{user.name}</h2>
<p className="text-sm text-gray-500">
{t('account.memberSince', { date: formatDate(user.createdAt) })}
</p>
</div>
</div>
<div className="space-y-3 border-t border-gray-100 pt-4">
<div className="flex items-center gap-2 text-sm text-gray-600">
<Mail className="h-4 w-4 text-brand-600" />
{user.email}
</div>
<div className="flex items-center gap-2 text-sm text-gray-600">
<Phone className="h-4 w-4 text-brand-600" />
{user.phone}
</div>
<div className="flex items-start gap-2 text-sm text-gray-600">
<MapPin className="mt-0.5 h-4 w-4 shrink-0 text-brand-600" />
{user.address.street}, {user.address.city}, {user.address.state}{' '}
{user.address.zip}
</div>
</div>
</div>
<div className="card-premium p-4">
<Link
href="/wishlist"
className="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-gray-600 transition-colors hover:bg-brand-50 hover:text-brand-700"
>
<Heart className="h-4 w-4" />
{t('account.myWishlist')}
</Link>
<button
onClick={handleLogout}
className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-red-500 transition-colors hover:bg-red-50"
>
<LogOut className="h-4 w-4" />
{t('account.signOut')}
</button>
</div>
</div>
<div className="lg:col-span-2" id="orders">
<div className="card-premium p-6">
<div className="mb-6 flex items-center gap-2">
<Package className="h-5 w-5 text-brand-700" />
<h2 className="font-display text-lg font-semibold">
{t('account.orderHistory')}
</h2>
</div>
{orders.length === 0 ? (
<div className="py-12 text-center">
<p className="mb-2 text-gray-500">{t('account.noOrders')}</p>
<Link href="/shop">
<Button variant="primary">{t('account.startShopping')}</Button>
</Link>
</div>
) : (
<div className="space-y-4">
{orders.map((order) => (
<div
key={order.id}
className="rounded-xl border border-gray-100 p-4 transition-colors hover:border-brand-200"
>
<div className="mb-3 flex items-center justify-between">
<div>
<p className="text-sm font-semibold text-brand-900">{order.id}</p>
<p className="text-xs text-gray-400">
{formatDate(order.createdAt)}
</p>
</div>
<div className="text-end">
<p className="font-bold text-brand-800">{fmt(order.total)}</p>
<span className="inline-block rounded-full bg-brand-50 px-2 py-0.5 text-xs font-medium capitalize text-brand-700">
{t(`orderStatus.${order.status}`)}
</span>
</div>
</div>
<div className="space-y-1">
{order.items.map((item) => {
const localized = localizeProduct(item.product, t);
return (
<div
key={item.id}
className="flex justify-between text-sm text-gray-600"
>
<Link
href={`/product/${item.product.slug}`}
className="hover:text-brand-700"
>
{localized.name} × {item.quantity}
<span className="ms-2 text-xs text-gold-600">
({item.customizationLabel})
</span>
</Link>
<span>{fmt(item.product.price * item.quantity)}</span>
</div>
);
})}
</div>
</div>
))}
</div>
)}
</div>
</div>
</div>
</div>
</div>
);
}