update address
This commit is contained in:
@@ -6,6 +6,7 @@ import Modal from '@/components/utils/Modal';
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { ef } from '@/lib/helpers/utfNumbers';
|
import { ef } from '@/lib/helpers/utfNumbers';
|
||||||
|
import { Edit2 } from 'iconsax-react';
|
||||||
|
|
||||||
const formatAddress = (address: Address) => {
|
const formatAddress = (address: Address) => {
|
||||||
return `${address.address}، ${address.city}، ${address.province}`;
|
return `${address.address}، ${address.city}، ${address.province}`;
|
||||||
@@ -78,6 +79,20 @@ export const AddressSelectionModal = ({
|
|||||||
<p className='text-xs mt-2 text-disabled-text'>
|
<p className='text-xs mt-2 text-disabled-text'>
|
||||||
تلفن: {ef(address.phone)}
|
تلفن: {ef(address.phone)}
|
||||||
</p>
|
</p>
|
||||||
|
<div className='mt-3 flex justify-end'>
|
||||||
|
<Link
|
||||||
|
href={`/${name}/profile/address/new?id=${address.id}&redirect=${encodeURIComponent(redirectUrl)}`}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='text-xs text-primary dark:text-foreground flex items-center gap-1'
|
||||||
|
>
|
||||||
|
<Edit2 className='size-4 stroke-primary dark:stroke-foreground' />
|
||||||
|
ویرایش
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ export const useUpdateAddress = () => {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: updateAddress,
|
mutationFn: updateAddress,
|
||||||
onSuccess: () => {
|
onSuccess: (_data, variables) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ["addresses"] });
|
queryClient.invalidateQueries({ queryKey: ["addresses"] });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["address", variables.id] });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet';
|
|||||||
import Button from '@/components/button/PrimaryButton';
|
import Button from '@/components/button/PrimaryButton';
|
||||||
import { AddressDisplay } from './AddressDisplay';
|
import { AddressDisplay } from './AddressDisplay';
|
||||||
import { AddressForm } from './AddressForm';
|
import { AddressForm } from './AddressForm';
|
||||||
import { NominatimReverseGeocodingResponse } from '../../types/Types';
|
import { Address, NominatimReverseGeocodingResponse } from '../../types/Types';
|
||||||
import { Location } from 'iconsax-react';
|
import { Location } from 'iconsax-react';
|
||||||
|
|
||||||
interface AddressDetailsModalProps {
|
interface AddressDetailsModalProps {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
selectedAddress: NominatimReverseGeocodingResponse | null;
|
selectedAddress: NominatimReverseGeocodingResponse | null;
|
||||||
|
existingAddress?: Address | null;
|
||||||
formData: {
|
formData: {
|
||||||
title: string;
|
title: string;
|
||||||
addressDetails: string;
|
addressDetails: string;
|
||||||
@@ -26,6 +27,7 @@ interface AddressDetailsModalProps {
|
|||||||
export const AddressDetailsModal = ({
|
export const AddressDetailsModal = ({
|
||||||
visible,
|
visible,
|
||||||
selectedAddress,
|
selectedAddress,
|
||||||
|
existingAddress,
|
||||||
formData,
|
formData,
|
||||||
isPending,
|
isPending,
|
||||||
editMode = false,
|
editMode = false,
|
||||||
@@ -41,13 +43,13 @@ export const AddressDetailsModal = ({
|
|||||||
blurOpacity={null}
|
blurOpacity={null}
|
||||||
noBlur
|
noBlur
|
||||||
visible={visible}
|
visible={visible}
|
||||||
title='آدرس'
|
title={editMode ? 'ویرایش آدرس' : 'آدرس'}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
overrideClassName='bg-container!'
|
overrideClassName='bg-container!'
|
||||||
>
|
>
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={onSubmit}>
|
||||||
<div className='px-4'>
|
<div className='px-4'>
|
||||||
<AddressDisplay selectedAddress={selectedAddress} />
|
<AddressDisplay selectedAddress={selectedAddress} existingAddress={existingAddress} />
|
||||||
{editMode && onChangePosition && (
|
{editMode && onChangePosition && (
|
||||||
<div className='mt-4 mb-6 flex justify-end'>
|
<div className='mt-4 mb-6 flex justify-end'>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
import { NominatimReverseGeocodingResponse } from '../../types/Types';
|
import { Address, NominatimReverseGeocodingResponse } from '../../types/Types';
|
||||||
import { formatSelectedAddress } from '../utils/formatAddress';
|
import { formatAddress, formatSelectedAddress } from '../utils/formatAddress';
|
||||||
|
|
||||||
interface AddressDisplayProps {
|
interface AddressDisplayProps {
|
||||||
selectedAddress: NominatimReverseGeocodingResponse | null;
|
selectedAddress: NominatimReverseGeocodingResponse | null;
|
||||||
|
existingAddress?: Address | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AddressDisplay = ({ selectedAddress }: AddressDisplayProps) => {
|
export const AddressDisplay = ({ selectedAddress, existingAddress }: AddressDisplayProps) => {
|
||||||
|
const displayText = selectedAddress
|
||||||
|
? formatSelectedAddress(selectedAddress)
|
||||||
|
: existingAddress
|
||||||
|
? formatAddress(existingAddress)
|
||||||
|
: 'آدرس را به صورت دستی وارد کنید';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='px-4 mt-2 bg-container'>
|
<div className='px-4 mt-2 bg-container'>
|
||||||
<span className='text-sm'>
|
<span className='text-sm'>
|
||||||
{!selectedAddress ? (
|
{displayText}
|
||||||
'آدرس را به صورت دستی وارد کنید'
|
|
||||||
) : (
|
|
||||||
formatSelectedAddress(selectedAddress)
|
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
<hr className='border border-border mt-3 mb-10' />
|
<hr className='border border-border mt-3 mb-10' />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { ArrowLeft } from 'iconsax-react';
|
|||||||
import { useAuthStore } from '@/zustand/authStore';
|
import { useAuthStore } from '@/zustand/authStore';
|
||||||
import { AddressDetailsModal } from './components/AddressDetailsModal';
|
import { AddressDetailsModal } from './components/AddressDetailsModal';
|
||||||
import { useAddressForm } from './hooks/useAddressForm';
|
import { useAddressForm } from './hooks/useAddressForm';
|
||||||
import { useGetAddressById } from '../hooks/useAddressData';
|
import { useGetAddresses } from '../hooks/useAddressData';
|
||||||
import { useGetAbout } from '@/app/[name]/(Main)/about/hooks/useAboutData';
|
import { useGetAbout } from '@/app/[name]/(Main)/about/hooks/useAboutData';
|
||||||
|
|
||||||
function OrderTrackingPage() {
|
function OrderTrackingPage() {
|
||||||
@@ -15,9 +15,14 @@ function OrderTrackingPage() {
|
|||||||
const id = params.get('id');
|
const id = params.get('id');
|
||||||
const editMode = !!id;
|
const editMode = !!id;
|
||||||
|
|
||||||
const { data: addressResponse, isLoading: isLoadingAddress } = useGetAddressById(id);
|
const { data: addressesResponse, isLoading: isLoadingAddresses } = useGetAddresses();
|
||||||
const { data: aboutData } = useGetAbout();
|
const { data: aboutData } = useGetAbout();
|
||||||
const address = addressResponse?.data;
|
|
||||||
|
const address = useMemo(() => {
|
||||||
|
if (!editMode || !id) return null;
|
||||||
|
return addressesResponse?.data?.find((item) => item.id === id) ?? null;
|
||||||
|
}, [editMode, id, addressesResponse?.data]);
|
||||||
|
|
||||||
const user = useAuthStore((state) => state.user);
|
const user = useAuthStore((state) => state.user);
|
||||||
const restaurant = aboutData?.data;
|
const restaurant = aboutData?.data;
|
||||||
|
|
||||||
@@ -55,7 +60,7 @@ function OrderTrackingPage() {
|
|||||||
addressData: address || null,
|
addressData: address || null,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (editMode && isLoadingAddress) {
|
if (editMode && isLoadingAddresses) {
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 bg-gray-50 flex items-center justify-center">
|
<div className="fixed inset-0 bg-gray-50 flex items-center justify-center">
|
||||||
<p className="text-sm2 text-disabled-text">در حال بارگذاری...</p>
|
<p className="text-sm2 text-disabled-text">در حال بارگذاری...</p>
|
||||||
@@ -63,8 +68,22 @@ function OrderTrackingPage() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (editMode && !address) {
|
||||||
|
return (
|
||||||
|
<div className="fixed inset-0 bg-gray-50 flex flex-col items-center justify-center gap-4 px-4">
|
||||||
|
<p className="text-sm2 text-disabled-text text-center">آدرس مورد نظر یافت نشد</p>
|
||||||
|
<button
|
||||||
|
onClick={() => router.back()}
|
||||||
|
className="p-2 rounded-full bg-container shadow-sm"
|
||||||
|
>
|
||||||
|
<ArrowLeft size={24} className="stroke-foreground" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!restaurant) {
|
if (!restaurant) {
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -82,6 +101,7 @@ function OrderTrackingPage() {
|
|||||||
<AddressDetailsModal
|
<AddressDetailsModal
|
||||||
visible
|
visible
|
||||||
selectedAddress={null}
|
selectedAddress={null}
|
||||||
|
existingAddress={address}
|
||||||
formData={formData}
|
formData={formData}
|
||||||
isPending={isPending}
|
isPending={isPending}
|
||||||
editMode={editMode}
|
editMode={editMode}
|
||||||
@@ -94,4 +114,4 @@ function OrderTrackingPage() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default OrderTrackingPage;
|
export default OrderTrackingPage;
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { NominatimReverseGeocodingResponse } from '../../types/Types';
|
import { Address, NominatimReverseGeocodingResponse } from '../../types/Types';
|
||||||
|
|
||||||
|
export const formatAddress = (address: Address): string => {
|
||||||
|
return `${address.address}، ${address.city}، ${address.province}`;
|
||||||
|
};
|
||||||
|
|
||||||
export const formatSelectedAddress = (selectedAddress: NominatimReverseGeocodingResponse | null): string => {
|
export const formatSelectedAddress = (selectedAddress: NominatimReverseGeocodingResponse | null): string => {
|
||||||
if (!selectedAddress) {
|
if (!selectedAddress) {
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ function UserAddressesPage({ }: Props) {
|
|||||||
return `${address.address}، ${address.city}، ${address.province}`;
|
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 (
|
return (
|
||||||
<div className='overflow-y-auto h-full noscrollbar flex flex-col'>
|
<div className='overflow-y-auto h-full noscrollbar flex flex-col'>
|
||||||
<div className='grid grid-cols-3 items-center'>
|
<div className='grid grid-cols-3 items-center'>
|
||||||
@@ -134,7 +139,7 @@ function UserAddressesPage({ }: Props) {
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Link href={`address/new?id=${address.id}`}>
|
<Link href={getEditHref(address.id)}>
|
||||||
<Button className='bg-background! text-foreground! flex justify-center items-center gap-2 text-xs p-0! size-8!'>
|
<Button className='bg-background! text-foreground! flex justify-center items-center gap-2 text-xs p-0! size-8!'>
|
||||||
<Edit2 className='stroke-foreground size-5 mb-0.5' />
|
<Edit2 className='stroke-foreground size-5 mb-0.5' />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user