(
+
+ )}
+ />
+ );
+};
+export default CityController;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/CreateFormContent.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/CreateFormContent.jsx
new file mode 100644
index 0000000..d7ae67c
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/CreateFormContent.jsx
@@ -0,0 +1,232 @@
+import React, { useState } from "react";
+import { Controller, useForm } from "react-hook-form";
+import { yupResolver } from "@hookform/resolvers/yup";
+import { array, mixed, number, object, string } from "yup";
+import { useTheme } from "@emotion/react";
+import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material";
+import StyledForm from "@/core/components/StyledForm";
+import FileCopyIcon from "@mui/icons-material/FileCopy";
+import InfoIcon from "@mui/icons-material/Info";
+import ExitToAppIcon from "@mui/icons-material/ExitToApp";
+import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
+import BeenhereIcon from "@mui/icons-material/Beenhere";
+import MinorCrashIcon from "@mui/icons-material/MinorCrash";
+import DamageInfo from "./DamageInfo";
+import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
+import DamageReport from "./DamageReport";
+import DamageItem from "./DamageItem";
+
+function TabPanel(props) {
+ const { children, value, index } = props;
+ return (
+
+ {value === index && {children}}
+
+ );
+}
+
+const validationSchema = object({
+ accident_date: string().required("لطفا تاریخ تصادف را وارد کنید!!!"),
+ accident_time: string().required("لطفا زمان تصادف را وارد کنید!!!"),
+ accident_type: string().required("لطفا نوع تصادف را وارد کنید!!!"),
+ province_id: number().required("لطفا استان را وارد کنید!!!"),
+ city_id: number().required("لطفا شهرستان را وارد کنید!!!"),
+ axis_name: string().required("لطفا نام محور را وارد کنید!!!"),
+ driver_name: string().required("لطفا نام و نام خانوادگی را وارد کنید!!!"),
+ phone_number: mixed()
+ .test("max", "تلفن همراه باید شامل 11 رقم باشد", (value) => {
+ const stringValue = String(value);
+ return stringValue.length === 11;
+ })
+ .required("لطفا تلفن همراه را وارد کنید!!!"),
+ national_code: mixed()
+ .test("max", "کد ملی باید شامل 10 رقم باشد", (value) => value.toString().length === 10)
+ .required("لطفا کد ملی را وارد کنید!!!"),
+ start_point: mixed()
+ .test("start-point-required", "لطفاً نقطه تصادف را مشخص کنید!", function (value) {
+ return !!value; // چک میکند که مقدار موجود است
+ })
+ .required("لطفاً نقطه تصادف را مشخص کنید!"),
+ plate_part1: mixed()
+ .test("max", "2رقم", (value) => value.toString().length === 2)
+ .required("plate_part1 الزامیست"),
+ plate_part2: mixed().required("plate_part2 الزامیست"),
+ plate_part3: mixed()
+ .test("max", "3رقم", (value) => value.toString().length === 3)
+ .required("plate_part3الزامیست"),
+ plate_part4: mixed()
+ .test("max", "2رقم", (value) => value.toString().length === 2)
+ .required("plate_part4الزامیست"),
+ damage_picture1: mixed().nullable().required("لطفا عکس تصادف را بارگذاری کنید!"),
+ damage_picture2: mixed().nullable().required("لطفا عکس تصادف را بارگذاری کنید!"),
+ police_serial: string().when("police_file_checkbox", {
+ is: "police_file_checkbox", // زمانی که گزینه "police_file_checkbox" انتخاب شده باشد
+ then: (schema) => schema.required("شماره کروکی یا نامه پلیس راه الزامی است"),
+ }),
+ police_file_date: string().when("police_file_checkbox", {
+ is: "police_file_checkbox", // زمانی که گزینه "police_file_checkbox" انتخاب شده باشد
+ then: (schema) => schema.required("تاریخ کروکی یا نامه پلیس راه الزامی است"),
+ }),
+ police_file: string().when("police_file_checkbox", {
+ is: "police_file_checkbox", // زمانی که گزینه "police_file_checkbox" انتخاب شده باشد
+ then: (schema) => schema.required("تصویر کروکی یا نامه پلیس راه الزامی است"),
+ }),
+ items_damage: array().min(1, "حداقل یک ایتم خسارت ضروریست!!!"),
+});
+
+const CreateFormContent = ({ setOpen, mutate }) => {
+ const defaultValues = {
+ accident_date: "",
+ accident_time: "",
+ accident_type: "",
+ province_id: null,
+ city_id: null,
+ axis_name: "",
+ driver_name: "",
+ phone_number: "",
+ national_code: "",
+ plate_part1: "",
+ plate_part2: "الف",
+ plate_part3: "",
+ plate_part4: "",
+ damage_picture1: null,
+ damage_picture2: null,
+ report_base: "",
+ police_file_checkbox: "",
+ police_file: "",
+ police_file_date: "",
+ police_serial: "",
+ start_point: "",
+ items_damage: [],
+ };
+
+ const [tabState, setTabState] = useState(1);
+ const theme = useTheme();
+ const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
+ const handleClose = () => setOpen(false);
+ const handleChangeTab = (event, newValue) => setTabState(newValue);
+ const handlePrev = () => {
+ if (tabState === 0) {
+ handleClose();
+ } else {
+ setTabState(tabState - 1);
+ }
+ };
+ const {
+ control,
+ handleSubmit,
+ setValue,
+ trigger,
+ formState: { errors, isSubmitting, isValid },
+ } = useForm({
+ defaultValues,
+ resolver: yupResolver(validationSchema),
+ mode: "all",
+ });
+ const onSubmitBase = async (data) => {
+ console.log(data);
+ };
+ const handleNext = async () => {
+ let fieldsToValidate = [];
+ if (tabState === 0) {
+ fieldsToValidate = [
+ "phone_number",
+ "start_point",
+ "plate_part1",
+ "plate_part2",
+ "plate_part3",
+ "plate_part4",
+ "accident_date",
+ "accident_type",
+ "national_code",
+ "accident_time",
+ "province_id",
+ "city_id",
+ "axis_name",
+ "driver_name",
+ "damage_picture1",
+ "damage_picture2",
+ ];
+ } else if (tabState === 1) {
+ fieldsToValidate = ["report_base", "police_file", "police_file_date", "police_serial"];
+ } else if (tabState === 2) {
+ fieldsToValidate = ["items_damage"];
+ }
+ const isValid = await trigger(fieldsToValidate);
+ if (isValid) {
+ setTabState(tabState + 1);
+ }
+ };
+ return (
+
+
+ } label="اطلاعات تصادف" />
+ } label="گزارش میزان خسارت" />
+ } label="ایتم خسارت" />
+
+
+
+
+
+
+
+
+
+
+ {
+ return ;
+ }}
+ />
+
+
+
+
+ : }
+ >
+ {tabState === 0 ? "بستن" : "مرحله قبل"}
+
+ {tabState !== 2 ? (
+ }
+ >
+ مرحله بعد
+
+ ) : (
+ }
+ >
+ {!isValid ? "حداقل یک ایتم خسارت ضروریست" : isSubmitting ? "در حال ثبت خسارت" : "ثبت خسارت"}
+
+ )}
+
+
+ );
+};
+export default CreateFormContent;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageAmount.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageAmount.jsx
new file mode 100644
index 0000000..b2c7b90
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageAmount.jsx
@@ -0,0 +1,55 @@
+import { Controller, useWatch } from "react-hook-form";
+import { Grid } from "@mui/material";
+import NumberField from "@/core/components/NumberField";
+import { useEffect } from "react";
+
+const DamageAmount = ({ control, damageItemList, setValue }) => {
+ const itemDamage = useWatch({ control, name: "items_damge_id" });
+ const itemValue = useWatch({ control, name: "items_damge_value" });
+ const itemDamageId = damageItemList.find((damageItem) => damageItem.id === itemDamage);
+ const isDisabled = itemDamageId?.base_price ? itemDamageId?.base_price !== 0 : false;
+ const calculatedValue = itemValue * (itemDamageId?.base_price ? itemDamageId?.base_price : 0);
+ useEffect(() => {
+ if (isDisabled) {
+ setValue("items_damge_amount", calculatedValue);
+ }
+ }, [itemValue, itemDamageId, isDisabled, setValue]);
+ return (
+
+ {
+ return (
+ {
+ const inputValue = event.target.value;
+ if (isNaN(Number(inputValue))) {
+ return;
+ }
+ if (!isDisabled) {
+ field.onChange(inputValue);
+ }
+ }}
+ label={`هزینه خسارت (ریال)`}
+ fullWidth
+ size="small"
+ disabled={isDisabled || itemDamage === null}
+ error={error}
+ helperText={error?.message}
+ />
+ );
+ }}
+ />
+
+ );
+};
+export default DamageAmount;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageInfo.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageInfo.jsx
new file mode 100644
index 0000000..4b3457b
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageInfo.jsx
@@ -0,0 +1,273 @@
+import { Controller } from "react-hook-form";
+import { Grid, Stack, TextField } from "@mui/material";
+import MuiDatePicker from "@/core/components/MuiDatePicker";
+import MuiTimePicker from "@/core/components/MuiTimePicker";
+import SelectBox from "@/core/components/SelectBox";
+import useProvinces from "@/lib/hooks/useProvince";
+import PlateNumber from "@/core/components/PlateNumber";
+import ImageUpload from "./ImageUpload";
+import MapInfoOneMarker from "@/core/components/MapInfoOneMarker";
+import CityController from "@/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/CityController";
+
+const DamageInfo = ({ control, setValue, errors }) => {
+ const { provinces, errorProvinces, loadingProvinces } = useProvinces();
+
+ return (
+
+
+
+ {
+ return (
+ field.onChange(value || [])}
+ helperText={error ? error.message : null}
+ />
+ );
+ }}
+ name={"accident_date"}
+ />
+
+
+ {
+ return (
+ field.onChange(value || null)}
+ helperText={error ? error.message : null}
+ />
+ );
+ }}
+ name={"accident_time"}
+ />
+
+
+ {
+ return (
+
+ );
+ }}
+ />
+
+
+
+
+ {
+ return (
+
+ );
+ }}
+ />
+
+
+
+
+
+ (
+
+ )}
+ />
+
+
+
+
+ (
+
+ )}
+ />
+
+
+ (
+ {
+ const inputValue = event.target.value;
+ if (isNaN(Number(inputValue))) {
+ return;
+ }
+ field.onChange(inputValue);
+ }}
+ label="کد ملی"
+ placeholder={"کد ملی را وارد کنید"}
+ fullWidth
+ size="small"
+ error={error}
+ helperText={error?.message}
+ />
+ )}
+ />
+
+
+
+
+ (
+ {
+ const inputValue = event.target.value;
+ if (isNaN(Number(inputValue))) {
+ return;
+ }
+ field.onChange(inputValue);
+ }}
+ label="شماره تماس"
+ placeholder={"شماره تماس را وارد کنید"}
+ fullWidth
+ size="small"
+ error={error}
+ helperText={error?.message}
+ />
+ )}
+ />
+
+
+
+
+
+
+
+ (
+
+ )}
+ />
+
+
+ (
+
+ )}
+ />
+
+
+
+
+
+
+ );
+};
+export default DamageInfo;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageItem.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageItem.jsx
new file mode 100644
index 0000000..3a5de73
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageItem.jsx
@@ -0,0 +1,136 @@
+import { Autocomplete, Box, Button, Chip, Divider, Fade, Grid, Stack, TextField, Typography } from "@mui/material";
+import { Controller, useController, useForm } from "react-hook-form";
+import LinearProgress from "@mui/material/LinearProgress";
+import { useEffect, useState } from "react";
+import DamageItemInfo from "./DamageItemInfo";
+import { number, object } from "yup";
+import useDamageItemList from "@/lib/hooks/useDamageItemList";
+import DamagePrice from "./DamagePrice";
+import { yupResolver } from "@hookform/resolvers/yup";
+
+const schema = object({
+ items_damge_id: number().required("لطفا نوع خسارت را وارد کنید!!!"),
+ items_damge_value: number().required("لطفا میزان خسارت را وارد کنید!!!"),
+ items_damge_amount: number().required("لطفا هزینه خسارت را وارد کنید!!!"),
+});
+const defaultValues = {
+ items_damge_id: null,
+ items_damge_value: null,
+ items_damge_amount: null,
+};
+const DamageItem = ({ baseOnChange, getValues }) => {
+ const [selectedDamageItemList, setSelectedDamageItemList] = useState([]);
+ const { damageItemList, loadingDamageItemList, errorDamageItemList } = useDamageItemList();
+ const { control, handleSubmit, reset, setValue } = useForm({
+ defaultValues,
+ resolver: yupResolver(schema),
+ mode: "onBlur",
+ });
+ const deleteDamageItem = (id) => {
+ setSelectedDamageItemList((prev) => prev.filter((DamageItem) => DamageItem.items_damge_id !== id));
+ };
+ useEffect(() => {
+ baseOnChange(selectedDamageItemList);
+ }, [selectedDamageItemList]);
+ const handleCreateDamage = (data) => {
+ setSelectedDamageItemList((prev) => {
+ const isDuplicate = prev.some((item) => item.items_damge_id === data.items_damge_id);
+ if (!isDuplicate) {
+ return [...prev, data];
+ } else {
+ return prev;
+ }
+ });
+ reset();
+ };
+
+ return (
+ <>
+
+ {loadingDamageItemList ? (
+
+
+
+ ) : (
+ <>
+
+ (
+ option.title}
+ isOptionEqualToValue={(option, value) => option.id === value.id}
+ loading={loadingDamageItemList}
+ renderInput={(params) => (
+
+ )}
+ onChange={(_, value) => field.onChange(value?.id)}
+ value={damageItemList.find((item) => item.id === field.value) || null}
+ />
+ )}
+ />
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
+
+ {selectedDamageItemList.length === 0 && (
+
+
+ ابتدا اطلاعات بالا را تکمیل نمایید
+
+
+ )}
+
+
+ {selectedDamageItemList.length !== 0 &&
+ selectedDamageItemList.map((selectedDamageItem, index) => (
+
+
+
+ ))}
+
+
+ >
+ );
+};
+export default DamageItem;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageItemInfo.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageItemInfo.jsx
new file mode 100644
index 0000000..7af4ff4
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageItemInfo.jsx
@@ -0,0 +1,43 @@
+import { Box, Card, IconButton, Stack, Typography } from "@mui/material";
+import DeleteIcon from "@mui/icons-material/Delete";
+import React from "react";
+import MinorCrashIcon from "@mui/icons-material/MinorCrash";
+
+const DamageItemInfo = ({ deleteDamageItem, selectedDamageItem, damageItemList }) => {
+ const itemDamageId = damageItemList.find((item) => item.id == selectedDamageItem.items_damge_id);
+ return (
+
+
+
+
+
+ {itemDamageId.title}
+
+
+ میزان خسارت ({itemDamageId.unit}): {selectedDamageItem.items_damge_value}
+
+
+ هزینه خسارت (ریال): {selectedDamageItem.items_damge_amount}
+
+
+
+
+ deleteDamageItem(selectedDamageItem.items_damge_id)}>
+
+
+
+
+ );
+};
+export default DamageItemInfo;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamagePrice.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamagePrice.jsx
new file mode 100644
index 0000000..02fe21a
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamagePrice.jsx
@@ -0,0 +1,48 @@
+import { Controller, useWatch } from "react-hook-form";
+import { Grid, TextField } from "@mui/material";
+import DamageAmount from "./DamageAmount";
+
+const DamagePrice = ({ damageItemList, control, setValue }) => {
+ const itemDamage = useWatch({ control, name: "items_damge_id" });
+ const itemDamageId = damageItemList.find((damageItem) => damageItem.id === itemDamage);
+
+ return (
+ <>
+
+ {
+ return (
+ {
+ const inputValue = event.target.value;
+ if (isNaN(Number(inputValue))) {
+ return;
+ }
+ field.onChange(inputValue);
+ }}
+ label={`میزان خسارت ${itemDamageId?.unit ? `(${itemDamageId?.unit})` : ""}`}
+ fullWidth
+ size="small"
+ error={error}
+ helperText={error?.message}
+ />
+ );
+ }}
+ />
+
+
+ >
+ );
+};
+export default DamagePrice;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageReport.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageReport.jsx
new file mode 100644
index 0000000..a649b14
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/DamageReport.jsx
@@ -0,0 +1,53 @@
+import { FormControlLabel, RadioGroup, Stack } from "@mui/material";
+import { Controller } from "react-hook-form";
+import { useState } from "react";
+import PoliceFileReport from "./PoliceFileReport";
+import Radio from "@mui/material/Radio";
+
+const DamageReport = ({ control, setValue }) => {
+ const [selectedOption, setSelectedOption] = useState("report_base");
+
+ const handleOptionChange = (e) => {
+ setSelectedOption(e.target.value);
+ if (e.target.value === "report_base") {
+ setValue("police_file_checkbox", "");
+ setValue("report_base", "1");
+ }
+ };
+
+ return (
+ <>
+
+
+ }
+ />
+ }
+ label="کروکی یا نامه پلیس راه (معرفی فرد به اداره)"
+ />
+ }
+ />
+ }
+ label="بازدید عوامل و کارشناسان راهداری"
+ />
+
+
+ {selectedOption === "police_file_checkbox" && }
+ >
+ );
+};
+export default DamageReport;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/ImageUpload.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/ImageUpload.jsx
new file mode 100644
index 0000000..107d640
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/ImageUpload.jsx
@@ -0,0 +1,77 @@
+import { FormControl, FormHelperText } from "@mui/material";
+import UploadSystem from "@/core/components/UploadSystem";
+import React, { useEffect, useState } from "react";
+
+const ImageUpload = ({ name, value, onChange, error, beforeImage = null, title }) => {
+ const [beforeImg, setBeforeImg] = useState(beforeImage ? beforeImage : null);
+ const [beforeFileType, setBeforeFileType] = useState(beforeImage ? "image/" : null);
+ const [beforeFileName, setBeforeFileName] = useState(null);
+ const [showBeforeImage, setShowBeforeImage] = useState(!beforeImage);
+
+ useEffect(() => {
+ if (value) {
+ setShowBeforeImage(false);
+ if (typeof value === "string") {
+ setBeforeImg(value);
+ setBeforeFileType("image/");
+ } else if (value instanceof File) {
+ setBeforeImg(URL.createObjectURL(value));
+ setBeforeFileType(value.type);
+ }
+ }
+ }, [value]);
+
+ const handleFileChange = (event) => {
+ const uploadedFile = event.target?.files?.[0];
+ if (uploadedFile) {
+ const fileType = event.target?.files?.[0].type;
+ const fileName = event.target?.files?.[0].name;
+ setBeforeImg(URL.createObjectURL(uploadedFile));
+ setBeforeFileType(fileType);
+ setBeforeFileName(fileName);
+ onChange(uploadedFile);
+ setShowBeforeImage(false);
+ }
+ };
+
+ return (
+
+
+ {title}
+
+
+ {error ? error.message : null}
+
+ );
+};
+export default ImageUpload;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/PoliceFileReport.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/PoliceFileReport.jsx
new file mode 100644
index 0000000..9a93566
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/PoliceFileReport.jsx
@@ -0,0 +1,65 @@
+import { Controller } from "react-hook-form";
+import { Grid, Stack, TextField } from "@mui/material";
+import MuiDatePicker from "@/core/components/MuiDatePicker";
+import ImageUpload from "./ImageUpload";
+
+const PoliceFileReport = ({ control }) => {
+ return (
+
+
+
+
+ (
+
+ )}
+ />
+
+
+ {
+ return (
+ field.onChange(value || [])}
+ helperText={error ? error.message : null}
+ />
+ );
+ }}
+ name={"police_file_date"}
+ />
+
+
+
+ (
+
+ )}
+ />
+
+ );
+};
+export default PoliceFileReport;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/index.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/index.jsx
new file mode 100644
index 0000000..86c05f8
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/index.jsx
@@ -0,0 +1,12 @@
+"use client";
+import { Dialog } from "@mui/material";
+import CreateFormContent from "@/components/dashboard/technicalBuildingDamage/operator/Actions/create/Forms/CreateFormContent";
+
+const OperatorCreateForm = ({ open, setOpen, mutate }) => {
+ return (
+
+ );
+};
+export default OperatorCreateForm;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/index.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/index.jsx
new file mode 100644
index 0000000..5816c12
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Actions/create/index.jsx
@@ -0,0 +1,38 @@
+"use client";
+import { Button, IconButton, useMediaQuery } from "@mui/material";
+import { useTheme } from "@emotion/react";
+import { useState } from "react";
+import { AddCircle } from "@mui/icons-material";
+import OperatorCreateForm from "./Forms";
+
+const OperatorCreate = ({ mutate }) => {
+ const theme = useTheme();
+ const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
+ const [open, setOpen] = useState(false);
+
+ const handleOpen = () => {
+ setOpen(true);
+ };
+
+ return (
+ <>
+ {isMobile ? (
+
+
+
+ ) : (
+ }
+ onClick={handleOpen}
+ >
+ ثبت خسارت
+
+ )}
+
+ >
+ );
+};
+export default OperatorCreate;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/OperatorList.jsx b/src/components/dashboard/technicalBuildingDamage/operator/OperatorList.jsx
new file mode 100644
index 0000000..04955b3
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/OperatorList.jsx
@@ -0,0 +1,356 @@
+"use client";
+import { useEffect, useMemo, useState } from "react";
+import { Box, Stack, Typography } from "@mui/material";
+import DataTableWithAuth from "@/core/components/DataTableWithAuth";
+import Toolbar from "./Toolbar";
+import { GET_TECHNICAL_DAMAGE_OPERATOR_LIST } from "@/core/utils/routes";
+import moment from "jalali-moment";
+import RowActions from "./RowActions";
+import useProvinces from "@/lib/hooks/useProvince";
+import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency";
+import useEdaratLists from "@/lib/hooks/useEdaratLists";
+import ImageDialog from "./RowActions/ImageDialog";
+import LocationForm from "./RowActions/LocationForm";
+import ShowPlate from "./RowActions/ShowPlate";
+
+const OperatorList = () => {
+ const statusOptions = [
+ { value: 0, label: "بدون اقدام" },
+ { value: 1, label: "صدور نامه بیمه و کارشناسی داغی" },
+ { value: 2, label: "فیش ها ثبت شده است" },
+ { value: 3, label: "فاکتور صادر شده است" },
+ { value: 4, label: "فاکتور پرداخت شده است" },
+ { value: 5, label: "نامه پلیس راه صادر شده است" },
+ ];
+ const columns = useMemo(() => {
+ return [
+ {
+ accessorKey: "id",
+ header: "کد یکتا", // Unique Code
+ id: "id",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "equals",
+ sortDescFirst: false,
+ columnFilterModeOptions: ["equals", "contains"],
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "province_id",
+ header: "استان",
+ id: "province_id",
+ enableColumnFilter: true,
+ datatype: "numeric",
+ filterMode: "equals",
+ grow: false,
+ size: 130,
+ ColumnSelectComponent: (props) => {
+ const { provinces, errorProvinces, loadingProvinces } = useProvinces();
+ const getColumnSelectOptions = useMemo(() => {
+ if (loadingProvinces) {
+ return [{ value: "loading", label: "در حال بارگذاری..." }];
+ }
+ if (errorProvinces) {
+ return [{ value: "error", label: "خطا در بارگذاری" }];
+ }
+ return [
+ { value: "", label: "کل کشور" },
+ ...provinces.map((province) => ({
+ value: province.id,
+ label: province.name_fa,
+ })),
+ ];
+ }, [provinces, errorProvinces, loadingProvinces]);
+ return (
+
+ );
+ },
+ Cell: ({ row }) => <>{row.original.province_fa}>,
+ },
+ {
+ accessorKey: "city_id",
+ header: "شهرستان", // Office
+ id: "city_id",
+ enableColumnFilter: true,
+ datatype: "numeric",
+ filterMode: "equals",
+ dependencyId: "province_id",
+ grow: false,
+ size: 120,
+ ColumnSelectComponent: (props) => {
+ const { edaratList, loadingEdaratList, errorEdaratList } = useEdaratLists(
+ props.dependencyFieldValue.value
+ );
+ const [prevDependency, setPrevDependency] = useState(props.dependencyFieldValue.value);
+
+ const getColumnSelectOptions = useMemo(() => {
+ if (props.dependencyFieldValue.value === "") {
+ return [{ value: "empty", label: "ابتدا استان را انتخاب کنید" }];
+ }
+ if (loadingEdaratList) {
+ return [{ value: "loading", label: "در حال بارگذاری..." }];
+ }
+ if (errorEdaratList) {
+ return [{ value: "error", label: "خطا در بارگذاری" }];
+ }
+ return [
+ { value: "", label: "شهر" },
+ ...edaratList.map((edare) => ({
+ value: edare.id,
+ label: edare.name_fa,
+ })),
+ ];
+ }, [edaratList, loadingEdaratList, errorEdaratList]);
+ useEffect(() => {
+ if (prevDependency === props.dependencyFieldValue?.value) return;
+ props.handleChange({ ...props.filterParameters, value: "" });
+ setPrevDependency(props.dependencyFieldValue?.value);
+ }, [props.dependencyFieldValue?.value]);
+ return (
+
+ );
+ },
+ Cell: ({ row }) => <>{row.original.city_fa}>,
+ },
+ {
+ accessorKey: "axis_name",
+ header: "نام محور",
+ id: "axis_name",
+ enableColumnFilter: true,
+ enableSorting: true,
+ datatype: "text",
+ filterMode: "equals",
+ columnFilterModeOptions: ["equals", "contains"],
+ grow: false,
+ size: 120,
+ },
+ {
+ accessorKey: "accident_type",
+ header: "نوع تصادف", // Value
+ id: "accident_type",
+ enableColumnFilter: true,
+ enableSorting: true,
+ datatype: "text",
+ filterMode: "equals",
+ columnFilterModeOptions: ["equals", "contains"],
+ grow: false,
+ size: 120,
+ Cell: ({ row }) => <>{row.original.accident_type_fa}>,
+ },
+ {
+ accessorFn: (row) => {
+ const formattedDate = moment(row.accident_date, "YYYY-MM-DD"); // تنظیم فرمت صحیح تاریخ
+ const formattedTime = row.accident_time || "00:00:00"; // در صورت خالی بودن مقدار، مقدار پیشفرض داده شود
+ return moment(`${formattedDate.format("YYYY-MM-DD")}T${formattedTime}`)
+ .locale("fa")
+ .format("HH:mm | YYYY/MM/DD");
+ },
+ header: "تاریخ تصادف",
+ id: "accident_date",
+ enableColumnFilter: true,
+ datatype: "date",
+ filterMode: "between",
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "files",
+ header: "تصاویر",
+ id: "files",
+ enableColumnFilter: false,
+ enableSorting: false,
+ datatype: "array",
+ grow: false,
+ size: 100,
+ muiTableBodyCellProps: {
+ sx: {
+ borderLeft: "1px solid #e1e1e1",
+ py: 0,
+ "&:first-of-type": {
+ borderLeft: "unset",
+ },
+ },
+ },
+ Cell: ({ row }) => {
+ if (row.original.damage_picture1) {
+ const imagesList = [row.original.damage_picture1, row.original.damage_picture2];
+ return (
+
+
+
+ );
+ }
+ return (
+
+ بدون تصویر
+
+ );
+ },
+ },
+ {
+ accessorKey: "location",
+ header: "موقعیت",
+ id: "location",
+ enableColumnFilter: false,
+ enableSorting: false,
+ datatype: "array",
+ grow: false,
+ size: 100,
+ muiTableBodyCellProps: {
+ sx: {
+ borderLeft: "1px solid #e1e1e1",
+ py: 0,
+ "&:first-of-type": {
+ borderLeft: "unset",
+ },
+ },
+ },
+ Cell: ({ row }) => {
+ return (
+
+
+
+ );
+ },
+ },
+ {
+ accessorKey: "sum",
+ header: "مبلغ کل خسارت (ریال)",
+ id: "sum",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "equals",
+ columnFilterModeOptions: ["equals", "contains"],
+ sortDescFirst: true,
+ grow: false,
+ size: 100,
+ Cell: ({ row }) => (
+
+ {(row.original.sum / 1).toLocaleString()}
+
+ ),
+ },
+ {
+ accessorKey: "plaque",
+ header: "پلاک",
+ id: "plaque",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "equals",
+ sortDescFirst: true,
+ grow: false,
+ size: 100,
+ Cell: ({ renderedCellValue }) => ,
+ },
+ {
+ accessorFn: (row) => moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ header: "تاریخ ثبت",
+ id: "created_at",
+ enableColumnFilter: true,
+ datatype: "date",
+ filterMode: "between",
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "status",
+ header: "اخرین وضعیت",
+ id: "status",
+ enableColumnFilter: true,
+ datatype: "numeric",
+ filterMode: "equals",
+ grow: false,
+ size: 100,
+ columnSelectOption: () => {
+ return statusOptions.map((status) => ({
+ value: status.value,
+ label: status.label,
+ }));
+ },
+ Cell: ({ row }) => {
+ return {row.original.status_fa};
+ },
+ },
+ {
+ header: "اطلاعات واریز",
+ id: "items",
+ enableColumnFilter: false,
+ enableSorting: false,
+ grow: false,
+ size: 50,
+ columns: [
+ {
+ header: "مبلغ فیش (ریال)",
+ id: "final_amount",
+ enableColumnFilter: false,
+ grow: false,
+ size: 100,
+ Cell: ({ row }) => (
+
+ {(row.original.final_amount / 1).toLocaleString()}
+
+ ),
+ },
+ {
+ header: "مبلغ بیمه (ریال)",
+ id: "deposit_insurance_amount",
+ enableColumnFilter: false,
+ grow: false,
+ size: 100,
+ Cell: ({ row }) => (
+
+ {(row.original.deposit_insurance_amount / 1).toLocaleString()}
+
+ ),
+ },
+ {
+ header: "مبلغ داغی (ریال)",
+ id: "deposit_daghi_amount",
+ enableColumnFilter: false,
+ grow: false,
+ size: 100,
+ Cell: ({ row }) => (
+
+ {(row.original.deposit_daghi_amount / 1).toLocaleString()}
+
+ ),
+ },
+ ],
+ },
+ ];
+ }, []);
+
+ return (
+ <>
+
+
+
+ >
+ );
+};
+export default OperatorList;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ImageDialog/ImageFormContent.jsx b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ImageDialog/ImageFormContent.jsx
new file mode 100644
index 0000000..9aaa92e
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ImageDialog/ImageFormContent.jsx
@@ -0,0 +1,44 @@
+import { Box, DialogContent, Paper, Stack, Typography, useTheme } from "@mui/material";
+import Image from "next/image";
+
+const ImageFormContent = ({ image, title }) => {
+ const theme = useTheme();
+ return (
+
+
+ {title}
+
+
+
+
+
+ );
+};
+export default ImageFormContent;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ImageDialog/index.jsx b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ImageDialog/index.jsx
new file mode 100644
index 0000000..6e442ca
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ImageDialog/index.jsx
@@ -0,0 +1,44 @@
+import { Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Paper, Tooltip } from "@mui/material";
+import { useState } from "react";
+import PhotoLibraryIcon from "@mui/icons-material/PhotoLibrary";
+import ImageFormContent from "./ImageFormContent";
+
+const ImageDialog = ({ images }) => {
+ const [openImageDialog, setOpenImageDialog] = useState(false);
+
+ return (
+ <>
+
+ setOpenImageDialog(true)}>
+
+
+
+
+ >
+ );
+};
+export default ImageDialog;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/RowActions/LocationForm/LocationFormContent.jsx b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/LocationForm/LocationFormContent.jsx
new file mode 100644
index 0000000..14b3db3
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/LocationForm/LocationFormContent.jsx
@@ -0,0 +1,35 @@
+"use client";
+import { Box, Button, DialogActions, DialogContent, Stack } from "@mui/material";
+import React from "react";
+import dynamic from "next/dynamic";
+import MapLoading from "@/core/components/MapLayer/Loading";
+import ShowLocationMarker from "@/core/components/ShowLocationMarker";
+const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
+ loading: () => ,
+ ssr: false,
+});
+
+const LocationFormContent = ({ setOpenLocationDialog, start_lat, start_lng, end_lat, end_lng }) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+export default LocationFormContent;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/RowActions/LocationForm/index.jsx b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/LocationForm/index.jsx
new file mode 100644
index 0000000..f578ca8
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/LocationForm/index.jsx
@@ -0,0 +1,38 @@
+import React, { useState } from "react";
+import { Tooltip, IconButton, Dialog, DialogTitle } from "@mui/material";
+import ExploreIcon from "@mui/icons-material/Explore";
+import LocationFormContent from "./LocationFormContent";
+const LocationForm = ({ start_lat, start_lng, end_lat, end_lng }) => {
+ const [openLocationDialog, setOpenLocationDialog] = useState(false);
+
+ return (
+ <>
+
+ setOpenLocationDialog(true)}>
+
+
+
+
+ >
+ );
+};
+export default LocationForm;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ShowPlate/index.jsx b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ShowPlate/index.jsx
new file mode 100644
index 0000000..90d3ad0
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/ShowPlate/index.jsx
@@ -0,0 +1,38 @@
+import { Stack } from "@mui/material";
+
+const ShowPlate = ({ plate }) => {
+ return (
+
+
+ {plate.split("-")[3]}
+
+
+
+ {plate.split("-")[2]}
+
+
+ {plate.split("-")[1]}
+
+
+ {plate.split("-")[0]}
+
+
+
+ );
+};
+export default ShowPlate;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/RowActions/index.jsx b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/index.jsx
new file mode 100644
index 0000000..c9e69ef
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/RowActions/index.jsx
@@ -0,0 +1,6 @@
+import { Box } from "@mui/material";
+
+const RowActions = ({ row }) => {
+ return ;
+};
+export default RowActions;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/Toolbar.jsx b/src/components/dashboard/technicalBuildingDamage/operator/Toolbar.jsx
new file mode 100644
index 0000000..b774945
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/Toolbar.jsx
@@ -0,0 +1,11 @@
+import { Box } from "@mui/material";
+import OperatorCreate from "./Actions/create";
+
+const Toolbar = ({ table, filterData, mutate }) => {
+ return (
+
+
+
+ );
+};
+export default Toolbar;
diff --git a/src/components/dashboard/technicalBuildingDamage/operator/index.jsx b/src/components/dashboard/technicalBuildingDamage/operator/index.jsx
new file mode 100644
index 0000000..4936664
--- /dev/null
+++ b/src/components/dashboard/technicalBuildingDamage/operator/index.jsx
@@ -0,0 +1,14 @@
+"use client";
+import PageTitle from "@/core/components/PageTitle";
+import { Stack } from "@mui/material";
+import OperatorList from "./OperatorList";
+
+const OperatorPage = () => {
+ return (
+
+
+
+
+ );
+};
+export default OperatorPage;
diff --git a/src/core/components/MapInfoOneMarker.jsx b/src/core/components/MapInfoOneMarker.jsx
index b9574c1..a68d4bf 100644
--- a/src/core/components/MapInfoOneMarker.jsx
+++ b/src/core/components/MapInfoOneMarker.jsx
@@ -37,7 +37,7 @@ const createCustomIcon = (size, iconUrl, labelText, color) => {
};
const MAX_ZOOM_FOR_MARKER = 13;
-const MapInteraction = ({ setValue, startLat, startLng }) => {
+const MapInteraction = ({ setValue, startLat, startLng, title }) => {
const [isMarkerLocked, setIsMarkerLocked] = useState(!!(startLat && startLng));
const [enableSend, setEnableSend] = useState(false);
const [startIconColor, setStartIconColor] = useState(startLat ? "#1CAC66" : "#003d4f");
@@ -109,7 +109,7 @@ const MapInteraction = ({ setValue, startLat, startLng }) => {
>
- برای ثبت محل فعالیت، لطفاً نقشه را بیشتر زوم کنید.
+ {title}
@@ -131,7 +131,12 @@ const MapInteraction = ({ setValue, startLat, startLng }) => {
);
};
-const MapInfoOneMarker = ({ setValue, errors, StartPoint = null }) => {
+const MapInfoOneMarker = ({
+ setValue,
+ errors,
+ StartPoint = null,
+ title = "برای ثبت محل فعالیت، لطفاً نقشه را بیشتر زوم کنید.",
+}) => {
return (
@@ -140,6 +145,7 @@ const MapInfoOneMarker = ({ setValue, errors, StartPoint = null }) => {
setValue={setValue}
startLat={StartPoint ? StartPoint.lat : null}
startLng={StartPoint ? StartPoint.lng : null}
+ title={title}
/>
diff --git a/src/core/components/MuiDatePicker.jsx b/src/core/components/MuiDatePicker.jsx
index 0b5d8b1..f931188 100644
--- a/src/core/components/MuiDatePicker.jsx
+++ b/src/core/components/MuiDatePicker.jsx
@@ -8,67 +8,69 @@ import moment from "jalali-moment";
function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error, label }) {
return (
-
-
- {
- const date = new Date(value);
- const formattedDate = moment(date).locale("en").format("YYYY-MM-DD");
- setFieldValue(name, formattedDate);
- }}
- minDate={minDate ? new Date(minDate) : null}
- maxDate={maxDate ? new Date(maxDate) : null}
- slotProps={{
- textField: {
- error: error,
- size: "small",
- placeholder: placeholder,
- InputLabelProps: {
- shrink: true,
+ <>
+
+
+ {
+ const date = new Date(value);
+ const formattedDate = moment(date).locale("en").format("YYYY-MM-DD");
+ setFieldValue(name, formattedDate);
+ }}
+ minDate={minDate ? new Date(minDate) : null}
+ maxDate={maxDate ? new Date(maxDate) : null}
+ slotProps={{
+ textField: {
+ error: error,
+ size: "small",
+ placeholder: placeholder,
+ InputLabelProps: {
+ shrink: true,
+ },
+ InputProps: {
+ endAdornment: (
+
+ {
+ event.stopPropagation();
+ setFieldValue(name, "");
+ }}
+ sx={{
+ color: "#bfbfbf",
+ "&:hover": {
+ backgroundColor: "rgba(189, 189, 189, 0.1)",
+ color: "#363434",
+ },
+ }}
+ >
+
+
+
+ ),
+ },
},
- InputProps: {
- endAdornment: (
-
- {
- event.stopPropagation();
- setFieldValue(name, "");
- }}
- sx={{
- color: "#bfbfbf",
- "&:hover": {
- backgroundColor: "rgba(189, 189, 189, 0.1)",
- color: "#363434",
- },
- }}
- >
-
-
-
- ),
- },
- },
- }}
- />
- {helperText ? (
-
- {helperText}
-
- ) : null}
-
-
+ }}
+ />
+
+
+ {helperText && (
+
+ {helperText}
+
+ )}
+ >
);
}
diff --git a/src/core/components/MuiTimePicker.jsx b/src/core/components/MuiTimePicker.jsx
index b3336d4..a8fc46c 100644
--- a/src/core/components/MuiTimePicker.jsx
+++ b/src/core/components/MuiTimePicker.jsx
@@ -13,66 +13,68 @@ function MuiTimePicker({ value, setFieldValue, name, minTime, maxTime, helperTex
const parsedMaxTime = maxTime || null;
return (
-
-
- {
- setFieldValue(name, newValue);
- }}
- minTime={parsedMinTime}
- maxTime={parsedMaxTime}
- slotProps={{
- textField: {
- placeholder: placeholder,
- size: "small",
- error: error,
- InputLabelProps: {
- shrink: true,
+ <>
+
+
+ {
+ setFieldValue(name, newValue);
+ }}
+ minTime={parsedMinTime}
+ maxTime={parsedMaxTime}
+ slotProps={{
+ textField: {
+ placeholder: placeholder,
+ size: "small",
+ error: error,
+ InputLabelProps: {
+ shrink: true,
+ },
+ InputProps: {
+ endAdornment: (
+
+ {
+ event.stopPropagation();
+ setFieldValue(name, "");
+ }}
+ sx={{
+ color: "#bfbfbf",
+ "&:hover": {
+ backgroundColor: "rgba(189, 189, 189, 0.1)",
+ color: "#363434",
+ },
+ }}
+ >
+
+
+
+ ),
+ },
},
- InputProps: {
- endAdornment: (
-
- {
- event.stopPropagation();
- setFieldValue(name, "");
- }}
- sx={{
- color: "#bfbfbf",
- "&:hover": {
- backgroundColor: "rgba(189, 189, 189, 0.1)",
- color: "#363434",
- },
- }}
- >
-
-
-
- ),
- },
- },
- }}
- />
- {helperText ? (
-
- {helperText}
-
- ) : null}
-
-
+ }}
+ />
+
+
+ {helperText && (
+
+ {helperText}
+
+ )}
+ >
);
}
diff --git a/src/core/components/PlateNumber.jsx b/src/core/components/PlateNumber.jsx
new file mode 100644
index 0000000..7b396d5
--- /dev/null
+++ b/src/core/components/PlateNumber.jsx
@@ -0,0 +1,197 @@
+import { Box, Button, Drawer, FormHelperText, Stack, TextField } from "@mui/material";
+import AccessibleIcon from "@mui/icons-material/Accessible";
+import { Controller, useFormState, useWatch } from "react-hook-form";
+import { useEffect, useState } from "react";
+
+const plate_words = [
+ { id: 1, value: "الف", name: "الف" },
+ { id: 2, value: "ب", name: "ب" },
+ { id: 3, value: "پ", name: "پ" },
+ { id: 4, value: "ت", name: "ت" },
+ { id: 5, value: "ث", name: "ث" },
+ { id: 6, value: "ج", name: "ج" },
+ { id: 7, value: "د", name: "د" },
+ { id: 8, value: "ز", name: "ز" },
+ { id: 9, value: "س", name: "س" },
+ { id: 10, value: "ش", name: "ش" },
+ { id: 11, value: "ص", name: "ص" },
+ { id: 12, value: "ط", name: "ط" },
+ { id: 13, value: "ع", name: "ع" },
+ { id: 14, value: "ف", name: "ف" },
+ { id: 15, value: "ق", name: "ق" },
+ { id: 16, value: "ک", name: "گ" },
+ { id: 17, value: "ل", name: "ل" },
+ { id: 18, value: "م", name: "م" },
+ { id: 19, value: "ن", name: "ن" },
+ { id: 20, value: "و", name: "و" },
+ { id: 21, value: "ه", name: "ه" },
+ { id: 22, value: "ی", name: "ی" },
+ { id: 23, value: "*", name: },
+];
+
+const PlateNumber = ({ control }) => {
+ const platePart2 = useWatch({ control, name: "plate_part2" });
+ const [plateDrawer, setPlateDrawer] = useState(false);
+ const { errors } = useFormState({ control });
+ const plateErrors = ["plate_part1", "plate_part2", "plate_part3", "plate_part4"].some((part) => errors[part]);
+
+ return (
+ <>
+
+ (
+ {
+ const inputValue = event.target.value;
+ if (isNaN(Number(inputValue))) {
+ return;
+ }
+ inputValue.length <= 2 ? field.onChange(inputValue) : null;
+ }}
+ size="small"
+ placeholder="xx"
+ sx={{ flexGrow: 2, "& fieldset": { border: "none" } }}
+ />
+ )}
+ />
+ (
+ {
+ const inputValue = event.target.value;
+ if (isNaN(Number(inputValue))) {
+ return;
+ }
+ inputValue.length <= 3 ? field.onChange(inputValue) : null;
+ }}
+ size="small"
+ placeholder="xxx"
+ sx={{
+ flexGrow: 3,
+ borderLeft: 1,
+ borderRadius: 0,
+ borderColor: "divider",
+ "& fieldset": { border: "none" },
+ }}
+ />
+ )}
+ />
+
+
+
+ setPlateDrawer(false)}
+ >
+
+ {plate_words.map((item) => (
+ (
+
+ )}
+ />
+ ))}
+
+
+ (
+ {
+ const inputValue = event.target.value;
+ if (isNaN(Number(inputValue))) {
+ return;
+ }
+ inputValue.length <= 2 ? field.onChange(inputValue) : null;
+ }}
+ />
+ )}
+ />
+
+
+
+
+
+
+ {plateErrors && (
+
+ پلاک نامعتبر است!!!
+
+ )}
+ >
+ );
+};
+export default PlateNumber;
diff --git a/src/core/components/SelectBox.jsx b/src/core/components/SelectBox.jsx
new file mode 100644
index 0000000..e6e8552
--- /dev/null
+++ b/src/core/components/SelectBox.jsx
@@ -0,0 +1,49 @@
+import { FormControl, FormHelperText, InputLabel, MenuItem, Select } from "@mui/material";
+
+function SelectBox({
+ name,
+ value,
+ onChange,
+ onBlur,
+ selectors,
+ label,
+ error,
+ schema,
+ disabled,
+ helperText,
+ isLoading,
+ errorEcured,
+ variant = "outlined",
+}) {
+ return (
+
+ {label}
+
+ {helperText || error?.message}
+
+ );
+}
+export default SelectBox;
diff --git a/src/core/components/ShowPlak.jsx b/src/core/components/ShowPlak.jsx
index 5d51455..6e02934 100644
--- a/src/core/components/ShowPlak.jsx
+++ b/src/core/components/ShowPlak.jsx
@@ -14,7 +14,6 @@ const ShowPlak = ({ plak_number }) => {
};
};
const plakParts = processPlak(plak_number);
-
return (
value === true);
+ const flattenObject = (obj) => {
+ let result = {};
+ for (const key in obj) {
+ if (typeof obj[key] === "object" && obj[key] !== null) {
+ Object.assign(result, flattenObject(obj[key])); // باز کردن اشیای تودرتو
+ } else {
+ result[key] = obj[key];
+ }
+ }
+ return result;
+ };
+ // تبدیل آبجکت به آبجکت فلت شده
+ const flatHideData = flattenObject(hideData);
+
+ const CheckHideValues = Object.values(flatHideData).every((value) => value === true);
hasAnyConflict =
!CheckHideValues || JSON.stringify(sortData) !== JSON.stringify(initialSort) || !CheckFilterValues;
diff --git a/src/lib/hooks/useDamageItemList.js b/src/lib/hooks/useDamageItemList.js
new file mode 100644
index 0000000..a353627
--- /dev/null
+++ b/src/lib/hooks/useDamageItemList.js
@@ -0,0 +1,29 @@
+import { useEffect, useState } from "react";
+import { GET_DAMAGE_ITEM_LIST, GET_PROVINCE_LISTS } from "@/core/utils/routes";
+import useRequest from "@/lib/hooks/useRequest";
+
+const useDamageItemList = () => {
+ const requestServer = useRequest();
+ const [damageItemList, setDamageItemList] = useState([]);
+ const [loadingDamageItemList, setLoadingDamageItemList] = useState(true);
+ const [errorDamageItemList, setErrorDamageItemList] = useState(null);
+
+ useEffect(() => {
+ const fetchCities = async () => {
+ try {
+ const response = await requestServer(`${GET_DAMAGE_ITEM_LIST}`);
+ setDamageItemList(response.data.data);
+ setLoadingDamageItemList(false);
+ } catch (e) {
+ setErrorDamageItemList(e);
+ setLoadingDamageItemList(false);
+ }
+ };
+
+ fetchCities();
+ }, []);
+
+ return { damageItemList, loadingDamageItemList, errorDamageItemList };
+};
+
+export default useDamageItemList;
diff --git a/src/lib/hooks/useProvince.js b/src/lib/hooks/useProvince.js
index f6b98b8..a36df7d 100644
--- a/src/lib/hooks/useProvince.js
+++ b/src/lib/hooks/useProvince.js
@@ -15,7 +15,6 @@ const useProvinces = () => {
setProvinces(response.data.data);
setLoadingProvinces(false);
} catch (e) {
- console.error("Error fetching provinces:", e);
setErrorProvinces(e);
setLoadingProvinces(false);
}