Feature/gasht rahdari cartable
This commit is contained in:
@@ -21,7 +21,7 @@ const AzmayeshList = () => {
|
||||
datatype: "text",
|
||||
filterMode: "notEquals",
|
||||
grow: false,
|
||||
size: 100
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "province_name",
|
||||
|
||||
@@ -23,7 +23,7 @@ import VerifiedIcon from "@mui/icons-material/Verified";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
const MAX_ZOOM_FOR_MARKER = 13
|
||||
const MAX_ZOOM_FOR_MARKER = 13;
|
||||
|
||||
const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
const theme = useTheme();
|
||||
@@ -43,7 +43,7 @@ const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
|
||||
const map = useMapEvents({
|
||||
move(e) {
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER)
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
|
||||
if (!mapBoxData) {
|
||||
mapAzmayeshMarker.current.setLatLng(e.target.getCenter());
|
||||
}
|
||||
@@ -59,8 +59,8 @@ const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
}
|
||||
},
|
||||
zoom(e) {
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER)
|
||||
}
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -74,9 +74,8 @@ const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
}
|
||||
}, [mapBoxData, mapAzmayeshMarker.current]);
|
||||
|
||||
|
||||
const handleMarkerClick = () => {
|
||||
if (!enableSend) return
|
||||
if (!enableSend) return;
|
||||
if (!mapBoxData) {
|
||||
setMapBoxData({
|
||||
lat: mapAzmayeshMarker.current.getLatLng().lat,
|
||||
@@ -91,44 +90,44 @@ const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Marker
|
||||
position={map.getCenter()}
|
||||
ref={mapAzmayeshMarker}
|
||||
eventHandlers={{ click: handleMarkerClick }}
|
||||
/>
|
||||
<Marker position={map.getCenter()} ref={mapAzmayeshMarker} eventHandlers={{ click: handleMarkerClick }} />
|
||||
<Stack
|
||||
direction={'row'}
|
||||
justifyContent={'center'}
|
||||
direction={"row"}
|
||||
justifyContent={"center"}
|
||||
sx={{
|
||||
zIndex: "400",
|
||||
width: '100%',
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
}}
|
||||
>
|
||||
<Zoom in={!enableSend}>
|
||||
<Alert sx={{ mt: 1, py: .5, px: 2, borderRadius: 2, border: 1 }} icon={false} color={'warning'}>برای ثبت محل آزمایش، لطفاً نقشه را بیشتر زوم کنید.</Alert>
|
||||
<Alert sx={{ mt: 1, py: 0.5, px: 2, borderRadius: 2, border: 1 }} icon={false} color={"warning"}>
|
||||
برای ثبت محل آزمایش، لطفاً نقشه را بیشتر زوم کنید.
|
||||
</Alert>
|
||||
</Zoom>
|
||||
</Stack>
|
||||
<Stack
|
||||
direction={'row'}
|
||||
direction={"row"}
|
||||
sx={{
|
||||
zIndex: "400",
|
||||
width: '100%',
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
}}
|
||||
>
|
||||
<Box sx={{
|
||||
background: "#ffffff94",
|
||||
flex: isMobile ? 1 : "",
|
||||
m: 1,
|
||||
p: 2,
|
||||
borderRadius: 2,
|
||||
boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px",
|
||||
}}>
|
||||
<Box
|
||||
sx={{
|
||||
background: "#ffffff94",
|
||||
flex: isMobile ? 1 : "",
|
||||
m: 1,
|
||||
p: 2,
|
||||
borderRadius: 2,
|
||||
boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px",
|
||||
}}
|
||||
>
|
||||
<Stack sx={{ gap: 2 }}>
|
||||
<Tooltip title="با کلیک بر روی مارکر، محل آزمایش را انتخاب کنید" arrow>
|
||||
<FormControl size="small" variant="outlined">
|
||||
|
||||
@@ -119,8 +119,7 @@ const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
|
||||
});
|
||||
mutate();
|
||||
handleClose();
|
||||
} catch (error) {
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -191,8 +190,8 @@ const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
|
||||
? "در حال ویرایش آزمایش"
|
||||
: "ویرایش آزمایش"
|
||||
: isSubmitting
|
||||
? "در حال ثبت آزمایش"
|
||||
: "ثبت آزمایش"}
|
||||
? "در حال ثبت آزمایش"
|
||||
: "ثبت آزمایش"}
|
||||
</Button>
|
||||
)}
|
||||
</DialogActions>
|
||||
|
||||
@@ -14,7 +14,7 @@ const ShowSampleOfAzmayesh = ({ rowData }) => {
|
||||
.then((response) => {
|
||||
setSampleInfo(response.data.data);
|
||||
})
|
||||
.catch(() => { })
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setOpenShowSampleDialog(true);
|
||||
});
|
||||
|
||||
@@ -57,7 +57,7 @@ const RoadSafetyFormContext = ({ rowId, mutate, setOpenRoadSafetyForm }) => {
|
||||
setOpenRoadSafetyForm(false);
|
||||
mutate();
|
||||
})
|
||||
.catch(() => { });
|
||||
.catch(() => {});
|
||||
};
|
||||
return (
|
||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||
|
||||
@@ -50,7 +50,7 @@ const ReferFormContext = ({ setOpenReferDialog, rowId, mutate }) => {
|
||||
setOpenReferDialog(false);
|
||||
mutate();
|
||||
})
|
||||
.catch(() => { });
|
||||
.catch(() => {});
|
||||
};
|
||||
return (
|
||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||
|
||||
@@ -57,7 +57,7 @@ const RoadSafetyFormContext = ({ rowId, mutate, setOpenRoadSafetyForm }) => {
|
||||
setOpenRoadSafetyForm(false);
|
||||
mutate();
|
||||
})
|
||||
.catch(() => { });
|
||||
.catch(() => {});
|
||||
};
|
||||
return (
|
||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||
|
||||
@@ -34,7 +34,7 @@ const defaultValues = {
|
||||
start_date: "",
|
||||
before_image: null,
|
||||
after_image: null,
|
||||
cmms_machine_id: null,
|
||||
cmms_machines: null,
|
||||
rahdaran_id: null,
|
||||
start_point: "",
|
||||
end_point: "",
|
||||
@@ -43,7 +43,7 @@ const validationSchema = object({
|
||||
itemId: string().required("نوع آیتم را مشخص کنید!"),
|
||||
itemSubId: string().required("موضوع مشاهده شده را مشخص کنید!"),
|
||||
amount: string().required("وارد کردن مقدار الزامیست!"),
|
||||
cmms_machine_id: object().required("وارد کردن کد خودرو الزامیست!"),
|
||||
cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"),
|
||||
rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), // بررسی حداقل یک آیتم,
|
||||
action_date: string().required("لطفا زمان فعالیت را انتخاب کنید!"),
|
||||
start_date: string().required("لطفاً تاریخ شروع فعالیت را انتخاب کنید!"),
|
||||
@@ -82,12 +82,11 @@ const validationSchema = object({
|
||||
}),
|
||||
});
|
||||
|
||||
const CreateFormContent = ({ setOpen, mutate, rowId }) => {
|
||||
const CreateFormContent = ({ setOpen, mutate, onSubmit }) => {
|
||||
const [tabState, setTabState] = useState(0);
|
||||
const [itemsList, setItemsList] = useState();
|
||||
const [subItemsList, setSubItemsList] = useState([]);
|
||||
const theme = useTheme();
|
||||
const requestServer = useRequest({ notificationSuccess: true });
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
@@ -98,6 +97,20 @@ const CreateFormContent = ({ setOpen, mutate, rowId }) => {
|
||||
};
|
||||
|
||||
const handlePrev = () => {
|
||||
if (tabState === 2) {
|
||||
const fieldsToReset = [
|
||||
"amount",
|
||||
"action_date",
|
||||
"start_date",
|
||||
"before_image",
|
||||
"after_image",
|
||||
"cmms_machines",
|
||||
"rahdaran_id",
|
||||
"start_point",
|
||||
"end_point",
|
||||
];
|
||||
fieldsToReset.forEach((field) => resetField(field));
|
||||
}
|
||||
if (tabState === 0) {
|
||||
handleClose();
|
||||
} else {
|
||||
@@ -111,6 +124,7 @@ const CreateFormContent = ({ setOpen, mutate, rowId }) => {
|
||||
register,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
resetField,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm({
|
||||
defaultValues,
|
||||
@@ -119,32 +133,6 @@ const CreateFormContent = ({ setOpen, mutate, rowId }) => {
|
||||
context: { subItemsList },
|
||||
});
|
||||
|
||||
const onSubmit = async (data) => {
|
||||
console.log(data);
|
||||
let endPoint;
|
||||
let startPoint = `${data.start_point.lat},${data.start_point.lng}`;
|
||||
data.end_point !== "" && (endPoint = `${data.end_point.lat},${data.end_point.lng}`);
|
||||
const formData = new FormData();
|
||||
data.rahdaran_id.map((rahdar, index) => formData.append(`rahdaran_id[${index}]`, rahdar.id));
|
||||
formData.append("item_id", data.itemId);
|
||||
formData.append("sub_item_id", data.itemSubId);
|
||||
formData.append("amount", data.amount);
|
||||
formData.append("activity_time", data.action_date);
|
||||
formData.append("activity_date", data.start_date);
|
||||
formData.append("cmms_machine_id", data.cmms_machine_id.id);
|
||||
data.before_image !== null && formData.append("before_image", data.before_image);
|
||||
data.after_image !== null && formData.append("after_image", data.after_image);
|
||||
data.start_point !== "" && formData.append("start_point", startPoint);
|
||||
data.end_point !== "" && formData.append("end_point", endPoint);
|
||||
requestServer(CREATE_ROAD_ITEMS, "post", {
|
||||
data: formData,
|
||||
})
|
||||
.then((response) => {
|
||||
mutate();
|
||||
setOpen(false);
|
||||
})
|
||||
.catch((error) => {});
|
||||
};
|
||||
return (
|
||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||
<Tabs
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Controller } from "react-hook-form";
|
||||
import CarCode from "@/core/components/CarCode";
|
||||
import RahdarCode from "@/core/components/RahdarCode";
|
||||
import PreviousStatesInfo from "./PreviousStatesInfo";
|
||||
import NumberField from "@/core/components/NumberField";
|
||||
|
||||
const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, errors, watch, getValues }) => {
|
||||
return (
|
||||
@@ -16,12 +17,14 @@ const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, err
|
||||
<PreviousStatesInfo itemsList={itemsList} subItemsList={subItemsList} />
|
||||
</Stack>
|
||||
<Stack>
|
||||
<TextField
|
||||
<NumberField
|
||||
{...register("amount")}
|
||||
label={`مقدار (${subItemsList.unit})`}
|
||||
error={!!errors.amount}
|
||||
value={watch("amount")}
|
||||
type="text"
|
||||
size={"small"}
|
||||
unit={subItemsList.unit}
|
||||
inputProps={{
|
||||
inputMode: "number",
|
||||
min: 0,
|
||||
@@ -45,13 +48,14 @@ const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, err
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<CarCode
|
||||
carCode={field.value || null}
|
||||
setCarCode={(value) => field.onChange(value || null)}
|
||||
carCode={field.value || []}
|
||||
setCarCode={(value) => field.onChange(value || [])}
|
||||
error={error}
|
||||
multiple={true}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
name={"cmms_machine_id"}
|
||||
name={"cmms_machines"}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack>
|
||||
|
||||
@@ -1,11 +1,39 @@
|
||||
"use client";
|
||||
import { Dialog } from "@mui/material";
|
||||
import CreateFormContent from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent";
|
||||
import { CREATE_ROAD_ITEMS } from "@/core/utils/routes";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
|
||||
const OperatorCreateForm = ({ open, setOpen, mutate, rowId }) => {
|
||||
const requestServer = useRequest({ notificationSuccess: true });
|
||||
const HandleSubmit = async (data) => {
|
||||
let endPoint;
|
||||
let startPoint = `${data.start_point.lat},${data.start_point.lng}`;
|
||||
data.end_point !== "" && (endPoint = `${data.end_point.lat},${data.end_point.lng}`);
|
||||
const formData = new FormData();
|
||||
data.rahdaran_id.map((rahdar, index) => formData.append(`rahdaran_id[${index}]`, rahdar.id));
|
||||
formData.append("item_id", data.itemId);
|
||||
formData.append("sub_item_id", data.itemSubId);
|
||||
formData.append("amount", data.amount);
|
||||
formData.append("activity_time", data.action_date);
|
||||
formData.append("activity_date", data.start_date);
|
||||
data.cmms_machines.map((machine, index) => formData.append(`machines_id[${index}]`, machine.id));
|
||||
data.before_image !== null && formData.append("before_image", data.before_image);
|
||||
data.after_image !== null && formData.append("after_image", data.after_image);
|
||||
data.start_point !== "" && formData.append("start_point", startPoint);
|
||||
data.end_point !== "" && formData.append("end_point", endPoint);
|
||||
await requestServer(CREATE_ROAD_ITEMS, "post", {
|
||||
data: formData,
|
||||
})
|
||||
.then((response) => {
|
||||
mutate();
|
||||
setOpen(false);
|
||||
})
|
||||
.catch((error) => {});
|
||||
};
|
||||
return (
|
||||
<Dialog open={open} fullWidth maxWidth="sm">
|
||||
<CreateFormContent setOpen={setOpen} mutate={mutate} rowId={rowId} />
|
||||
<CreateFormContent setOpen={setOpen} mutate={mutate} onSubmit={HandleSubmit} />
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ const PrintExcel = ({ table, filterData }) => {
|
||||
const filename = `خروجی کارتابل فعالیت روزانه تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`;
|
||||
FileSaver.saveAs(response.data, filename);
|
||||
})
|
||||
.catch(() => { })
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
"use client";
|
||||
import { useMemo } from "react";
|
||||
import { Box, Stack, Typography } from "@mui/material";
|
||||
import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency";
|
||||
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
|
||||
import Toolbar from "./Toolbar";
|
||||
import { GET_ROAD_ITEMS_OPERATOR_LIST } from "@/core/utils/routes";
|
||||
import useRoadItemGetSubItems from "@/lib/hooks/useRoadItemGetISubtems";
|
||||
import useRoadItemGetItems from "@/lib/hooks/useRoadItemGetItems";
|
||||
import { Box, Stack, Typography } from "@mui/material";
|
||||
import moment from "jalali-moment";
|
||||
import { useMemo } from "react";
|
||||
import RowActions from "./RowActions";
|
||||
import LocationForm from "./RowActions/LocationForm";
|
||||
import ImageDialog from "./RowActions/ImageForm";
|
||||
import LocationForm from "./RowActions/LocationForm";
|
||||
import RahdaranDialog from "./RowActions/RahdaranForm";
|
||||
import Toolbar from "./Toolbar";
|
||||
import DescriptionForm from "./RowActions/DescriptionForm";
|
||||
import MachinesCodeDialog from "./RowActions/MachinesCodeForm";
|
||||
|
||||
const OperatorList = () => {
|
||||
const statusOptions = [
|
||||
{ value: 0, label: "درحال بررسی" },
|
||||
{ value: 1, label: "تایید" },
|
||||
{ value: 2, label: "عدم تایید" },
|
||||
];
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -21,24 +31,78 @@ const OperatorList = () => {
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "item_fa",
|
||||
header: "آیتم فعالیت",
|
||||
id: "item_fa",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { itemsList, loadingItemsList, errorItemsList } = useRoadItemGetItems();
|
||||
|
||||
const getColumnSelectOptions = () => {
|
||||
if (loadingItemsList) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorItemsList) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...itemsList.map((item) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
})),
|
||||
];
|
||||
};
|
||||
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "sub_item_fa",
|
||||
header: "موضوع مشاهده شده", // Observed Subject
|
||||
header: "موضوع مشاهده شده",
|
||||
id: "sub_item_fa",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
dependencyId: "item_fa",
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetSubItems(
|
||||
props.dependencyFieldValue.value
|
||||
);
|
||||
|
||||
const getColumnSelectOptions = () => {
|
||||
if (props.dependencyFieldValue.value === "") {
|
||||
return [{ value: "empty", label: "ابتدا آیتم فعالیت را انتخاب کنید" }];
|
||||
}
|
||||
if (loadingSubItemsList) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorSubItemsList) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...subItemsList.map((item) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
})),
|
||||
];
|
||||
};
|
||||
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "value",
|
||||
@@ -48,11 +112,17 @@ const OperatorList = () => {
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 120,
|
||||
Cell: ({ renderedCellValue, row }) => {
|
||||
return (
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Typography variant="body2">{row.original.sub_item_data}</Typography>
|
||||
<Typography variant="body2">{`(${row.original.unit_fa})`}</Typography>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<Typography sx={{ margin: 1 }} component="span">
|
||||
{(row.original.sub_item_data / 1).toLocaleString()}
|
||||
</Typography>
|
||||
<Typography component="span" variant="caption">
|
||||
{`(${row.original.unit_fa})`}
|
||||
</Typography>
|
||||
</Stack>
|
||||
);
|
||||
},
|
||||
@@ -64,6 +134,8 @@ const OperatorList = () => {
|
||||
enableColumnFilter: false,
|
||||
enableSorting: false,
|
||||
datatype: "array",
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
@@ -95,6 +167,8 @@ const OperatorList = () => {
|
||||
enableColumnFilter: false,
|
||||
enableSorting: false,
|
||||
datatype: "array",
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
@@ -118,14 +192,35 @@ const OperatorList = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "cmms_machine_code",
|
||||
accessorKey: "cmms_machines",
|
||||
header: "کد خودرو", // Car ID
|
||||
id: "cmms_machine_code",
|
||||
id: "cmmsMachines__machine_code",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
filterMode: "contains",
|
||||
enableSorting: false,
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
py: 0,
|
||||
"&:first-of-type": {
|
||||
borderLeft: "unset",
|
||||
},
|
||||
},
|
||||
},
|
||||
Cell: ({ renderedCellValue }) => {
|
||||
if (renderedCellValue) {
|
||||
return (
|
||||
<Stack alignItems={"center"} justifyContent={"center"}>
|
||||
<MachinesCodeDialog machinesLists={renderedCellValue} />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
return <Typography variant="body2">کد خودرویی وجود ندارد</Typography>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "rahdaran",
|
||||
@@ -134,6 +229,8 @@ const OperatorList = () => {
|
||||
enableColumnFilter: false,
|
||||
enableSorting: false,
|
||||
datatype: "array",
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
@@ -162,6 +259,8 @@ const OperatorList = () => {
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
@@ -171,25 +270,53 @@ const OperatorList = () => {
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "status_fa",
|
||||
accessorKey: "status",
|
||||
header: "وضعیت", // Status
|
||||
id: "status_fa",
|
||||
id: "status",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
sortDescFirst: true,
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
columnSelectOption: () => {
|
||||
return statusOptions.map((status) => ({
|
||||
value: status.value,
|
||||
label: status.label,
|
||||
}));
|
||||
},
|
||||
Cell: ({ renderedCellValue, row }) => <>{row.original.status_fa}</>,
|
||||
},
|
||||
{
|
||||
accessorKey: "supervisor_description",
|
||||
header: "توضیحات", // Description
|
||||
header: "توضیحات کارشناس", // Description
|
||||
id: "supervisor_description",
|
||||
enableColumnFilter: false,
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 70,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
py: 0,
|
||||
"&:first-of-type": {
|
||||
borderLeft: "unset",
|
||||
},
|
||||
},
|
||||
},
|
||||
Cell: ({ renderedCellValue }) => {
|
||||
return (
|
||||
<Stack alignItems={"center"} justifyContent={"center"}>
|
||||
<DescriptionForm description={renderedCellValue} />
|
||||
</Stack>
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
@@ -202,7 +329,7 @@ const OperatorList = () => {
|
||||
need_filter={true}
|
||||
columns={columns}
|
||||
sorting={[
|
||||
{ id: "status_fa", desc: true },
|
||||
{ id: "status", desc: true },
|
||||
{ id: "id", desc: true },
|
||||
]}
|
||||
table_url={GET_ROAD_ITEMS_OPERATOR_LIST}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Dialog, DialogContent, DialogTitle, IconButton, Tooltip, Typography, Card, CardContent } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
|
||||
const DescriptionForm = ({ description }) => {
|
||||
const [openOfficerDescriptionDialog, setOpenOfficerDescriptionDialog] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="توضیحات کارشناس">
|
||||
<IconButton color="primary" onClick={() => setOpenOfficerDescriptionDialog(true)}>
|
||||
<RemoveRedEyeIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Dialog
|
||||
open={openOfficerDescriptionDialog}
|
||||
onClose={() => setOpenOfficerDescriptionDialog(false)}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
transition: "all .3s",
|
||||
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
|
||||
borderRadius: 2,
|
||||
padding: 1,
|
||||
},
|
||||
}}
|
||||
maxWidth="sm"
|
||||
fullWidth
|
||||
dir="rtl"
|
||||
>
|
||||
<DialogTitle sx={{ display: "flex", justifyContent: "space-between", padding: "16px 24px" }}>
|
||||
<Typography variant="body1" sx={{ fontWeight: "bold", fontSize: "large" }}>
|
||||
توضیحات کارشناس
|
||||
</Typography>
|
||||
<IconButton onClick={() => setOpenOfficerDescriptionDialog(false)} size="small">
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Card sx={{ padding: 2, boxShadow: 3, borderRadius: 2 }}>
|
||||
<CardContent>
|
||||
<Typography variant="body2">{description || "هیچ توضیحی موجود نیست"} </Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DescriptionForm;
|
||||
@@ -0,0 +1,29 @@
|
||||
import { LinearProgress, Typography } from "@mui/material";
|
||||
import EditFormContent from "./EditFormContent";
|
||||
import useRoadItemGetISubtems from "@/lib/hooks/useRoadItemGetISubtems";
|
||||
|
||||
const EditController = ({ rowId, mutate, setOpenEditDialog, row }) => {
|
||||
const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetISubtems(row.original?.item);
|
||||
const subItem = subItemsList.find((SubItem) => SubItem.sub_item === row.original?.sub_item);
|
||||
|
||||
return (
|
||||
<>
|
||||
{errorSubItemsList ? (
|
||||
<Typography color={"error"} textAlign={"center"}>
|
||||
خطا در دریافت اطلاعات!!!
|
||||
</Typography>
|
||||
) : loadingSubItemsList ? (
|
||||
<LinearProgress />
|
||||
) : (
|
||||
<EditFormContent
|
||||
subItem={subItem}
|
||||
rowId={rowId}
|
||||
row={row}
|
||||
mutate={mutate}
|
||||
setOpenEditDialog={setOpenEditDialog}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default EditController;
|
||||
@@ -12,10 +12,11 @@ import { UPDATE_ROAD_ITEMS } from "@/core/utils/routes";
|
||||
import CarCode from "@/core/components/CarCode";
|
||||
import RahdarCode from "@/core/components/RahdarCode";
|
||||
import useRoadItemGetISubtems from "@/lib/hooks/useRoadItemGetISubtems";
|
||||
import NumberField from "@/core/components/NumberField";
|
||||
|
||||
const validationSchema = object({
|
||||
amount: string().required("وارد کردن مقدار الزامیست!"),
|
||||
cmms_machine_id: object().required("وارد کردن کد خودرو الزامیست!"),
|
||||
cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"),
|
||||
rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"),
|
||||
before_image: mixed()
|
||||
.nullable()
|
||||
@@ -59,7 +60,7 @@ const EditFormContent = ({ row, mutate, setOpenEditDialog, rowId, subItem }) =>
|
||||
amount: row.original.sub_item_data || null,
|
||||
start_point: { lat: row.original.start_lat || "", lng: row.original.start_lng || "" },
|
||||
end_point: { lat: row.original.end_lat || "", lng: row.original.end_lng || "" },
|
||||
cmms_machine_id: row.original.cmms_machine,
|
||||
cmms_machines: row.original.cmms_machines || null,
|
||||
rahdaran_id: row.original.rahdaran || null,
|
||||
};
|
||||
const requestServer = useRequest();
|
||||
@@ -91,12 +92,12 @@ const EditFormContent = ({ row, mutate, setOpenEditDialog, rowId, subItem }) =>
|
||||
data.after_image !== defaultValues.after_image &&
|
||||
formData.append("after_image", data.after_image);
|
||||
formData.append("amount", data.amount);
|
||||
formData.append("cmms_machine_id", data.cmms_machine_id.id);
|
||||
data.cmms_machines.map((machine, index) => formData.append(`machines_id[${index}]`, machine.id));
|
||||
data.rahdaran_id.map((rahdar, index) => formData.append(`rahdaran_id[${index}]`, rahdar.id));
|
||||
formData.append("start_point", startPoint);
|
||||
subItem.needs_end_point === 1 && formData.append("end_point", endPoint);
|
||||
|
||||
requestServer(`${UPDATE_ROAD_ITEMS}/${rowId}`, "post", {
|
||||
await requestServer(`${UPDATE_ROAD_ITEMS}/${rowId}`, "post", {
|
||||
notificationSuccess: true,
|
||||
data: formData,
|
||||
})
|
||||
@@ -104,8 +105,9 @@ const EditFormContent = ({ row, mutate, setOpenEditDialog, rowId, subItem }) =>
|
||||
mutate();
|
||||
setOpenEditDialog(false);
|
||||
})
|
||||
.catch((err) => { });
|
||||
.catch((err) => {});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||
@@ -124,11 +126,14 @@ const EditFormContent = ({ row, mutate, setOpenEditDialog, rowId, subItem }) =>
|
||||
) : null}
|
||||
</Stack>
|
||||
<Stack>
|
||||
<TextField
|
||||
<NumberField
|
||||
{...register("amount")}
|
||||
label={`مقدار (${row.original.unit_fa})`}
|
||||
label={`مقدار (${subItem.unit})`}
|
||||
error={!!errors.amount}
|
||||
value={watch("amount")}
|
||||
type="text"
|
||||
size={"small"}
|
||||
unit={subItem.unit}
|
||||
inputProps={{
|
||||
inputMode: "number",
|
||||
min: 0,
|
||||
@@ -141,7 +146,6 @@ const EditFormContent = ({ row, mutate, setOpenEditDialog, rowId, subItem }) =>
|
||||
setValue("amount", watch("amount"));
|
||||
}
|
||||
}}
|
||||
error={!!errors.amount}
|
||||
helperText={errors.amount ? errors.amount.message : null}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
@@ -153,14 +157,15 @@ const EditFormContent = ({ row, mutate, setOpenEditDialog, rowId, subItem }) =>
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<CarCode
|
||||
carCode={field.value || null}
|
||||
setCarCode={(value) => field.onChange(value || "")}
|
||||
inputValueDefault={row.original.cmms_machine_code}
|
||||
carCode={field.value || []}
|
||||
setCarCode={(value) => field.onChange(value || [])}
|
||||
inputValueDefault={row.original.cmms_machines}
|
||||
multiple={true}
|
||||
error={error} // اگر خطا وجود داشته باشد
|
||||
/>
|
||||
);
|
||||
}}
|
||||
name={"cmms_machine_id"}
|
||||
name={"cmms_machines"}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { Dialog, DialogTitle, IconButton, LinearProgress, Tooltip, Typography } from "@mui/material";
|
||||
import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import BorderColorIcon from "@mui/icons-material/BorderColor";
|
||||
import EditFormContent from "@/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent";
|
||||
import useRoadItemGetISubtems from "@/lib/hooks/useRoadItemGetISubtems";
|
||||
import EditController from "./EditController";
|
||||
|
||||
const EditForm = ({ row, mutate, rowId }) => {
|
||||
const [openEditDialog, setOpenEditDialog] = useState(false);
|
||||
const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetISubtems(row.original?.item);
|
||||
const subItem = subItemsList.find((subItem) => subItem.sub_item === row.original?.sub_item);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="ویرایش اطلاعات" arrow placement="right">
|
||||
@@ -32,21 +30,7 @@ const EditForm = ({ row, mutate, rowId }) => {
|
||||
}}
|
||||
>
|
||||
<DialogTitle>ویرایش اطلاعات</DialogTitle>
|
||||
{errorSubItemsList ? (
|
||||
<Typography color={"error"} textAlign={"center"}>
|
||||
خطا در دریافت اطلاعات!!!
|
||||
</Typography>
|
||||
) : loadingSubItemsList ? (
|
||||
<LinearProgress />
|
||||
) : (
|
||||
<EditFormContent
|
||||
subItem={subItem}
|
||||
rowId={rowId}
|
||||
row={row}
|
||||
mutate={mutate}
|
||||
setOpenEditDialog={setOpenEditDialog}
|
||||
/>
|
||||
)}
|
||||
<EditController setOpenEditDialog={setOpenEditDialog} rowId={rowId} row={row} mutate={mutate} />
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { DialogContent, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material";
|
||||
import ShowPlak from "@/core/components/ShowPlak";
|
||||
|
||||
const MachinesCodeContent = ({ machinesLists }) => {
|
||||
return (
|
||||
<>
|
||||
<DialogContent>
|
||||
<Paper
|
||||
elevation={0}
|
||||
sx={{
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
"*::-webkit-scrollbar": {
|
||||
width: "0.5em",
|
||||
},
|
||||
"*::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: "primary.main",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<TableContainer sx={{ maxHeight: 600 }}>
|
||||
<Table stickyHeader sx={{ minWidth: 800 }}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>کد ماشین</TableCell>
|
||||
<TableCell>نام خودرو</TableCell>
|
||||
<TableCell>پلاک</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{machinesLists.map((machine) => {
|
||||
return (
|
||||
<TableRow
|
||||
key={machine.id}
|
||||
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
|
||||
>
|
||||
<TableCell>{machine.machine_code}</TableCell>
|
||||
<TableCell>{machine.car_name}</TableCell>
|
||||
<TableCell>
|
||||
{machine.plak_number ? (
|
||||
<ShowPlak plak_number={machine.plak_number} />
|
||||
) : null}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Paper>
|
||||
</DialogContent>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default MachinesCodeContent;
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
|
||||
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
|
||||
import { useState } from "react";
|
||||
import MachinesCodeContent from "./MachinesCodeContent";
|
||||
|
||||
const MachinesCodeDialog = ({ machinesLists }) => {
|
||||
const [openMachinesCodeDialog, setOpenMachinesCodeDialog] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="کد خودرو">
|
||||
<IconButton color="primary" onClick={() => setOpenMachinesCodeDialog(true)}>
|
||||
<DirectionsCarIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Dialog
|
||||
fullWidth
|
||||
open={openMachinesCodeDialog}
|
||||
onClose={() => setOpenMachinesCodeDialog(false)}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
|
||||
},
|
||||
}}
|
||||
dir="rtl"
|
||||
maxWidth={"md"}
|
||||
>
|
||||
<DialogTitle sx={{ fontSize: "large" }}>کد خودرو</DialogTitle>
|
||||
<MachinesCodeContent machinesLists={machinesLists} />
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => setOpenMachinesCodeDialog(false)}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
autoFocus
|
||||
>
|
||||
بستن
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default MachinesCodeDialog;
|
||||
@@ -28,7 +28,7 @@ const ConfirmContent = ({ rowId, mutate, setOpenConfirmDialog }) => {
|
||||
mutate();
|
||||
setOpenConfirmDialog(false);
|
||||
})
|
||||
.catch(() => { });
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { DialogContent, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material";
|
||||
import ShowPlak from "@/core/components/ShowPlak";
|
||||
|
||||
const MachinesCodeContent = ({ machinesLists }) => {
|
||||
return (
|
||||
<>
|
||||
<DialogContent>
|
||||
<Paper
|
||||
elevation={0}
|
||||
sx={{
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
"*::-webkit-scrollbar": {
|
||||
width: "0.5em",
|
||||
},
|
||||
"*::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: "primary.main",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<TableContainer sx={{ maxHeight: 600 }}>
|
||||
<Table stickyHeader sx={{ minWidth: 800 }}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>کد ماشین</TableCell>
|
||||
<TableCell>نام خودرو</TableCell>
|
||||
<TableCell>پلاک</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{machinesLists.map((machine) => {
|
||||
return (
|
||||
<TableRow
|
||||
key={machine.id}
|
||||
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
|
||||
>
|
||||
<TableCell>{machine.machine_code}</TableCell>
|
||||
<TableCell>{machine.car_name}</TableCell>
|
||||
<TableCell>
|
||||
{machine.plak_number ? (
|
||||
<ShowPlak plak_number={machine.plak_number} />
|
||||
) : null}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Paper>
|
||||
</DialogContent>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default MachinesCodeContent;
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
|
||||
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
|
||||
import { useState } from "react";
|
||||
import MachinesCodeContent from "./MachinesCodeContent";
|
||||
|
||||
const MachinesCodeDialog = ({ machinesLists }) => {
|
||||
const [openMachinesCodeDialog, setOpenMachinesCodeDialog] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="کد خودرو">
|
||||
<IconButton color="primary" onClick={() => setOpenMachinesCodeDialog(true)}>
|
||||
<DirectionsCarIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Dialog
|
||||
fullWidth
|
||||
open={openMachinesCodeDialog}
|
||||
onClose={() => setOpenMachinesCodeDialog(false)}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
|
||||
},
|
||||
}}
|
||||
dir="rtl"
|
||||
maxWidth={"md"}
|
||||
>
|
||||
<DialogTitle sx={{ fontSize: "large" }}>کد خودرو</DialogTitle>
|
||||
<MachinesCodeContent machinesLists={machinesLists} />
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => setOpenMachinesCodeDialog(false)}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
autoFocus
|
||||
>
|
||||
بستن
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default MachinesCodeDialog;
|
||||
@@ -36,7 +36,7 @@ const RejectContent = ({ rowId, mutate, setOpenRejectDialog }) => {
|
||||
mutate();
|
||||
setOpenRejectDialog(false);
|
||||
})
|
||||
.catch(() => { })
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
reset();
|
||||
});
|
||||
|
||||
@@ -8,8 +8,19 @@ import RowActions from "./RowActions";
|
||||
import LocationForm from "./RowActions/LocationForm";
|
||||
import ImageDialog from "./RowActions/ImageForm";
|
||||
import RahdaranDialog from "./RowActions/RahdaranForm";
|
||||
import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency";
|
||||
import useProvinces from "@/lib/hooks/useProvince";
|
||||
import useRoadItemGetItems from "@/lib/hooks/useRoadItemGetItems";
|
||||
import useRoadItemGetSubItems from "@/lib/hooks/useRoadItemGetISubtems";
|
||||
import useEdaratLists from "@/lib/hooks/useEdaratLists";
|
||||
import MachinesCodeDialog from "./RowActions/MachinesCodeForm";
|
||||
|
||||
const SupervisorList = () => {
|
||||
const statusOptions = [
|
||||
{ value: 0, label: "درحال بررسی" },
|
||||
{ value: 1, label: "تایید" },
|
||||
{ value: 2, label: "عدم تایید" },
|
||||
];
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -21,42 +32,141 @@ const SupervisorList = () => {
|
||||
filterMode: "equals",
|
||||
sortDescFirst: false,
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "province_fa",
|
||||
accessorKey: "province_id",
|
||||
header: "استان", // Province
|
||||
id: "province_fa",
|
||||
id: "province_id",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 130,
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
|
||||
const getColumnSelectOptions = () => {
|
||||
if (loadingProvinces) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorProvinces) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...provinces.map((province) => ({
|
||||
value: province.id,
|
||||
label: province.name_fa,
|
||||
})),
|
||||
];
|
||||
};
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
Cell: ({ renderedCellValue, row }) => <>{row.original.province_fa}</>,
|
||||
},
|
||||
{
|
||||
accessorKey: "edarat_name",
|
||||
accessorKey: "edarat_id",
|
||||
header: "اداره", // Office
|
||||
id: "edarat_name",
|
||||
id: "edarat_id",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
dependencyId: "province_id",
|
||||
grow: false,
|
||||
size: 120,
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { edaratList, loadingEdaratList, errorEdaratList } = useEdaratLists(
|
||||
props.dependencyFieldValue.value
|
||||
);
|
||||
|
||||
const getColumnSelectOptions = () => {
|
||||
if (props.dependencyFieldValue.value === "") {
|
||||
return [{ value: "empty", label: "ابتدا استان را انتخاب کنید" }];
|
||||
}
|
||||
if (loadingEdaratList) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorEdaratList) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...edaratList.map((edare) => ({
|
||||
value: edare.id,
|
||||
label: edare.name_fa,
|
||||
})),
|
||||
];
|
||||
};
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
Cell: ({ renderedCellValue, row }) => <>{row.original.edarat_name}</>,
|
||||
},
|
||||
{
|
||||
accessorKey: "item_fa",
|
||||
header: "آیتم فعالیت",
|
||||
id: "item_fa",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { itemsList, loadingItemsList, errorItemsList } = useRoadItemGetItems();
|
||||
const getColumnSelectOptions = () => {
|
||||
if (loadingItemsList) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorItemsList) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...itemsList.map((item) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
})),
|
||||
];
|
||||
};
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "sub_item_fa",
|
||||
header: "موضوع مشاهده شده", // Observed Subject
|
||||
header: "موضوع مشاهده شده",
|
||||
id: "sub_item_fa",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
dependencyId: "item_fa",
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetSubItems(
|
||||
props.dependencyFieldValue.value
|
||||
);
|
||||
const getColumnSelectOptions = () => {
|
||||
if (props.dependencyFieldValue.value === "") {
|
||||
return [{ value: "empty", label: "ابتدا آیتم فعالیت را انتخاب کنید" }];
|
||||
}
|
||||
if (loadingSubItemsList) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorSubItemsList) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...subItemsList.map((item) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
})),
|
||||
];
|
||||
};
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "value",
|
||||
@@ -65,12 +175,18 @@ const SupervisorList = () => {
|
||||
enableColumnFilter: false,
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
grow: false,
|
||||
size: 120,
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
Cell: ({ renderedCellValue, row }) => {
|
||||
return (
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Typography variant="body2">{row.original.sub_item_data}</Typography>
|
||||
<Typography variant="body2">{`(${row.original.unit_fa})`}</Typography>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<Typography sx={{ margin: 1 }} component="span">
|
||||
{(row.original.sub_item_data / 1).toLocaleString()}
|
||||
</Typography>
|
||||
<Typography component="span" variant="caption">
|
||||
{`(${row.original.unit_fa})`}
|
||||
</Typography>
|
||||
</Stack>
|
||||
);
|
||||
},
|
||||
@@ -82,6 +198,8 @@ const SupervisorList = () => {
|
||||
enableColumnFilter: false,
|
||||
enableSorting: false,
|
||||
datatype: "array",
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
@@ -113,6 +231,8 @@ const SupervisorList = () => {
|
||||
enableColumnFilter: false,
|
||||
enableSorting: false,
|
||||
datatype: "array",
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
@@ -136,14 +256,35 @@ const SupervisorList = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "cmms_machine_code",
|
||||
accessorKey: "cmms_machines",
|
||||
header: "کد خودرو", // Car ID
|
||||
id: "cmms_machine_code",
|
||||
id: "cmmsMachines__machine_code",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
filterMode: "contains",
|
||||
enableSorting: false,
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
py: 0,
|
||||
"&:first-of-type": {
|
||||
borderLeft: "unset",
|
||||
},
|
||||
},
|
||||
},
|
||||
Cell: ({ renderedCellValue }) => {
|
||||
if (renderedCellValue) {
|
||||
return (
|
||||
<Stack alignItems={"center"} justifyContent={"center"}>
|
||||
<MachinesCodeDialog machinesLists={renderedCellValue} />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
return <Typography variant="body2">کد خودرویی وجود ندارد</Typography>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "rahdaran",
|
||||
@@ -152,6 +293,8 @@ const SupervisorList = () => {
|
||||
enableColumnFilter: false,
|
||||
enableSorting: false,
|
||||
datatype: "array",
|
||||
grow: false,
|
||||
size: 100,
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
@@ -180,6 +323,8 @@ const SupervisorList = () => {
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
@@ -189,25 +334,26 @@ const SupervisorList = () => {
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "status_fa",
|
||||
accessorKey: "status",
|
||||
header: "وضعیت", // Status
|
||||
id: "status_fa",
|
||||
id: "status",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
sortDescFirst: true,
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
},
|
||||
{
|
||||
accessorKey: "supervisor_description",
|
||||
header: "توضیحات", // Description
|
||||
id: "supervisor_description",
|
||||
enableColumnFilter: false,
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
columnSelectOption: () => {
|
||||
return statusOptions.map((status) => ({
|
||||
value: status.value,
|
||||
label: status.label,
|
||||
}));
|
||||
},
|
||||
Cell: ({ renderedCellValue, row }) => <>{row.original.status_fa}</>,
|
||||
},
|
||||
],
|
||||
[]
|
||||
@@ -220,7 +366,7 @@ const SupervisorList = () => {
|
||||
need_filter={true}
|
||||
columns={columns}
|
||||
sorting={[
|
||||
{ id: "status_fa", desc: false },
|
||||
{ id: "status", desc: false },
|
||||
{ id: "id", desc: true },
|
||||
]}
|
||||
table_url={GET_ROAD_ITEMS_SUPERVISOR_LIST}
|
||||
|
||||
@@ -18,6 +18,8 @@ const OperatorList = () => {
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "operator_name",
|
||||
@@ -29,9 +31,9 @@ const OperatorList = () => {
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
},
|
||||
{
|
||||
accessorKey: "phone_number",
|
||||
accessorKey: "officer_phone_number",
|
||||
header: "تلفن همراه",
|
||||
id: "phone_number",
|
||||
id: "officer_phone_number",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
@@ -47,46 +49,37 @@ const OperatorList = () => {
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
},
|
||||
{
|
||||
accessorKey: "start_date",
|
||||
accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
header: "تاریخ شروع",
|
||||
id: "start_date",
|
||||
enableColumnFilter: true,
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "end_date",
|
||||
accessorFn: (row) => moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
header: "تاریخ پایان",
|
||||
id: "end_date",
|
||||
enableColumnFilter: true,
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "register_date",
|
||||
accessorFn: (row) => moment(row.register_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
header: "تاریخ ثبت",
|
||||
id: "register_date",
|
||||
enableColumnFilter: true,
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
],
|
||||
[]
|
||||
@@ -99,6 +92,7 @@ const OperatorList = () => {
|
||||
table_title={"عملیات"}
|
||||
need_filter={true}
|
||||
columns={columns}
|
||||
sorting={[{ id: "id", desc: true }]}
|
||||
table_url={GET_ROAD_PATROL_OPERATOR_LIST}
|
||||
page_name={"operator"}
|
||||
table_name={"operatorList"}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Tooltip, IconButton } from "@mui/material";
|
||||
import PrintIcon from "@mui/icons-material/Print";
|
||||
|
||||
const ReportForm = ({ rowId }) => {
|
||||
const reportUrl = "https://rms.rmto.ir/v2/road_patrols/operator/report/97314"; // TODO replace id here
|
||||
const reportUrl = "https://rms.rmto.ir/v2/road_patrols/operator/report/96872"; // TODO replace id here
|
||||
|
||||
return (
|
||||
<Tooltip title="گزارش" arrow placement="right">
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Tooltip, IconButton } from "@mui/material";
|
||||
import PrintIcon from "@mui/icons-material/Print";
|
||||
|
||||
const ReportForm = ({ rowId }) => {
|
||||
const reportUrl = "https://rms.rmto.ir/v2/road_patrols/operator/report/541938"; // TODO replace id here
|
||||
const reportUrl = "https://rms.rmto.ir/v2/road_patrols/operator/report/96872"; // TODO replace id here
|
||||
|
||||
return (
|
||||
<Tooltip title="گزارش" arrow placement="right">
|
||||
|
||||
@@ -7,10 +7,11 @@ import { GET_ROAD_PATROL_SUPERVISOR_LIST } from "@/core/utils/routes";
|
||||
import moment from "jalali-moment";
|
||||
import RowActions from "./RowActions";
|
||||
import useProvinces from "@/lib/hooks/useProvince";
|
||||
import useRoadItemGetItems from "@/lib/hooks/useRoadItemGetItems";
|
||||
import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency";
|
||||
import useEdaratLists from "@/lib/hooks/useEdaratLists";
|
||||
|
||||
const OperatorList = () => {
|
||||
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
|
||||
const citiesListApi = "https://rms.rmto.ir/public/contents/edarate_shahri_by_province";
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -21,44 +22,74 @@ const OperatorList = () => {
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "province",
|
||||
accessorKey: "province_id",
|
||||
header: "استان",
|
||||
id: "province",
|
||||
id: "province_id",
|
||||
enableColumnFilter: true,
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
columnSelectOption: () => {
|
||||
if (loadingProvinces) {
|
||||
return [{ value: "", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
|
||||
if (errorProvinces) {
|
||||
return [{ value: "", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
|
||||
return provinces.map((province) => ({
|
||||
value: province.id,
|
||||
label: province.name_fa,
|
||||
}));
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
|
||||
const getColumnSelectOptions = () => {
|
||||
if (loadingProvinces) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorProvinces) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...provinces.map((province) => ({
|
||||
value: province.id,
|
||||
label: province.name_fa,
|
||||
})),
|
||||
];
|
||||
};
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
Cell: ({ renderedCellValue, row }) => <>{row.original.province_fa}</>,
|
||||
},
|
||||
{
|
||||
accessorKey: "office",
|
||||
accessorKey: "edare_id",
|
||||
header: "اداره",
|
||||
id: "office",
|
||||
id: "edare_id",
|
||||
enableColumnFilter: true,
|
||||
datatype: "numeric",
|
||||
filterMode: "equals",
|
||||
dependencyId: "province",
|
||||
columnSelectOption: (dependencyField) => {
|
||||
if (dependencyField.value === "") {
|
||||
return [{ value: "", label: "ابتدا استان را انتخاب کنید" }];
|
||||
}
|
||||
|
||||
return [{ value: dependencyField.value, label: dependencyField.value }];
|
||||
dependencyId: "province_id",
|
||||
grow: false,
|
||||
size: 120,
|
||||
ColumnSelectComponent: (props) => {
|
||||
const { edaratList, loadingEdaratList, errorEdaratList } = useEdaratLists(
|
||||
props.dependencyFieldValue.value
|
||||
);
|
||||
const getColumnSelectOptions = () => {
|
||||
if (props.dependencyFieldValue.value === "") {
|
||||
return [{ value: "empty", label: "ابتدا استان را انتخاب کنید" }];
|
||||
}
|
||||
if (loadingEdaratList) {
|
||||
return [{ value: "loading", label: "در حال بارگذاری..." }];
|
||||
}
|
||||
if (errorEdaratList) {
|
||||
return [{ value: "error", label: "خطا در بارگذاری" }];
|
||||
}
|
||||
return [
|
||||
{ value: "", label: props.column.header },
|
||||
...edaratList.map((edare) => ({
|
||||
value: edare.id,
|
||||
label: edare.name_fa,
|
||||
})),
|
||||
];
|
||||
};
|
||||
const columnSelectOption = getColumnSelectOptions();
|
||||
return <CustomSelectByDependency {...props} columnSelectOption={columnSelectOption} />;
|
||||
},
|
||||
Cell: ({ renderedCellValue, row }) => <>{row.original.edare_name}</>,
|
||||
},
|
||||
{
|
||||
accessorKey: "operator_name",
|
||||
@@ -70,9 +101,9 @@ const OperatorList = () => {
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
},
|
||||
{
|
||||
accessorKey: "phone_number",
|
||||
accessorKey: "officer_phone_number",
|
||||
header: "تلفن همراه",
|
||||
id: "phone_number",
|
||||
id: "officer_phone_number",
|
||||
enableColumnFilter: true,
|
||||
datatype: "text",
|
||||
filterMode: "equals",
|
||||
@@ -88,49 +119,40 @@ const OperatorList = () => {
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
},
|
||||
{
|
||||
accessorKey: "start_date",
|
||||
accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
header: "تاریخ شروع",
|
||||
id: "start_date",
|
||||
enableColumnFilter: true,
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "end_date",
|
||||
accessorFn: (row) => moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
header: "تاریخ پایان",
|
||||
id: "end_date",
|
||||
enableColumnFilter: true,
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
accessorKey: "register_date",
|
||||
accessorFn: (row) => moment(row.register_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
|
||||
header: "تاریخ ثبت",
|
||||
id: "register_date",
|
||||
enableColumnFilter: true,
|
||||
datatype: "date",
|
||||
filterMode: "equals",
|
||||
columnFilterModeOptions: ["equals", "contains"],
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
grow: false,
|
||||
size: 100,
|
||||
},
|
||||
],
|
||||
[provinces]
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -140,6 +162,7 @@ const OperatorList = () => {
|
||||
table_title={"ارزیابی"}
|
||||
need_filter={true}
|
||||
columns={columns}
|
||||
sorting={[{ id: "id", desc: true }]}
|
||||
table_url={GET_ROAD_PATROL_SUPERVISOR_LIST}
|
||||
page_name={"supervisor"}
|
||||
table_name={"supervisorList"}
|
||||
|
||||
@@ -4,11 +4,12 @@ import useRequest from "@/lib/hooks/useRequest";
|
||||
import { debounce } from "@mui/material/utils";
|
||||
import { GET_CAR_LIST_SEARCH } from "@/core/utils/routes";
|
||||
|
||||
const CarCode = ({ carCode, setCarCode, inputValueDefault = "", error }) => {
|
||||
const CarCode = ({ carCode, setCarCode, inputValueDefault = "", error, multiple = false }) => {
|
||||
const [inputValue, setInputValue] = useState(inputValueDefault);
|
||||
const [options, setOptions] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const requestServer = useRequest();
|
||||
|
||||
const fetchCarCodes = (inputValue, controller) => {
|
||||
const debouncer = debounce((query) => {
|
||||
if (!query || query?.length < 3) {
|
||||
@@ -40,20 +41,32 @@ const CarCode = ({ carCode, setCarCode, inputValueDefault = "", error }) => {
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
multiple={multiple}
|
||||
value={carCode}
|
||||
size="small"
|
||||
onChange={(event, newValue) => {
|
||||
setCarCode(newValue || null); // Set an empty string if no value is selected
|
||||
setCarCode(multiple ? newValue || [] : newValue || null);
|
||||
}}
|
||||
inputValue={inputValue}
|
||||
onInputChange={(event, newInputValue) => {
|
||||
setInputValue(newInputValue || ""); // Prevent inputValue from being null or undefined
|
||||
}}
|
||||
options={options}
|
||||
getOptionLabel={(option) => (typeof option === "string" ? option : option.machine_code)}
|
||||
getOptionLabel={(option) => {
|
||||
if (typeof option === "string") return option;
|
||||
const { machine_code, car_name, plak_number } = option;
|
||||
let label = `${machine_code || ""}`;
|
||||
if (car_name) {
|
||||
label += ` | ${car_name}`;
|
||||
}
|
||||
if (plak_number) {
|
||||
label += ` | ${plak_number}`;
|
||||
}
|
||||
return label;
|
||||
}}
|
||||
isOptionEqualToValue={(option, value) => {
|
||||
if (!value) return false; // Handle null/undefined values
|
||||
if (value === "") return option.machine_code === ""; // Handle empty string case
|
||||
if (!value) return false;
|
||||
if (value === "") return option.machine_code === "";
|
||||
return option.machine_code === (value?.machine_code || value);
|
||||
}}
|
||||
loading={loading}
|
||||
@@ -65,8 +78,8 @@ const CarCode = ({ carCode, setCarCode, inputValueDefault = "", error }) => {
|
||||
{...params}
|
||||
label="کد خودرو"
|
||||
fullWidth
|
||||
error={!!error} // نمایش خطا
|
||||
helperText={error?.message} // پیام خطا
|
||||
error={!!error}
|
||||
helperText={error?.message}
|
||||
InputProps={{
|
||||
...params.InputProps,
|
||||
endAdornment: (
|
||||
|
||||
@@ -44,7 +44,7 @@ const DataTable_Main = (props) => {
|
||||
.filter((filter) => !isValueEmpty(filter.value))
|
||||
.map(({ filterMode, id, ...rest }) => ({
|
||||
...rest,
|
||||
id: id.replace(/__/g, '.'),
|
||||
id: id.replace(/__/g, "."),
|
||||
fn: filterMode,
|
||||
}));
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Controller, useWatch } from "react-hook-form";
|
||||
import FilterBodyField from "./FilterBodyField";
|
||||
|
||||
const FilterBodyController = ({ column, control, reset, errors }) => {
|
||||
const dependencyField = useWatch({ control, name: column?.dependencyId });
|
||||
const dependencyField = useWatch({ control, name: column.dependencyId });
|
||||
|
||||
return (
|
||||
<Controller
|
||||
@@ -14,7 +14,7 @@ const FilterBodyController = ({ column, control, reset, errors }) => {
|
||||
filterParameters={value}
|
||||
handleChange={onChange}
|
||||
handleBlur={onBlur}
|
||||
dependencyFieldValue={dependencyField || null}
|
||||
dependencyFieldValue={column.dependencyId ? dependencyField : null}
|
||||
resetForm={() => reset()}
|
||||
errors={errors}
|
||||
/>
|
||||
|
||||
@@ -54,10 +54,13 @@ function FilterBodyField({
|
||||
return <CustomTextFieldRange {...commonProps} />;
|
||||
}
|
||||
if (filterParameters.filterMode === "equals") {
|
||||
return <CustomSelect {...commonProps} />;
|
||||
return column.ColumnSelectComponent ? (
|
||||
<column.ColumnSelectComponent {...commonProps} />
|
||||
) : (
|
||||
<CustomSelect {...commonProps} />
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case "date":
|
||||
if (filterParameters.filterMode === "equals") {
|
||||
return <CustomDatePicker {...commonProps} />;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
"use client";
|
||||
|
||||
import { FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography } from "@mui/material";
|
||||
import { useCallback, useEffect } from "react";
|
||||
|
||||
function CustomSelectByDependency({
|
||||
column,
|
||||
filterParameters,
|
||||
defaultFilterTranslation,
|
||||
handleChange,
|
||||
columnSelectOption,
|
||||
}) {
|
||||
const isValidValue = columnSelectOption.some((option) => option.value === filterParameters.value);
|
||||
|
||||
const handleInvalidValue = useCallback(() => {
|
||||
if (!isValidValue && filterParameters.value !== "") {
|
||||
handleChange({ ...filterParameters, value: columnSelectOption[0]?.value || "" });
|
||||
}
|
||||
}, [isValidValue, filterParameters, handleChange, columnSelectOption]);
|
||||
|
||||
useEffect(() => {
|
||||
handleInvalidValue();
|
||||
}, [handleInvalidValue]);
|
||||
|
||||
const selectedValue = isValidValue ? filterParameters.value : columnSelectOption[0]?.value || "";
|
||||
|
||||
return (
|
||||
<FormControl fullWidth sx={{ marginY: 1 }}>
|
||||
<InputLabel id={`label${column.id}`}>{column.header}</InputLabel>
|
||||
<Select
|
||||
labelId={`label${column.id}`}
|
||||
id={column.id}
|
||||
name={`${column.id}.value`}
|
||||
value={selectedValue}
|
||||
input={<OutlinedInput label={column.header} />}
|
||||
onChange={(e) => handleChange({ ...filterParameters, value: e.target.value })}
|
||||
>
|
||||
{columnSelectOption.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<FormHelperText>
|
||||
<Typography variant="button" sx={{ color: "#155175" }}>
|
||||
نوع فیلتر: {defaultFilterTranslation}
|
||||
</Typography>
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomSelectByDependency;
|
||||
@@ -9,14 +9,16 @@ function FilterColumn({ columns, user_id, page_name, table_name }) {
|
||||
return (
|
||||
<>
|
||||
<FilterButton drawerState={open} setDrawerState={setOpen} />
|
||||
<FilterBody
|
||||
columns={columns}
|
||||
drawerState={open}
|
||||
setDrawerState={setOpen}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
/>
|
||||
{open && (
|
||||
<FilterBody
|
||||
columns={columns}
|
||||
drawerState={open}
|
||||
setDrawerState={setOpen}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import useDataTable from "@/lib/hooks/useDataTable";
|
||||
|
||||
function ResetStorage({ user_id, page_name, table_name }) {
|
||||
const { resetAction } = useTableSetting();
|
||||
const { isDirty } = useDataTable();
|
||||
const { isAnyDirty } = useDataTable();
|
||||
const reset = () => {
|
||||
resetAction(user_id, page_name, table_name);
|
||||
};
|
||||
@@ -14,7 +14,7 @@ function ResetStorage({ user_id, page_name, table_name }) {
|
||||
return (
|
||||
<Tooltip title="بازنشانی اطلاعات">
|
||||
<IconButton onClick={reset} aria-label="reset table data">
|
||||
{isDirty ? (
|
||||
{isAnyDirty ? (
|
||||
<Badge
|
||||
anchorOrigin={{
|
||||
vertical: "top",
|
||||
|
||||
@@ -11,7 +11,7 @@ const InputType = ({ itemInfo, defaultValues, setDefaultValues }) => {
|
||||
};
|
||||
console.log(itemInfo);
|
||||
|
||||
const label = itemInfo.unit ? `${itemInfo.name} (${itemInfo.unit})` : itemInfo.name
|
||||
const label = itemInfo.unit ? `${itemInfo.name} (${itemInfo.unit})` : itemInfo.name;
|
||||
|
||||
return (
|
||||
<FormControl size="small" fullWidth variant="outlined">
|
||||
|
||||
@@ -9,7 +9,7 @@ const SelectType = ({ itemInfo, defaultValues, setDefaultValues }) => {
|
||||
[itemInfo.id]: newValue,
|
||||
}));
|
||||
};
|
||||
const label = itemInfo.unit ? `${itemInfo.name} (${itemInfo.unit})` : itemInfo.name
|
||||
const label = itemInfo.unit ? `${itemInfo.name} (${itemInfo.unit})` : itemInfo.name;
|
||||
return (
|
||||
<FormControl size="small" fullWidth variant="outlined">
|
||||
<InputLabel id={itemInfo.id}>{label}</InputLabel>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
|
||||
import { Marker, useMapEvents } from "react-leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import L from "leaflet";
|
||||
import { Box, Button, Typography } from "@mui/material";
|
||||
import { Alert, Box, Button, Stack, Typography, Zoom } from "@mui/material";
|
||||
import dynamic from "next/dynamic";
|
||||
import MapLoading from "@/core/components/MapLayer/Loading";
|
||||
import HereIcon from "@/assets/images/examine_marker_active.png";
|
||||
@@ -40,9 +40,11 @@ const createCustomIcon = (size, iconUrl, labelText) => {
|
||||
popupAnchor: [0, -size[1]],
|
||||
});
|
||||
};
|
||||
const MAX_ZOOM_FOR_MARKER = 13;
|
||||
|
||||
const MapInteraction = ({ setValue, startLat, startLng }) => {
|
||||
const [isMarkerLocked, setIsMarkerLocked] = useState(!!(startLat && startLng)); // وضعیت قفل مارکر
|
||||
const [enableSend, setEnableSend] = useState(false);
|
||||
const [markerPosition, setMarkerPosition] = useState(
|
||||
startLat && startLng ? { lat: startLat, lng: startLng } : null
|
||||
);
|
||||
@@ -50,11 +52,13 @@ const MapInteraction = ({ setValue, startLat, startLng }) => {
|
||||
|
||||
const map = useMapEvents({
|
||||
move(e) {
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
|
||||
if (!isMarkerLocked && markerRef.current) {
|
||||
markerRef.current.setLatLng(e.target.getCenter());
|
||||
}
|
||||
},
|
||||
zoom(e) {
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
|
||||
if (!isMarkerLocked && markerRef.current) {
|
||||
markerRef.current.setLatLng(e.target.getCenter());
|
||||
}
|
||||
@@ -69,6 +73,7 @@ const MapInteraction = ({ setValue, startLat, startLng }) => {
|
||||
}, [startLat, startLng, map]);
|
||||
|
||||
const handleMarkerClick = () => {
|
||||
if (!enableSend) return;
|
||||
if (!isMarkerLocked) {
|
||||
const center = map.getCenter();
|
||||
setValue("start_point", { lat: center.lat.toString(), lng: center.lng.toString() });
|
||||
@@ -93,6 +98,23 @@ const MapInteraction = ({ setValue, startLat, startLng }) => {
|
||||
click: handleMarkerClick,
|
||||
}}
|
||||
/>
|
||||
<Stack
|
||||
direction={"row"}
|
||||
justifyContent={"center"}
|
||||
sx={{
|
||||
zIndex: "400",
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
}}
|
||||
>
|
||||
<Zoom in={!enableSend}>
|
||||
<Alert sx={{ mt: 1, py: 0.5, px: 2, borderRadius: 2, border: 1 }} icon={false} color={"warning"}>
|
||||
برای ثبت محل فعالیت، لطفاً نقشه را بیشتر زوم کنید.
|
||||
</Alert>
|
||||
</Zoom>
|
||||
</Stack>
|
||||
{isMarkerLocked && (
|
||||
<Box
|
||||
sx={{
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
|
||||
import { Marker, useMapEvents } from "react-leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import L from "leaflet";
|
||||
import { Box, Button, Typography } from "@mui/material";
|
||||
import { Alert, Box, Button, Stack, Typography, Zoom } from "@mui/material";
|
||||
import dynamic from "next/dynamic";
|
||||
import MapLoading from "@/core/components/MapLayer/Loading";
|
||||
import EndIcon from "@/assets/images/examine_marker_active.png";
|
||||
@@ -40,17 +40,20 @@ const createCustomIcon = (size, iconUrl, labelText) => {
|
||||
popupAnchor: [0, -size[1]],
|
||||
});
|
||||
};
|
||||
const MAX_ZOOM_FOR_MARKER = 13;
|
||||
|
||||
const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => {
|
||||
const [isStartLocked, setIsStartLocked] = useState(!!(startLat && startLng)); // وضعیت قفل نقطه آغاز
|
||||
const [isEndLocked, setIsEndLocked] = useState(!!(endLat && endLng)); // وضعیت قفل نقطه پایان
|
||||
const [startPosition, setStartPosition] = useState(startLat && startLng ? { lat: startLat, lng: startLng } : null);
|
||||
const [endPosition, setEndPosition] = useState(endLat && endLng ? { lat: endLat, lng: endLng } : null);
|
||||
const [enableSend, setEnableSend] = useState(false);
|
||||
const startRef = useRef();
|
||||
const endRef = useRef();
|
||||
|
||||
const map = useMapEvents({
|
||||
move(e) {
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
|
||||
if (!isStartLocked && startRef.current) {
|
||||
startRef.current.setLatLng(e.target.getCenter());
|
||||
} else if (isStartLocked && !isEndLocked && endRef.current) {
|
||||
@@ -58,6 +61,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => {
|
||||
}
|
||||
},
|
||||
zoom(e) {
|
||||
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
|
||||
if (!isStartLocked && startRef.current) {
|
||||
startRef.current.setLatLng(e.target.getCenter());
|
||||
} else if (isStartLocked && !isEndLocked && endRef.current) {
|
||||
@@ -101,6 +105,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => {
|
||||
icon={createCustomIcon([35, 35], StartIcon.src, "نقطه شروع")}
|
||||
eventHandlers={{
|
||||
click: () => {
|
||||
if (!enableSend) return;
|
||||
if (!isStartLocked) {
|
||||
const center = map.getCenter();
|
||||
setValue("start_point", { lat: center.lat.toString(), lng: center.lng.toString() });
|
||||
@@ -110,6 +115,23 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => {
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Stack
|
||||
direction={"row"}
|
||||
justifyContent={"center"}
|
||||
sx={{
|
||||
zIndex: "400",
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
}}
|
||||
>
|
||||
<Zoom in={!enableSend}>
|
||||
<Alert sx={{ mt: 1, py: 0.5, px: 2, borderRadius: 2, border: 1 }} icon={false} color={"warning"}>
|
||||
برای ثبت محل فعالیت، لطفاً نقشه را بیشتر زوم کنید.
|
||||
</Alert>
|
||||
</Zoom>
|
||||
</Stack>
|
||||
{isStartLocked && !isEndLocked && (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -125,21 +147,45 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => {
|
||||
</Box>
|
||||
)}
|
||||
{isStartLocked && (
|
||||
<Marker
|
||||
position={endPosition || map.getCenter()}
|
||||
ref={endRef}
|
||||
icon={createCustomIcon([35, 35], EndIcon.src, "نقطه پایان")}
|
||||
eventHandlers={{
|
||||
click: () => {
|
||||
if (!isEndLocked) {
|
||||
const center = map.getCenter();
|
||||
setValue("end_point", { lat: center.lat.toString(), lng: center.lng.toString() });
|
||||
setEndPosition({ lat: center.lat, lng: center.lng });
|
||||
setIsEndLocked(true);
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<>
|
||||
<Stack
|
||||
direction={"row"}
|
||||
justifyContent={"center"}
|
||||
sx={{
|
||||
zIndex: "400",
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
}}
|
||||
>
|
||||
<Zoom in={!enableSend}>
|
||||
<Alert
|
||||
sx={{ mt: 1, py: 0.5, px: 2, borderRadius: 2, border: 1 }}
|
||||
icon={false}
|
||||
color={"warning"}
|
||||
>
|
||||
برای ثبت محل فعالیت، لطفاً نقشه را بیشتر زوم کنید.
|
||||
</Alert>
|
||||
</Zoom>
|
||||
</Stack>
|
||||
<Marker
|
||||
position={endPosition || map.getCenter()}
|
||||
ref={endRef}
|
||||
icon={createCustomIcon([35, 35], EndIcon.src, "نقطه پایان")}
|
||||
eventHandlers={{
|
||||
click: () => {
|
||||
if (!enableSend) return;
|
||||
if (!isEndLocked) {
|
||||
const center = map.getCenter();
|
||||
setValue("end_point", { lat: center.lat.toString(), lng: center.lng.toString() });
|
||||
setEndPosition({ lat: center.lat, lng: center.lng });
|
||||
setIsEndLocked(true);
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{isEndLocked && (
|
||||
<Box
|
||||
|
||||
29
src/core/components/NumberField.jsx
Normal file
29
src/core/components/NumberField.jsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import LtrTextField from "@/core/components/LtrTextField";
|
||||
import InputAdornment from "@mui/material/InputAdornment";
|
||||
|
||||
const NumberField = React.forwardRef((props, ref) => {
|
||||
return (
|
||||
<LtrTextField
|
||||
{...props}
|
||||
ref={ref}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<Typography sx={{ margin: 1 }} component="span">
|
||||
{(props.value / 1).toLocaleString()}
|
||||
</Typography>
|
||||
<Typography component="span" variant="caption">
|
||||
{props.unit}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
NumberField.displayName = "NumberField";
|
||||
export default NumberField;
|
||||
@@ -5,7 +5,7 @@ import useRequest from "@/lib/hooks/useRequest";
|
||||
import { debounce } from "@mui/material/utils";
|
||||
import { GET_RAHDARANS_LIST_SEARCH } from "@/core/utils/routes";
|
||||
|
||||
const RahdarCode = ({ rahdarsCode, setRahdarsCode, error }) => {
|
||||
const RahdarCode = ({ rahdarsCode, setRahdarsCode, error, multiple = true }) => {
|
||||
const [inputValue, setInputValue] = useState(""); // مدیریت مقدار تایپشده
|
||||
const [options, setOptions] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -42,11 +42,11 @@ const RahdarCode = ({ rahdarsCode, setRahdarsCode, error }) => {
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
multiple // قابلیت انتخاب چندگانه
|
||||
multiple={multiple} // قابلیت انتخاب چندگانه داینامیک
|
||||
value={rahdarsCode} // آرایه موارد انتخابشده
|
||||
size="small"
|
||||
onChange={(event, newValue) => {
|
||||
setRahdarsCode(newValue || []); // بهروزرسانی موارد انتخابشده
|
||||
setRahdarsCode(multiple ? newValue || [] : newValue || null); // مدیریت حالت چندگانه و تکگانه
|
||||
}}
|
||||
inputValue={inputValue} // مقدار تایپشده
|
||||
onInputChange={(event, newInputValue) => {
|
||||
@@ -86,5 +86,4 @@ const RahdarCode = ({ rahdarsCode, setRahdarsCode, error }) => {
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default RahdarCode;
|
||||
|
||||
62
src/core/components/ShowPlak.jsx
Normal file
62
src/core/components/ShowPlak.jsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Stack } from "@mui/material";
|
||||
|
||||
const ShowPlak = ({ plak_number }) => {
|
||||
const processPlak = (plak_number) => {
|
||||
const parts = plak_number.match(/^([\u0600-\u06FF]+)(\d+)-(\d+)([^\d]*)(\d+)$/);
|
||||
if (!parts) return {};
|
||||
|
||||
return {
|
||||
region: parts[1], // "ايران"
|
||||
mainNumber: parts[2], // "13"
|
||||
serial: parts[3], // "189"
|
||||
letter: parts[4], // "الف"
|
||||
number: parts[5], // "15"
|
||||
};
|
||||
};
|
||||
const plakParts = processPlak(plak_number);
|
||||
|
||||
return (
|
||||
<Stack sx={{ border: 1, borderColor: "divider", borderRadius: 1, maxWidth: "150px" }} direction={"row"}>
|
||||
<Stack
|
||||
sx={{
|
||||
borderRight: 1,
|
||||
borderColor: "divider",
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{plakParts.region} {plakParts.mainNumber}
|
||||
</Stack>
|
||||
<Stack spacing={1} direction={"row"} sx={{ width: "100%" }}>
|
||||
<Stack
|
||||
sx={{
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
px: 1,
|
||||
}}
|
||||
>
|
||||
{plakParts.serial}
|
||||
</Stack>
|
||||
<Stack
|
||||
sx={{
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
pl: 1,
|
||||
}}
|
||||
>
|
||||
{plakParts.letter}
|
||||
</Stack>
|
||||
<Stack
|
||||
sx={{
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
px: 1,
|
||||
}}
|
||||
>
|
||||
{plakParts.number}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
export default ShowPlak;
|
||||
@@ -124,13 +124,6 @@ export const pageMenu = [
|
||||
hasSubitems: true,
|
||||
badges: ["road_items.operation_cnt"],
|
||||
Subitems: [
|
||||
{
|
||||
id: "roadItemManagmentOparationCreate",
|
||||
label: "ثبت فعالیت",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/create",
|
||||
permissions: ["create-road-item"],
|
||||
},
|
||||
{
|
||||
id: "roadItemManagmentOparationCartable",
|
||||
label: "کارتابل",
|
||||
@@ -186,7 +179,7 @@ export const pageMenu = [
|
||||
id: "roadPatrolManagmentSupervisorCartable",
|
||||
label: "کارتابل",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/supervisor/cartable",
|
||||
route: "/dashboard/road-patrols/supervisor",
|
||||
permissions: [
|
||||
"show-road-patrol-supervise-cartable",
|
||||
"show-road-patrol-supervise-cartable-province",
|
||||
@@ -206,14 +199,14 @@ export const pageMenu = [
|
||||
id: "roadPatrolManagmentOparationCreate",
|
||||
label: "ثبت اقدام",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create",
|
||||
route: "/dashboard/road-patrols/operator",
|
||||
permissions: ["add-road-patrol"],
|
||||
},
|
||||
{
|
||||
id: "roadPatrolManagmentOparationCartable",
|
||||
label: "کارتابل",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable",
|
||||
route: "/dashboard/road-patrols/operator",
|
||||
permissions: ["add-road-patrol"],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -29,9 +29,9 @@ export const ADD_AZMAYESH_TYPE = api + "/api/v3/azmayesh_types/store";
|
||||
export const UPDATE_AZMAYESH_TYPE = api + "/api/v3/azmayesh_types/update";
|
||||
|
||||
//road patrol
|
||||
export const GET_ROAD_PATROL_OPERATOR_LIST = "/v3/api/fake-road-patrol/operator";
|
||||
export const GET_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator_index";
|
||||
export const EXPORT_ROAD_PATROL_OPERATOR_LIST = "https://rms.rmto.ir/v2/road_patrols/operator/cartable/report";
|
||||
export const GET_ROAD_PATROL_SUPERVISOR_LIST = "/v3/api/fake-road-patrol/supervisor";
|
||||
export const GET_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor_index";
|
||||
export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = "https://rms.rmto.ir/v2/road_patrols/supervisor/cartable/report";
|
||||
|
||||
// road items
|
||||
@@ -41,6 +41,7 @@ export const GET_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator_i
|
||||
export const EXPORT_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator_report";
|
||||
export const GET_ROAD_ITEMS_ITEM = "https://rms.witel.ir/v2/items";
|
||||
export const GET_ROAD_ITEMS_SUB_ITEM = "https://rms.witel.ir/v2/sub_items";
|
||||
export const GET_EDARAT_LISTS = "https://rms.witel.ir/public/contents/edarate_shahri_by_province";
|
||||
export const CREATE_ROAD_ITEMS = api + "/api/v3/road_items/store";
|
||||
export const UPDATE_ROAD_ITEMS = api + "/api/v3/road_items/update";
|
||||
export const VERIFY_BY_SUPERVISOR = api + "/api/v3/road_items/verify_by_supervisor";
|
||||
|
||||
@@ -18,14 +18,23 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns,
|
||||
const [initHide, setInitHide] = useState({});
|
||||
const [hideData, setHideData] = useState({});
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
const [isAnyDirty, setIsAnyDirty] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let hasAnyConflict = false;
|
||||
const hasConflict =
|
||||
JSON.stringify(hideData) !== JSON.stringify(initHide) ||
|
||||
JSON.stringify(sortData) !== JSON.stringify(initSort) ||
|
||||
JSON.stringify(filterData) !== JSON.stringify(initFilter);
|
||||
|
||||
const CheckFilterValues = Object.values(filterData).every((innerObject) => innerObject.value === "");
|
||||
const CheckHideValues = Object.values(hideData).every((value) => value === true);
|
||||
|
||||
hasAnyConflict =
|
||||
!CheckHideValues || JSON.stringify(sortData) !== JSON.stringify(initialSort) || !CheckFilterValues;
|
||||
|
||||
setIsDirty(hasConflict);
|
||||
setIsAnyDirty(hasAnyConflict);
|
||||
}, [hideData, sortData, filterData, initHide, initSort, initFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -136,7 +145,7 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns,
|
||||
|
||||
return (
|
||||
<DataTableContext.Provider
|
||||
value={{ filterData, setFilterData, sortData, setSortData, hideData, setHideData, isDirty }}
|
||||
value={{ filterData, setFilterData, sortData, setSortData, hideData, setHideData, isDirty, isAnyDirty }}
|
||||
>
|
||||
{children}
|
||||
</DataTableContext.Provider>
|
||||
|
||||
@@ -2,9 +2,9 @@ import { useContext } from "react";
|
||||
import { DataTableContext } from "@/lib/contexts/DataTable";
|
||||
|
||||
const useTableSetting = () => {
|
||||
const { filterData, setFilterData, sortData, setSortData, hideData, setHideData, isDirty } =
|
||||
const { filterData, setFilterData, sortData, setSortData, hideData, setHideData, isDirty, isAnyDirty } =
|
||||
useContext(DataTableContext);
|
||||
return { filterData, setFilterData, sortData, setSortData, hideData, setHideData, isDirty };
|
||||
return { filterData, setFilterData, sortData, setSortData, hideData, setHideData, isDirty, isAnyDirty };
|
||||
};
|
||||
|
||||
export default useTableSetting;
|
||||
|
||||
62
src/lib/hooks/useEdaratLists.js
Normal file
62
src/lib/hooks/useEdaratLists.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import { useEffect, useReducer } from "react";
|
||||
import { GET_EDARAT_LISTS } from "@/core/utils/routes";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
|
||||
const ACTIONS = {
|
||||
LOADING: "loading",
|
||||
SUCCESS: "success",
|
||||
ERROR: "error",
|
||||
RESET: "reset",
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
data: [],
|
||||
loading: true,
|
||||
error: null,
|
||||
};
|
||||
|
||||
function reducer(state, action) {
|
||||
switch (action.type) {
|
||||
case ACTIONS.LOADING:
|
||||
return { ...state, loading: true, error: null };
|
||||
case ACTIONS.SUCCESS:
|
||||
return { ...state, loading: false, data: action.payload };
|
||||
case ACTIONS.ERROR:
|
||||
return { ...state, loading: false, error: action.payload };
|
||||
case ACTIONS.RESET:
|
||||
return { ...initialState, loading: false };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
const useEdaratLists = (id) => {
|
||||
const requestServer = useRequest({ notificationShow: false });
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
useEffect(() => {
|
||||
if (!id) {
|
||||
dispatch({ type: ACTIONS.RESET });
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchEdaratLists = async () => {
|
||||
dispatch({ type: ACTIONS.LOADING });
|
||||
try {
|
||||
const response = await requestServer(`${GET_EDARAT_LISTS}/${id}`);
|
||||
dispatch({ type: ACTIONS.SUCCESS, payload: response.data.data });
|
||||
} catch (error) {
|
||||
dispatch({ type: ACTIONS.ERROR, payload: error });
|
||||
}
|
||||
};
|
||||
|
||||
fetchEdaratLists();
|
||||
}, [id]);
|
||||
|
||||
return {
|
||||
edaratList: state.data,
|
||||
loadingEdaratList: state.loading,
|
||||
errorEdaratList: state.error,
|
||||
};
|
||||
};
|
||||
|
||||
export default useEdaratLists;
|
||||
@@ -10,7 +10,7 @@ const defaultOptions = {
|
||||
},
|
||||
notificationShow: true,
|
||||
notificationSuccess: false,
|
||||
notificationFailed: true
|
||||
notificationFailed: true,
|
||||
};
|
||||
|
||||
const useRequest = (initOptions) => {
|
||||
|
||||
@@ -1,29 +1,62 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useReducer } from "react";
|
||||
import { GET_ROAD_ITEMS_SUB_ITEM } from "@/core/utils/routes";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
|
||||
const useRoadItemGetItems = (id) => {
|
||||
const requestServer = useRequest();
|
||||
const [subItemsList, setSubItemsList] = useState([]);
|
||||
const [loadingSubItemsList, setLoadingSubItemsList] = useState(true);
|
||||
const [errorSubItemsList, setErrorSubItemsList] = useState(null);
|
||||
const ACTIONS = {
|
||||
LOADING: "loading",
|
||||
SUCCESS: "success",
|
||||
ERROR: "error",
|
||||
RESET: "reset",
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
data: [],
|
||||
loading: true,
|
||||
error: null,
|
||||
};
|
||||
|
||||
function reducer(state, action) {
|
||||
switch (action.type) {
|
||||
case ACTIONS.LOADING:
|
||||
return { ...state, loading: true, error: null };
|
||||
case ACTIONS.SUCCESS:
|
||||
return { ...state, loading: false, data: action.payload };
|
||||
case ACTIONS.ERROR:
|
||||
return { ...state, loading: false, error: action.payload };
|
||||
case ACTIONS.RESET:
|
||||
return { ...initialState, loading: false };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
const useRoadItemGetItems = (id) => {
|
||||
const requestServer = useRequest({ notificationShow: false });
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
useEffect(() => {
|
||||
if (!id) {
|
||||
dispatch({ type: ACTIONS.RESET });
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchSubItems = async () => {
|
||||
dispatch({ type: ACTIONS.LOADING });
|
||||
try {
|
||||
const response = await requestServer(`${GET_ROAD_ITEMS_SUB_ITEM}/${id}`);
|
||||
setSubItemsList(response.data.data);
|
||||
setLoadingSubItemsList(false);
|
||||
} catch (e) {
|
||||
setErrorSubItemsList(e);
|
||||
setLoadingSubItemsList(false);
|
||||
dispatch({ type: ACTIONS.SUCCESS, payload: response.data.data });
|
||||
} catch (error) {
|
||||
dispatch({ type: ACTIONS.ERROR, payload: error });
|
||||
}
|
||||
};
|
||||
|
||||
fetchSubItems();
|
||||
}, []);
|
||||
}, [id]);
|
||||
|
||||
return { subItemsList, loadingSubItemsList, errorSubItemsList };
|
||||
return {
|
||||
subItemsList: state.data,
|
||||
loadingSubItemsList: state.loading,
|
||||
errorSubItemsList: state.error,
|
||||
};
|
||||
};
|
||||
|
||||
export default useRoadItemGetItems;
|
||||
|
||||
@@ -14,6 +14,7 @@ const useRoadItemGetItems = () => {
|
||||
const response = await requestServer(`${GET_ROAD_ITEMS_ITEM}`);
|
||||
setItemsList(response.data.data);
|
||||
setLoadingItemsList(false);
|
||||
setErrorItemsList(false);
|
||||
} catch (e) {
|
||||
setErrorItemsList(e);
|
||||
setLoadingItemsList(false);
|
||||
|
||||
Reference in New Issue
Block a user