add: multiple addresses
This commit is contained in:
@@ -8,7 +8,6 @@ import {
|
|||||||
zValidateNumber,
|
zValidateNumber,
|
||||||
zValidateNumberOptional,
|
zValidateNumberOptional,
|
||||||
zValidateString,
|
zValidateString,
|
||||||
zValidateStringOptional,
|
|
||||||
} from "../../data/getFormTypeErrors";
|
} from "../../data/getFormTypeErrors";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { useApiMutation } from "../../utils/useApiRequest";
|
import { useApiMutation } from "../../utils/useApiRequest";
|
||||||
@@ -21,11 +20,11 @@ import { getToastResponse } from "../../data/getToastResponse";
|
|||||||
import { useUserProfileStore } from "../../context/zustand-store/userStore";
|
import { useUserProfileStore } from "../../context/zustand-store/userStore";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Checkbox from "../../components/CheckBox/CheckBox";
|
import Checkbox from "../../components/CheckBox/CheckBox";
|
||||||
|
import { PlusIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
name: zValidateString("نام سازمان"),
|
name: zValidateString("نام سازمان"),
|
||||||
national_unique_id: zValidateString("شناسه کشوری"),
|
national_unique_id: zValidateString("شناسه کشوری"),
|
||||||
address: zValidateStringOptional("آدرس"),
|
|
||||||
field_of_activity: zValidateAutoComplete("حوزه فعالیت"),
|
field_of_activity: zValidateAutoComplete("حوزه فعالیت"),
|
||||||
province: zValidateNumber("استان"),
|
province: zValidateNumber("استان"),
|
||||||
city: zValidateNumber("شهر"),
|
city: zValidateNumber("شهر"),
|
||||||
@@ -75,7 +74,6 @@ export const AddOrganization = ({ getData, item }: AddPageProps) => {
|
|||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
name: item?.name || "",
|
name: item?.name || "",
|
||||||
address: item?.address || "",
|
|
||||||
national_unique_id: item?.national_unique_id || "",
|
national_unique_id: item?.national_unique_id || "",
|
||||||
free_visibility_by_scope: item?.free_visibility_by_scope || false,
|
free_visibility_by_scope: item?.free_visibility_by_scope || false,
|
||||||
field_of_activity:
|
field_of_activity:
|
||||||
@@ -95,16 +93,48 @@ export const AddOrganization = ({ getData, item }: AddPageProps) => {
|
|||||||
city: string | any;
|
city: string | any;
|
||||||
}>({ province: "", city: "" });
|
}>({ province: "", city: "" });
|
||||||
|
|
||||||
|
const [addresses, setAddresses] = useState<
|
||||||
|
{ postal_code: string; address: string }[]
|
||||||
|
>(
|
||||||
|
item?.addresses?.length
|
||||||
|
? item.addresses.map((a: any) => ({
|
||||||
|
postal_code: a.postal_code || "",
|
||||||
|
address: a.address || "",
|
||||||
|
}))
|
||||||
|
: [{ postal_code: "", address: "" }],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleAddAddress = () => {
|
||||||
|
setAddresses((prev) => [...prev, { postal_code: "", address: "" }]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemoveAddress = (index: number) => {
|
||||||
|
setAddresses((prev) => prev.filter((_, i) => i !== index));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddressChange = (
|
||||||
|
index: number,
|
||||||
|
field: "postal_code" | "address",
|
||||||
|
value: string,
|
||||||
|
) => {
|
||||||
|
setAddresses((prev) =>
|
||||||
|
prev.map((item, i) => (i === index ? { ...item, [field]: value } : item)),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const onSubmit = async (data: FormValues) => {
|
const onSubmit = async (data: FormValues) => {
|
||||||
try {
|
try {
|
||||||
await mutation.mutateAsync({
|
await mutation.mutateAsync({
|
||||||
|
addresses: addresses.filter(
|
||||||
|
(a) => a.postal_code.trim() || a.address.trim(),
|
||||||
|
),
|
||||||
organization: {
|
organization: {
|
||||||
name: `${data?.name} ${
|
name: `${data?.name} ${
|
||||||
data?.is_repeatable
|
data?.is_repeatable
|
||||||
? ""
|
? ""
|
||||||
: data.field_of_activity[0] === "CI"
|
: data.field_of_activity[0] === "CI"
|
||||||
? LocationValues.city
|
? LocationValues.city
|
||||||
: LocationValues.province
|
: LocationValues.province
|
||||||
}`,
|
}`,
|
||||||
|
|
||||||
...(data.organizationType !== undefined && {
|
...(data.organizationType !== undefined && {
|
||||||
@@ -118,7 +148,6 @@ export const AddOrganization = ({ getData, item }: AddPageProps) => {
|
|||||||
}),
|
}),
|
||||||
field_of_activity: data.field_of_activity[0],
|
field_of_activity: data.field_of_activity[0],
|
||||||
free_visibility_by_scope: data.free_visibility_by_scope,
|
free_visibility_by_scope: data.free_visibility_by_scope,
|
||||||
address: data.address,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
showToast(getToastResponse(item, "سازمان"), "success");
|
showToast(getToastResponse(item, "سازمان"), "success");
|
||||||
@@ -128,12 +157,12 @@ export const AddOrganization = ({ getData, item }: AddPageProps) => {
|
|||||||
if (error?.status === 403) {
|
if (error?.status === 403) {
|
||||||
showToast(
|
showToast(
|
||||||
error?.response?.data?.message || "این سازمان تکراری است!",
|
error?.response?.data?.message || "این سازمان تکراری است!",
|
||||||
"error"
|
"error",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
showToast(
|
showToast(
|
||||||
error?.response?.data?.message || "خطا در ثبت اطلاعات!",
|
error?.response?.data?.message || "خطا در ثبت اطلاعات!",
|
||||||
"error"
|
"error",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,7 +287,7 @@ export const AddOrganization = ({ getData, item }: AddPageProps) => {
|
|||||||
defaultKey={item?.parent_organization?.id}
|
defaultKey={item?.parent_organization?.id}
|
||||||
title="سازمان والد (اختیاری)"
|
title="سازمان والد (اختیاری)"
|
||||||
api={`auth/api/v1/organization/organizations_by_province?province=${getValues(
|
api={`auth/api/v1/organization/organizations_by_province?province=${getValues(
|
||||||
"province"
|
"province",
|
||||||
)}`}
|
)}`}
|
||||||
keyField="id"
|
keyField="id"
|
||||||
valueField="name"
|
valueField="name"
|
||||||
@@ -273,20 +302,53 @@ export const AddOrganization = ({ getData, item }: AddPageProps) => {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Controller
|
<div className="flex flex-col gap-2 w-full">
|
||||||
name="address"
|
<div className="flex items-center justify-between">
|
||||||
control={control}
|
<span className="text-sm font-medium text-gray-700">آدرسها</span>
|
||||||
render={({ field }) => (
|
<button
|
||||||
<Textfield
|
type="button"
|
||||||
fullWidth
|
onClick={handleAddAddress}
|
||||||
placeholder="آدرس (اختیاری)"
|
className="flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 transition-colors"
|
||||||
value={field.value}
|
>
|
||||||
onChange={field.onChange}
|
<PlusIcon className="w-4 h-4" />
|
||||||
error={!!errors.address}
|
افزودن آدرس
|
||||||
helperText={errors.address?.message}
|
</button>
|
||||||
/>
|
</div>
|
||||||
)}
|
{addresses.map((addr, index) => (
|
||||||
/>
|
<div
|
||||||
|
key={index}
|
||||||
|
className="flex items-start gap-2 p-3 border border-gray-200 rounded-lg"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col gap-2 flex-1">
|
||||||
|
<Textfield
|
||||||
|
fullWidth
|
||||||
|
placeholder="کد پستی"
|
||||||
|
value={addr.postal_code}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleAddressChange(index, "postal_code", e.target.value)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Textfield
|
||||||
|
fullWidth
|
||||||
|
placeholder="آدرس"
|
||||||
|
value={addr.address}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleAddressChange(index, "address", e.target.value)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{addresses.length > 1 && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleRemoveAddress(index)}
|
||||||
|
className="mt-2 text-red-500 hover:text-red-700 transition-colors shrink-0"
|
||||||
|
>
|
||||||
|
<TrashIcon className="w-5 h-5" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Controller
|
<Controller
|
||||||
name="free_visibility_by_scope"
|
name="free_visibility_by_scope"
|
||||||
|
|||||||
@@ -53,13 +53,20 @@ export const OrganizationsList = () => {
|
|||||||
item?.field_of_activity === "CO"
|
item?.field_of_activity === "CO"
|
||||||
? "کشور"
|
? "کشور"
|
||||||
: item?.field_of_activity === "PR"
|
: item?.field_of_activity === "PR"
|
||||||
? "استان"
|
? "استان"
|
||||||
: item?.field_of_activity === "CI"
|
: item?.field_of_activity === "CI"
|
||||||
? "شهرستان"
|
? "شهرستان"
|
||||||
: "نامشخص",
|
: "نامشخص",
|
||||||
item?.province?.name,
|
item?.province?.name,
|
||||||
item?.city?.name,
|
item?.city?.name,
|
||||||
item?.address || "-",
|
<ShowMoreInfo
|
||||||
|
key={`address-${i}`}
|
||||||
|
title="آدرسها"
|
||||||
|
disabled={!item?.addresses?.length}
|
||||||
|
data={item?.addresses}
|
||||||
|
columns={["کد پستی", "آدرس"]}
|
||||||
|
accessKeys={[["postal_code"], ["address"]]}
|
||||||
|
/>,
|
||||||
<ShowMoreInfo
|
<ShowMoreInfo
|
||||||
key={i}
|
key={i}
|
||||||
title="اطلاعات حساب"
|
title="اطلاعات حساب"
|
||||||
|
|||||||
Reference in New Issue
Block a user