Files
parsshop/app/cart/page.tsx
2026-04-02 14:18:37 +03:30

215 lines
14 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 { useCart } from "@/components/context/cartcontext";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react"; // اضافه شدن useState
import {
Trash2,
ShoppingBag,
ChevronLeft,
Plus,
Minus,
ShieldCheck,
Truck,
CreditCard
} from "lucide-react";
// مسیر ایمپورت کامپوننت Notlogin را بر اساس ساختار پوشه‌بندی خود تنظیم کنید
import NotLogin from "@/components/Notlogin";
export default function CartPage() {
const { cart, clearCart, addToCart, decreaseQuantity } = useCart();
const router = useRouter();
// استیت برای مدیریت نمایش مودال/کامپوننت لاگین نشده‌ها
const [showNotLogin, setShowNotLogin] = useState(false);
// بررسی لاگین کاربر
const handleCheckoutNavigation = () => {
const token = localStorage.getItem('accessToken');
if (token) {
// اگر لاگین بود برود به چک اوت
router.push('/checkout');
} else {
// اگر لاگین نبود، کامپوننت Notlogin نمایش داده شود
setShowNotLogin(true);
}
};
// تبدیل رشته قیمت به عدد
const parsePrice = (priceStr?: number | null) => {
if (!priceStr) return 0;
return Number(priceStr.toString().replace(/,/g, ''));
};
// محاسبه قیمت کل و تعداد کل
const totalPrice = cart.reduce((total, item) => total + (parsePrice(item.price) * item.quantity), 0);
const totalItems = cart.reduce((total, item) => total + item.quantity, 0);
// دیزاین حالت سبد خرید خالی
if (cart.length === 0) {
return (
<div className="min-h-screen bg-gray-50/50 flex flex-col items-center justify-center p-6">
<div className="bg-white p-12 rounded-[3rem] shadow-sm border border-gray-100 flex flex-col items-center max-w-md w-full text-center">
<div className="bg-blue-50/50 w-32 h-32 rounded-full flex items-center justify-center mb-8 relative">
<ShoppingBag size={56} className="text-blue-500 relative z-10" />
<div className="absolute inset-0 bg-blue-100 rounded-full animate-ping opacity-20"></div>
</div>
<h2 className="text-2xl font-black text-gray-800 mb-3">سبد خرید شما خالی است!</h2>
<p className="text-gray-500 mb-10 leading-relaxed text-sm">
هنوز هیچ محصولی به سبد خرید خود اضافه نکردهاید. برای مشاهده محصولات به صفحه اصلی برگردید.
</p>
<Link href="/" className="w-full bg-[#ffb900] hover:bg-[#e5a600] text-black font-bold text-lg px-8 py-4 rounded-2xl transition-all shadow-[0_4px_20px_rgba(255,185,0,0.3)] hover:shadow-[0_6px_25px_rgba(255,185,0,0.4)] flex items-center justify-center gap-2">
بازگشت به فروشگاه
<ChevronLeft size={20} />
</Link>
</div>
</div>
);
}
return (
<main className="bg-gray-50/30 min-h-screen pb-20">
{/* رندر کردن کامپوننت Notlogin به صورت شرطی */}
{/* اگر نیاز است که کاربر بتواند آن را ببندد، پراپ onClose را به آن پاس بدهید */}
{showNotLogin && (
<NotLogin
buttonText="بازگشت به سبد خرید"
onClose={() => setShowNotLogin(false)} />
)}
<div className="container mx-auto px-4 py-8 max-w-6xl">
<div className="mb-10">
<div className="flex items-center justify-between mb-8">
<h1 className="text-xl md:text-3xl font-black text-gray-800 flex items-center gap-3">
سبد خرید
<span className="bg-[#ffb900]/20 text-[#d99d00] text-xs md:text-sm font-bold py-1 px-3 rounded-xl flex items-center">
{totalItems} کالا
</span>
</h1>
</div>
<div className="mb-10">
<div className="relative w-full max-w-2xl mx-auto px-2 sm:px-0 mb-12">
<div className="absolute top-[20px] sm:top-[24px] left-[16.5%] right-[16.5%] h-[2px] bg-gray-200 z-0">
<div className="h-full bg-[#ffb900] w-[50%] transition-all duration-500 ease-in-out"></div>
</div>
<div className="flex justify-between relative z-10">
<Link href="/cart" className="flex flex-col items-center w-1/3 group cursor-pointer">
<div className=" w-10 h-10 sm:w-12 sm:h-12 bg-[#ffb900] text-[#1A2332] rounded-full flex items-center justify-center shadow-[0_0_15px_rgba(255,185,0,0.4)] mb-2 sm:mb-3 ring-[6px] ring-[#ffb900]/20 transition-all">
<ShoppingBag className="w-5 h-5 sm:w-6 sm:h-6" strokeWidth={2} />
</div>
<span className="text-[10px] sm:text-sm font-bold text-[#1A2332] text-center">سبد خرید</span>
</Link>
{/* کلیک روی آیکون اطلاعات ارسال */}
<div onClick={handleCheckoutNavigation} className="flex flex-col items-center w-1/3 cursor-pointer group">
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-white border-2 border-gray-200 text-gray-400 rounded-full flex items-center justify-center mb-2 sm:mb-3 ring-[6px] ring-[#f8fafc] sm:ring-[#f8fafc] group-hover:border-[#ffb900] transition-colors">
<Truck className="w-4 h-4 sm:w-5 sm:h-5" strokeWidth={2} />
</div>
<span className="text-[10px] sm:text-sm font-bold text-[#1A2332] text-center">اطلاعات ارسال</span>
</div>
<div className="flex flex-col items-center w-1/3">
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-white border-2 border-gray-200 text-gray-400 rounded-full flex items-center justify-center mb-2 sm:mb-3 ring-[6px] ring-[#f8fafc] sm:ring-[#f8fafc]">
<CreditCard className="w-4 h-4 sm:w-5 sm:h-5" />
</div>
<span className="text-[10px] sm:text-sm font-medium text-gray-400 text-center">پرداخت</span>
</div>
</div>
</div>
</div>
</div>
<div className="flex flex-col lg:flex-row gap-6 lg:gap-8">
<div className="flex-1">
<div className="bg-white rounded-[1rem] p-4 md:p-8 shadow-sm ">
<div className="flex justify-between items-center mb-6 pb-6 border-b border-gray-100">
<h2 className="text-base md:text-lg font-bold text-gray-800">محصولات انتخاب شده</h2>
<button onClick={clearCart} className="text-xs md:text-sm text-red-500 hover:text-red-700 transition flex items-center gap-1.5 bg-red-50 hover:bg-red-100 px-3 py-1.5 rounded-lg">
<Trash2 size={16} />
حذف همه
</button>
</div>
<div className="flex flex-col gap-6">
{cart.map((item) => {
const itemTotal = parsePrice(item.price) * item.quantity;
return (
<div key={item.id} className="group flex flex-col sm:flex-row gap-4 sm:gap-6 items-start sm:items-center border-b border-gray-50 pb-6 last:border-0 last:pb-0">
<div className="bg-gray-50/80 p-3 rounded-2xl border border-gray-100 shrink-0 relative group-hover:bg-white transition-colors duration-300 w-full sm:w-auto flex justify-center">
<Image src={item.image} alt={item.title} width={100} height={100} className="object-contain w-24 h-24 drop-shadow-sm" />
</div>
<div className="flex-1 w-full">
<p className="text-xs font-medium text-blue-500 mb-1.5">{item.brand}</p>
<h3 className="text-sm md:text-base font-bold text-gray-800 line-clamp-2 leading-tight mb-3 group-hover:text-blue-600 transition-colors">{item.title}</h3>
</div>
<div className="flex sm:flex-col justify-between sm:justify-end items-center sm:items-end w-full sm:w-auto gap-4 shrink-0 mt-2 sm:mt-0">
<span className="font-black text-base md:text-lg text-gray-900">
{item.price ? `${itemTotal.toLocaleString('fa-IR')} ت` : 'استعلام'}
</span>
<div className="flex items-center gap-1 bg-gray-50 border border-gray-200 rounded-full p-1 shadow-sm">
<button onClick={() => addToCart(item)} className="w-7 h-7 md:w-8 md:h-8 flex items-center justify-center rounded-full bg-white text-gray-600 hover:text-green-600 hover:shadow-sm transition-all">
<Plus size={14} strokeWidth={2.5} />
</button>
<span className="text-xs md:text-sm font-bold text-gray-800 w-6 text-center">{item.quantity}</span>
<button onClick={() => decreaseQuantity(item.id)} className="w-7 h-7 md:w-8 md:h-8 flex items-center justify-center rounded-full bg-white text-gray-600 hover:text-red-500 hover:shadow-sm transition-all">
{item.quantity === 1 ? <Trash2 size={14} /> : <Minus size={14} strokeWidth={2.5} />}
</button>
</div>
</div>
</div>
);
})}
</div>
</div>
</div>
<div className="w-full lg:w-[340px] shrink-0">
<div className="bg-white rounded-[1rem] p-4 md:p-8 shadow-sm sticky top-6">
<h2 className="text-lg md:text-xl font-bold text-gray-800 mb-6">خلاصه صورتحساب</h2>
<div className="space-y-4 mb-6">
<div className="flex justify-between items-center text-xs md:text-sm">
<span className="text-gray-500">تعداد کالاها</span>
<span className="font-bold text-gray-800">{totalItems} عدد</span>
</div>
<div className="flex justify-between items-center text-xs md:text-sm">
<span className="text-gray-500">هزینه ارسال</span>
<span className="text-blue-600 font-bold bg-blue-50 px-2 py-1 rounded-md text-[10px] md:text-xs">در مرحله بعد</span>
</div>
</div>
<div className="w-full border-t-2 border-dashed border-gray-200 my-6"></div>
<div className="flex justify-between items-center mb-8">
<span className="text-xs md:text-sm font-bold text-gray-600">مبلغ قابل پرداخت</span>
<span className="font-black text-xl md:text-2xl text-[#ffb900] tracking-tight">
{totalPrice > 0 ? `${totalPrice.toLocaleString('fa-IR')}` : 'استعلام'}
{totalPrice > 0 && <span className="text-xs md:text-sm font-medium text-gray-500 mr-1">تومان</span>}
</span>
</div>
{/* دکمه تایید و ادامه */}
<button
onClick={handleCheckoutNavigation}
className="w-full bg-[#ffb900] hover:bg-[#e5a600] text-black py-3 md:py-4 rounded-xl font-bold text-base md:text-lg transition-all shadow-[0_4px_15px_rgba(255,185,0,0.2)] hover:shadow-[0_6px_20px_rgba(255,185,0,0.3)] flex justify-center items-center gap-2 mb-6"
>
تایید و ادامه
<ChevronLeft size={20} />
</button>
<div className="flex items-center justify-center gap-2 md:gap-4 text-[10px] md:text-xs font-medium text-gray-400 bg-gray-50 py-3 rounded-xl border border-gray-100">
<div className="flex items-center gap-1"><ShieldCheck size={14} className="text-green-500" /> پرداخت امن</div>
<div className="w-1 h-1 bg-gray-300 rounded-full"></div>
<div className="flex items-center gap-1"><Truck size={14} className="text-blue-500" /> ارسال سریع</div>
</div>
</div>
</div>
</div>
</div>
</main>
);
}