181 lines
8.3 KiB
TypeScript
181 lines
8.3 KiB
TypeScript
"use client";
|
||
|
||
import Button from '@/components/button/PrimaryButton';
|
||
import { ef } from '@/lib/helpers/utfNumbers';
|
||
import { ArrowLeft, Edit2, TickCircle, Trash } from 'iconsax-react';
|
||
import Link from 'next/link';
|
||
import { useRouter, useSearchParams } from 'next/navigation';
|
||
import React, { useState } from 'react';
|
||
import { useGetAddresses, useSetDefaultAddress, useDeleteAddress } from './hooks/useAddressData';
|
||
import { Address } from './types/Types';
|
||
import Prompt from '@/components/utils/Prompt';
|
||
import { toast } from '@/components/Toast';
|
||
import useToggle from '@/hooks/helpers/useToggle';
|
||
|
||
type Props = object
|
||
|
||
function UserAddressesPage({ }: Props) {
|
||
|
||
const { data: addressesResponse, isLoading } = useGetAddresses();
|
||
const router = useRouter();
|
||
const searchParams = useSearchParams();
|
||
const redirect = searchParams.get('redirect');
|
||
const { mutate: setDefault, isPending: isSettingDefault } = useSetDefaultAddress();
|
||
const { mutate: deleteAddressMutation, isPending: isDeleting } = useDeleteAddress();
|
||
const { state: deleteModalVisible, set: setDeleteModal } = useToggle();
|
||
const [selectedAddressId, setSelectedAddressId] = useState<string | null>(null);
|
||
|
||
const addresses = addressesResponse?.data || [];
|
||
|
||
const handleSetDefault = (addressId: string) => {
|
||
setDefault(addressId, {
|
||
onSuccess: () => {
|
||
toast('آدرس به عنوان پیشفرض تنظیم شد', 'success');
|
||
if (redirect) {
|
||
router.replace(redirect);
|
||
}
|
||
},
|
||
onError: (error) => {
|
||
const errorMessage = error instanceof Error ? error.message : 'خطا در تنظیم آدرس پیشفرض';
|
||
toast(errorMessage, 'error');
|
||
},
|
||
});
|
||
};
|
||
|
||
const handleDeleteClick = (addressId: string) => {
|
||
setSelectedAddressId(addressId);
|
||
setDeleteModal(true);
|
||
};
|
||
|
||
const handleDeleteConfirm = () => {
|
||
if (!selectedAddressId) return;
|
||
|
||
deleteAddressMutation(selectedAddressId, {
|
||
onSuccess: () => {
|
||
toast('آدرس با موفقیت حذف شد', 'success');
|
||
setDeleteModal(false);
|
||
setSelectedAddressId(null);
|
||
},
|
||
onError: (error) => {
|
||
const errorMessage = error instanceof Error ? error.message : 'خطا در حذف آدرس';
|
||
toast(errorMessage, 'error');
|
||
},
|
||
});
|
||
};
|
||
|
||
const handleDeleteCancel = () => {
|
||
setDeleteModal(false);
|
||
setSelectedAddressId(null);
|
||
};
|
||
|
||
const formatAddress = (address: Address) => {
|
||
return `${address.address}، ${address.city}، ${address.province}`;
|
||
};
|
||
|
||
const getEditHref = (addressId: string) => {
|
||
const base = `address/new?id=${addressId}`;
|
||
return redirect ? `${base}&redirect=${encodeURIComponent(redirect)}` : base;
|
||
};
|
||
|
||
return (
|
||
<div className='overflow-y-auto h-full noscrollbar flex flex-col'>
|
||
<div className='grid grid-cols-3 items-center'>
|
||
<span></span>
|
||
<h1 className='text-sm2 place-self-center font-medium'>افزودن و انتخاب آدرس</h1>
|
||
<ArrowLeft
|
||
className='cursor-pointer place-self-end'
|
||
size='24'
|
||
color='currentColor'
|
||
onClick={() => { router.back() }}
|
||
/>
|
||
</div>
|
||
|
||
<div className="mt-8 flex-1 w-full py-0 flex flex-col gap-4">
|
||
{isLoading ? (
|
||
<div className='flex-1 flex flex-col items-center justify-center gap-4'>
|
||
<p className='text-center text-sm2 text-disabled-text'>
|
||
در حال بارگذاری...
|
||
</p>
|
||
</div>
|
||
) : addresses.length === 0 ? (
|
||
<div className='flex-1 flex flex-col items-center justify-center gap-4'>
|
||
<p className='text-center text-sm2 text-disabled-text'>
|
||
شما هیچ آدرسی ثبت نکرده اید. برای ثبت آدرس دکمه افزودن را بزنید
|
||
</p>
|
||
</div>
|
||
) : (
|
||
addresses.map((address) => (
|
||
<div
|
||
key={address.id}
|
||
className={`bg-container rounded-container w-full shadow-xl px-4 py-4 flex flex-col justify-between ${address.isDefault ? 'border border-primary' : ''}`}
|
||
>
|
||
<div className="flex justify-between items-start mb-2">
|
||
<h2 className='text-sm font-medium'>{address.title}</h2>
|
||
{address.isDefault && (
|
||
<span className='text-xs bg-primary/10 text-primary px-2 py-1 rounded-full'>
|
||
پیشفرض
|
||
</span>
|
||
)}
|
||
</div>
|
||
<p className='text-sm2 mt-2'>
|
||
{formatAddress(address)}
|
||
</p>
|
||
<p className='text-xs mt-2 text-disabled-text'>
|
||
کد پستی: {ef(address.postalCode || 'ثبت نشده')}
|
||
</p>
|
||
<p className='text-xs mt-2 text-disabled-text'>
|
||
تلفن: {ef(address.phone)}
|
||
</p>
|
||
<div className="flex justify-between items-center mt-4 gap-2">
|
||
{!address.isDefault && (
|
||
<Button
|
||
onClick={() => handleSetDefault(address.id)}
|
||
disabled={isSettingDefault}
|
||
pending={isSettingDefault}
|
||
className='bg-background! pattern-secondary-bg text-foreground! flex items-center gap-2 text-xs h-8 flex-1'
|
||
>
|
||
<TickCircle variant='Bold' className='fill-foreground stroke-background size-4.5 mb-0.5' />
|
||
تنظیم به عنوان فعال
|
||
</Button>
|
||
)}
|
||
<div className="flex gap-2">
|
||
<Link href={getEditHref(address.id)}>
|
||
<Button className='bg-background! pattern-secondary-bg text-foreground! flex justify-center items-center gap-2 text-xs p-0! size-8!'>
|
||
<Edit2 className='stroke-foreground size-5 mb-0.5' />
|
||
</Button>
|
||
</Link>
|
||
<Button
|
||
onClick={() => handleDeleteClick(address.id)}
|
||
disabled={isDeleting}
|
||
className='bg-background! pattern-secondary-bg text-foreground! flex justify-center items-center gap-2 text-xs p-0! size-8!'
|
||
>
|
||
<Trash className='stroke-foreground size-5 mb-0.5' />
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))
|
||
)}
|
||
</div>
|
||
|
||
<div className='w-full text-center mt-6'>
|
||
<Link href={'address/new'}>
|
||
<Button>افزودن آدرس</Button>
|
||
</Link>
|
||
</div>
|
||
|
||
<Prompt
|
||
title='حذف آدرس'
|
||
description='آیا از حذف این آدرس اطمینان دارید؟'
|
||
textConfirm='بله، حذف کن'
|
||
textCancel='انصراف'
|
||
visible={deleteModalVisible}
|
||
onConfirm={handleDeleteConfirm}
|
||
onCancel={handleDeleteCancel}
|
||
onClick={handleDeleteCancel}
|
||
/>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default UserAddressesPage |