From a2de32dfad0453e557731dab5b1a18983aabb30c Mon Sep 17 00:00:00 2001 From: haniyeroozmand <147385975+haniyeroozmand@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:18:37 +0330 Subject: [PATCH] checkout accessibility/category products --- app/cart/page.tsx | 108 +++++++++----------- app/category/[categoryName]/page.tsx | 77 +++++++++------ app/checkout/page.tsx | 136 ++++++++++---------------- app/dashboard/page.tsx | 15 +-- app/page.tsx | 141 +++++++++------------------ app/products/page.tsx | 2 +- components/Notlogin.tsx | 58 +++++++++++ components/header.tsx | 4 +- components/productcard.tsx | 4 +- public/src/services/auth/api.tsx | 13 +-- public/src/services/products/api.tsx | 2 - public/src/types/auth.tsx | 11 +++ 12 files changed, 270 insertions(+), 301 deletions(-) create mode 100644 components/Notlogin.tsx create mode 100644 public/src/types/auth.tsx diff --git a/app/cart/page.tsx b/app/cart/page.tsx index 32c13e9..ef5a306 100644 --- a/app/cart/page.tsx +++ b/app/cart/page.tsx @@ -3,6 +3,8 @@ 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, @@ -11,14 +13,33 @@ import { Minus, ShieldCheck, Truck, - CreditCard, ChevronRight, Check + 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?: string | null) => { + const parsePrice = (priceStr?: number | null) => { if (!priceStr) return 0; return Number(priceStr.toString().replace(/,/g, '')); }; @@ -51,9 +72,16 @@ export default function CartPage() { return (
+ {/* رندر کردن کامپوننت Notlogin به صورت شرطی */} + {/* اگر نیاز است که کاربر بتواند آن را ببندد، پراپ onClose را به آن پاس بدهید */} + {showNotLogin && ( + setShowNotLogin(false)} /> + )} +
- {/* بخش هدر */}

@@ -64,19 +92,13 @@ export default function CartPage() {

- {/* بخش هدر و تایم‌لاین */}
- - {/* Breadcrumb (تایم‌لاین اکتیو شده برای مرحله ۲) */}
- {/* خط سراسری بک‌گراند */}
- {/* پر شدن خط مرحله دوم (۵۰ درصد پیشرفت) */}
- {/* مرحله 1 (تکمیل شده) */}
@@ -84,16 +106,14 @@ export default function CartPage() { سبد خرید - {/* مرحله 2 (اکتیو و فعلی) */} - - {/* استفاده از ring زرد با opacity برای نشان دادن حالت اکتیو */} -
+ {/* کلیک روی آیکون اطلاعات ارسال */} +
+
اطلاعات ارسال - +
- {/* مرحله 3 (غیرفعال) */}
@@ -106,8 +126,6 @@ export default function CartPage() {
- - {/* بخش لیست محصولات */}
@@ -121,50 +139,25 @@ export default function CartPage() {
{cart.map((item) => { const itemTotal = parsePrice(item.price) * item.quantity; - return (
- - {/* تصویر محصول */}
{item.title}
- - {/* اطلاعات محصول */}

{item.brand}

{item.title}

- - {/* ویژگی‌ها (Badges) */} -
- L : {item.l} - D : {item.d} -
- - {/* قیمت و کنترلر */}
{item.price ? `${itemTotal.toLocaleString('fa-IR')} ت` : 'استعلام'} - - {/* کنترلر تعداد طرح کپسولی */}
- - - - {item.quantity} - - -
@@ -176,26 +169,20 @@ export default function CartPage() {
- {/* بخش صورتحساب (Sidebar) */}

خلاصه صورتحساب

-
تعداد کالاها {totalItems} عدد
-
هزینه ارسال در مرحله بعد
- - {/* خط‌چین جداکننده */}
-
مبلغ قابل پرداخت @@ -204,22 +191,19 @@ export default function CartPage() {
- + {/* دکمه تایید و ادامه */} + - {/* بج‌های اعتماد (Trust Badges) */}
-
- - پرداخت امن -
+
پرداخت امن
-
- - ارسال سریع -
+
ارسال سریع
diff --git a/app/category/[categoryName]/page.tsx b/app/category/[categoryName]/page.tsx index 6a988a4..40d1a01 100644 --- a/app/category/[categoryName]/page.tsx +++ b/app/category/[categoryName]/page.tsx @@ -1,40 +1,61 @@ +import ProductCard from "@/components/productcard"; // 1. ایمپورت کردن کامپوننت کارت محصول import { getProductsByCategory } from "@/public/src/services/products/api"; +import { Product } from "@/public/src/types/product"; // بهتر است تایپ محصول را هم برای خوانایی ایمپورت کنید -export default async function CategoryPage({ params }:any) { - +export default async function CategoryPage({ params }: any) { const { categoryName } = await params; - console.log("🔎 CategoryPage slug:", categoryName); + // منطق دریافت دیتا از API بدون تغییر باقی می‌ماند + const categoryData = await getProductsByCategory(categoryName); - const products = await getProductsByCategory(categoryName); + // مدیریت حالتی که محصولی یافت نشود + if (!categoryData || !categoryData.items || categoryData.items.length === 0) { + return ( +
+

+ محصولی در دسته‌بندی «{decodeURIComponent(categoryName)}» یافت نشد. +

+
+ ); + } + + const pageTitle = categoryData.items[0]?.primaryCategory?.name || decodeURIComponent(categoryName); return ( -
- -

- دسته‌بندی: {categoryName} -

- -
- - {products.items.map((product:any) => ( -
- -
- -

- {product.title} -

- -

- {product.brand} -

- +
+
+ {/* عنوان و تعداد محصولات */} +
+

+ {pageTitle} + + {categoryData.meta.total} کالا + +

+
+
- ))} +
+ {/* 2. جایگزینی div ساده با کامپوننت ProductCard در حلقه */} +
+ {categoryData.items.map((apiProduct: any) => { + // 3. تبدیل داده‌های API به فرمت مورد انتظار کامپوننت ProductCard + const productForCard: Product = { + id: apiProduct.id, + title: apiProduct.title, + brand: apiProduct.brand, + slug: apiProduct.slug, + price: apiProduct.calculated_price, // تبدیل نام فیلد + stock: apiProduct.stock, + image: apiProduct.mainImageUrl || "/placeholder.png", // تبدیل نام فیلد و افزودن جایگزین + attributes: apiProduct.attributes, + }; + + return ; + })} +
- -
+
); } diff --git a/app/checkout/page.tsx b/app/checkout/page.tsx index ada35f1..dfa3178 100644 --- a/app/checkout/page.tsx +++ b/app/checkout/page.tsx @@ -2,44 +2,78 @@ import { useCart } from "@/components/context/cartcontext"; import Link from "next/link"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import { ShoppingBag, ChevronLeft, ChevronRight, Truck, CreditCard, - Check, MapPin, User, - Phone, - Mail + Lock // آیکون قفل برای صفحه لاگین نشده } from "lucide-react"; export default function CheckoutPage() { const { cart } = useCart(); - - // استیت برای روش ارسال (صرفا جهت نمایش UI) const [shippingMethod, setShippingMethod] = useState('post'); + const [isAuthenticated, setIsAuthenticated] = useState(false); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const token = localStorage.getItem('accessToken'); + if (token) { + setIsAuthenticated(true); + } + setIsLoading(false); // پایان بررسی وضعیت + }, []); // محاسبه قیمت کل و تعداد - const parsePrice = (priceStr?: string | null) => { + 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); - - // هزینه ارسال فرضی const shippingCost = shippingMethod === 'post' ? 45000 : 75000; const finalPrice = totalPrice + shippingCost; + // حالت در حال بررسی توکن + if (isLoading) { + return ( +
+
+
+ ); + } + + // اگر کاربر لاگین نبود، این صفحه به جای محتوای چک‌اوت نمایش داده می‌شود + if (!isAuthenticated) { + return ( +
+
+
+ +
+

دسترسی محدود

+

+ برای ثبت نهایی سفارش و مشاهده این صفحه، باید ابتدا وارد حساب کاربری خود شوید یا ثبت‌نام کنید. +

+ + + بازگشت به سبد خرید + +
+
+ ); + } + + // اگر لاگین بود، محتوای اصلی رندر می‌شود (کد اصلی شما در اینجا قرار می‌گیرد) return (
- {/* بخش هدر و تایم‌لاین */}

@@ -51,16 +85,12 @@ export default function CheckoutPage() {

- {/* Breadcrumb (تایم‌لاین اکتیو شده برای مرحله ۲) */}
- {/* خط سراسری بک‌گراند */}
- {/* پر شدن خط مرحله دوم (۵۰ درصد پیشرفت) */}
- {/* مرحله 1 (تکمیل شده) */}
@@ -68,16 +98,13 @@ export default function CheckoutPage() { سبد خرید - {/* مرحله 2 (اکتیو و فعلی) */}
- {/* استفاده از ring زرد با opacity برای نشان دادن حالت اکتیو */}
اطلاعات ارسال
- {/* مرحله 3 (غیرفعال) */}
@@ -89,11 +116,7 @@ export default function CheckoutPage() {
- - {/* بخش فرم اطلاعات */}
- - {/* فرم مشخصات گیرنده */}
@@ -101,30 +124,18 @@ export default function CheckoutPage() {

مشخصات گیرنده

-
- +
-
- -
+
- {/* فرم آدرس */}
@@ -132,7 +143,6 @@ export default function CheckoutPage() {

آدرس پستی

-
@@ -151,63 +161,39 @@ export default function CheckoutPage() {
-
-