Files
shop-front/src/app/cart/payment/page.tsx
T
2025-09-14 12:47:51 +03:30

169 lines
6.9 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 CartSummary from '@/components/CartSummary'
import Layout from '@/hoc/Layout'
import { NextPage } from 'next'
import TitleBack from '../components/TitleBack'
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import DiscountCard from '../components/DiscountCard'
import { usePaymentMethods, useGetCart, useShippingCost } from '../hooks/useCartData'
import { useState } from 'react'
import { toast } from '@/components/Toast'
import { useGetProfile } from '@/app/profile/hooks/useProfileData'
const CartPayment: NextPage = () => {
const { data: paymentMethodsData, isLoading: paymentMethodsLoading } = usePaymentMethods()
const { data: cartData, isLoading: cartLoading } = useGetCart()
const { data: shippingData, isLoading: shippingLoading } = useShippingCost()
const { data: profileData, isLoading: profileLoading } = useGetProfile()
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<string>('')
const [discountCode, setDiscountCode] = useState<string>('')
const [isApplyingDiscount, setIsApplyingDiscount] = useState(false)
const isLoading = paymentMethodsLoading || cartLoading || shippingLoading || profileLoading
if (isLoading) {
return (
<div className="mt-14 px-4 sm:px-8 lg:px-20">
<div className="flex items-center justify-center h-64">
<div className="text-lg">در حال بارگذاری...</div>
</div>
</div>
)
}
const cart = cartData?.results?.cart
const paymentMethods = paymentMethodsData?.results?.paymentMethods || []
const profile = profileData?.results?.info
if (!cart?.items?.length) {
return (
<div className="mt-14 px-4 sm:px-8 lg:px-20">
<div className="flex items-center justify-center h-64">
<div className="text-lg">سبد خرید شما خالی است</div>
</div>
</div>
)
}
// محاسبه هزینه ارسال
const totalShippingCost = shippingData?.results?.shipping?.reduce((total, shop) => {
return total + (shop.shippers?.[0]?.totalShippingCost || 0)
}, 0) || 0
// محاسبه قیمت نهایی
const finalTotal = (cart?.payable_price || 0) + totalShippingCost
const handlePaymentMethodChange = (value: string) => {
setSelectedPaymentMethod(value)
}
const handleDiscountCodeSubmit = async () => {
if (!discountCode.trim()) {
toast('لطفاً کد تخفیف را وارد کنید', 'error')
return
}
setIsApplyingDiscount(true)
try {
// TODO: پیاده‌سازی API اعمال کد تخفیف
// await applyDiscountCode(discountCode)
toast('کد تخفیف با موفقیت اعمال شد', 'success')
} catch {
toast('کد تخفیف نامعتبر است', 'error')
} finally {
setIsApplyingDiscount(false)
}
}
const handlePayment = async () => {
if (!selectedPaymentMethod) {
toast('لطفاً روش پرداخت را انتخاب کنید', 'error')
return
}
if (!profile?.userAddress) {
toast('لطفاً ابتدا آدرس خود را تکمیل کنید', 'error')
return
}
try {
// TODO: پیاده‌سازی API پرداخت نهایی
// await processPayment({
// paymentMethodId: selectedPaymentMethod,
// discountCode: discountCode || null,
// shippingAddress: profile.userAddress
// })
toast('پرداخت با موفقیت انجام شد', 'success')
} catch {
toast('خطا در پردازش پرداخت', 'error')
}
}
return (
<div className="mt-14 px-4 sm:px-8 lg:px-20">
<div className="mt-6 flex flex-col lg:flex-row gap-6">
<div className='flex-1'>
<TitleBack title='پرداخت' />
<DiscountCard
discountCode={discountCode}
setDiscountCode={setDiscountCode}
onSubmit={handleDiscountCodeSubmit}
isLoading={isApplyingDiscount}
/>
<div className='mt-5 border border-border rounded-2xl p-4 sm:p-6 font-light'>
<div>انتخاب روش پرداخت</div>
<div className='mt-6 sm:mt-10 text-[#333333] font-light'>
<RadioGroup
value={selectedPaymentMethod}
onValueChange={handlePaymentMethodChange}
>
{paymentMethods.map((method) => (
<div key={method._id} className="flex items-center gap-2 mb-3">
<RadioGroupItem
value={method._id}
id={method._id}
disabled={!method.isActive}
/>
<label
htmlFor={method._id}
className={`text-sm ${method.isActive ? 'cursor-pointer' : 'cursor-not-allowed'} ${!method.isActive ? 'text-gray-400' : ''}`}
>
<span className="font-medium">{method.title_fa}</span>
{method.provider && (
<span className="text-xs text-gray-500 mr-2">
({method.provider})
</span>
)}
</label>
</div>
))}
</RadioGroup>
</div>
</div>
</div>
<div className="w-full lg:w-[360px] lg:flex-shrink-0">
<CartSummary
itemsCount={cart?.items_count || 0}
itemsPrice={cart?.retail_price || 0}
discount={cart?.total_discount || 0}
shippingCost={totalShippingCost}
total={finalTotal}
onConfirm={handlePayment}
confirmLabel="پرداخت"
className="w-full"
/>
</div>
</div>
</div>
)
}
export default function CartPaymentWithLayout() {
return (
<Layout>
<CartPayment />
</Layout>
)
}