174 lines
7.5 KiB
TypeScript
174 lines
7.5 KiB
TypeScript
'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, useApplyDiscountCode, useCheckoutCart } 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 applyDiscountMutation = useApplyDiscountCode()
|
||
const checkoutMutation = useCheckoutCart()
|
||
|
||
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<string>('')
|
||
const [discountCode, setDiscountCode] = useState<string>('')
|
||
|
||
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>
|
||
)
|
||
}
|
||
|
||
// بارگذاری انتخابهای ارسال از localStorage
|
||
const savedShipments = typeof window !== 'undefined' ? localStorage.getItem('selectedShipments') : null
|
||
const selectedShipments = savedShipments ? JSON.parse(savedShipments) : {}
|
||
|
||
// محاسبه هزینه ارسال بر اساس انتخابهای کاربر
|
||
const totalShippingCost = shippingData?.results?.shipping?.reduce((total, shop) => {
|
||
const selectedShipperId = selectedShipments[shop.shopId]
|
||
const selectedShipper = shop.shippers?.find(shipper => shipper.shipperId === selectedShipperId)
|
||
return total + (selectedShipper?.totalShippingCost || 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
|
||
}
|
||
|
||
try {
|
||
await applyDiscountMutation.mutateAsync({ discount_code: discountCode })
|
||
toast('کد تخفیف با موفقیت اعمال شد', 'success')
|
||
setDiscountCode('')
|
||
} catch (error: unknown) {
|
||
const errorMessage = (error as { response?: { data?: { message?: string } } })?.response?.data?.message || 'کد تخفیف نامعتبر است'
|
||
toast(errorMessage, 'error')
|
||
}
|
||
}
|
||
|
||
const handlePayment = async () => {
|
||
if (!selectedPaymentMethod) {
|
||
toast('لطفاً روش پرداخت را انتخاب کنید', 'error')
|
||
return
|
||
}
|
||
|
||
if (!profile?.userAddress) {
|
||
toast('لطفاً ابتدا آدرس خود را تکمیل کنید', 'error')
|
||
return
|
||
}
|
||
|
||
const response = await checkoutMutation.mutateAsync({
|
||
payment_method_id: selectedPaymentMethod
|
||
})
|
||
|
||
if (response?.results?.paymentData?.redirectUrl) {
|
||
window.location.href = response.results.paymentData.redirectUrl
|
||
} else {
|
||
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={applyDiscountMutation.isPending}
|
||
/>
|
||
<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"
|
||
isLoading={checkoutMutation.isPending}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default function CartPaymentWithLayout() {
|
||
return (
|
||
<Layout>
|
||
<CartPayment />
|
||
</Layout>
|
||
)
|
||
} |