remove province and city
Build and Deploy Docker Images / build_and_deploy (push) Has been cancelled

This commit is contained in:
hamid zarghami
2026-06-23 14:12:02 +03:30
parent cee1f98972
commit 037e94d7ac
9 changed files with 189 additions and 223 deletions
@@ -14,7 +14,7 @@ import useToggle from '@/hooks/helpers/useToggle';
import { AddressSelectionModal } from './AddressSelectionModal'; import { AddressSelectionModal } from './AddressSelectionModal';
const formatAddress = (address: Address) => { const formatAddress = (address: Address) => {
return `${address.address}، ${address.city}، ${address.province}`; return address.address;
}; };
export const AddressSection = () => { export const AddressSection = () => {
@@ -9,7 +9,7 @@ import { ef } from '@/lib/helpers/utfNumbers';
import { Edit2 } from 'iconsax-react'; import { Edit2 } from 'iconsax-react';
const formatAddress = (address: Address) => { const formatAddress = (address: Address) => {
return `${address.address}، ${address.city}، ${address.province}`; return address.address;
}; };
interface AddressSelectionModalProps { interface AddressSelectionModalProps {
@@ -196,8 +196,6 @@ export interface OrderAddress {
user: OrderUser; user: OrderUser;
title: string; title: string;
address: string; address: string;
city: string;
province: string;
postalCode: string; postalCode: string;
latitude: number; latitude: number;
longitude: number; longitude: number;
@@ -439,12 +437,10 @@ export interface OrderDetailCarAddress {
} }
export interface OrderDetailUserAddress { export interface OrderDetailUserAddress {
city: string;
phone: string; phone: string;
address: string; address: string;
fullName: string; fullName: string;
latitude: number; latitude: number;
province: string;
longitude: number; longitude: number;
postalCode: string; postalCode: string;
} }
@@ -79,12 +79,10 @@ export interface HistoryOrderDeliveryMethod {
} }
export interface HistoryOrderUserAddress { export interface HistoryOrderUserAddress {
city: string;
phone: string; phone: string;
address: string; address: string;
fullName: string; fullName: string;
latitude: number; latitude: number;
province: string;
longitude: number; longitude: number;
postalCode: string; postalCode: string;
} }
@@ -97,8 +95,6 @@ export interface HistoryOrderAddress {
user: string; user: string;
title: string; title: string;
address: string; address: string;
city: string;
province: string;
postalCode: string; postalCode: string;
latitude: number; latitude: number;
longitude: number; longitude: number;
@@ -1,90 +1,80 @@
import InputField from '@/components/input/InputField'; import InputField from "@/components/input/InputField";
import { NominatimReverseGeocodingResponse } from '../../types/Types'; import { useEffect } from "react";
import { useGetProfile } from '../../../hooks/userProfileData'; import { useGetProfile } from "../../../hooks/userProfileData";
import { useEffect } from 'react'; import { NominatimReverseGeocodingResponse } from "../../types/Types";
interface AddressFormProps { interface AddressFormProps {
formData: { formData: {
title: string; title: string;
addressDetails: string; addressDetails: string;
phone: string; phone: string;
postalCode: string; postalCode: string;
isDefault: boolean; isDefault: boolean;
}; };
selectedAddress: NominatimReverseGeocodingResponse | null; selectedAddress: NominatimReverseGeocodingResponse | null;
onFormDataChange: (data: Partial<AddressFormProps['formData']>) => void; onFormDataChange: (data: Partial<AddressFormProps["formData"]>) => void;
} }
export const AddressForm = ({ export const AddressForm = ({ formData, selectedAddress, onFormDataChange }: AddressFormProps) => {
formData, const { data: profileData } = useGetProfile();
selectedAddress,
onFormDataChange,
}: AddressFormProps) => {
const { data: profileData } = useGetProfile() useEffect(() => {
if (profileData?.data?.phone && !formData.phone) {
onFormDataChange({ phone: "0" + profileData.data.phone });
}
}, [profileData?.data?.phone, formData.phone, onFormDataChange]);
useEffect(() => { return (
if (profileData?.data?.phone && !formData.phone) { <div className="px-4">
onFormDataChange({ phone: '0' + profileData.data.phone }); <InputField
} htmlFor={"addressTitle"}
}, [profileData?.data?.phone, formData.phone, onFormDataChange]); labelText={"عنوان آدرس"}
placeholder="مثال: منزل، محل کار ..."
return ( className="bg-inherit"
<div className='px-4'> inputClassName="text-xs!"
<InputField value={formData.title}
htmlFor={'addressTitle'} onChange={(e) => onFormDataChange({ title: e.target.value })}
labelText={'عنوان آدرس'} />
placeholder='مثال: منزل، محل کار ...' <InputField
className='bg-inherit' htmlFor={"addressDetails"}
inputClassName='text-xs!' labelText={"جزئیات آدرس"}
value={formData.title} placeholder="میدان باغ ملی، مجتمع آسمان، واحد 12، پلاک 1234567890"
onChange={(e) => onFormDataChange({ title: e.target.value })} className="bg-inherit mt-8"
value={formData.addressDetails}
/> onChange={(e) => onFormDataChange({ addressDetails: e.target.value })}
<InputField inputClassName="text-xs!"
htmlFor={'addressDetails'} />
labelText={'جزئیات آدرس'} <InputField
placeholder='میدان باغ ملی، مجتمع آسمان، واحد 12، پلاک 1234567890' htmlFor={"phone"}
className='bg-inherit mt-8' labelText={"شماره تلفن"}
value={formData.addressDetails} placeholder="09123456789"
onChange={(e) => onFormDataChange({ addressDetails: e.target.value })} className="bg-inherit mt-8"
inputClassName='text-xs!' value={formData.phone}
/> onChange={(e) => onFormDataChange({ phone: e.target.value })}
<InputField inputClassName="text-xs!"
htmlFor={'phone'} />
labelText={'شماره تلفن'} <InputField
placeholder='09123456789' htmlFor={"postalCode"}
className='bg-inherit mt-8' labelText={"کد پستی"}
value={formData.phone} placeholder={selectedAddress?.address?.postcode || "1234567890"}
onChange={(e) => onFormDataChange({ phone: e.target.value })} className="bg-inherit mt-8"
inputClassName='text-xs!' value={formData.postalCode || selectedAddress?.address?.postcode || ""}
/> onChange={(e) => onFormDataChange({ postalCode: e.target.value })}
<InputField inputClassName="text-xs!"
htmlFor={'postalCode'} />
labelText={'کد پستی'} <div className="inline-flex justify-between items-center w-full mt-8">
placeholder={selectedAddress?.address?.postcode || '1234567890'} <label htmlFor={"isDefault"} className="text-sm2 px-2 py-0.5 mt-0.5 cursor-pointer">
className='bg-inherit mt-8' تنظیم به عنوان آدرس پیشفرض
value={formData.postalCode || selectedAddress?.address?.postcode || ''} </label>
onChange={(e) => onFormDataChange({ postalCode: e.target.value })} <input
inputClassName='text-xs!' name={"isDefault"}
/> id={"isDefault"}
<div className='inline-flex justify-between items-center w-full mt-8'> className="h-4.5 w-4.5 checked:accent-primary cursor-pointer"
<label onChange={(e) => onFormDataChange({ isDefault: e.target.checked })}
htmlFor={'isDefault'} type="checkbox"
className='text-sm2 px-2 py-0.5 mt-0.5 cursor-pointer' checked={formData.isDefault}
> />
تنظیم به عنوان آدرس پیشفرض </div>
</label> </div>
<input );
name={'isDefault'}
id={'isDefault'}
className='h-4.5 w-4.5 checked:accent-primary cursor-pointer'
onChange={(e) => onFormDataChange({ isDefault: e.target.checked })}
type='checkbox'
checked={formData.isDefault}
/>
</div>
</div>
);
}; };
@@ -1,134 +1,124 @@
import { useState, useEffect } from 'react'; import { toast } from "@/components/Toast";
import { useRouter, useSearchParams } from 'next/navigation'; import { useRouter, useSearchParams } from "next/navigation";
import { useCreateAddress, useUpdateAddress } from '../../hooks/useAddressData'; import { useEffect, useState } from "react";
import { toast } from '@/components/Toast'; import { useCreateAddress, useUpdateAddress } from "../../hooks/useAddressData";
import { CreateAddressType, UpdateAddressType, NominatimReverseGeocodingResponse, Address } from '../../types/Types'; import { Address, CreateAddressType, NominatimReverseGeocodingResponse, UpdateAddressType } from "../../types/Types";
interface UseAddressFormProps { interface UseAddressFormProps {
selectedPosition: [number, number] | null; selectedPosition: [number, number] | null;
selectedAddress: NominatimReverseGeocodingResponse | null; selectedAddress: NominatimReverseGeocodingResponse | null;
fallbackPosition?: [number, number] | null; fallbackPosition?: [number, number] | null;
initialPhone?: string; initialPhone?: string;
editMode?: boolean; editMode?: boolean;
addressData?: Address | null; addressData?: Address | null;
} }
export const useAddressForm = ({ export const useAddressForm = ({ selectedPosition, selectedAddress, fallbackPosition = [0, 0], initialPhone = "", editMode = false, addressData = null }: UseAddressFormProps) => {
selectedPosition, const router = useRouter();
selectedAddress, const searchParams = useSearchParams();
fallbackPosition = [0, 0], const redirect = searchParams.get("redirect");
initialPhone = '', const { mutate: createAddress, isPending: isCreating } = useCreateAddress();
editMode = false, const { mutate: updateAddress, isPending: isUpdating } = useUpdateAddress();
addressData = null, const isPending = isCreating || isUpdating;
}: UseAddressFormProps) => {
const router = useRouter();
const searchParams = useSearchParams();
const redirect = searchParams.get('redirect');
const { mutate: createAddress, isPending: isCreating } = useCreateAddress();
const { mutate: updateAddress, isPending: isUpdating } = useUpdateAddress();
const isPending = isCreating || isUpdating;
const [formData, setFormData] = useState({
title: '',
addressDetails: '',
phone: initialPhone,
postalCode: '',
isDefault: false,
});
useEffect(() => { const [formData, setFormData] = useState({
if (editMode && addressData) { title: "",
setFormData({ addressDetails: "",
title: addressData.title || '', phone: initialPhone,
addressDetails: addressData.address || '', postalCode: "",
phone: addressData.phone || initialPhone, isDefault: false,
postalCode: addressData.postalCode || '', });
isDefault: addressData.isDefault || false,
});
}
}, [editMode, addressData, initialPhone]);
const handleFormDataChange = (data: Partial<typeof formData>) => { useEffect(() => {
setFormData((prev) => ({ ...prev, ...data })); if (editMode && addressData) {
setFormData({
title: addressData.title || "",
addressDetails: addressData.address || "",
phone: addressData.phone || initialPhone,
postalCode: addressData.postalCode || "",
isDefault: addressData.isDefault || false,
});
}
}, [editMode, addressData, initialPhone]);
const handleFormDataChange = (data: Partial<typeof formData>) => {
setFormData((prev) => ({ ...prev, ...data }));
};
const submitAddress = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const positionToUse: [number, number] = selectedPosition || fallbackPosition || [0, 0];
if (!formData.title.trim()) {
toast("لطفا عنوان آدرس را وارد کنید", "error");
return;
}
if (!formData.addressDetails.trim()) {
toast("لطفا جزئیات آدرس را وارد کنید", "error");
return;
}
if (!formData.phone.trim()) {
toast("لطفا شماره تلفن را وارد کنید", "error");
return;
}
const baseAddressData = {
title: formData.title,
address: formData.addressDetails,
postalCode: formData.postalCode || selectedAddress?.address?.postcode || addressData?.postalCode || "",
latitude: positionToUse[0],
longitude: positionToUse[1],
phone: formData.phone,
isDefault: formData.isDefault,
}; };
const submitAddress = (e: React.FormEvent<HTMLFormElement>) => { if (editMode && addressData) {
e.preventDefault(); const updateData: UpdateAddressType = {
...baseAddressData,
id: addressData.id,
};
const positionToUse: [number, number] = selectedPosition || fallbackPosition || [0, 0]; updateAddress(updateData, {
onSuccess: () => {
toast("آدرس با موفقیت به‌روزرسانی شد", "success");
if (redirect) {
router.replace(redirect);
} else {
router.back();
}
},
onError: (error) => {
const errorMessage = error instanceof Error ? error.message : "خطا در به‌روزرسانی آدرس";
toast(errorMessage, "error");
},
});
} else {
const createData: CreateAddressType = baseAddressData;
if (!formData.title.trim()) { createAddress(createData, {
toast('لطفا عنوان آدرس را وارد کنید', 'error'); onSuccess: () => {
return; toast("آدرس با موفقیت ثبت شد", "success");
} if (redirect) {
router.replace(redirect);
} else {
router.back();
}
},
onError: (error) => {
const errorMessage = error instanceof Error ? error.message : "خطا در ثبت آدرس";
toast(errorMessage, "error");
},
});
}
};
if (!formData.addressDetails.trim()) { return {
toast('لطفا جزئیات آدرس را وارد کنید', 'error'); formData,
return; isPending,
} handleFormDataChange,
submitAddress,
if (!formData.phone.trim()) { };
toast('لطفا شماره تلفن را وارد کنید', 'error');
return;
}
const baseAddressData = {
title: formData.title,
address: formData.addressDetails,
city: selectedAddress?.address?.city || selectedAddress?.address?.district || addressData?.city || '',
province: selectedAddress?.address?.province || selectedAddress?.address?.state || addressData?.province || '',
postalCode: formData.postalCode || selectedAddress?.address?.postcode || addressData?.postalCode || '',
latitude: positionToUse[0],
longitude: positionToUse[1],
phone: formData.phone,
isDefault: formData.isDefault,
};
if (editMode && addressData) {
const updateData: UpdateAddressType = {
...baseAddressData,
id: addressData.id,
};
updateAddress(updateData, {
onSuccess: () => {
toast('آدرس با موفقیت به‌روزرسانی شد', 'success');
if (redirect) {
router.replace(redirect);
} else {
router.back();
}
},
onError: (error) => {
const errorMessage = error instanceof Error ? error.message : 'خطا در به‌روزرسانی آدرس';
toast(errorMessage, 'error');
},
});
} else {
const createData: CreateAddressType = baseAddressData;
createAddress(createData, {
onSuccess: () => {
toast('آدرس با موفقیت ثبت شد', 'success');
if (redirect) {
router.replace(redirect);
} else {
router.back();
}
},
onError: (error) => {
const errorMessage = error instanceof Error ? error.message : 'خطا در ثبت آدرس';
toast(errorMessage, 'error');
},
});
}
};
return {
formData,
isPending,
handleFormDataChange,
submitAddress,
};
}; };
@@ -1,7 +1,7 @@
import { Address, NominatimReverseGeocodingResponse } from '../../types/Types'; import { Address, NominatimReverseGeocodingResponse } from '../../types/Types';
export const formatAddress = (address: Address): string => { export const formatAddress = (address: Address): string => {
return `${address.address}، ${address.city}، ${address.province}`; return address.address;
}; };
export const formatSelectedAddress = (selectedAddress: NominatimReverseGeocodingResponse | null): string => { export const formatSelectedAddress = (selectedAddress: NominatimReverseGeocodingResponse | null): string => {
@@ -11,8 +11,6 @@ export const formatSelectedAddress = (selectedAddress: NominatimReverseGeocoding
try { try {
return [ return [
selectedAddress.address.state ?? selectedAddress.address.province,
selectedAddress.address.city,
selectedAddress.address.neighbourhood, selectedAddress.address.neighbourhood,
!selectedAddress.address.road.startsWith('میدان') && !selectedAddress.address.road.startsWith('میدان') &&
!selectedAddress.address.road.startsWith('بلوار') && !selectedAddress.address.road.startsWith('بلوار') &&
@@ -70,7 +70,7 @@ function UserAddressesPage({ }: Props) {
}; };
const formatAddress = (address: Address) => { const formatAddress = (address: Address) => {
return `${address.address}، ${address.city}، ${address.province}`; return address.address;
}; };
const getEditHref = (addressId: string) => { const getEditHref = (addressId: string) => {
@@ -9,8 +9,6 @@ export interface Address {
user: string; user: string;
title: string; title: string;
address: string; address: string;
city: string;
province: string;
postalCode: string; postalCode: string;
latitude: number; latitude: number;
longitude: number; longitude: number;
@@ -25,8 +23,6 @@ export type AddressResponse = BaseResponse<Address>;
export type CreateAddressType = { export type CreateAddressType = {
title: string; title: string;
address: string; address: string;
city: string;
province: string;
postalCode: string; postalCode: string;
latitude: number; latitude: number;
longitude: number; longitude: number;