push rasad front on new repo
This commit is contained in:
574
src/features/province/components/create-guilds/CreateGuilds.js
Normal file
574
src/features/province/components/create-guilds/CreateGuilds.js
Normal file
@@ -0,0 +1,574 @@
|
||||
import React, { useContext, useEffect, useState, useCallback } from "react";
|
||||
import { useFormik } from "formik";
|
||||
import { useDispatch } from "react-redux";
|
||||
import {
|
||||
Button,
|
||||
Box,
|
||||
Typography,
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogActions,
|
||||
} from "@mui/material";
|
||||
import { Add as AddIcon } from "@mui/icons-material";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { updateGuildByNationalIdNewService } from "../../services/update-guild-by-national-id-new";
|
||||
import { deactivateGuildService } from "../../services/deactivate-guild";
|
||||
import { provinceGetCitiesService } from "../../services/province-get-cities";
|
||||
import { provinceGetFieldOfWorks } from "../../services/ProvinceGetFieldOfWorks";
|
||||
import { provinceGetTypeActivity } from "../../services/provinceGetTypeActivity";
|
||||
import { provinceGetRegisterCodeStateService } from "../../services/province-get-register-code-state";
|
||||
import { mainGetGuildsForUpdateOrCreateService } from "../../services/main-get-guilds-for-update-or-create";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { PersonalInfoSection } from "./components/PersonalInfoSection";
|
||||
import { InquiryForm } from "./components/InquiryForm";
|
||||
import { UpdateFromExternalButton } from "./components/UpdateFromExternalButton";
|
||||
import { ConfirmationDialog } from "./components/ConfirmationDialog";
|
||||
import { FormActions } from "./components/FormActions";
|
||||
import { GuildInfoAccordionItem } from "./components/GuildInfoAccordionItem";
|
||||
import { getValidationSchema, getInitialValues } from "./utils/formUtils";
|
||||
import {
|
||||
mapResponseDataToFormFields,
|
||||
prepareSubmitData,
|
||||
} from "./utils/dataMapping";
|
||||
import { handleSubmitSuccess, handleSubmitError } from "./utils/submitHandlers";
|
||||
|
||||
const DeleteConfirmationDialog = ({ open, onClose, onConfirm, isDeleting }) => {
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
|
||||
<DialogTitle>آیا مطمئن هستید؟</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography variant="body2">
|
||||
آیا از حذف این صنف مطمئن هستید؟ این عمل قابل بازگشت نیست.
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ gap: 2, p: 2 }}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={onClose}
|
||||
disabled={isDeleting}
|
||||
sx={{ flex: 1 }}
|
||||
>
|
||||
انصراف
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={onConfirm}
|
||||
disabled={isDeleting}
|
||||
sx={{ flex: 1 }}
|
||||
>
|
||||
{isDeleting ? "در حال حذف..." : "حذف"}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export const CreateGuilds = ({ guild, updateTable }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [hasRegisterCode, setHasRegisterCode] = useState();
|
||||
const [inquiryNationalCode, setInquiryNationalCode] = useState("");
|
||||
const [isInquiryDone, setIsInquiryDone] = useState(false);
|
||||
const [dbRegister, setDbRegister] = useState(null);
|
||||
const [hasInquiry, setHasInquiry] = useState(null);
|
||||
const [guildActive, setGuildActive] = useState(null);
|
||||
const [guildsList, setGuildsList] = useState(() => (guild ? [guild] : []));
|
||||
const [expandedAccordion, setExpandedAccordion] = useState(0);
|
||||
const [guildsFormValues, setGuildsFormValues] = useState(() => {
|
||||
// Initialize with guild data if editing
|
||||
if (guild) {
|
||||
return [getInitialValues(guild)];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
const [cities, setCities] = useState([]);
|
||||
const [typeActivities, setTypeActivities] = useState([]);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [deleteDialogIndex, setDeleteDialogIndex] = useState(null);
|
||||
const [isDeletingGuild, setIsDeletingGuild] = useState(false);
|
||||
|
||||
const originalPhoneNumber = guild?.phoneNumber || null;
|
||||
|
||||
const currentRole = getRoleFromUrl();
|
||||
const isAdmin = currentRole === "AdminX";
|
||||
const isSuperAdmin = currentRole === "SuperAdmin";
|
||||
const isKillHouse = currentRole === "KillHouse";
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: getInitialValues(guild),
|
||||
validationSchema: getValidationSchema(!!guild),
|
||||
validateOnMount: true,
|
||||
onSubmit: (values) => {
|
||||
const guildsDataArray = guildsList.map((guildItem, index) => {
|
||||
const guildValues = guildsFormValues[index] || values;
|
||||
const combinedValues = {
|
||||
...values, // Personal info (shared)
|
||||
...guildValues, // Guild-specific info (overrides if same keys exist)
|
||||
};
|
||||
return prepareSubmitData(
|
||||
combinedValues,
|
||||
guildItem,
|
||||
originalPhoneNumber,
|
||||
hasInquiry
|
||||
);
|
||||
});
|
||||
|
||||
dispatch(updateGuildByNationalIdNewService(guildsDataArray)).then(
|
||||
(result) => {
|
||||
if (result.payload.error) {
|
||||
handleSubmitError(openNotif, result.payload.error);
|
||||
} else {
|
||||
handleSubmitSuccess(
|
||||
dispatch,
|
||||
openNotif,
|
||||
updateTable,
|
||||
values,
|
||||
result.payload?.data
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(provinceGetRegisterCodeStateService()).then((r) => {
|
||||
const isActive = r.payload.data?.[0]?.active;
|
||||
setHasRegisterCode(isActive);
|
||||
if (isActive === false) {
|
||||
formik.setFieldValue("isAccepted", true);
|
||||
}
|
||||
});
|
||||
dispatch(provinceGetCitiesService()).then((r) => {
|
||||
setCities(r.payload.data || []);
|
||||
});
|
||||
dispatch(provinceGetFieldOfWorks());
|
||||
dispatch(provinceGetTypeActivity()).then((r) => {
|
||||
setTypeActivities(r.payload.data || []);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
const mapResponseToFormFields = useCallback(
|
||||
(responseData) => {
|
||||
const guildsData = Array.isArray(responseData.guilds)
|
||||
? responseData.guilds
|
||||
: [];
|
||||
|
||||
mapResponseDataToFormFields(responseData, inquiryNationalCode, formik);
|
||||
|
||||
if (responseData.dbRegister === false) {
|
||||
setDbRegister(false);
|
||||
setHasInquiry(null);
|
||||
} else {
|
||||
setHasInquiry(responseData.hasInquiry ?? null);
|
||||
const firstGuild = guildsData.length > 0 ? guildsData[0] : null;
|
||||
const activeStatus = firstGuild?.active ?? responseData.active ?? null;
|
||||
setGuildActive(activeStatus);
|
||||
formik.setFieldValue("active", activeStatus);
|
||||
setDbRegister(true);
|
||||
}
|
||||
|
||||
if (guildsData.length > 0) {
|
||||
setGuildsList(guildsData);
|
||||
const initialGuildValues = guildsData.map((guildItem) => {
|
||||
const combinedGuild = {
|
||||
...guildItem,
|
||||
user: responseData.user || {},
|
||||
};
|
||||
return getInitialValues(combinedGuild);
|
||||
});
|
||||
setGuildsFormValues(initialGuildValues);
|
||||
setExpandedAccordion(0);
|
||||
} else {
|
||||
setGuildsList([]);
|
||||
setGuildsFormValues([]);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
formik.validateField("mobile");
|
||||
formik.validateField("national_id");
|
||||
}, 0);
|
||||
},
|
||||
[formik, inquiryNationalCode]
|
||||
);
|
||||
|
||||
const handleInquiry = useCallback(() => {
|
||||
if (!inquiryNationalCode) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "لطفا کد ملی را وارد کنید",
|
||||
severity: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAdmin && inquiryNationalCode.length !== 10) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید",
|
||||
severity: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
mainGetGuildsForUpdateOrCreateService({
|
||||
national_code: inquiryNationalCode,
|
||||
update: false,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
setHasInquiry(false);
|
||||
if (isAdmin) {
|
||||
setIsInquiryDone(true);
|
||||
formik.setFieldValue("national_id", inquiryNationalCode);
|
||||
}
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
if (!isAdmin) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (r.payload.data) {
|
||||
mapResponseToFormFields(r.payload.data);
|
||||
setIsInquiryDone(true);
|
||||
|
||||
if (r.payload.data.dbRegister === false) {
|
||||
setHasInquiry(true);
|
||||
}
|
||||
|
||||
const successMsg =
|
||||
r.payload.data.dbRegister === false
|
||||
? "اطلاعات از سامانه خارجی دریافت شد"
|
||||
: "اطلاعات از پایگاه داده دریافت شد";
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: successMsg,
|
||||
severity: "success",
|
||||
});
|
||||
} else {
|
||||
setHasInquiry(false);
|
||||
setIsInquiryDone(true);
|
||||
if (isAdmin) {
|
||||
formik.setFieldValue("national_id", inquiryNationalCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [
|
||||
dispatch,
|
||||
inquiryNationalCode,
|
||||
openNotif,
|
||||
mapResponseToFormFields,
|
||||
isAdmin,
|
||||
formik,
|
||||
]);
|
||||
|
||||
const handleUpdateFromExternal = useCallback(() => {
|
||||
if (!formik.values.national_id || formik.values.national_id.length !== 10) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید",
|
||||
severity: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
mainGetGuildsForUpdateOrCreateService({
|
||||
national_code: formik.values.national_id,
|
||||
update: true,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
setHasInquiry(false);
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (r.payload.data) {
|
||||
const updateResponse = {
|
||||
...r.payload.data,
|
||||
dbRegister: false,
|
||||
};
|
||||
mapResponseToFormFields(updateResponse);
|
||||
setHasInquiry(true);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "اطلاعات از سامانه خارجی بروزرسانی شد",
|
||||
severity: "success",
|
||||
});
|
||||
} else {
|
||||
setHasInquiry(false);
|
||||
}
|
||||
});
|
||||
}, [dispatch, formik.values.national_id, openNotif, mapResponseToFormFields]);
|
||||
|
||||
const handleAddGuild = () => {
|
||||
const newIndex = guildsList.length;
|
||||
setGuildsList([...guildsList, null]);
|
||||
setGuildsFormValues([...guildsFormValues, getInitialValues(null)]);
|
||||
setExpandedAccordion(newIndex);
|
||||
};
|
||||
|
||||
const handleDeleteGuild = (index) => {
|
||||
const guildToDelete = guildsList[index];
|
||||
if (guildToDelete?.key) {
|
||||
setDeleteDialogIndex(index);
|
||||
setDeleteDialogOpen(true);
|
||||
return;
|
||||
}
|
||||
if (guildsList.length > 1) {
|
||||
setGuildsList(guildsList.filter((_, i) => i !== index));
|
||||
setGuildsFormValues(guildsFormValues.filter((_, i) => i !== index));
|
||||
if (expandedAccordion === index) {
|
||||
setExpandedAccordion(0);
|
||||
} else if (expandedAccordion > index) {
|
||||
setExpandedAccordion(expandedAccordion - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirmDelete = () => {
|
||||
if (deleteDialogIndex === null) return;
|
||||
|
||||
const guildToDelete = guildsList[deleteDialogIndex];
|
||||
if (!guildToDelete?.key) return;
|
||||
|
||||
setIsDeletingGuild(true);
|
||||
dispatch(deactivateGuildService(guildToDelete.key)).then((r) => {
|
||||
setIsDeletingGuild(false);
|
||||
setDeleteDialogOpen(false);
|
||||
setDeleteDialogIndex(null);
|
||||
|
||||
if (r.payload?.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "صنف با موفقیت حذف شد",
|
||||
severity: "success",
|
||||
});
|
||||
// Remove from list after successful deletion
|
||||
if (guildsList.length > 1) {
|
||||
setGuildsList(guildsList.filter((_, i) => i !== deleteDialogIndex));
|
||||
setGuildsFormValues(
|
||||
guildsFormValues.filter((_, i) => i !== deleteDialogIndex)
|
||||
);
|
||||
// If deleted accordion was expanded, expand the first one
|
||||
if (expandedAccordion === deleteDialogIndex) {
|
||||
setExpandedAccordion(0);
|
||||
} else if (expandedAccordion > deleteDialogIndex) {
|
||||
// Adjust expanded index if deleted item was before it
|
||||
setExpandedAccordion(expandedAccordion - 1);
|
||||
}
|
||||
}
|
||||
if (updateTable) {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleCloseDeleteDialog = () => {
|
||||
if (!isDeletingGuild) {
|
||||
setDeleteDialogOpen(false);
|
||||
setDeleteDialogIndex(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleGuildValuesChange = useCallback((index, fieldName, value) => {
|
||||
setGuildsFormValues((prev) => {
|
||||
const newValues = [...prev];
|
||||
if (!newValues[index]) {
|
||||
newValues[index] = getInitialValues(null);
|
||||
}
|
||||
newValues[index] = {
|
||||
...newValues[index],
|
||||
[fieldName]: value,
|
||||
};
|
||||
return newValues;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleAccordionChange = (index) => (event, isExpanded) => {
|
||||
setExpandedAccordion(isExpanded ? index : false);
|
||||
};
|
||||
|
||||
const shouldShowUpdateButton =
|
||||
formik?.values?.national_id &&
|
||||
(isAdmin ||
|
||||
(dbRegister !== false &&
|
||||
(guild ||
|
||||
(!guild &&
|
||||
((dbRegister === true && hasInquiry === false) ||
|
||||
(isAdmin && isInquiryDone))))));
|
||||
|
||||
const shouldShowInquiryForm = !guild && !isInquiryDone;
|
||||
const shouldShowFormContent = guild || isInquiryDone;
|
||||
|
||||
return (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.TINY}
|
||||
maxHeight="80vh"
|
||||
minWidth={
|
||||
!guild && !isInquiryDone
|
||||
? "auto"
|
||||
: { xs: "96vw", md: "90vw", nlg: "1280px" }
|
||||
}
|
||||
overflow="auto"
|
||||
p={2}
|
||||
>
|
||||
{shouldShowUpdateButton && (
|
||||
<UpdateFromExternalButton
|
||||
onUpdate={handleUpdateFromExternal}
|
||||
disabled={!!formik.errors.national_id}
|
||||
/>
|
||||
)}
|
||||
|
||||
{shouldShowInquiryForm && (
|
||||
<InquiryForm
|
||||
inquiryNationalCode={inquiryNationalCode}
|
||||
setInquiryNationalCode={setInquiryNationalCode}
|
||||
onInquiry={handleInquiry}
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
)}
|
||||
|
||||
{shouldShowFormContent && (
|
||||
<>
|
||||
<Grid container xs={12}>
|
||||
<PersonalInfoSection
|
||||
formik={formik}
|
||||
guild={guild}
|
||||
hasInquiry={hasInquiry}
|
||||
isAdmin={isAdmin}
|
||||
isSuperAdmin={isSuperAdmin}
|
||||
isKillHouse={isKillHouse}
|
||||
/>
|
||||
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
lg={6}
|
||||
pr={{ xs: 0, md: 2 }}
|
||||
pl={{ xs: 0, md: 3 }}
|
||||
>
|
||||
<Grid container gap={SPACING.TINY} direction="column">
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
اطلاعات صنفی
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
{guildsList.map((guildItem, index) => (
|
||||
<Box key={index} sx={{ mb: 2 }}>
|
||||
<GuildInfoAccordionItem
|
||||
guildIndex={index}
|
||||
guildData={guildItem}
|
||||
guildActive={guildActive}
|
||||
isAdmin={isAdmin}
|
||||
cities={cities}
|
||||
typeActivities={typeActivities}
|
||||
onDelete={() => handleDeleteGuild(index)}
|
||||
canDelete={
|
||||
(guildsList.length > 1 || !guild) && isAdmin
|
||||
}
|
||||
guildFormValues={guildsFormValues[index]}
|
||||
onGuildValuesChange={handleGuildValuesChange}
|
||||
expanded={expandedAccordion === index}
|
||||
onChange={handleAccordionChange(index)}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Grid>
|
||||
{isAdmin && (
|
||||
<Grid item xs={12} xl={4}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<AddIcon />}
|
||||
onClick={handleAddGuild}
|
||||
fullWidth
|
||||
sx={{ mb: 2 }}
|
||||
>
|
||||
افزودن واحد صنفی
|
||||
</Button>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container item xs={12}>
|
||||
{hasRegisterCode &&
|
||||
(!(!guild && hasInquiry === true) ||
|
||||
isAdmin ||
|
||||
isSuperAdmin ||
|
||||
isKillHouse) && (
|
||||
<ConfirmationDialog
|
||||
isAccepted={formik.values.isAccepted}
|
||||
onAccept={() => formik.setFieldValue("isAccepted", true)}
|
||||
onReject={() => formik.setFieldValue("isAccepted", false)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<FormActions
|
||||
formik={formik}
|
||||
onClose={() => dispatch(CLOSE_MODAL())}
|
||||
showCloseButton={
|
||||
!guild &&
|
||||
hasInquiry === true &&
|
||||
!isAdmin &&
|
||||
!isSuperAdmin &&
|
||||
!isKillHouse
|
||||
}
|
||||
isKillHouse={isKillHouse}
|
||||
onSubmit={formik.handleSubmit}
|
||||
/>
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
<DeleteConfirmationDialog
|
||||
open={deleteDialogOpen}
|
||||
onClose={handleCloseDeleteDialog}
|
||||
onConfirm={handleConfirmDelete}
|
||||
isDeleting={isDeletingGuild}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Button,
|
||||
Typography,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
} from "@mui/material";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../../data/spacing";
|
||||
import { DialogAlert } from "../../../../../components/dialog-alert/DialogAlert";
|
||||
import { Done } from "@mui/icons-material";
|
||||
|
||||
export const ConfirmationDialog = ({ isAccepted, onAccept, onReject }) => {
|
||||
return (
|
||||
<Grid item pb={2} mt={2}>
|
||||
<DialogAlert
|
||||
title="تعهد نامه"
|
||||
content={
|
||||
<>
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<Done />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="لطفا صحت اطلاعات وارد شده را بررسی نمایید. پس از تکمیل و ثبت درخواست، یک کد احراز هویت از طریق پیامک برای صنف یا مباشر به شماره تلفن اعلامی ارسال میگردد." />
|
||||
</ListItem>
|
||||
<Typography></Typography>
|
||||
</>
|
||||
}
|
||||
actions={
|
||||
<Grid container gap={SPACING.TINY}>
|
||||
<Button variant="outlined" color="error" onClick={onReject}>
|
||||
رد
|
||||
</Button>
|
||||
<Button variant="contained" color="success" onClick={onAccept}>
|
||||
موافقم
|
||||
</Button>
|
||||
</Grid>
|
||||
}
|
||||
btnTitle="تایید صحت اطلاعات"
|
||||
isAccepted={isAccepted}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
import React from "react";
|
||||
import { Button, Typography, Checkbox, FormControlLabel } from "@mui/material";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
|
||||
export const FormActions = ({
|
||||
formik,
|
||||
onClose,
|
||||
showCloseButton,
|
||||
isKillHouse,
|
||||
onSubmit,
|
||||
}) => {
|
||||
if (showCloseButton) {
|
||||
return (
|
||||
<Grid item xs={12} mt={4}>
|
||||
<Button color="primary" fullWidth variant="contained" onClick={onClose}>
|
||||
متوجه شدم
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
// For KillHouse: check if area_activity contains "مرغ"
|
||||
const isAreaActivityValid = isKillHouse
|
||||
? formik.values.area_activity && formik.values.area_activity.includes("مرغ")
|
||||
: true;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid item xs={12}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={formik.values.verify_mobile}
|
||||
onChange={formik.handleChange}
|
||||
name="verify_mobile"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="احراز شماره موبایل"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Button
|
||||
disabled={
|
||||
formik.errors.isAccepted ||
|
||||
Boolean(formik.errors.national_id) ||
|
||||
!isAreaActivityValid
|
||||
}
|
||||
color="primary"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={onSubmit}
|
||||
type="button"
|
||||
>
|
||||
ثبت
|
||||
</Button>
|
||||
{isKillHouse && !isAreaActivityValid && (
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="error"
|
||||
sx={{ mt: 1, display: "block" }}
|
||||
>
|
||||
رسته واحد صنفی باید شامل کلمه "مرغ" باشد
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,97 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
Typography,
|
||||
IconButton,
|
||||
} from "@mui/material";
|
||||
import {
|
||||
ExpandMore as ExpandMoreIcon,
|
||||
Delete as DeleteIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { GuildInfoSection } from "./GuildInfoSection";
|
||||
|
||||
export const GuildInfoAccordionItem = ({
|
||||
guildIndex,
|
||||
guildData,
|
||||
guildActive,
|
||||
isAdmin,
|
||||
cities,
|
||||
typeActivities,
|
||||
onDelete,
|
||||
canDelete,
|
||||
guildFormValues,
|
||||
onGuildValuesChange,
|
||||
expanded,
|
||||
onChange,
|
||||
}) => {
|
||||
// Create a formik-like object for this guild's values
|
||||
const guildFormik = {
|
||||
values: guildFormValues || {},
|
||||
setFieldValue: (fieldName, value) => {
|
||||
onGuildValuesChange(guildIndex, fieldName, value);
|
||||
},
|
||||
handleChange: (e) => {
|
||||
onGuildValuesChange(guildIndex, e.target.name, e.target.value);
|
||||
},
|
||||
handleBlur: () => {},
|
||||
errors: {},
|
||||
touched: {},
|
||||
};
|
||||
const getGuildTitle = () => {
|
||||
if (guildData?.guildsName) {
|
||||
return guildData.guildsName;
|
||||
}
|
||||
if (guildData?.title) {
|
||||
return guildData.title;
|
||||
}
|
||||
if (guildFormik.values.guild_name) {
|
||||
return guildFormik.values.guild_name;
|
||||
}
|
||||
return `واحد صنفی ${guildIndex + 1}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<Accordion expanded={expanded} onChange={onChange}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
sx={{
|
||||
"& .MuiAccordionSummary-content": {
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6" sx={{ flexGrow: 1, fontSize: 18 }}>
|
||||
{getGuildTitle()}
|
||||
</Typography>
|
||||
{canDelete && (
|
||||
<IconButton
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDelete();
|
||||
}}
|
||||
color="error"
|
||||
size="small"
|
||||
sx={{ mr: 1 }}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<GuildInfoSection
|
||||
formik={guildFormik}
|
||||
guild={guildData}
|
||||
guildActive={guildActive}
|
||||
isAdmin={isAdmin}
|
||||
cities={cities}
|
||||
typeActivities={typeActivities}
|
||||
hideTitle={true}
|
||||
noGridWrapper={true}
|
||||
/>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,566 @@
|
||||
import React from "react";
|
||||
import {
|
||||
TextField,
|
||||
Typography,
|
||||
RadioGroup,
|
||||
FormControl,
|
||||
Radio,
|
||||
FormControlLabel,
|
||||
Select,
|
||||
MenuItem,
|
||||
InputLabel,
|
||||
Checkbox,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import BusinessIcon from "@mui/icons-material/Business";
|
||||
import PublicIcon from "@mui/icons-material/Public";
|
||||
import LocationCityIcon from "@mui/icons-material/LocationCity";
|
||||
import DateRangeIcon from "@mui/icons-material/DateRange";
|
||||
import ConfirmationNumberIcon from "@mui/icons-material/ConfirmationNumber";
|
||||
import AccountBalanceIcon from "@mui/icons-material/AccountBalance";
|
||||
import LocalPostOfficeIcon from "@mui/icons-material/LocalPostOffice";
|
||||
import PhoneIcon from "@mui/icons-material/Phone";
|
||||
import BadgeIcon from "@mui/icons-material/Badge";
|
||||
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
||||
import HomeIcon from "@mui/icons-material/Home";
|
||||
import CorporateFareIcon from "@mui/icons-material/CorporateFare";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../../data/spacing";
|
||||
import { LabelField } from "../../../../../components/label-field/LabelField";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
import { STATUS_VALUES } from "../constants";
|
||||
import {
|
||||
convertPersianToGregorian,
|
||||
convertGregorianToPersian,
|
||||
} from "../utils/dateUtils";
|
||||
|
||||
export const GuildInfoSection = ({
|
||||
formik,
|
||||
guild,
|
||||
guildActive,
|
||||
isAdmin,
|
||||
cities,
|
||||
typeActivities,
|
||||
hideTitle = false,
|
||||
noGridWrapper = false,
|
||||
}) => {
|
||||
const getForeignerDisplay = (isForeigner) => {
|
||||
if (isForeigner === STATUS_VALUES.NO || isForeigner === false)
|
||||
return STATUS_VALUES.NO;
|
||||
if (isForeigner === STATUS_VALUES.YES || isForeigner === true)
|
||||
return STATUS_VALUES.YES;
|
||||
return "-";
|
||||
};
|
||||
|
||||
const getLicenseExpireDateDisplay = () => {
|
||||
return formik.values.license_expire_date || "-";
|
||||
};
|
||||
|
||||
const getActiveStatusDisplay = () => {
|
||||
const activeValue =
|
||||
formik.values.active !== null
|
||||
? formik.values.active
|
||||
: guild?.active === true || guildActive === true;
|
||||
return activeValue === true ? "فعال" : "غیر فعال";
|
||||
};
|
||||
|
||||
const content = (
|
||||
<Grid container gap={SPACING.TINY} direction="column">
|
||||
{!hideTitle && (
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
اطلاعات صنفی
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid container xs={12}>
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
xs={12}
|
||||
md={6}
|
||||
px={SPACING.TINY}
|
||||
gap={SPACING.TINY}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام واحد"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="guild_name"
|
||||
name="guild_name"
|
||||
value={formik.values.guild_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BusinessIcon}
|
||||
label="نام واحد"
|
||||
value={formik.values.guild_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="area-activity-select-label">
|
||||
رسته واحد صنفی
|
||||
</InputLabel>
|
||||
<Select
|
||||
labelId="area-activity-select-label"
|
||||
id="area_activity"
|
||||
name="area_activity"
|
||||
value={formik.values.area_activity || ""}
|
||||
label="رسته واحد صنفی"
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("area_activity", e.target.value);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
>
|
||||
{typeActivities.map((activity) => (
|
||||
<MenuItem key={activity.key} value={activity.title}>
|
||||
{activity.title}
|
||||
</MenuItem>
|
||||
))}
|
||||
{/* Show current value if it doesn't exist in options */}
|
||||
{formik.values.area_activity &&
|
||||
!typeActivities.some(
|
||||
(activity) =>
|
||||
activity.title === formik.values.area_activity
|
||||
) && (
|
||||
<MenuItem
|
||||
key="current-value"
|
||||
value={formik.values.area_activity}
|
||||
>
|
||||
{formik.values.area_activity}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BusinessIcon}
|
||||
label="رسته واحد صنفی"
|
||||
value={formik.values.area_activity}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="استان"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="state"
|
||||
name="state"
|
||||
value={formik.values.state}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PublicIcon}
|
||||
label="استان"
|
||||
value={formik.values.state}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="city-select-label">شهرستان</InputLabel>
|
||||
<Select
|
||||
labelId="city-select-label"
|
||||
id="city"
|
||||
name="city"
|
||||
value={formik.values.city || ""}
|
||||
label="شهرستان"
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("city", e.target.value);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
>
|
||||
{cities.map((city) => (
|
||||
<MenuItem key={city.key} value={city.name}>
|
||||
{city.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
{/* Show current value if it doesn't exist in options */}
|
||||
{formik.values.city &&
|
||||
!cities.some(
|
||||
(city) => city.name === formik.values.city
|
||||
) && (
|
||||
<MenuItem key="current-value" value={formik.values.city}>
|
||||
{formik.values.city}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={LocationCityIcon}
|
||||
label="شهرستان"
|
||||
value={formik.values.city}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<DatePicker
|
||||
label="تاریخ انقضا مجوز"
|
||||
value={
|
||||
formik.values.license_expire_date
|
||||
? moment(
|
||||
convertPersianToGregorian(
|
||||
formik.values.license_expire_date
|
||||
)
|
||||
)
|
||||
: null
|
||||
}
|
||||
onChange={(newValue) => {
|
||||
if (newValue) {
|
||||
const gregorianDate = moment(newValue).format("YYYY-MM-DD");
|
||||
const persianDate =
|
||||
convertGregorianToPersian(gregorianDate);
|
||||
formik.setFieldValue("license_expire_date", persianDate);
|
||||
} else {
|
||||
formik.setFieldValue("license_expire_date", "");
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} fullWidth variant="outlined" />
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={DateRangeIcon}
|
||||
label="تاریخ انقضا مجوز"
|
||||
value={getLicenseExpireDateDisplay()}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شماره مجوز"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="license_number"
|
||||
name="license_number"
|
||||
value={formik.values.license_number}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={ConfirmationNumberIcon}
|
||||
label="شماره مجوز"
|
||||
value={formik.values.license_number}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام اتحادیه"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="union_name"
|
||||
name="union_name"
|
||||
value={formik.values.union_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={AccountBalanceIcon}
|
||||
label="نام اتحادیه"
|
||||
value={formik.values.union_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="وضعیت">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="active"
|
||||
value={
|
||||
formik.values.active === true
|
||||
? "true"
|
||||
: formik.values.active === false
|
||||
? "false"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
"active",
|
||||
e.target.value === "true" ? true : false
|
||||
);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="true"
|
||||
control={<Radio />}
|
||||
label="فعال"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="false"
|
||||
control={<Radio />}
|
||||
label="غیر فعال"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="وضعیت"
|
||||
value={getActiveStatusDisplay()}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
md={6}
|
||||
px={SPACING.TINY}
|
||||
direction="column"
|
||||
gap={SPACING.TINY}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="کد پستی"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="postal_code"
|
||||
name="postal_code"
|
||||
value={formik.values.postal_code}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={LocalPostOfficeIcon}
|
||||
label="کد پستی"
|
||||
value={formik.values.postal_code}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شماره تلفن"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="phone_number"
|
||||
name="phone_number"
|
||||
value={formik.values.phone_number}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PhoneIcon}
|
||||
label="شماره تلفن"
|
||||
value={formik.values.phone_number}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="آیا اتباع است؟">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="is_foreigner"
|
||||
value={
|
||||
formik.values.is_foreigner === "بلی" ||
|
||||
formik.values.is_foreigner === true
|
||||
? "بلی"
|
||||
: formik.values.is_foreigner === "خیر" ||
|
||||
formik.values.is_foreigner === false
|
||||
? "خیر"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
"is_foreigner",
|
||||
e.target.value === "بلی" ? "بلی" : "خیر"
|
||||
);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="بلی"
|
||||
control={<Radio />}
|
||||
label="بلی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="خیر"
|
||||
control={<Radio />}
|
||||
label="خیر"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PublicIcon}
|
||||
label="آیا اتباع است؟"
|
||||
value={getForeignerDisplay(formik.values.is_foreigner)}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام شرکت"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="corporation_name"
|
||||
name="corporation_name"
|
||||
value={formik.values.corporation_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CorporateFareIcon}
|
||||
label="نام شرکت"
|
||||
value={formik.values.corporation_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شناسه ملی شرکت"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="guild_national_id"
|
||||
name="guild_national_id"
|
||||
value={formik.values.guild_national_id}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BadgeIcon}
|
||||
label="شناسه ملی شرکت"
|
||||
value={formik.values.guild_national_id}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="وضعیت مجوز"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="license_status"
|
||||
name="license_status"
|
||||
value={formik.values.license_status}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="وضعیت مجوز"
|
||||
value={formik.values.license_status}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="آدرس"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
multiline
|
||||
rows={3}
|
||||
id="address"
|
||||
name="address"
|
||||
value={formik.values.address}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={HomeIcon}
|
||||
label="آدرس"
|
||||
value={formik.values.address}
|
||||
iconSx={{ mt: 0.5 }}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ display: "flex", mt: 2, pl: 2, mb: 2 }}>
|
||||
{isAdmin ? (
|
||||
<>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={formik.values.steward || false}
|
||||
onChange={(e) =>
|
||||
formik.setFieldValue("steward", e.target.checked)
|
||||
}
|
||||
name="steward"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="مباشر"
|
||||
/>
|
||||
<FormControlLabel
|
||||
sx={{ ml: 3 }}
|
||||
control={
|
||||
<Checkbox
|
||||
checked={formik.values.guild || false}
|
||||
onChange={(e) =>
|
||||
formik.setFieldValue("guild", e.target.checked)
|
||||
}
|
||||
name="guild"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="صنف"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="مباشر"
|
||||
value={formik.values.steward ? "بلی" : "خیر"}
|
||||
/>
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="صنف"
|
||||
value={formik.values.guild ? "بلی" : "خیر"}
|
||||
sx={{ ml: 3 }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
if (noGridWrapper) {
|
||||
return <>{content}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid item xs={12} lg={6} pr={{ xs: 0, md: 2 }} pl={{ xs: 0, md: 3 }}>
|
||||
{content}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from "react";
|
||||
import { Box, Typography } from "@mui/material";
|
||||
|
||||
export const InfoBox = ({ icon: Icon, label, value, iconSx }) => (
|
||||
<Box
|
||||
display="flex"
|
||||
alignItems={iconSx ? "flex-start" : "center"}
|
||||
gap={1}
|
||||
px={1.5}
|
||||
py={0.5}
|
||||
bgcolor="#f5f5f5"
|
||||
borderRadius={1}
|
||||
>
|
||||
<Icon color="action" sx={iconSx} />
|
||||
<Box>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{label}
|
||||
</Typography>
|
||||
<Typography variant="body1">{value || "-"}</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from "react";
|
||||
import { TextField, Button } from "@mui/material";
|
||||
|
||||
export const InquiryForm = ({
|
||||
inquiryNationalCode,
|
||||
setInquiryNationalCode,
|
||||
onInquiry,
|
||||
isAdmin,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
label="کد ملی برای استعلام"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={inquiryNationalCode}
|
||||
onChange={(e) => setInquiryNationalCode(e.target.value)}
|
||||
placeholder={
|
||||
isAdmin ? "کد ملی را وارد کنید" : "کد ملی 10 رقمی را وارد کنید"
|
||||
}
|
||||
inputProps={isAdmin ? {} : { maxLength: 10 }}
|
||||
/>
|
||||
<Button
|
||||
color="primary"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={onInquiry}
|
||||
disabled={!isAdmin && inquiryNationalCode.length !== 10}
|
||||
>
|
||||
استعلام
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,369 @@
|
||||
import React from "react";
|
||||
import {
|
||||
TextField,
|
||||
Typography,
|
||||
RadioGroup,
|
||||
FormControl,
|
||||
Radio,
|
||||
FormControlLabel,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import PersonIcon from "@mui/icons-material/Person";
|
||||
import PhoneIcon from "@mui/icons-material/Phone";
|
||||
import BadgeIcon from "@mui/icons-material/Badge";
|
||||
import CakeIcon from "@mui/icons-material/Cake";
|
||||
import FaceIcon from "@mui/icons-material/Face";
|
||||
import LocationCityIcon from "@mui/icons-material/LocationCity";
|
||||
import FavoriteIcon from "@mui/icons-material/Favorite";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../../data/spacing";
|
||||
import { LabelField } from "../../../../../components/label-field/LabelField";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
import { GENDER_VALUES, ALIVE_STATUS } from "../constants";
|
||||
import {
|
||||
convertPersianToGregorian,
|
||||
convertGregorianToPersian,
|
||||
} from "../utils/dateUtils";
|
||||
|
||||
export const PersonalInfoSection = ({
|
||||
formik,
|
||||
guild,
|
||||
hasInquiry,
|
||||
isAdmin,
|
||||
isSuperAdmin,
|
||||
isKillHouse,
|
||||
}) => {
|
||||
const getGenderDisplay = (gender) => {
|
||||
if (gender === "True" || gender === true) return GENDER_VALUES.MALE;
|
||||
if (gender === "False" || gender === false) return GENDER_VALUES.FEMALE;
|
||||
return "-";
|
||||
};
|
||||
|
||||
const getAliveStatusDisplay = (isAlive) => {
|
||||
if (isAlive === ALIVE_STATUS.YES || isAlive === true)
|
||||
return ALIVE_STATUS.YES;
|
||||
if (isAlive === ALIVE_STATUS.NO || isAlive === false)
|
||||
return ALIVE_STATUS.NO;
|
||||
return "-";
|
||||
};
|
||||
|
||||
const getBirthDateDisplay = () => {
|
||||
return formik.values.birth_date || "-";
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
lg={6}
|
||||
pl={{ xs: 0, md: 2 }}
|
||||
pr={{ xs: 0, md: 3 }}
|
||||
mb={2}
|
||||
>
|
||||
<Grid container direction="column" gap={SPACING.SMALL}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
اطلاعات شخصی
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container xs={12}>
|
||||
<Grid container xs={12} md={6} gap={SPACING.TINY} px={SPACING.TINY}>
|
||||
<Grid item xs={12}>
|
||||
{guild || isAdmin ? (
|
||||
<TextField
|
||||
label="کد ملی"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="national_id"
|
||||
name="national_id"
|
||||
value={formik.values.national_id}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={Boolean(formik.errors.national_id)}
|
||||
helperText={formik.errors.national_id}
|
||||
inputProps={{ maxLength: 10 }}
|
||||
disabled={!isAdmin || isKillHouse}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BadgeIcon}
|
||||
label="کد ملی"
|
||||
value={formik.values.national_id}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="first_name"
|
||||
name="first_name"
|
||||
value={formik.values.first_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PersonIcon}
|
||||
label="نام"
|
||||
value={formik.values.first_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام خانوادگی"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="last_name"
|
||||
name="last_name"
|
||||
value={formik.values.last_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PersonIcon}
|
||||
label="نام خانوادگی"
|
||||
value={formik.values.last_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شماره شناسنامه"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="national_code"
|
||||
name="national_code"
|
||||
value={formik.values.national_code}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BadgeIcon}
|
||||
label="شماره شناسنامه"
|
||||
value={formik.values.national_code}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="در قید حیات">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="is_alive"
|
||||
value={
|
||||
formik.values.is_alive === "بلی" ||
|
||||
formik.values.is_alive === true
|
||||
? "بلی"
|
||||
: formik.values.is_alive === "خیر" ||
|
||||
formik.values.is_alive === false
|
||||
? "خیر"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
"is_alive",
|
||||
e.target.value === "بلی" ? "بلی" : "خیر"
|
||||
);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="بلی"
|
||||
control={<Radio />}
|
||||
label="بلی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="خیر"
|
||||
control={<Radio />}
|
||||
label="خیر"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={FavoriteIcon}
|
||||
label="در قید حیات"
|
||||
value={getAliveStatusDisplay(formik.values.is_alive)}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
md={6}
|
||||
gap={SPACING.TINY}
|
||||
px={SPACING.TINY}
|
||||
mt={{ xs: 1, md: 0 }}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<DatePicker
|
||||
label="تاریخ تولد"
|
||||
value={
|
||||
formik.values.birth_date
|
||||
? moment(
|
||||
convertPersianToGregorian(formik.values.birth_date)
|
||||
)
|
||||
: null
|
||||
}
|
||||
onChange={(newValue) => {
|
||||
if (newValue) {
|
||||
const gregorianDate =
|
||||
moment(newValue).format("YYYY-MM-DD");
|
||||
const persianDate =
|
||||
convertGregorianToPersian(gregorianDate);
|
||||
formik.setFieldValue("birth_date", persianDate);
|
||||
} else {
|
||||
formik.setFieldValue("birth_date", "");
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} fullWidth variant="outlined" />
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CakeIcon}
|
||||
label="تاریخ تولد"
|
||||
value={getBirthDateDisplay()}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام پدر"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="father_name"
|
||||
name="father_name"
|
||||
value={formik.values.father_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PersonIcon}
|
||||
label="نام پدر"
|
||||
value={formik.values.father_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="جنسیت">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="gender"
|
||||
value={
|
||||
formik.values.gender === "True" ||
|
||||
formik.values.gender === true
|
||||
? "True"
|
||||
: formik.values.gender === "False" ||
|
||||
formik.values.gender === false
|
||||
? "False"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("gender", e.target.value);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="True"
|
||||
control={<Radio />}
|
||||
label="مرد"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="False"
|
||||
control={<Radio />}
|
||||
label="زن"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={FaceIcon}
|
||||
label="جنسیت"
|
||||
value={getGenderDisplay(formik.values.gender)}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شهر"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="person_city"
|
||||
name="person_city"
|
||||
value={formik.values.person_city}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={LocationCityIcon}
|
||||
label="شهر"
|
||||
value={formik.values.person_city}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12} mt={{ xs: 1, md: 0 }}>
|
||||
{!guild &&
|
||||
hasInquiry &&
|
||||
!isAdmin &&
|
||||
!isSuperAdmin &&
|
||||
!isKillHouse ? (
|
||||
<InfoBox
|
||||
icon={PhoneIcon}
|
||||
label="شماره همراه"
|
||||
value={formik.values.mobile}
|
||||
/>
|
||||
) : isKillHouse &&
|
||||
formik.values.mobile &&
|
||||
/^[0-9]{11}$/.test(formik.values.mobile) ? (
|
||||
<InfoBox
|
||||
icon={PhoneIcon}
|
||||
label="شماره همراه"
|
||||
value={formik.values.mobile}
|
||||
/>
|
||||
) : (
|
||||
<TextField
|
||||
label="شماره همراه"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="mobile"
|
||||
name="mobile"
|
||||
value={formik.values.mobile}
|
||||
onChange={formik.handleChange}
|
||||
error={formik.touched.mobile && Boolean(formik.errors.mobile)}
|
||||
helperText={formik.touched.mobile && formik.errors.mobile}
|
||||
disabled={
|
||||
isKillHouse &&
|
||||
formik.values.mobile &&
|
||||
/^[0-9]{11}$/.test(formik.values.mobile)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import { Button } from "@mui/material";
|
||||
import { Refresh } from "@mui/icons-material";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
|
||||
export const UpdateFromExternalButton = ({ onUpdate, disabled }) => {
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="flex-end">
|
||||
<Button
|
||||
onClick={onUpdate}
|
||||
disabled={disabled}
|
||||
color="primary"
|
||||
size="small"
|
||||
>
|
||||
بروزرسانی از سامانه واحد <Refresh />
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
17
src/features/province/components/create-guilds/constants.js
Normal file
17
src/features/province/components/create-guilds/constants.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export const STATUS_VALUES = {
|
||||
YES: "بلی",
|
||||
NO: "خیر",
|
||||
TRUE: "True",
|
||||
FALSE: "False",
|
||||
};
|
||||
|
||||
export const GENDER_VALUES = {
|
||||
MALE: "مرد",
|
||||
FEMALE: "زن",
|
||||
};
|
||||
|
||||
export const ALIVE_STATUS = {
|
||||
YES: "بلی",
|
||||
NO: "خیر",
|
||||
};
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
import { getRoleFromUrl } from "../../../../../utils/getRoleFromUrl";
|
||||
import { normalizeExternalApiDate, normalizeDatabaseDate } from "./dateUtils";
|
||||
import { formatDateForSubmit } from "./dateUtils";
|
||||
|
||||
export const prepareSubmitData = (
|
||||
values,
|
||||
guild,
|
||||
originalPhoneNumber,
|
||||
hasInquiry
|
||||
) => {
|
||||
const baseData = {
|
||||
national_id: values.national_id,
|
||||
mobile: values.mobile,
|
||||
mobilenumber: values.mobile,
|
||||
steward: !!values.steward,
|
||||
guild: !!values.guild,
|
||||
active_register_code: !!values.verify_mobile,
|
||||
firstName: values.first_name || "",
|
||||
lastName: values.last_name || "",
|
||||
fatherName: values.father_name || "",
|
||||
gender: values.gender || "",
|
||||
identityNo: values.national_code || "",
|
||||
isLive: values.is_alive === "بلی" || values.is_alive === true,
|
||||
birthDate: formatDateForSubmit(
|
||||
values.birth_date || "",
|
||||
hasInquiry === true
|
||||
),
|
||||
city: values.city || "",
|
||||
address: values.address || "",
|
||||
postalcode: values.postal_code || "",
|
||||
licenseNumber: values.license_number || "",
|
||||
licenseExpireDate: formatDateForSubmit(
|
||||
values.license_expire_date || "",
|
||||
hasInquiry === true
|
||||
),
|
||||
licenseIssueDate: formatDateForSubmit(
|
||||
values.license_issue_date || "",
|
||||
hasInquiry === true
|
||||
),
|
||||
licenseType: values.license_type || "",
|
||||
licenseStatus: values.license_status || "",
|
||||
isicname: values.area_activity || "",
|
||||
corporationName: values.corporation_name || "",
|
||||
nationalId: values.guild_national_id || "",
|
||||
unionName: values.union_name || "",
|
||||
phonenumber: values.phone_number || "",
|
||||
hasPartner: values.has_partner === true || values.has_partner === "بلی",
|
||||
isForeigner: values.is_foreigner === true || values.is_foreigner === "بلی",
|
||||
title: values.guild_name || "",
|
||||
role: getRoleFromUrl(),
|
||||
has_inquiry: hasInquiry !== null ? hasInquiry : false,
|
||||
...(values.active !== null && { active: values.active }),
|
||||
};
|
||||
|
||||
if (guild) {
|
||||
baseData.guilds_key = guild.key;
|
||||
if (values.mobile !== originalPhoneNumber) {
|
||||
baseData.mobile = values.mobile;
|
||||
baseData.mobilenumber = values.mobile;
|
||||
}
|
||||
}
|
||||
|
||||
return baseData;
|
||||
};
|
||||
|
||||
export const mapResponseDataToFormFields = (
|
||||
responseData,
|
||||
inquiryNationalCode,
|
||||
formik
|
||||
) => {
|
||||
const isExternalApi = responseData.dbRegister === false;
|
||||
|
||||
// New structure: user is at top level, guilds is an array
|
||||
const userData = responseData.user || {};
|
||||
// For personal info, we use the first guild's data if available, or empty
|
||||
const firstGuild =
|
||||
Array.isArray(responseData.guilds) && responseData.guilds.length > 0
|
||||
? responseData.guilds[0]
|
||||
: {};
|
||||
const guildData = firstGuild || {};
|
||||
const layerTwo = guildData.layerTwo || {};
|
||||
const addressData = firstGuild?.address || guildData.address || {};
|
||||
const provinceData = addressData.province || {};
|
||||
const cityData = addressData.city || {};
|
||||
|
||||
const nationalIdValue = isExternalApi
|
||||
? String(
|
||||
layerTwo.nationalcode || userData.nationalCode || inquiryNationalCode
|
||||
).trim()
|
||||
: String(userData.nationalId || inquiryNationalCode).trim();
|
||||
|
||||
const birthDatePersian = isExternalApi
|
||||
? normalizeExternalApiDate(userData.birthDate || "")
|
||||
: normalizeDatabaseDate(userData.birthday || "");
|
||||
|
||||
const licenseExpireDatePersian = isExternalApi
|
||||
? normalizeExternalApiDate(guildData.licenseExpireDate || "")
|
||||
: normalizeDatabaseDate(firstGuild.licenseExpireDate || "");
|
||||
|
||||
const licenseIssueDatePersian = isExternalApi
|
||||
? normalizeExternalApiDate(layerTwo.licenseIssueDate || "")
|
||||
: normalizeDatabaseDate(responseData.licenseIssueDate || "");
|
||||
|
||||
const genderValue = isExternalApi
|
||||
? userData.gender === true
|
||||
? "True"
|
||||
: userData.gender === false
|
||||
? "False"
|
||||
: ""
|
||||
: userData.gender || "";
|
||||
|
||||
const isAliveValue = isExternalApi
|
||||
? userData.isLive === true
|
||||
? "بلی"
|
||||
: userData.isLive === false
|
||||
? "خیر"
|
||||
: ""
|
||||
: userData.isAlive === false
|
||||
? "خیر"
|
||||
: userData.isAlive === true
|
||||
? "بلی"
|
||||
: "";
|
||||
|
||||
const isForeignerValue = isExternalApi
|
||||
? layerTwo.isForeigner === "خیر"
|
||||
? false
|
||||
: layerTwo.isForeigner === "بلی"
|
||||
? true
|
||||
: ""
|
||||
: responseData.isForeignNational === false
|
||||
? false
|
||||
: responseData.isForeignNational === true
|
||||
? true
|
||||
: "";
|
||||
|
||||
const hasStewardValue = isExternalApi
|
||||
? layerTwo.hasSteward === "خیر"
|
||||
? false
|
||||
: layerTwo.hasSteward === "بلی"
|
||||
? true
|
||||
: ""
|
||||
: responseData.steward === false
|
||||
? false
|
||||
: responseData.steward === true
|
||||
? true
|
||||
: "";
|
||||
|
||||
const hasPartnerValue = isExternalApi
|
||||
? layerTwo.hasPartner === "خیر"
|
||||
? false
|
||||
: layerTwo.hasPartner === "بلی"
|
||||
? true
|
||||
: ""
|
||||
: responseData.hasPartner === false
|
||||
? false
|
||||
: responseData.hasPartner === true
|
||||
? true
|
||||
: "";
|
||||
|
||||
const values = {
|
||||
first_name: userData.firstName || "",
|
||||
last_name: userData.lastName || "",
|
||||
national_id: nationalIdValue,
|
||||
national_code: isExternalApi
|
||||
? userData.identityNo || ""
|
||||
: userData.nationalCode || "",
|
||||
birth_date: birthDatePersian,
|
||||
father_name: userData.fatherName || "",
|
||||
gender: genderValue,
|
||||
person_city: userData.city || "",
|
||||
is_alive: isAliveValue,
|
||||
// Guild fields - will be set per guild in accordion, so we set empty or first guild's data
|
||||
guild_name: isExternalApi
|
||||
? guildData.title || ""
|
||||
: firstGuild.guildsName || "",
|
||||
area_activity: isExternalApi
|
||||
? guildData.isicname || ""
|
||||
: firstGuild.areaActivity || "",
|
||||
state: isExternalApi ? guildData.state || "" : provinceData.name || "",
|
||||
city: isExternalApi ? guildData.city || "" : cityData.name || "",
|
||||
address: isExternalApi
|
||||
? guildData.address || ""
|
||||
: addressData.address || "",
|
||||
license_expire_date: licenseExpireDatePersian,
|
||||
license_status: isExternalApi
|
||||
? guildData.licenseStatus || ""
|
||||
: firstGuild.licenseStatus || "",
|
||||
license_type: isExternalApi
|
||||
? guildData.licenseType || ""
|
||||
: firstGuild.licenseType || "",
|
||||
license_number: isExternalApi
|
||||
? guildData.licenseNumber || ""
|
||||
: firstGuild.licenseNumber || "",
|
||||
union_name: isExternalApi
|
||||
? layerTwo.unionName || ""
|
||||
: firstGuild.unionName || "",
|
||||
postal_code: isExternalApi
|
||||
? layerTwo.postalcode || ""
|
||||
: addressData.postalCode || "",
|
||||
phone_number: isExternalApi
|
||||
? layerTwo.phonenumber || ""
|
||||
: firstGuild.phoneNumber || "",
|
||||
mobile: isExternalApi ? layerTwo.mobilenumber || "" : userData.mobile || "",
|
||||
guild_national_id: isExternalApi
|
||||
? layerTwo.nationalId || ""
|
||||
: firstGuild.nationalCode || "",
|
||||
is_foreigner: isForeignerValue,
|
||||
corporation_name: isExternalApi
|
||||
? layerTwo.corporationName || ""
|
||||
: firstGuild.companyName || "",
|
||||
has_steward: hasStewardValue,
|
||||
has_partner: hasPartnerValue,
|
||||
steward: isExternalApi ? false : firstGuild.isSteward || false,
|
||||
guild: isExternalApi
|
||||
? typeof guildData.guild === "boolean"
|
||||
? guildData.guild
|
||||
: false
|
||||
: typeof firstGuild.guild === "boolean"
|
||||
? firstGuild.guild
|
||||
: false,
|
||||
license_issue_date: licenseIssueDatePersian,
|
||||
...(isExternalApi
|
||||
? {}
|
||||
: {
|
||||
company_name: firstGuild.companyName || "",
|
||||
company_identifier: firstGuild.companyIdentifier || "",
|
||||
type_activity_name: firstGuild.typeActivity || "",
|
||||
}),
|
||||
};
|
||||
|
||||
formik.setValues({ ...formik.values, ...values });
|
||||
};
|
||||
@@ -0,0 +1,158 @@
|
||||
import {
|
||||
convertToIranianTime,
|
||||
convertPersianToEnglishNumerals,
|
||||
} from "../../../../../utils/formatTime";
|
||||
import { fromJalali } from "../../../../../utils/jalali";
|
||||
|
||||
export const convertGregorianToPersian = (gregorianDateString) => {
|
||||
if (!gregorianDateString || typeof gregorianDateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Check if the date is already in Persian format (YYYY/MM/DD with year < 1500)
|
||||
const persianPattern = /^\d{4}\/\d{2}\/\d{2}$/;
|
||||
if (persianPattern.test(gregorianDateString)) {
|
||||
const year = parseInt(gregorianDateString.split("/")[0]);
|
||||
// If year is < 1500, it's likely Persian, return as is
|
||||
if (year < 1500) {
|
||||
return gregorianDateString;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to convert using convertToIranianTime
|
||||
try {
|
||||
return convertToIranianTime(gregorianDateString);
|
||||
} catch (error) {
|
||||
console.error("Error converting Gregorian date to Persian:", error);
|
||||
return gregorianDateString; // Return original on error
|
||||
}
|
||||
};
|
||||
|
||||
export const convertPersianToGregorian = (persianDateString) => {
|
||||
if (!persianDateString || typeof persianDateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
const normalizedDateString =
|
||||
convertPersianToEnglishNumerals(persianDateString);
|
||||
|
||||
const gregorianPattern = /^\d{4}[-/]\d{2}[-/]\d{2}$/;
|
||||
if (gregorianPattern.test(normalizedDateString)) {
|
||||
const year = parseInt(normalizedDateString.split(/[-/]/)[0]);
|
||||
if (year > 1500) {
|
||||
return normalizedDateString.replace(/\//g, "-");
|
||||
}
|
||||
}
|
||||
|
||||
const parts = normalizedDateString.split("/");
|
||||
if (parts.length !== 3) {
|
||||
return persianDateString;
|
||||
}
|
||||
|
||||
const py = parseInt(parts[0]);
|
||||
const pm = parseInt(parts[1]);
|
||||
const pd = parseInt(parts[2]);
|
||||
|
||||
if (isNaN(py) || isNaN(pm) || isNaN(pd)) {
|
||||
return persianDateString;
|
||||
}
|
||||
|
||||
try {
|
||||
const gregorianDate = fromJalali(py, pm, pd);
|
||||
const year = gregorianDate.getFullYear();
|
||||
const month = String(gregorianDate.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(gregorianDate.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
} catch (error) {
|
||||
console.error("Error converting Persian date to Gregorian:", error);
|
||||
return persianDateString;
|
||||
}
|
||||
};
|
||||
|
||||
export const normalizeExternalApiDate = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
return convertPersianToEnglishNumerals(dateString);
|
||||
};
|
||||
|
||||
export const normalizeDatabaseDate = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
const first10Chars = dateString.substring(0, 10);
|
||||
const normalizedDate = first10Chars.replace(/-/g, "/");
|
||||
return convertToIranianTime(normalizedDate);
|
||||
};
|
||||
|
||||
export const formatDateForSubmitExternal = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
return convertPersianToEnglishNumerals(dateString);
|
||||
};
|
||||
|
||||
export const formatDateForSubmitDatabase = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
const normalizedDate = convertPersianToEnglishNumerals(dateString);
|
||||
const persianPattern = /^\d{4}\/\d{2}\/\d{2}$/;
|
||||
|
||||
if (persianPattern.test(normalizedDate)) {
|
||||
const year = parseInt(normalizedDate.split("/")[0]);
|
||||
if (year < 1500) {
|
||||
const parts = normalizedDate.split("/");
|
||||
const py = parseInt(parts[0]);
|
||||
const pm = parseInt(parts[1]);
|
||||
const pd = parseInt(parts[2]);
|
||||
|
||||
if (!isNaN(py) && !isNaN(pm) && !isNaN(pd)) {
|
||||
try {
|
||||
const gregorianDate = fromJalali(py, pm, pd);
|
||||
const gy = gregorianDate.getFullYear();
|
||||
const gm = String(gregorianDate.getMonth() + 1).padStart(2, "0");
|
||||
const gd = String(gregorianDate.getDate()).padStart(2, "0");
|
||||
return `${gy}/${gm}/${gd}`;
|
||||
} catch (error) {
|
||||
console.error("Error converting Persian to Gregorian:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const gregorianPattern = /^\d{4}[-/]\d{2}[-/]\d{2}$/;
|
||||
if (gregorianPattern.test(normalizedDate)) {
|
||||
const year = parseInt(normalizedDate.split(/[-/]/)[0]);
|
||||
if (year > 1900) {
|
||||
return normalizedDate.replace(/-/g, "/");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const date = new Date(normalizedDate);
|
||||
if (!isNaN(date.getTime())) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}/${month}/${day}`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error formatting database date:", error);
|
||||
}
|
||||
|
||||
return normalizedDate.replace(/-/g, "/");
|
||||
};
|
||||
|
||||
export const formatDateForSubmit = (dateString, isExternalApi = false) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (isExternalApi) {
|
||||
return formatDateForSubmitExternal(dateString);
|
||||
} else {
|
||||
return formatDateForSubmitDatabase(dateString);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
import * as yup from "yup";
|
||||
import { normalizeDatabaseDate } from "./dateUtils";
|
||||
|
||||
export const getValidationSchema = (isEditMode) =>
|
||||
yup.object({
|
||||
national_id: yup
|
||||
.string()
|
||||
.required("کد ملی الزامی است")
|
||||
.matches(/^[0-9]{10}$/, "کد ملی باید 10 رقم باشد"),
|
||||
mobile: isEditMode
|
||||
? yup
|
||||
.string()
|
||||
.nullable()
|
||||
.test(
|
||||
"mobile-format",
|
||||
"شماره تلفن باید 11 رقم باشد",
|
||||
(value) => !value || /^[0-9]{11}$/.test(value)
|
||||
)
|
||||
: yup
|
||||
.string()
|
||||
.required("شماره تلفن الزامی است")
|
||||
.matches(/^[0-9]{11}$/, "شماره تلفن باید 11 رقم باشد"),
|
||||
first_name: yup.string(),
|
||||
last_name: yup.string(),
|
||||
guild_name: yup.string(),
|
||||
guild_category: yup.string(),
|
||||
state: yup.string(),
|
||||
city: yup.string(),
|
||||
address: yup.string(),
|
||||
license_expire_date: yup.string(),
|
||||
license_status: yup.string(),
|
||||
union_name: yup.string(),
|
||||
postal_code: yup.string(),
|
||||
guild_national_id: yup.string(),
|
||||
is_foreigner: yup.string(),
|
||||
national_code: yup.string(),
|
||||
has_steward: yup.string(),
|
||||
has_partner: yup.string(),
|
||||
license_number: yup.string(),
|
||||
isAccepted: yup
|
||||
.boolean()
|
||||
.test("req", "باید تعهد نامه را بپذیرید!", (val) => {
|
||||
return val === true;
|
||||
})
|
||||
.required("این فیلد اجباری است!"),
|
||||
});
|
||||
|
||||
export const getInitialValues = (guild) => ({
|
||||
first_name: guild?.user?.firstName || "",
|
||||
last_name: guild?.user?.lastName || "",
|
||||
corporation_name: guild?.companyName || "",
|
||||
national_id: guild?.user?.nationalId || "",
|
||||
national_code: guild?.user?.nationalCode || "",
|
||||
birth_date: normalizeDatabaseDate(guild?.user?.birthday || ""),
|
||||
father_name: guild?.user?.fatherName || "",
|
||||
gender: guild?.user?.gender || "",
|
||||
person_city: guild?.user?.city || "",
|
||||
is_alive: guild?.user?.isAlive || "",
|
||||
guild_name: guild?.guildsName || "",
|
||||
area_activity: guild?.areaActivity || "",
|
||||
state: guild?.address?.province?.name || "",
|
||||
city: guild?.address?.city?.name || "",
|
||||
address: guild?.address?.address || "",
|
||||
license_expire_date: normalizeDatabaseDate(guild?.licenseExpireDate || ""),
|
||||
license_status: guild?.licenseStatus || "",
|
||||
license_type: guild?.licenseType || "",
|
||||
union_name: guild?.unionName || "",
|
||||
postal_code: guild?.address?.postalCode || "",
|
||||
phone_number: guild?.phoneNumber || "",
|
||||
mobile: guild?.user?.mobile || "",
|
||||
is_foreigner: guild?.is_foreign_national || "",
|
||||
has_steward: guild?.hasSteward || "",
|
||||
has_partner: guild?.hasPartner || "",
|
||||
license_number: guild?.licenseNumber || "",
|
||||
isAccepted: guild?.provinceAcceptState === "accepted" || false,
|
||||
steward:
|
||||
typeof guild?.steward === "boolean"
|
||||
? guild.steward
|
||||
: typeof guild?.isSteward === "boolean"
|
||||
? guild.isSteward
|
||||
: false,
|
||||
guild:
|
||||
typeof guild?.guild === "boolean"
|
||||
? guild.guild
|
||||
: typeof guild?.isGuild === "boolean"
|
||||
? guild.isGuild
|
||||
: false,
|
||||
verify_mobile: guild?.verifyMobile || false,
|
||||
guild_national_id: guild?.nationalId || "",
|
||||
license_issue_date: normalizeDatabaseDate(guild?.licenseIssueDate || ""),
|
||||
company_name: guild?.companyName || "",
|
||||
company_identifier: guild?.companyIdentifier || "",
|
||||
type_activity_name: guild?.typeActivityName || "",
|
||||
active: guild?.active ?? null,
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import {
|
||||
CLOSE_MODAL,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../../lib/redux/slices/appSlice";
|
||||
import { ProvinceManageGuildsSubmitRegisterCode } from "../../province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode";
|
||||
|
||||
export const handleSubmitSuccess = (
|
||||
dispatch,
|
||||
openNotif,
|
||||
updateTable,
|
||||
values,
|
||||
responseData
|
||||
) => {
|
||||
updateTable();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
dispatch(CLOSE_MODAL());
|
||||
|
||||
if (values.verify_mobile && responseData) {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت کد احراز",
|
||||
content: (
|
||||
<ProvinceManageGuildsSubmitRegisterCode
|
||||
item={responseData}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const handleSubmitError = (openNotif, error) => {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: error,
|
||||
severity: "error",
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user