From 725f95000453623ea99b6a507600275f21389e2d Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Sun, 31 Aug 2025 13:13:55 +0330 Subject: [PATCH 01/10] add request mission without process --- .../MapControlPolygon/DrawBound/index.jsx | 129 +++++++++ .../Form/Area/MapControlPolygon/index.jsx | 116 ++++++++ .../MapControlPolyline/DrawBound/index.jsx | 129 +++++++++ .../Form/Area/MapControlPolyline/index.jsx | 116 ++++++++ .../Form/Area/SelectBoundType/index.jsx | 25 ++ .../CreateWithoutProcess/Form/Area/index.jsx | 54 ++++ .../Form/GetDateTime/MissionDates/index.jsx | 90 ++++++ .../Form/GetDateTime/index.jsx | 59 ++++ .../Dialog/List/RowActions/SelectId/index.jsx | 20 ++ .../Dialog/List/RowActions/index.jsx | 10 + .../FastReactCode/Dialog/List/index.jsx | 274 ++++++++++++++++++ .../FastReactCode/Dialog/index.jsx | 49 ++++ .../Form/GetItemInfo/FastReactCode/index.jsx | 22 ++ .../Form/GetItemInfo/index.jsx | 153 ++++++++++ .../DriversSearch/Form/index.jsx | 61 ++++ .../DriversDialog/DriversSearch/index.jsx | 11 + .../MachineAndDriver/DriversDialog/index.jsx | 41 +++ .../MachineList/RowActions/Allocate/index.jsx | 20 ++ .../MachineList/RowActions/index.jsx | 6 + .../MachinesDialog/MachineList/index.jsx | 68 +++++ .../MachineAndDriver/MachinesDialog/index.jsx | 43 +++ .../Form/MachineAndDriver/index.jsx | 82 ++++++ .../Form/Rahdaran/Form/index.jsx | 66 +++++ .../Form/Rahdaran/List/index.jsx | 56 ++++ .../Form/Rahdaran/index.jsx | 36 +++ .../Form/Verify/index.jsx | 133 +++++++++ .../CreateWithoutProcess/Form/index.jsx | 125 ++++++++ .../Actions/CreateWithoutProcess/index.jsx | 121 ++++++++ .../roadMissions/operator/Toolbar.jsx | 2 + .../RowActions/Allocation/Form/index.jsx | 4 +- src/core/utils/routes.js | 1 + 31 files changed, 2120 insertions(+), 2 deletions(-) create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/DrawBound/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/DrawBound/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/SelectBoundType/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/Form/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/Allocate/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/Form/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/List/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/DrawBound/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/DrawBound/index.jsx new file mode 100644 index 0000000..a2134c5 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/DrawBound/index.jsx @@ -0,0 +1,129 @@ +import React, { useCallback, useEffect, useRef, useState } from "react"; +import L from "leaflet"; +import { FeatureGroup, useMap } from "react-leaflet"; +import "leaflet-draw"; + +const DrawBound = ({ control, controlDispach, bound, setBound }) => { + const map = useMap(); + const featureRef = useRef(null); + const [area, setArea] = useState(); + const drawControlRef = useRef(null); + + const safeFlyToBounds = (layer) => { + if (!layer || !map) return; + try { + const latLngs = layer.getLatLngs(); + map.flyToBounds(latLngs, { + paddingTopLeft: [20, 35], + paddingBottomRight: [20, 55], + }); + } catch (e) { + console.warn("flyToBounds failed:", e); + } + }; + + const safeFitBounds = (layer) => { + if (!layer || !map) return; + try { + const latLngs = layer.getLatLngs(); + map.fitBounds(latLngs, { + paddingTopLeft: [20, 35], + paddingBottomRight: [20, 55], + }); + } catch (e) { + console.warn("fitBounds failed:", e); + } + }; + + const bindEditEvent = (layer) => { + if (!layer) return; + layer.on("edit", function (e) { + const editedLayer = e.target; + setArea(editedLayer); + setBound(editedLayer); + safeFlyToBounds(editedLayer); + }); + }; + + const handlerCreatedBound = useCallback((event) => { + const { layer } = event; + layer.editing.enable(); + featureRef.current.addLayer(layer); // 🟢 اول اضافه به نقشه + setArea(layer); + setBound(layer); + safeFlyToBounds(layer); + bindEditEvent(layer); + controlDispach({ type: "SET_STATUS", status: 2 }); + }, []); + + useEffect(() => { + if ( + control.status === 1 && + drawControlRef.current && + drawControlRef.current._toolbars?.draw?._modes?.polygon?.handler + ) { + drawControlRef.current._toolbars.draw._modes.polygon.handler.enable(); + } + }, [control.status]); + + useEffect(() => { + if (control.status === 0 && area && featureRef.current) { + featureRef.current.removeLayer(area); + setArea(null); + setBound(null); + } + }, [control.status, area]); + + useEffect(() => { + if (control.status === 2 && bound && featureRef.current) { + setArea(bound); + featureRef.current.addLayer(bound); + bound.editing.enable(); + safeFitBounds(bound); + bindEditEvent(bound); + } + }, [control.status, bound]); + + useEffect(() => { + if (!featureRef.current) return; + + L.drawLocal.draw.handlers.polygon.tooltip.start = "برای شروع ترسیم محدوده، روی نقشه کلیک کنید"; + L.drawLocal.draw.handlers.polygon.tooltip.cont = "برای ادامه ترسیم، نقاط بعدی را کلیک کنید"; + L.drawLocal.draw.handlers.polygon.tooltip.end = "برای بستن محدوده، روی نقطه‌ی شروع کلیک کنید"; + + const drawControl = new L.Control.Draw({ + draw: { + polygon: { + shapeOptions: { + color: "#3388ff", + weight: 3, + clickable: true, + }, + }, + polyline: false, + rectangle: false, + circle: false, + marker: false, + circlemarker: false, + }, + edit: { + featureGroup: featureRef.current, + edit: true, + remove: false, + }, + }); + + drawControlRef.current = drawControl; + map.addControl(drawControl); + map.on(L.Draw.Event.CREATED, handlerCreatedBound); + + return () => { + map.off(L.Draw.Event.CREATED, handlerCreatedBound); + map.removeControl(drawControl); + }; + }, [map, handlerCreatedBound]); + + return ; +}; + +export default DrawBound; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/index.jsx new file mode 100644 index 0000000..186a0b6 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolygon/index.jsx @@ -0,0 +1,116 @@ +import { Delete, Route } from "@mui/icons-material"; +import { Box, Button, Stack, Typography } from "@mui/material"; +import { useReducer } from "react"; +import DrawBound from "./DrawBound"; + +const statusType = [ + { + id: 0, + message: "برای آغاز ترسیم محدوده، کلیک کنید!", + buttons: [ + { + label: "شروع ترسیم محدوده", + key: "start", + color: "primary", + icon: , + onclick: (controlDispach) => { + controlDispach({ type: "SET_STATUS", status: 1 }); + }, + }, + ], + }, + { + id: 1, + message: "محدوده‌ی موردنظر را با کلیک روی نقشه مشخص کنید. برای اتمام، روی نقطه‌ی ابتدایی کلیک کنید!", + buttons: [], + }, + { + id: 2, + message: "برای اصلاح محدوده، گوشه‌ها را بکشید. برای ترسیم دوباره، آن را حذف کنید", + buttons: [ + { + label: "حذف", + key: "end", + color: "error", + icon: , + onclick: (controlDispach) => { + controlDispach({ type: "SET_STATUS", status: 0 }); + }, + }, + ], + }, +]; + +const createInitialState = (bound) => { + if (bound) { + return { status: 2 }; + } + return { status: 0 }; +}; + +const reducer = (state, action) => { + switch (action.type) { + case "SET_STATUS": + return { ...state, status: action.status }; + default: + return state; + } +}; + +const MapControlPolygon = ({ bound, setBound }) => { + const [control, controlDispach] = useReducer(reducer, bound, createInitialState); + + return ( + <> + + + theme.palette.info.main, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + py: 0.5, + px: 2, + }} + > + + {statusType.find((st) => st.id == control.status).message} + + + + + + {statusType + .find((st) => st.id == control.status) + .buttons.map((button) => ( + + ))} + + + + ); +}; +export default MapControlPolygon; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/DrawBound/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/DrawBound/index.jsx new file mode 100644 index 0000000..682be24 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/DrawBound/index.jsx @@ -0,0 +1,129 @@ +import React, { useCallback, useEffect, useRef, useState } from "react"; +import L from "leaflet"; +import { FeatureGroup, useMap } from "react-leaflet"; +import "leaflet-draw"; + +const DrawBound = ({ control, controlDispach, bound, setBound }) => { + const map = useMap(); + const featureRef = useRef(null); + const [area, setArea] = useState(); + const drawControlRef = useRef(null); + + const safeFlyToBounds = (layer) => { + if (!layer || !map) return; + try { + const latLngs = layer.getLatLngs(); + map.flyToBounds(latLngs, { + paddingTopLeft: [20, 35], + paddingBottomRight: [20, 55], + }); + } catch (e) { + console.warn("flyToBounds failed:", e); + } + }; + + const safeFitBounds = (layer) => { + if (!layer || !map) return; + try { + const latLngs = layer.getLatLngs(); + map.fitBounds(latLngs, { + paddingTopLeft: [20, 35], + paddingBottomRight: [20, 55], + }); + } catch (e) { + console.warn("fitBounds failed:", e); + } + }; + + const bindEditEvent = (layer) => { + if (!layer) return; + layer.on("edit", function (e) { + const editedLayer = e.target; + setArea(editedLayer); + setBound(editedLayer); + safeFlyToBounds(editedLayer); + }); + }; + + const handlerCreatedBound = useCallback((event) => { + const { layer } = event; + layer.editing.enable(); + featureRef.current.addLayer(layer); // 🟢 اول اضافه به نقشه + setArea(layer); + setBound(layer); + safeFlyToBounds(layer); + bindEditEvent(layer); + controlDispach({ type: "SET_STATUS", status: 2 }); + }, []); + + useEffect(() => { + if ( + control.status === 1 && + drawControlRef.current && + drawControlRef.current._toolbars?.draw?._modes?.polyline?.handler + ) { + drawControlRef.current._toolbars.draw._modes.polyline.handler.enable(); + } + }, [control.status]); + + useEffect(() => { + if (control.status === 0 && area && featureRef.current) { + featureRef.current.removeLayer(area); + setArea(null); + setBound(null); + } + }, [control.status, area]); + + useEffect(() => { + if (control.status === 2 && bound && featureRef.current) { + setArea(bound); + featureRef.current.addLayer(bound); + bound.editing.enable(); + safeFitBounds(bound); + bindEditEvent(bound); + } + }, [control.status, bound]); + + useEffect(() => { + if (!featureRef.current) return; + + L.drawLocal.draw.handlers.polyline.tooltip.start = "برای شروع ترسیم مسیر، روی نقشه کلیک کنید"; + L.drawLocal.draw.handlers.polyline.tooltip.cont = "برای ادامه ترسیم، نقاط بعدی را کلیک کنید"; + L.drawLocal.draw.handlers.polyline.tooltip.end = "برای بستن مسیر، روی نقطه پایانی کلیک کنید"; + + const drawControl = new L.Control.Draw({ + draw: { + polyline: { + shapeOptions: { + color: "#3388ff", + weight: 3, + clickable: true, + }, + }, + polygon: false, + rectangle: false, + circle: false, + marker: false, + circlemarker: false, + }, + edit: { + featureGroup: featureRef.current, + edit: true, + remove: false, + }, + }); + + drawControlRef.current = drawControl; + map.addControl(drawControl); + map.on(L.Draw.Event.CREATED, handlerCreatedBound); + + return () => { + map.off(L.Draw.Event.CREATED, handlerCreatedBound); + map.removeControl(drawControl); + }; + }, [map, handlerCreatedBound]); + + return ; +}; + +export default DrawBound; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/index.jsx new file mode 100644 index 0000000..edd6cac --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/MapControlPolyline/index.jsx @@ -0,0 +1,116 @@ +import { Delete, Route } from "@mui/icons-material"; +import { Box, Button, Stack, Typography } from "@mui/material"; +import { useReducer } from "react"; +import DrawBound from "./DrawBound"; + +const statusType = [ + { + id: 0, + message: "برای آغاز ترسیم مسیر، کلیک کنید!", + buttons: [ + { + label: "شروع ترسیم مسیر", + key: "start", + color: "primary", + icon: , + onclick: (controlDispach) => { + controlDispach({ type: "SET_STATUS", status: 1 }); + }, + }, + ], + }, + { + id: 1, + message: "مسیر موردنظر را با کلیک روی نقشه مشخص کنید. برای اتمام، روی نقطه‌ی پایانی کلیک کنید!", + buttons: [], + }, + { + id: 2, + message: "برای اصلاح مسیر، گوشه‌ها را بکشید. برای ترسیم دوباره، آن را حذف کنید", + buttons: [ + { + label: "حذف", + key: "end", + color: "error", + icon: , + onclick: (controlDispach) => { + controlDispach({ type: "SET_STATUS", status: 0 }); + }, + }, + ], + }, +]; + +const createInitialState = (bound) => { + if (bound) { + return { status: 2 }; + } + return { status: 0 }; +}; + +const reducer = (state, action) => { + switch (action.type) { + case "SET_STATUS": + return { ...state, status: action.status }; + default: + return state; + } +}; + +const MapControlPolyline = ({ bound, setBound }) => { + const [control, controlDispach] = useReducer(reducer, bound, createInitialState); + + return ( + <> + + + theme.palette.info.main, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + py: 0.5, + px: 2, + }} + > + + {statusType.find((st) => st.id == control.status).message} + + + + + + {statusType + .find((st) => st.id == control.status) + .buttons.map((button) => ( + + ))} + + + + ); +}; +export default MapControlPolyline; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/SelectBoundType/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/SelectBoundType/index.jsx new file mode 100644 index 0000000..a69a0ba --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/SelectBoundType/index.jsx @@ -0,0 +1,25 @@ +import SelectBox from "@/core/components/SelectBox"; + +export const boundTypes = [ + { id: "polygon", name_fa: "محدوده" }, + { id: "polyline", name_fa: "مسیر" }, +]; + +const SelectBoundType = ({ boundType, setBoundType, setBound, setAllData }) => { + return ( + <> + { + setBound(null); + setBoundType(newValue); + setAllData({ bound_type: newValue }); + }} + /> + + ); +}; +export default SelectBoundType; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/index.jsx new file mode 100644 index 0000000..91dd0d3 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Area/index.jsx @@ -0,0 +1,54 @@ +import MapLoading from "@/core/components/MapLayer/Loading"; +import { Box, Button, DialogActions, DialogContent, Stack } from "@mui/material"; +import dynamic from "next/dynamic"; +import { useCallback, useState } from "react"; +import MapControlPolygon from "./MapControlPolygon"; +import MapControlPolyline from "./MapControlPolyline"; +import SelectBoundType from "./SelectBoundType"; +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); + +const Area = ({ allData, setAllData, handlePrev, setTabState }) => { + const [bound, setBound] = useState(allData.bound); + const [boundType, setBoundType] = useState(allData.bound_type); + + const handleNext = useCallback(() => { + setAllData({ bound: bound }); + setTabState((s) => s + 1); + }, [bound]); + + return ( + <> + + + + + + {boundType == "polygon" ? ( + + ) : ( + + )} + + + + + + + + + + ); +}; +export default Area; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx new file mode 100644 index 0000000..35cca49 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx @@ -0,0 +1,90 @@ +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import MuiTimePicker from "@/core/components/MuiTimePicker"; +import { Grid } from "@mui/material"; +import { Controller } from "react-hook-form"; + +const MissionDates = ({ control }) => { + return ( + <> + + { + return ( + field.onChange(value || [])} + helperText={error ? error.message : null} + /> + ); + }} + /> + + + { + return ( + field.onChange(value || null)} + helperText={error ? error.message : null} + /> + ); + }} + /> + + + { + return ( + field.onChange(value || [])} + helperText={error ? error.message : null} + /> + ); + }} + /> + + + { + return ( + field.onChange(value || null)} + helperText={error ? error.message : null} + /> + ); + }} + /> + + + ); +}; +export default MissionDates; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/index.jsx new file mode 100644 index 0000000..9e35f41 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/index.jsx @@ -0,0 +1,59 @@ +import SelectBox from "@/core/components/SelectBox"; +import StyledForm from "@/core/components/StyledForm"; +import { missionTypes } from "@/core/utils/missionTypes"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Box, Button, DialogActions, DialogContent, Grid, Stack } from "@mui/material"; +import moment from "jalali-moment"; +import { Controller, useForm } from "react-hook-form"; +import { object, string } from "yup"; +import MissionDates from "./MissionDates"; + +const validationSchema = object({ + start_date: string().required("تاریخ شروع ماموریت را مشخص کنید!"), + start_time: string().required("زمان شروع ماموریت را مشخص کنید!"), + end_date: string().required("تاریخ پایان ماموریت را مشخص کنید!"), + end_time: string().required("زمان شروع ماموریت را مشخص کنید!"), +}); + +const GetDateTime = ({ allData, setAllData, handlePrev, setTabState }) => { + const defaultValues = { + start_date: allData.start_date, + start_time: allData.start_time ? moment(allData.start_time).toDate() : null, + end_date: allData.end_date, + end_time: allData.end_time ? moment(allData.end_time).toDate() : null, + }; + + const { control, handleSubmit } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "all", + }); + + const handleNext = (data) => { + setAllData(data); + setTabState((s) => s + 1); + }; + + return ( + + + + + + + + + + + + + + + + ); +}; +export default GetDateTime; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx new file mode 100644 index 0000000..1e7e881 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx @@ -0,0 +1,20 @@ +import { Done } from "@mui/icons-material"; +import { IconButton, Tooltip } from "@mui/material"; + +const SelectId = ({ row, onChange, setOpenFastReactDialog }) => { + const handleClick = () => { + onChange(row.original.id); + setOpenFastReactDialog(false); + }; + + return ( + <> + + + + + + + ); +}; +export default SelectId; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx new file mode 100644 index 0000000..3d0b958 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx @@ -0,0 +1,10 @@ +import SelectId from "./SelectId"; + +const RowActions = ({ row, onChange, setOpenFastReactDialog }) => { + return ( + <> + + + ); +}; +export default RowActions; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx new file mode 100644 index 0000000..82a0472 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx @@ -0,0 +1,274 @@ +import DataTableWithAuth from "@/core/components/DataTableWithAuth"; +import { GET_FAST_REACT_COMPLAINTS } from "@/core/utils/routes"; +import { Box, Stack, Typography } from "@mui/material"; +import { useMemo } from "react"; +import RowActions from "./RowActions"; +import { usePermissions } from "@/lib/hooks/usePermissions"; +import { useAuth } from "@/lib/contexts/auth"; +import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency"; +import DescriptionForm from "@/components/dashboard/fastReact/complaintList/RowActions/DescriptionDialog"; +import LocationForm from "@/components/dashboard/fastReact/complaintList/RowActions/LocationDialog"; +import moment from "jalali-moment"; +import useProvinces from "@/lib/hooks/useProvince"; +import useEdaratLists from "@/lib/hooks/useEdaratLists"; + +const FastReactList = ({ onChange, setOpenFastReactDialog }) => { + const { data: userPermissions } = usePermissions(); + const hasCountryPermission = userPermissions?.includes("show-fast-react"); + const { user } = useAuth(); + const columns = useMemo(() => { + const dynamicColumns = { + header: "استان", + id: "road_observeds__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}, + }; + return [ + { + accessorKey: "id", + header: "کد یکتا", + id: "road_observeds__id", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + ...(hasCountryPermission ? [dynamicColumns] : []), + { + header: "اداره", + id: "road_observeds__edarate_shahri_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + dependencyId: hasCountryPermission ? "road_observeds__province_id" : null, + grow: false, + size: 120, + ColumnSelectComponent: (props) => { + const { edaratList, loadingEdaratList, errorEdaratList } = useEdaratLists( + hasCountryPermission ? props.dependencyFieldValue.value : user.province_id + ); + const [prevDependency, setPrevDependency] = useState( + hasCountryPermission ? props.dependencyFieldValue.value : user.province_id + ); + + const getColumnSelectOptions = useMemo(() => { + if (hasCountryPermission && 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 (hasCountryPermission) return; + if (prevDependency === props.dependencyFieldValue?.value) return; + props.handleChange({ ...props.filterParameters, value: "" }); + setPrevDependency(props.dependencyFieldValue?.value); + }, [props.dependencyFieldValue?.value, hasCountryPermission]); + return ( + + ); + }, + Cell: ({ row }) => <>{row.original.edarate_shahri_name_fa}, + }, + { + header: "اطلاعات ثبت‌ شده در سامانه سوانح", + id: "fkInfo", + enableColumnFilter: false, + enableSorting: false, + grow: false, + size: 50, + columns: [ + { + accessorKey: "fk_RegisteredEventMessage", + header: "کد سوانح", + id: "fk_RegisteredEventMessage", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "Title", + header: "موضوع گزارش", + id: "Title", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "FeatureTypeTitle", + header: "نوع گزارش", + id: "FeatureTypeTitle", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "Description", + header: "توضیح گزارش", + id: "Description", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + sortDescFirst: 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 ( + + + + ); + } + return -; + }, + }, + { + 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: "MobileForSendEventSms", + header: "شماره تماس گیرنده", + id: "MobileForSendEventSms", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorFn: (row) => moment(row.StartTime_DateTime).locale("fa").format("HH:mm | yyyy/MM/DD"), + header: "تاریخ ثبت", + id: "StartTime_DateTime", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + ], + }, + ]; + }, []); + + return ( + <> + + ( + + )} + /> + + + ); +}; +export default FastReactList; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/index.jsx new file mode 100644 index 0000000..013f73f --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/Dialog/index.jsx @@ -0,0 +1,49 @@ +import { Close, Edit } from "@mui/icons-material"; +import { Button, Chip, Dialog, Divider, IconButton } from "@mui/material"; +import FastReactList from "./List"; +import { useState, forwardRef } from "react"; + +const FastReactDialog = forwardRef(({ onChange, value }, ref) => { + const [openFastReactDialog, setOpenFastReactDialog] = useState(false); + + return ( + <> + + {value === "" ? ( + + ) : ( + } + onDelete={() => setOpenFastReactDialog(true)} + /> + )} + + + setOpenFastReactDialog(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + {openFastReactDialog && ( + + )} + + + ); +}); + +FastReactDialog.displayName = "FastReactDialog"; + +export default FastReactDialog; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/index.jsx new file mode 100644 index 0000000..1545046 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/FastReactCode/index.jsx @@ -0,0 +1,22 @@ +import { Divider, Stack } from "@mui/material"; +import { Controller, useWatch } from "react-hook-form"; +import FastReactDialog from "./Dialog"; + +const FastReactCode = ({ control }) => { + const category_id = useWatch({ control, name: "category_id" }); + + if (category_id != 3) return null; + + return ( + ( + + + + )} + /> + ); +}; +export default FastReactCode; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/index.jsx new file mode 100644 index 0000000..3b3b513 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetItemInfo/index.jsx @@ -0,0 +1,153 @@ +import PersianTextField from "@/core/components/PersianTextField"; +import SelectBox from "@/core/components/SelectBox"; +import StyledForm from "@/core/components/StyledForm"; +import { missionCategoryTypes } from "@/core/utils/missionCategoryTypes"; +import { missionRegions } from "@/core/utils/missionRegions"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { ExitToApp } from "@mui/icons-material"; +import { Box, Button, DialogActions, DialogContent, Grid, Stack } from "@mui/material"; +import { Controller, useForm } from "react-hook-form"; +import { object, string } from "yup"; +import FastReactCode from "./FastReactCode"; + +const validationSchema = object({ + explanation: string().required("موضوع را مشخص کنید!"), + end_point: string().required("مقصد را مشخص کنید!"), + region: string().required("محور ماموریت را مشخص کنید!"), + category_id: string().required("نوع ماموریت را مشخص کنید!"), + road_observed_id: string().when("category_id", { + is: "3", + then: (schema) => schema.required("کد یکتا شکایت را مشخص کنید!"), + otherwise: (schema) => schema.notRequired(), + }), +}); + +const GetItemInfo = ({ allData, setAllData, handlePrev, setTabState }) => { + const defaultValues = { + explanation: allData.explanation, + end_point: allData.end_point, + region: allData.region, + category_id: allData.category_id, + road_observed_id: allData.road_observed_id, + }; + + const { control, handleSubmit } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "all", + }); + + const handleNext = (data) => { + setAllData(data); + setTabState((s) => s + 1); + }; + + return ( + + + + + + + ( + + )} + /> + + + ( + + )} + /> + + + ( + + )} + /> + + + + + + { + return ( + + ); + }} + /> + + + + + + + + + + + ); +}; +export default GetItemInfo; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/Form/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/Form/index.jsx new file mode 100644 index 0000000..93bb1d6 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/Form/index.jsx @@ -0,0 +1,61 @@ +import RahdarNameOrCode from "@/core/components/RahdarNameOrCode"; +import StyledForm from "@/core/components/StyledForm"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Done } from "@mui/icons-material"; +import { Button, Stack } from "@mui/material"; +import { Controller, useForm } from "react-hook-form"; +import { object } from "yup"; + +const schema = object().shape({ + rahdar: object().required("همراه الزامی است."), +}); +const DriverForm = ({ setDriver, setOpenDriversDialog }) => { + const defaultValues = { + rahdar: null, + }; + + const { + control, + handleSubmit, + formState: { isSubmitting, isValid }, + } = useForm({ defaultValues, resolver: yupResolver(schema), mode: "all" }); + + const submit = (data) => { + setDriver(data.rahdar); + setOpenDriversDialog(false); + }; + + return ( + + + + { + return ( + field.onChange(value)} + error={error} + multiple={false} + /> + ); + }} + name={"rahdar"} + /> + + + + + ); +}; +export default DriverForm; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/index.jsx new file mode 100644 index 0000000..b7136c9 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/DriversSearch/index.jsx @@ -0,0 +1,11 @@ +import { DialogContent } from "@mui/material"; +import DriverForm from "./Form"; + +const DriversSearch = ({ setDriver, setOpenDriversDialog }) => { + return ( + + + + ); +}; +export default DriversSearch; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/index.jsx new file mode 100644 index 0000000..3c1d406 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/DriversDialog/index.jsx @@ -0,0 +1,41 @@ +import { Close, Edit } from "@mui/icons-material"; +import { Button, Dialog, DialogTitle, IconButton } from "@mui/material"; +import { useState } from "react"; +import DriversSearch from "./DriversSearch"; + +const DriversDialog = ({ setDriver, mode }) => { + const [openDriversDialog, setOpenDriversDialog] = useState(false); + return ( + <> + {mode == "edit" ? ( + setOpenDriversDialog(true)} size="small"> + + + ) : ( + + )} + + setOpenDriversDialog(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + انتخاب راننده + {openDriversDialog && ( + + )} + + + ); +}; +export default DriversDialog; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/Allocate/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/Allocate/index.jsx new file mode 100644 index 0000000..f03579a --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/Allocate/index.jsx @@ -0,0 +1,20 @@ +import { Done } from "@mui/icons-material"; +import { IconButton, Tooltip } from "@mui/material"; + +const Allocate = ({ row, setMachine, setOpenMachinesDialog }) => { + const handleClick = () => { + setMachine(row.original); + setOpenMachinesDialog(false); + }; + + return ( + <> + + + + + + + ); +}; +export default Allocate; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/index.jsx new file mode 100644 index 0000000..bcfcc03 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/RowActions/index.jsx @@ -0,0 +1,6 @@ +import Allocate from "./Allocate"; + +const RowActions = ({ row, setMachine, setOpenMachinesDialog }) => { + return ; +}; +export default RowActions; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/index.jsx new file mode 100644 index 0000000..e070b01 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/MachineList/index.jsx @@ -0,0 +1,68 @@ +import DataTableWithAuth from "@/core/components/DataTableWithAuth"; +import { Box } from "@mui/material"; +import { useMemo } from "react"; +import RowActions from "./RowActions"; +import { GET_MACHINES_TABLE_LIST } from "@/core/utils/routes"; + +const MachinesList = ({ machineType, setMachine, setOpenMachinesDialog }) => { + const columns = useMemo( + () => [ + { + accessorKey: "machine_code", + header: "کد خودرو", + id: "machine_code", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "car_name", + header: "نام خودرو", + id: "car_name", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "car_type", + header: "نوع خودرو", + id: "car_type", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + ], + [] + ); + + return ( + <> + + ( + + )} + /> + + + ); +}; +export default MachinesList; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx new file mode 100644 index 0000000..a422439 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx @@ -0,0 +1,43 @@ +import { Close, Edit } from "@mui/icons-material"; +import { Button, Dialog, IconButton } from "@mui/material"; +import { useState } from "react"; +import MachinesList from "./MachineList"; + +const MachinesDialog = ({ setMachine, mode }) => { + const [openMachinesDialog, setOpenMachinesDialog] = useState(false); + return ( + <> + {mode == "edit" ? ( + setOpenMachinesDialog(true)} size="small"> + + + ) : ( + + )} + + setOpenMachinesDialog(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + {openMachinesDialog && ( + + )} + + + ); +}; +export default MachinesDialog; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx new file mode 100644 index 0000000..d8f8ea0 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx @@ -0,0 +1,82 @@ +import { Box, Button, Chip, DialogActions, DialogContent, Divider, Stack, Typography } from "@mui/material"; +import DriversDialog from "./DriversDialog"; +import MachinesDialog from "./MachinesDialog"; +import { useState } from "react"; + +const MachineAndDriver = ({ setTabState, allData, setAllData, handlePrev }) => { + const [machine, setMachine] = useState(allData.machine); + const [driver, setDriver] = useState(allData.driver); + + const handleNext = (data) => { + setAllData(data); + setTabState((s) => s + 1); + }; + + + return ( + <> + + + + + {machine ? ( + <> + خودرو + + + + + + ) : ( + + )} + + {machine && ( + + {driver ? ( + <> + راننده + + + + + + ) : ( + + )} + + )} + + + + + + + + + ) +} +export default MachineAndDriver \ No newline at end of file diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/Form/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/Form/index.jsx new file mode 100644 index 0000000..a4449fe --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/Form/index.jsx @@ -0,0 +1,66 @@ +import RahdarNameOrCode from "@/core/components/RahdarNameOrCode"; +import StyledForm from "@/core/components/StyledForm"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Add } from "@mui/icons-material"; +import { Button, Stack } from "@mui/material"; +import { Controller, useForm } from "react-hook-form"; +import { object } from "yup"; + +const schema = object().shape({ + rahdar: object().required("همراه الزامی است."), +}); +const RahdaranForm = ({ setRahdaran }) => { + const defaultValues = { + rahdar: null, + }; + + const { + control, + handleSubmit, + reset, + formState: { isSubmitting, isValid }, + } = useForm({ defaultValues, resolver: yupResolver(schema), mode: "all" }); + + const submit = (data) => { + setRahdaran((prev) => { + const alreadyExists = prev.some((r) => r.id === data.rahdar.id); + if (alreadyExists) return prev; + return [...prev, data.rahdar]; + }); + reset(); + }; + + return ( + + + + { + return ( + field.onChange(value)} + error={error} + multiple={false} + /> + ); + }} + name={"rahdar"} + /> + + + + + ); +}; +export default RahdaranForm; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/List/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/List/index.jsx new file mode 100644 index 0000000..ebc4edc --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/List/index.jsx @@ -0,0 +1,56 @@ +import { AccountCircle, Delete } from "@mui/icons-material"; +import { Card, Collapse, IconButton, Stack, Typography } from "@mui/material"; +import { TransitionGroup } from "react-transition-group"; + +const RahdaranList = ({ rahdaran, setRahdaran }) => { + const handleRemove = (index) => { + setRahdaran((prev) => prev.filter((_, i) => i !== index)); + }; + + return ( + + + {rahdaran.map((rahdar, index) => ( + + + + + + + نام و نام خانوادگی: + {rahdar.name} + + + کدملی: + {rahdar.code} + + + + handleRemove(index)}> + + + + + ))} + {rahdaran.length == 0 && ( + + همراهی ثبت نشده است + + )} + + + ); +}; +export default RahdaranList; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/index.jsx new file mode 100644 index 0000000..af01fe6 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Rahdaran/index.jsx @@ -0,0 +1,36 @@ +import { Box, Button, Chip, DialogActions, DialogContent, Divider } from "@mui/material"; +import { useCallback, useState } from "react"; +import RahdaranForm from "./Form"; +import RahdaranList from "./List"; + +const Rahdaran = ({ allData, setAllData, setTabState, handlePrev }) => { + const [rahdaran, setRahdaran] = useState(allData.rahdaran); + + const handleNext = useCallback(() => { + setAllData({ rahdaran: rahdaran }); + setTabState((s) => s + 1); + }, [rahdaran]); + + return ( + <> + + + + + + + + + + + + + + + ); +}; +export default Rahdaran; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx new file mode 100644 index 0000000..be33cd8 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx @@ -0,0 +1,133 @@ +import MapLoading from "@/core/components/MapLayer/Loading"; +import { missionCategoryTypes } from "@/core/utils/missionCategoryTypes"; +import { missionRegions } from "@/core/utils/missionRegions"; +import { Box, Button, Chip, DialogActions, DialogContent, Divider, Stack, Typography } from "@mui/material"; +import moment from "jalali-moment"; +import dynamic from "next/dynamic"; +import { useCallback } from "react"; +import ShowBound from "../../../showBound"; +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); + +const Verify = ({ allData, handlePrev, submitForm, submitting }) => { + const handleNext = useCallback(() => { + submitForm(allData); + }, [allData]); + + return ( + <> + + + + + + + + + + + + + + موضوع ماموریت + + + + + محدوده + + r.id == allData.region).name_fa} /> + + + نوع ماموریت + + t.id == allData.category_id).name_fa} + /> + + {allData.category_id == 3 && ( + + کد شکایت + + + + )} + + مقصد + + + + + تاریخ شروع ماموریت + + + + + تاریخ پایان ماموریت + + + + + + + + + + خودرو + + + + + راننده + + + + + + + + + {allData.rahdaran.length != 0 ? ( + allData.rahdaran.map((rahdar) => ( + + {rahdar.name} + + + + )) + ) : ( + + همراهی ثبت نشده است + + )} + + + + + + + + + + ); +}; +export default Verify; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/index.jsx new file mode 100644 index 0000000..00f9ef1 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/index.jsx @@ -0,0 +1,125 @@ +import { AccessTime, Engineering, InsertDriveFile, LocalShipping, Route, Verified } from "@mui/icons-material"; +import { Box, Tab, Tabs } from "@mui/material"; +import { useReducer, useState } from "react"; +import Area from "./Area"; +import GetDateTime from "./GetDateTime"; +import GetItemInfo from "./GetItemInfo"; +import Rahdaran from "./Rahdaran"; +import Verify from "./Verify"; +import MachineAndDriver from "./MachineAndDriver"; + +function TabPanel(props) { + const { children, value, index } = props; + return ( + + ); +} + +const reducer = (state, action) => { + switch (action.type) { + case "changeData": + return { ...state, ...action.data }; + default: + return state; + } +}; + +const CreateForm = ({ defaultValues, submitForm, setOpen, submitting }) => { + const [allData, dispatch] = useReducer(reducer, defaultValues); + const [tabState, setTabState] = useState(0); + const handleClose = () => { + setOpen(false); + }; + const handleChangeTab = (event, newValue) => { + setTabState(newValue); + }; + + const handlePrev = () => { + if (tabState === 0) { + handleClose(); + } else { + setTabState((t) => t - 1); + } + }; + + return ( + <> + + } label="مشخصات" /> + } label="زمانبندی" /> + } label="منطقه عملیاتی" /> + } label="خودرو و راننده" /> + } label="همراهان" /> + } label="بررسی نهایی" /> + + + { + dispatch({ type: "changeData", data }); + }} + handlePrev={handlePrev} + setTabState={setTabState} + /> + + + { + dispatch({ type: "changeData", data }); + }} + handlePrev={handlePrev} + setTabState={setTabState} + /> + + + { + dispatch({ type: "changeData", data }); + }} + handlePrev={handlePrev} + setTabState={setTabState} + /> + + + { + dispatch({ type: "changeData", data }); + }} + handlePrev={handlePrev} + setTabState={setTabState} + /> + + + { + dispatch({ type: "changeData", data }); + }} + handlePrev={handlePrev} + setTabState={setTabState} + /> + + + + + + ); +}; +export default CreateForm; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx new file mode 100644 index 0000000..0f150ed --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx @@ -0,0 +1,121 @@ +import { REQUEST_MISSION_WITHOUT_PROCESS } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { AddCircle, AddCircleOutline, Close } from "@mui/icons-material"; +import { Button, Dialog, IconButton, useMediaQuery, useTheme } from "@mui/material"; +import moment from "jalali-moment"; +import { useState } from "react"; +import CreateForm from "./Form"; + +const CreateWithoutProcess = ({ mutate }) => { + const [submitting, setSubmitting] = useState(false); + const requestServer = useRequest({ notificationSuccess: true }); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const [open, setOpen] = useState(false); + + const handleOpen = () => { + setOpen(true); + }; + + const submitForm = async (result) => { + setSubmitting(true); + const bound = result.bound.getLatLngs(); + let area = + result.bound_type == "polygon" + ? bound.map((ring) => ring.map((latlng) => [latlng.lat, latlng.lng]))[0] + : bound.map((latlng) => [latlng.lat, latlng.lng]); + + await requestServer(REQUEST_MISSION_WITHOUT_PROCESS, "post", { + data: { + explanation: result.explanation, + category_id: result.category_id, + ...(result.category_id == 3 + ? { + road_observed_id: result.road_observed_id, + } + : {}), + area: { + type: result.bound_type, + coordinates: area, + }, + ...(result.rahdaran.length != 0 ? { rahdaran: result.rahdaran.map((r) => r.id) } : {}), + zone: result.region, + end_point: result.end_point, + start_date: `${result.start_date} ${moment(result.start_time).format("HH:mm")}`, + end_date: `${result.end_date} ${moment(result.end_time).format("HH:mm")}`, + machines: [result.machine.id], + driver: result.driver.id, + }, + hasSidebarUpdate: true, + }) + .then((response) => { + mutate(); + setOpen(false); + }) + .catch((error) => { }) + .finally(() => { + setSubmitting(false); + }); + }; + + return ( + <> + {isMobile ? ( + + + + ) : ( + + )} + + setOpen(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + {open && ( + + )} + + + ); +}; +export default CreateWithoutProcess; diff --git a/src/components/dashboard/roadMissions/operator/Toolbar.jsx b/src/components/dashboard/roadMissions/operator/Toolbar.jsx index 5f49db7..9ddee3a 100644 --- a/src/components/dashboard/roadMissions/operator/Toolbar.jsx +++ b/src/components/dashboard/roadMissions/operator/Toolbar.jsx @@ -1,10 +1,12 @@ import { Stack } from "@mui/material"; import Create from "./Actions/Create"; +import CreateWithoutProcess from "./Actions/CreateWithoutProcess"; const Toolbar = ({ table, filterData, mutate }) => { return ( + ); }; diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx index e3e9c3b..4a6f44a 100644 --- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx +++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx @@ -36,7 +36,7 @@ const AllocationForm = ({ row, mutate, setOpenAllocationDialog }) => { mutate(); setOpenAllocationDialog(false); }) - .catch((error) => {}) + .catch((error) => { }) .finally(() => { setIsSubmitting(false); }); @@ -93,7 +93,7 @@ const AllocationForm = ({ row, mutate, setOpenAllocationDialog }) => { Date: Sun, 31 Aug 2025 13:14:53 +0330 Subject: [PATCH 02/10] formatting --- .../MachineAndDriver/MachinesDialog/index.jsx | 5 +--- .../Form/MachineAndDriver/index.jsx | 29 ++++++++----------- .../Form/Verify/index.jsx | 5 +--- .../Actions/CreateWithoutProcess/index.jsx | 6 ++-- .../RowActions/Allocation/Form/index.jsx | 2 +- 5 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx index a422439..8750142 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/MachinesDialog/index.jsx @@ -31,10 +31,7 @@ const MachinesDialog = ({ setMachine, mode }) => { {openMachinesDialog && ( - + )} diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx index d8f8ea0..7fda6e0 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx @@ -12,7 +12,6 @@ const MachineAndDriver = ({ setTabState, allData, setAllData, handlePrev }) => { setTabState((s) => s + 1); }; - return ( <> @@ -32,15 +31,10 @@ const MachineAndDriver = ({ setTabState, allData, setAllData, handlePrev }) => { size="small" /> - + ) : ( - + )} {machine && ( @@ -50,11 +44,7 @@ const MachineAndDriver = ({ setTabState, allData, setAllData, handlePrev }) => { راننده @@ -72,11 +62,16 @@ const MachineAndDriver = ({ setTabState, allData, setAllData, handlePrev }) => { - - ) -} -export default MachineAndDriver \ No newline at end of file + ); +}; +export default MachineAndDriver; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx index be33cd8..0393018 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/Verify/index.jsx @@ -92,10 +92,7 @@ const Verify = ({ allData, handlePrev, submitForm, submitting }) => { راننده - + diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx index 0f150ed..ab64c85 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/index.jsx @@ -31,8 +31,8 @@ const CreateWithoutProcess = ({ mutate }) => { category_id: result.category_id, ...(result.category_id == 3 ? { - road_observed_id: result.road_observed_id, - } + road_observed_id: result.road_observed_id, + } : {}), area: { type: result.bound_type, @@ -52,7 +52,7 @@ const CreateWithoutProcess = ({ mutate }) => { mutate(); setOpen(false); }) - .catch((error) => { }) + .catch((error) => {}) .finally(() => { setSubmitting(false); }); diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx index 4a6f44a..e06d06b 100644 --- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx +++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/index.jsx @@ -36,7 +36,7 @@ const AllocationForm = ({ row, mutate, setOpenAllocationDialog }) => { mutate(); setOpenAllocationDialog(false); }) - .catch((error) => { }) + .catch((error) => {}) .finally(() => { setIsSubmitting(false); }); From 0253b06018e331f70c2a8df6a18f65a8ae81a191 Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Tue, 2 Sep 2025 10:09:00 +0330 Subject: [PATCH 03/10] fixed min and max datetimes --- .../Form/GetDateTime/MissionDates/index.jsx | 24 ++++++++++++++++++- .../Form/GetDateTime/MissionDates/index.jsx | 19 ++++++++++++++- src/core/components/MuiDatePicker.jsx | 4 ++-- src/core/utils/makeDateTime.js | 9 +++++++ 4 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 src/core/utils/makeDateTime.js diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx index a2b5c07..2f6dc34 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx @@ -1,11 +1,21 @@ import MuiDatePicker from "@/core/components/MuiDatePicker"; import MuiTimePicker from "@/core/components/MuiTimePicker"; +import { makeDateTime } from "@/core/utils/makeDateTime"; import { Grid } from "@mui/material"; import { Controller, useWatch } from "react-hook-form"; const MissionDates = ({ control }) => { const type = useWatch({ control, name: "type" }); - return ( + const start_date = useWatch({ control, name: "start_date" }); + const end_date = useWatch({ control, name: "end_date" }); + const start_time = useWatch({ control, name: "start_time" }); + const end_time = useWatch({ control, name: "end_time" }); + + const startDateTime = makeDateTime(start_date, start_time); + const endDateTime = makeDateTime(end_date, end_time); + const now = new Date(); + + return type && ( <> { name="start_date" error={error} value={field.value} + disableFuture={false} + minDate={now} + maxDate={end_date ?? null} placeholder={"تاریخ شروع ماموریت را وارد کنید"} label={"تاریخ شروع ماموریت"} setFieldValue={(name, value) => field.onChange(value || [])} @@ -38,6 +51,12 @@ const MissionDates = ({ control }) => { error={error} value={field.value} views={["hours"]} + minTime={ + start_date && new Date(start_date).toDateString() === now.toDateString() + ? now + : null + } + maxTime={endDateTime ?? null} placeholder={"زمان شروع ماموریت را وارد کنید"} label={"زمان شروع ماموریت"} setFieldValue={(name, value) => field.onChange(value || null)} @@ -58,6 +77,8 @@ const MissionDates = ({ control }) => { name="end_date" error={error} value={field.value} + disableFuture={false} + minDate={start_date ? start_date : now} placeholder={"تاریخ پایان ماموریت را وارد کنید"} label={"تاریخ پایان ماموریت"} setFieldValue={(name, value) => field.onChange(value || [])} @@ -79,6 +100,7 @@ const MissionDates = ({ control }) => { error={error} value={field.value} views={["hours"]} + minTime={startDateTime ?? null} placeholder={"زمان پایان ماموریت را وارد کنید"} label={"زمان پایان ماموریت"} setFieldValue={(name, value) => field.onChange(value || null)} diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx index 35cca49..312d6dc 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx @@ -1,9 +1,17 @@ import MuiDatePicker from "@/core/components/MuiDatePicker"; import MuiTimePicker from "@/core/components/MuiTimePicker"; import { Grid } from "@mui/material"; -import { Controller } from "react-hook-form"; +import { Controller, useWatch } from "react-hook-form"; const MissionDates = ({ control }) => { + const start_date = useWatch({ control, name: "start_date" }); + const end_date = useWatch({ control, name: "end_date" }); + const start_time = useWatch({ control, name: "start_time" }); + const end_time = useWatch({ control, name: "end_time" }); + + const startDateTime = makeDateTime(start_date, start_time); + const endDateTime = makeDateTime(end_date, end_time); + const now = new Date(); return ( <> @@ -16,6 +24,7 @@ const MissionDates = ({ control }) => { name="start_date" error={error} value={field.value} + maxDate={end_date ?? null} placeholder={"تاریخ شروع ماموریت را وارد کنید"} label={"تاریخ شروع ماموریت"} setFieldValue={(name, value) => field.onChange(value || [])} @@ -36,6 +45,12 @@ const MissionDates = ({ control }) => { error={error} value={field.value} views={["hours"]} + minTime={ + start_date && new Date(start_date).toDateString() === now.toDateString() + ? now + : null + } + maxTime={endDateTime ?? null} placeholder={"زمان شروع ماموریت را وارد کنید"} label={"زمان شروع ماموریت"} setFieldValue={(name, value) => field.onChange(value || null)} @@ -55,6 +70,7 @@ const MissionDates = ({ control }) => { name="end_date" error={error} value={field.value} + minDate={start_date ? start_date : null} placeholder={"تاریخ پایان ماموریت را وارد کنید"} label={"تاریخ پایان ماموریت"} setFieldValue={(name, value) => field.onChange(value || [])} @@ -75,6 +91,7 @@ const MissionDates = ({ control }) => { error={error} value={field.value} views={["hours"]} + minTime={startDateTime ?? null} placeholder={"زمان پایان ماموریت را وارد کنید"} label={"زمان پایان ماموریت"} setFieldValue={(name, value) => field.onChange(value || null)} diff --git a/src/core/components/MuiDatePicker.jsx b/src/core/components/MuiDatePicker.jsx index cb2abc5..b97bf88 100644 --- a/src/core/components/MuiDatePicker.jsx +++ b/src/core/components/MuiDatePicker.jsx @@ -6,7 +6,7 @@ import { Box, FormHelperText, IconButton, InputAdornment } from "@mui/material"; import ClearIcon from "@mui/icons-material/Clear"; import moment from "jalali-moment"; -function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error, label }) { +function MuiDatePicker({ value, disableFuture = true, setFieldValue, name, minDate, maxDate, helperText, placeholder, error, label }) { return ( <> @@ -20,7 +20,7 @@ function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperTex id={name} name={name} closeOnSelect - disableFuture + disableFuture={disableFuture} label={label} aria-describedby="component-helper-text" onChange={(value) => { diff --git a/src/core/utils/makeDateTime.js b/src/core/utils/makeDateTime.js new file mode 100644 index 0000000..c3beb21 --- /dev/null +++ b/src/core/utils/makeDateTime.js @@ -0,0 +1,9 @@ +export const makeDateTime = (date, time) => { + if (!date) return null; + const d = new Date(date); + if (time) { + const t = new Date(time); + d.setHours(t.getHours(), t.getMinutes(), 0, 0); + } + return d; +}; \ No newline at end of file From 545e9de8eaf363c4e5a19d3ac0fbea7c49f30ea9 Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Tue, 2 Sep 2025 13:48:31 +0330 Subject: [PATCH 04/10] add mission to read item --- .../Create/Forms/CreateFormContent.jsx | 65 +--- .../Forms/{ => GetItemInfo}/ImageUpload.jsx | 346 +++++++++--------- .../RowActions/Allocate/index.jsx | 18 + .../MissionsList/RowActions/index.jsx | 6 + .../MissionsDialog/MissionsList/index.jsx | 111 ++++++ .../GetItemInfo/MissionsDialog/index.jsx | 40 ++ .../{ => GetItemInfo}/PreviousStatesInfo.jsx | 86 ++--- .../index.jsx} | 239 ++++++------ .../roadItems/operator/OperatorList.jsx | 58 +-- .../RowActions/EditForm/EditFormCreate.jsx | 69 +--- .../dashboard/roadItems/operator/Toolbar.jsx | 2 +- .../roadItems/supervisor/SupervisorList.jsx | 62 +--- .../Form/GetDateTime/MissionDates/index.jsx | 1 + .../Form/MachineAndDriver/index.jsx | 2 +- src/core/utils/missionCategoryTypes.js | 2 +- 15 files changed, 539 insertions(+), 568 deletions(-) rename src/components/dashboard/roadItems/operator/Actions/Create/Forms/{ => GetItemInfo}/ImageUpload.jsx (97%) create mode 100644 src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/index.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/index.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx rename src/components/dashboard/roadItems/operator/Actions/Create/Forms/{ => GetItemInfo}/PreviousStatesInfo.jsx (97%) rename src/components/dashboard/roadItems/operator/Actions/Create/Forms/{GetItemInfo.jsx => GetItemInfo/index.jsx} (69%) diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx index 293c6a7..b5e2105 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx @@ -1,20 +1,20 @@ -import React, { useState } from "react"; -import { 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 InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; -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 GetItemInfo from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo"; import GetItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm"; import GetSubItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm"; -import GetItemInfo from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo"; +import StyledForm from "@/core/components/StyledForm"; +import { useTheme } from "@emotion/react"; +import { yupResolver } from "@hookform/resolvers/yup"; +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import FileCopyIcon from "@mui/icons-material/FileCopy"; +import InfoIcon from "@mui/icons-material/Info"; +import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; +import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight"; +import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material"; import { format } from "date-fns"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { mixed, number, object, string } from "yup"; function TabPanel(props) { const { children, value, index } = props; @@ -29,24 +29,7 @@ const validationSchema = object({ item_id: number().required("نوع آیتم را مشخص کنید!"), sub_item_id: number().required("اقدام انجام شده را مشخص کنید!"), amount: string().required("وارد کردن مقدار الزامیست!"), - cmms_machines: array() - .test("cmms-machines-conditional", "وارد کردن کد خودرو الزامیست!", function (value) { - const { is_gasht } = this.options.context; - if (is_gasht) { - return true; // اگر is_gasht true باشد، این فیلد نیاز به اعتبارسنجی ندارد - } - return Array.isArray(value) && value.length > 0; // حداقل یک کد باید وجود داشته باشد - }) - .min(1, "حداقل یک کد خودرو باید وارد شود!"), // پیام خطا برای زمانی که شرط تست برقرار باشد - rahdaran_id: array() - .test("rahdaran-id-conditional", "وارد کردن کد راهداران الزامیست!", function (value) { - const { is_gasht } = this.options.context; - if (is_gasht) { - return true; // اگر is_gasht true باشد، این فیلد نیاز به اعتبارسنجی ندارد - } - return Array.isArray(value) && value.length > 0; // حداقل یک کد باید وجود داشته باشد - }) - .min(1, "حداقل یک کد راهدار باید وارد شود!"), // پیام خطا برای زمانی که شرط تست برقرار باشد + mission_id: object().required("ماموریت را مشخص کنید!"), activity_time: string().test("activity-time-conditional", "لطفا زمان فعالیت را انتخاب کنید!", function (value) { const { is_gasht } = this.options.context; // دسترسی به context if (is_gasht) { @@ -110,10 +93,9 @@ const CreateFormContent = ({ setOpen, onSubmit, is_gasht = false }) => { start_point: "", end_point: "", ...(!is_gasht && { + mission_id: null, activity_time: "", activity_date: "", - cmms_machines: [], - rahdaran_id: [], }), }; @@ -139,8 +121,6 @@ const CreateFormContent = ({ setOpen, onSubmit, is_gasht = false }) => { "activity_date", "before_image", "after_image", - "cmms_machines", - "rahdaran_id", "start_point", "end_point", ]; @@ -195,20 +175,9 @@ const CreateFormContent = ({ setOpen, onSubmit, is_gasht = false }) => { } if (!is_gasht) { - result.rahdaran_id.forEach((rahdar, index) => { - result[`rahdaran_id[${index}]`] = rahdar.id; - }); - delete result.rahdaran_id; - - result.cmms_machines.forEach((cmms_machine, index) => { - result[`machines_id[${index}]`] = cmms_machine.id; - }); - delete result.cmms_machines; - result[`activity_time`] = format(new Date(result.activity_time), "HH:mm"); + result.mission_id = result.mission_id.id } else { - delete result.rahdaran_id; - delete result.cmms_machines; delete result.activity_date; delete result.activity_time; } diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/ImageUpload.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/ImageUpload.jsx similarity index 97% rename from src/components/dashboard/roadItems/operator/Actions/Create/Forms/ImageUpload.jsx rename to src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/ImageUpload.jsx index 6e33e99..8c23c76 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/ImageUpload.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/ImageUpload.jsx @@ -1,173 +1,173 @@ -import { FormControl, FormHelperText, Grid } from "@mui/material"; -import UploadSystem from "@/core/components/UploadSystem"; -import { Controller } from "react-hook-form"; -import React, { useEffect, useState } from "react"; - -const ImageUpload = ({ control, setValue, errors, getValues, beforeImage = null, afterImage = null }) => { - const [beforeImg, setBeforeImg] = useState(beforeImage ? beforeImage : null); - const [beforeFileType, setBeforeFileType] = useState(beforeImage ? "image/" : null); - const [beforeFileName, setBeforeFileName] = useState(null); - const [showBeforeImage, setShowBeforeImage] = useState(!beforeImage); - - const [afterImg, setAfterImg] = useState(afterImage ? afterImage : null); - const [afterFileType, setAfterFileType] = useState(afterImage ? "image/" : null); - const [afterFileName, setAfterFileName] = useState(null); - const [showAfterImage, setShowAfterImage] = useState(!afterImage); - - useEffect(() => { - const beforeImage = getValues("before_image"); - const afterImage = getValues("after_image"); - - if (beforeImage) { - setShowBeforeImage(false); - - if (typeof beforeImage === "string") { - setBeforeImg(beforeImage); - setBeforeFileType("image/"); - } else if (beforeImage instanceof File) { - setBeforeImg(URL.createObjectURL(beforeImage)); - setBeforeFileType(beforeImage.type); - } - } - - if (afterImage) { - setShowAfterImage(false); - - if (typeof afterImage === "string") { - setAfterImg(afterImage); - setAfterFileType("image/"); - } else if (afterImage instanceof File) { - setAfterImg(URL.createObjectURL(afterImage)); - setAfterFileType(afterImage.type); - } - } - }, [getValues]); - - const handleBeforeFileChange = (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); - setValue("before_image", uploadedFile); - setShowBeforeImage(false); - } - }; - const handleAfterFileChange = (event) => { - const uploadedFile = event.target?.files?.[0]; - if (uploadedFile) { - const fileType = event.target?.files?.[0].type; - const fileName = event.target?.files?.[0].name; - setAfterImg(URL.createObjectURL(uploadedFile)); - setAfterFileType(fileType); - setAfterFileName(fileName); - setValue("after_image", uploadedFile); - setShowAfterImage(false); - } - }; - return ( - - - { - return ( - - - عکس قبل از اقدام - - - - {errors.before_image ? errors.before_image.message : null} - - - ); - }} - /> - - - { - return ( - - - عکس بعد از اقدام - - - - {errors.after_image ? errors.after_image.message : null} - - - ); - }} - /> - - - ); -}; -export default ImageUpload; +import { FormControl, FormHelperText, Grid } from "@mui/material"; +import UploadSystem from "@/core/components/UploadSystem"; +import { Controller } from "react-hook-form"; +import React, { useEffect, useState } from "react"; + +const ImageUpload = ({ control, setValue, errors, getValues, beforeImage = null, afterImage = null }) => { + const [beforeImg, setBeforeImg] = useState(beforeImage ? beforeImage : null); + const [beforeFileType, setBeforeFileType] = useState(beforeImage ? "image/" : null); + const [beforeFileName, setBeforeFileName] = useState(null); + const [showBeforeImage, setShowBeforeImage] = useState(!beforeImage); + + const [afterImg, setAfterImg] = useState(afterImage ? afterImage : null); + const [afterFileType, setAfterFileType] = useState(afterImage ? "image/" : null); + const [afterFileName, setAfterFileName] = useState(null); + const [showAfterImage, setShowAfterImage] = useState(!afterImage); + + useEffect(() => { + const beforeImage = getValues("before_image"); + const afterImage = getValues("after_image"); + + if (beforeImage) { + setShowBeforeImage(false); + + if (typeof beforeImage === "string") { + setBeforeImg(beforeImage); + setBeforeFileType("image/"); + } else if (beforeImage instanceof File) { + setBeforeImg(URL.createObjectURL(beforeImage)); + setBeforeFileType(beforeImage.type); + } + } + + if (afterImage) { + setShowAfterImage(false); + + if (typeof afterImage === "string") { + setAfterImg(afterImage); + setAfterFileType("image/"); + } else if (afterImage instanceof File) { + setAfterImg(URL.createObjectURL(afterImage)); + setAfterFileType(afterImage.type); + } + } + }, [getValues]); + + const handleBeforeFileChange = (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); + setValue("before_image", uploadedFile); + setShowBeforeImage(false); + } + }; + const handleAfterFileChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const fileType = event.target?.files?.[0].type; + const fileName = event.target?.files?.[0].name; + setAfterImg(URL.createObjectURL(uploadedFile)); + setAfterFileType(fileType); + setAfterFileName(fileName); + setValue("after_image", uploadedFile); + setShowAfterImage(false); + } + }; + return ( + + + { + return ( + + + عکس قبل از اقدام + + + + {errors.before_image ? errors.before_image.message : null} + + + ); + }} + /> + + + { + return ( + + + عکس بعد از اقدام + + + + {errors.after_image ? errors.after_image.message : null} + + + ); + }} + /> + + + ); +}; +export default ImageUpload; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx new file mode 100644 index 0000000..6fb60b0 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx @@ -0,0 +1,18 @@ +import { Done } from "@mui/icons-material"; +import { Button } from "@mui/material"; + +const Allocate = ({ row, setMission, setOpenDialog }) => { + const handleClick = () => { + setMission(row.original); + setOpenDialog(false); + }; + + return ( + <> + + + ); +}; +export default Allocate; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/index.jsx new file mode 100644 index 0000000..31e8824 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/index.jsx @@ -0,0 +1,6 @@ +import Allocate from "./Allocate"; + +const RowActions = ({ row, setMission, setOpenDialog }) => { + return ; +}; +export default RowActions; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/index.jsx new file mode 100644 index 0000000..a66e705 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/index.jsx @@ -0,0 +1,111 @@ +import DataTableWithAuth from "@/core/components/DataTableWithAuth"; +import { GET_ROAD_MISSIONS_OPERATOR_LIST } from "@/core/utils/routes"; +import { Box } from "@mui/material"; +import { useMemo } from "react"; +import RowActions from "./RowActions"; +import moment from "jalali-moment"; + +const MissionList = ({ setMission, setOpenDialog }) => { + const columns = useMemo( + () => [ + { + accessorKey: "id", + header: "کد یکتا", + id: "id", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "explanation", + header: "موضوع", + id: "explanation", + enableColumnFilter: false, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 100, + }, + { + accessorKey: "zone", + header: "محدوده", + id: "zone", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + sortDescFirst: true, + grow: false, + size: 100, + columnSelectOption: () => { + return missionRegions.map((region) => ({ + value: region.id, + label: region.name_fa, + })); + }, + Cell: ({ row }) => row.original.zone_fa, + }, + { + accessorFn: (row) => + row.type == 1 + ? moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD") + : moment(row.start_date).locale("fa").format("yyyy/MM/DD"), + header: "تاریخ شروع", + id: "start_date", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + { + accessorFn: (row) => + row.type == 1 + ? moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD") + : moment(row.end_date).locale("fa").format("yyyy/MM/DD"), + header: "تاریخ پایان", + id: "end_date", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + { + accessorKey: "end_point", + header: "مقصد", + id: "end_point", + enableColumnFilter: false, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 100, + }, + ], + [] + ); + + return ( + <> + + ( + + )} + /> + + + ); +}; +export default MissionList; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx new file mode 100644 index 0000000..dbc6856 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx @@ -0,0 +1,40 @@ +import { Close, Edit } from "@mui/icons-material"; +import { Button, Dialog, IconButton } from "@mui/material"; +import { useState } from "react"; +import MissionList from "./MissionsList"; + +const MissionsDialog = ({ setMission, mode }) => { + const [open, setOpen] = useState(false); + return ( + <> + {mode == "edit" ? ( + setOpen(true)}> + + + ) : ( + + )} + + setOpen(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + {open && ( + + )} + + + ); +}; +export default MissionsDialog; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/PreviousStatesInfo.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/PreviousStatesInfo.jsx similarity index 97% rename from src/components/dashboard/roadItems/operator/Actions/Create/Forms/PreviousStatesInfo.jsx rename to src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/PreviousStatesInfo.jsx index a944ccd..51fac42 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/PreviousStatesInfo.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/PreviousStatesInfo.jsx @@ -1,43 +1,43 @@ -import { Box, Chip, Divider, Grid, Typography } from "@mui/material"; -import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; -import FileCopyIcon from "@mui/icons-material/FileCopy"; - -const PreviousStatesInfo = ({ itemsList, subItemsList }) => { - return ( - - - - } - label={ - - آیتم انتخاب ‌شده - - } - /> - - - - {itemsList.name || "هیچ آیتمی انتخاب نشده است"} - - - - - } - label={ - - اقدام انجام شده - - } - /> - - - - {subItemsList?.name || "هیچ اقدامی انتخاب نشده است"} - - - - ); -}; -export default PreviousStatesInfo; +import { Box, Chip, Divider, Grid, Typography } from "@mui/material"; +import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; +import FileCopyIcon from "@mui/icons-material/FileCopy"; + +const PreviousStatesInfo = ({ itemsList, subItemsList }) => { + return ( + + + + } + label={ + + آیتم انتخاب ‌شده + + } + /> + + + + {itemsList.name || "هیچ آیتمی انتخاب نشده است"} + + + + + } + label={ + + اقدام انجام شده + + } + /> + + + + {subItemsList?.name || "هیچ اقدامی انتخاب نشده است"} + + + + ); +}; +export default PreviousStatesInfo; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/index.jsx similarity index 69% rename from src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo.jsx rename to src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/index.jsx index 82d5cca..48e1ce2 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/index.jsx @@ -1,124 +1,115 @@ -import { Grid, Stack } from "@mui/material"; -import ImageUpload from "./ImageUpload"; -import MuiDatePicker from "@/core/components/MuiDatePicker"; -import MuiTimePicker from "@/core/components/MuiTimePicker"; -import MapInfoTwoMarker from "@/core/components/MapInfoTwoMarker"; -import MapInfoOneMarker from "@/core/components/MapInfoOneMarker"; -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, is_gasht }) => { - return ( - - - - - - { - if (!isNaN(event.target.value)) { - setValue("amount", event.target.value); - } else { - setValue("amount", watch("amount")); - } - }} - helperText={errors.amount ? errors.amount.message : null} - variant="outlined" - fullWidth - /> - - {!is_gasht && ( - - { - return ( - field.onChange(value || [])} - error={error} - multiple={true} - /> - ); - }} - name={"cmms_machines"} - /> - - )} - {!is_gasht && ( - - { - return ( - field.onChange(value || [])} - error={error} - /> - ); - }} - name={"rahdaran_id"} - /> - - )} - - {subItemsList.needs_image ? ( - - ) : null} - - {!is_gasht ? ( - - - - - - - - - - - ) : null} - - {subItemsList?.needs_end_point === 1 ? ( - - ) : ( - - )} - - - ); -}; -export default GetItemInfo; +import MapInfoOneMarker from "@/core/components/MapInfoOneMarker"; +import MapInfoTwoMarker from "@/core/components/MapInfoTwoMarker"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import MuiTimePicker from "@/core/components/MuiTimePicker"; +import NumberField from "@/core/components/NumberField"; +import { Chip, Divider, FormHelperText, Grid, Stack, Typography } from "@mui/material"; +import ImageUpload from "./ImageUpload"; +import MissionsDialog from "./MissionsDialog"; +import PreviousStatesInfo from "./PreviousStatesInfo"; +import { Controller } from "react-hook-form"; + +const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, errors, watch, getValues, is_gasht }) => { + return ( + + + + + { + return value ? ( + + + + + onChange(m)} mode={"edit"} /> + + {error ? error.message : null} + + ) : ( + + onChange(m)} /> + {error ? error.message : null} + + ) + }} + /> + + { + if (!isNaN(event.target.value)) { + setValue("amount", event.target.value); + } else { + setValue("amount", watch("amount")); + } + }} + helperText={errors.amount ? errors.amount.message : null} + variant="outlined" + fullWidth + /> + + {!is_gasht ? ( + + + + + + + + + + + ) : null} + + {subItemsList.needs_image ? ( + + ) : null} + + + {subItemsList?.needs_end_point === 1 ? ( + + ) : ( + + )} + + + ); +}; +export default GetItemInfo; \ No newline at end of file diff --git a/src/components/dashboard/roadItems/operator/OperatorList.jsx b/src/components/dashboard/roadItems/operator/OperatorList.jsx index 06b98ff..f4a7648 100644 --- a/src/components/dashboard/roadItems/operator/OperatorList.jsx +++ b/src/components/dashboard/roadItems/operator/OperatorList.jsx @@ -129,8 +129,8 @@ const OperatorList = () => { props.dependencyFieldValue.value === "" ? "empty" : loadingSubItemsList - ? "loading" - : props.filterParameters.value + ? "loading" + : props.filterParameters.value } columnSelectOption={getColumnSelectOptions} /> @@ -219,60 +219,6 @@ const OperatorList = () => { ); }, }, - { - header: "خودرو ها", - id: "cmmsMachines__machine_code", - enableColumnFilter: true, - datatype: "text", - 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, row }) => { - return ( - - - - ); - }, - }, - { - header: "راهداران", - id: "rahdaran__code", - enableColumnFilter: true, - enableSorting: false, - datatype: "text", - filterMode: "contains", - columnFilterModeOptions: ["equals", "contains"], - grow: false, - size: 100, - muiTableBodyCellProps: { - sx: { - borderLeft: "1px solid #e1e1e1", - py: 0, - "&:first-of-type": { - borderLeft: "unset", - }, - }, - }, - Cell: ({ renderedCellValue, row }) => { - return ( - - - - ); - }, - }, { accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"), header: "تاریخ فعالیت", // Start Date diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx index 4004086..5a24c01 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx @@ -1,36 +1,15 @@ -import { Button, DialogActions, DialogContent, Stack } from "@mui/material"; -import ImageUpload from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/ImageUpload"; -import NumberField from "@/core/components/NumberField"; -import { Controller, useForm } from "react-hook-form"; -import CarCode from "@/core/components/CarCode"; -import RahdarCode from "@/core/components/RahdarCode"; -import MapInfoTwoMarker from "@/core/components/MapInfoTwoMarker"; import MapInfoOneMarker from "@/core/components/MapInfoOneMarker"; +import MapInfoTwoMarker from "@/core/components/MapInfoTwoMarker"; +import NumberField from "@/core/components/NumberField"; import StyledForm from "@/core/components/StyledForm"; -import React from "react"; import { yupResolver } from "@hookform/resolvers/yup"; -import { array, mixed, object, string } from "yup"; +import { Button, DialogActions, DialogContent, Stack } from "@mui/material"; +import { useForm } from "react-hook-form"; +import { mixed, object, string } from "yup"; +import ImageUpload from "../../Actions/ObservedGashtCreate/RowActions/ImageUpload"; const validationSchema = object({ amount: string().required("وارد کردن مقدار الزامیست!"), - cmms_machines: array() - .test("cmms-machines-conditional", "وارد کردن کد خودرو الزامیست!", function (value) { - const { is_gasht } = this.options.context; - if (is_gasht) { - return true; // اگر is_gasht true باشد، این فیلد نیاز به اعتبارسنجی ندارد - } - return Array.isArray(value) && value.length > 0; // حداقل یک کد باید وجود داشته باشد - }) - .min(1, "حداقل یک کد خودرو باید وارد شود!"), // پیام خطا برای زمانی که شرط تست برقرار باشد - rahdaran_id: array() - .test("rahdaran-id-conditional", "وارد کردن کد راهداران الزامیست!", function (value) { - const { is_gasht } = this.options.context; - if (is_gasht) { - return true; // اگر is_gasht true باشد، این فیلد نیاز به اعتبارسنجی ندارد - } - return Array.isArray(value) && value.length > 0; // حداقل یک کد باید وجود داشته باشد - }) - .min(1, "حداقل یک کد راهدار باید وارد شود!"), before_image: mixed() .nullable() .test("before-image-required", "لطفا عکس قبل از اقدام را بارگذاری کنید!", function (value) { @@ -124,42 +103,6 @@ const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, set fullWidth /> - {!is_gasht && ( - - { - return ( - field.onChange(value || [])} - inputValueDefault={defaultData?.cmms_machines} - multiple={true} - error={error} // اگر خطا وجود داشته باشد - /> - ); - }} - name={"cmms_machines"} - /> - - )} - {!is_gasht && ( - - { - return ( - field.onChange(value || [])} - error={error} - /> - ); - }} - name={"rahdaran_id"} - /> - - )} {subItem.needs_end_point === 1 ? ( { - + {/* */} ); }; diff --git a/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx b/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx index 807f417..0efcb18 100644 --- a/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx +++ b/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx @@ -127,8 +127,8 @@ const SupervisorList = () => { props.dependencyFieldValue?.value === "" ? "empty" : loadingEdaratList - ? "loading" - : props.filterParameters.value + ? "loading" + : props.filterParameters.value } columnSelectOption={getColumnSelectOptions} /> @@ -227,8 +227,8 @@ const SupervisorList = () => { props.dependencyFieldValue.value === "" ? "empty" : loadingSubItemsList - ? "loading" - : props.filterParameters.value + ? "loading" + : props.filterParameters.value } columnSelectOption={getColumnSelectOptions} /> @@ -316,60 +316,6 @@ const SupervisorList = () => { ); }, }, - { - header: "خودرو ها", - id: "cmmsMachines__machine_code", - enableColumnFilter: true, - datatype: "text", - 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, row }) => { - return ( - - - - ); - }, - }, - { - header: "راهداران", - id: "rahdaran__code", - enableColumnFilter: true, - enableSorting: false, - datatype: "text", - filterMode: "contains", - columnFilterModeOptions: ["equals", "contains"], - grow: false, - size: 100, - muiTableBodyCellProps: { - sx: { - borderLeft: "1px solid #e1e1e1", - py: 0, - "&:first-of-type": { - borderLeft: "unset", - }, - }, - }, - Cell: ({ renderedCellValue, row }) => { - return ( - - - - ); - }, - }, { accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"), header: "تاریخ فعالیت", // Start Date diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx index 312d6dc..f8ae064 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx @@ -1,5 +1,6 @@ import MuiDatePicker from "@/core/components/MuiDatePicker"; import MuiTimePicker from "@/core/components/MuiTimePicker"; +import { makeDateTime } from "@/core/utils/makeDateTime"; import { Grid } from "@mui/material"; import { Controller, useWatch } from "react-hook-form"; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx index 7fda6e0..24bfb15 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/MachineAndDriver/index.jsx @@ -1,7 +1,7 @@ import { Box, Button, Chip, DialogActions, DialogContent, Divider, Stack, Typography } from "@mui/material"; import DriversDialog from "./DriversDialog"; -import MachinesDialog from "./MachinesDialog"; import { useState } from "react"; +import MachinesDialog from "./MachinesDialog"; const MachineAndDriver = ({ setTabState, allData, setAllData, handlePrev }) => { const [machine, setMachine] = useState(allData.machine); diff --git a/src/core/utils/missionCategoryTypes.js b/src/core/utils/missionCategoryTypes.js index d0711ad..10ee11b 100644 --- a/src/core/utils/missionCategoryTypes.js +++ b/src/core/utils/missionCategoryTypes.js @@ -1,5 +1,5 @@ export const missionCategoryTypes = [ { id: 1, name_fa: "فعالیت روزانه" }, { id: 2, name_fa: "گشت راهداری" }, - { id: 3, name_fa: "واکنش سریع" }, + // { id: 3, name_fa: "واکنش سریع" }, ]; From e6e2aa3b55d2f7d7a01b50d4ccbaff7eff1b4cf6 Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Wed, 3 Sep 2025 11:04:05 +0330 Subject: [PATCH 05/10] add update --- .../roadMissions/control/ControlList.jsx | 10 ++++++++++ .../roadMissions/operator/OperatorList.jsx | 20 +++++++++++++++++++ .../roadPatrols/operator/Toolbar.jsx | 2 +- src/core/utils/pageMenuDev.js | 2 +- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/components/dashboard/roadMissions/control/ControlList.jsx b/src/components/dashboard/roadMissions/control/ControlList.jsx index 18e757a..bb631ab 100644 --- a/src/components/dashboard/roadMissions/control/ControlList.jsx +++ b/src/components/dashboard/roadMissions/control/ControlList.jsx @@ -102,6 +102,16 @@ const ControlList = () => { ); }, }, + { + accessorFn: (row) => row.start_time ? moment(row.start_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, + header: "تاریخ خروج", + id: "start_time", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, ], [] ); diff --git a/src/components/dashboard/roadMissions/operator/OperatorList.jsx b/src/components/dashboard/roadMissions/operator/OperatorList.jsx index df9528e..8837ea7 100644 --- a/src/components/dashboard/roadMissions/operator/OperatorList.jsx +++ b/src/components/dashboard/roadMissions/operator/OperatorList.jsx @@ -227,6 +227,26 @@ const OperatorList = () => { ); }, }, + { + accessorFn: (row) => row.start_time ? moment(row.start_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, + header: "تاریخ خروج", + id: "start_time", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + { + accessorFn: (row) => row.finish_time ? moment(row.finish_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, + header: "تاریخ ورود", + id: "finish_time", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, { accessorFn: (row) => moment(row.request_date).locale("fa").format("HH:mm | yyyy/MM/DD"), header: "تاریخ ثبت", diff --git a/src/components/dashboard/roadPatrols/operator/Toolbar.jsx b/src/components/dashboard/roadPatrols/operator/Toolbar.jsx index a799c26..e7b5d74 100644 --- a/src/components/dashboard/roadPatrols/operator/Toolbar.jsx +++ b/src/components/dashboard/roadPatrols/operator/Toolbar.jsx @@ -6,7 +6,7 @@ const Toolbar = ({ table, filterData, mutate }) => { return ( - + {/* */} ); }; diff --git a/src/core/utils/pageMenuDev.js b/src/core/utils/pageMenuDev.js index 118dacb..b4ea525 100644 --- a/src/core/utils/pageMenuDev.js +++ b/src/core/utils/pageMenuDev.js @@ -580,7 +580,7 @@ export const pageMenuDev = [ type: "page", route: "/dashboard/rahdaran", icon: , - permissions: ["all"], + permissions: ["show-rahdaran"], }, { id: "adminManagement", From 781018225bbf9ff37fe74abd426dddad78cdeb8b Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Wed, 3 Sep 2025 15:39:13 +0330 Subject: [PATCH 06/10] add update --- .../Form/GetDateTime/MissionDates/index.jsx | 88 +++++++------ src/core/utils/machineTypes.js | 121 +++++++++++++++++- 2 files changed, 170 insertions(+), 39 deletions(-) diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx index f8ae064..5062e90 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx @@ -13,26 +13,25 @@ const MissionDates = ({ control }) => { const startDateTime = makeDateTime(start_date, start_time); const endDateTime = makeDateTime(end_date, end_time); const now = new Date(); + return ( <> { - return ( - field.onChange(value || [])} - helperText={error ? error.message : null} - /> - ); - }} + render={({ field, fieldState: { error } }) => ( + field.onChange(value || null)} + helperText={error ? error.message : null} + /> + )} /> @@ -45,13 +44,16 @@ const MissionDates = ({ control }) => { name="start_time" error={error} value={field.value} - views={["hours"]} - minTime={ - start_date && new Date(start_date).toDateString() === now.toDateString() - ? now + views={["hours", "minutes"]} + maxTime={ + endDateTime && + start_date && + end_date && + new Date(start_date).toDateString() === + new Date(end_date).toDateString() + ? endDateTime : null } - maxTime={endDateTime ?? null} placeholder={"زمان شروع ماموریت را وارد کنید"} label={"زمان شروع ماموریت"} setFieldValue={(name, value) => field.onChange(value || null)} @@ -65,20 +67,19 @@ const MissionDates = ({ control }) => { { - return ( - field.onChange(value || [])} - helperText={error ? error.message : null} - /> - ); - }} + render={({ field, fieldState: { error } }) => ( + field.onChange(value || null)} + helperText={error ? error.message : null} + /> + )} /> @@ -91,8 +92,22 @@ const MissionDates = ({ control }) => { name="end_time" error={error} value={field.value} - views={["hours"]} - minTime={startDateTime ?? null} + views={["hours", "minutes"]} + minTime={ + startDateTime && + end_date && + start_date && + new Date(start_date).toDateString() === + new Date(end_date).toDateString() + ? startDateTime + : null + } + maxTime={ + end_date && + new Date(end_date).toDateString() === now.toDateString() + ? now + : null + } placeholder={"زمان پایان ماموریت را وارد کنید"} label={"زمان پایان ماموریت"} setFieldValue={(name, value) => field.onChange(value || null)} @@ -105,4 +120,5 @@ const MissionDates = ({ control }) => { ); }; -export default MissionDates; + +export default MissionDates; \ No newline at end of file diff --git a/src/core/utils/machineTypes.js b/src/core/utils/machineTypes.js index e2188bc..9987704 100644 --- a/src/core/utils/machineTypes.js +++ b/src/core/utils/machineTypes.js @@ -1,4 +1,119 @@ export const machineType = [ - { id: "گریدر", name_fa: "گریدر" }, - { id: "لودر", name_fa: "لودر" }, -]; + { "id": "آسفالت تراش", "name_fa": "آسفالت تراش" }, + { "id": "اتوبوس", "name_fa": "اتوبوس" }, + { "id": "اتومیکسر", "name_fa": "اتومیکسر" }, + { "id": "آمبولانس", "name_fa": "آمبولانس" }, + { "id": "اسپریدر کششی", "name_fa": "اسپریدر کششی" }, + { "id": "اسنوتراک", "name_fa": "اسنوتراک" }, + { "id": "بتونیر", "name_fa": "بتونیر" }, + { "id": "برفخور", "name_fa": "برفخور" }, + { "id": "برفخور لودری", "name_fa": "برفخور لودری" }, + { "id": "بلدوزر", "name_fa": "بلدوزر" }, + { "id": "بیل بکهو", "name_fa": "بیل بکهو" }, + { "id": "بیل مکانیکی", "name_fa": "بیل مکانیکی" }, + { "id": "بیل مکانیکی چرخ لاستیکی", "name_fa": "بیل مکانیکی چرخ لاستیکی" }, + { "id": "تانکر آبرسان", "name_fa": "تانکر آبرسان" }, + { "id": "تانکر آب", "name_fa": "تانکر آب" }, + { "id": "تانکر سوخت", "name_fa": "تانکر سوخت" }, + { "id": "تانکر قیر", "name_fa": "تانکر قیر" }, + { "id": "تراکتور", "name_fa": "تراکتور" }, + { "id": "تراگریدر", "name_fa": "تراگریدر" }, + { "id": "تریلر آبپاش", "name_fa": "تریلر آبپاش" }, + { "id": "تریلر بونکر", "name_fa": "تریلر بونکر" }, + { "id": "تریلر حمل قیر", "name_fa": "تریلر حمل قیر" }, + { "id": "تریلر سوخت رسان", "name_fa": "تریلر سوخت رسان" }, + { "id": "تریلر کارواش", "name_fa": "تریلر کارواش" }, + { "id": "تریلر کمپرسی", "name_fa": "تریلر کمپرسی" }, + { "id": "تیغ برفروب کامیونی", "name_fa": "تیغ برفروب کامیونی" }, + { "id": "تیغ برفروب لودری", "name_fa": "تیغ برفروب لودری" }, + { "id": "تیغه تراکتوری", "name_fa": "تیغه تراکتوری" }, + { "id": "جرثقیل", "name_fa": "جرثقیل" }, + { "id": "چکش هیدرولیکی", "name_fa": "چکش هیدرولیکی" }, + { "id": "رله تانک قیر", "name_fa": "رله تانک قیر" }, + { "id": "سواری بیابانی", "name_fa": "سواری بیابانی" }, + { "id": "سواری شهری", "name_fa": "سواری شهری" }, + { "id": "سنگ شکن", "name_fa": "سنگ شکن" }, + { "id": "سنگ شکن ثابت پارکر", "name_fa": "سنگ شکن ثابت پارکر" }, + { "id": "سنگ شکن سیار پارکر", "name_fa": "سنگ شکن سیار پارکر" }, + { "id": "سنگ شکن تلمیت", "name_fa": "سنگ شکن تلمیت" }, + { "id": "ضربه گیر پشت کامیونی", "name_fa": "ضربه گیر پشت کامیونی" }, + { "id": "غلتک", "name_fa": "غلتک" }, + { "id": "غلتک استاتیک", "name_fa": "غلتک استاتیک" }, + { "id": "غلتک پاچه بزی", "name_fa": "غلتک پاچه بزی" }, + { "id": "غلتک چرخ آهنی", "name_fa": "غلتک چرخ آهنی" }, + { "id": "غلتک چرخ لاستیکی", "name_fa": "غلتک چرخ لاستیکی" }, + { "id": "غلتک دستی", "name_fa": "غلتک دستی" }, + { "id": "غلتک کششی", "name_fa": "غلتک کششی" }, + { "id": "غلتک ویبره", "name_fa": "غلتک ویبره" }, + { "id": "غلطک دستی", "name_fa": "غلطک دستی" }, + { "id": "غلطک کششی", "name_fa": "غلطک کششی" }, + { "id": "فینیشر", "name_fa": "فینیشر" }, + { "id": "قیرپاش کششی", "name_fa": "قیرپاش کششی" }, + { "id": "کانتینر", "name_fa": "کانتینر" }, + { "id": "کانکس", "name_fa": "کانکس" }, + { "id": "کارخانه آسفالت", "name_fa": "کارخانه آسفالت" }, + { "id": "کارواش ثابت", "name_fa": "کارواش ثابت" }, + { "id": "کامیون آتشنشانی", "name_fa": "کامیون آتشنشانی" }, + { "id": "کامیون آب نمک پاش", "name_fa": "کامیون آب نمک پاش" }, + { "id": "کامیون آبپاش", "name_fa": "کامیون آبپاش" }, + { "id": "کامیون بالابر", "name_fa": "کامیون بالابر" }, + { "id": "کامیون باری", "name_fa": "کامیون باری" }, + { "id": "کامیون برفخور", "name_fa": "کامیون برفخور" }, + { "id": "کامیون برفروب", "name_fa": "کامیون برفروب" }, + { "id": "کامیون جاروب", "name_fa": "کامیون جاروب" }, + { "id": "کامیون جرثقیل", "name_fa": "کامیون جرثقیل" }, + { "id": "کامیون خط کش", "name_fa": "کامیون خط کش" }, + { "id": "کامیون فلاسک آسفالت", "name_fa": "کامیون فلاسک آسفالت" }, + { "id": "کامیون قیرپاش", "name_fa": "کامیون قیرپاش" }, + { "id": "کامیون کفی", "name_fa": "کامیون کفی" }, + { "id": "کامیون کمپرسی", "name_fa": "کامیون کمپرسی" }, + { "id": "کامیون کشنده", "name_fa": "کامیون کشنده" }, + { "id": "کامیون گاردریل شور", "name_fa": "کامیون گاردریل شور" }, + { "id": "کامیون میکسر", "name_fa": "کامیون میکسر" }, + { "id": "کامیون نمکپاش", "name_fa": "کامیون نمکپاش" }, + { "id": "کامیون کارواش", "name_fa": "کامیون کارواش" }, + { "id": "کامیونت", "name_fa": "کامیونت" }, + { "id": "کامیونت آتشنشانی", "name_fa": "کامیونت آتشنشانی" }, + { "id": "کامیونت بالابر", "name_fa": "کامیونت بالابر" }, + { "id": "کامیونت باری", "name_fa": "کامیونت باری" }, + { "id": "کامیونت تانکر آّب", "name_fa": "کامیونت تانکر آّب" }, + { "id": "کامیونت جرثقیل", "name_fa": "کامیونت جرثقیل" }, + { "id": "کامیونت جاروب", "name_fa": "کامیونت جاروب" }, + { "id": "کامیونت خط کش", "name_fa": "کامیونت خط کش" }, + { "id": "کامیونت سوخت رسان", "name_fa": "کامیونت سوخت رسان" }, + { "id": "کامیونت عملیات", "name_fa": "کامیونت عملیات" }, + { "id": "کامیونت کمپرسی", "name_fa": "کامیونت کمپرسی" }, + { "id": "کفی", "name_fa": "کفی" }, + { "id": "کمرشکن", "name_fa": "کمرشکن" }, + { "id": "کمپرسور", "name_fa": "کمپرسور" }, + { "id": "کوبیت ثابت", "name_fa": "کوبیت ثابت" }, + { "id": "گریدر", "name_fa": "گریدر" }, + { "id": "لکه گیر آسفالت", "name_fa": "لکه گیر آسفالت" }, + { "id": "لودر", "name_fa": "لودر" }, + { "id": "لیفتراک", "name_fa": "لیفتراک" }, + { "id": "ماسه ساز", "name_fa": "ماسه ساز" }, + { "id": "مینی بوس", "name_fa": "مینی بوس" }, + { "id": "مینی بیل", "name_fa": "مینی بیل" }, + { "id": "مینی لودر", "name_fa": "مینی لودر" }, + { "id": "مولد برق", "name_fa": "مولد برق" }, + { "id": "موتور جوش", "name_fa": "موتور جوش" }, + { "id": "موتور کارواش", "name_fa": "موتور کارواش" }, + { "id": "موتورسیکلت", "name_fa": "موتورسیکلت" }, + { "id": "نمک پاش", "name_fa": "نمک پاش" }, + { "id": "نمک پاش ثابت", "name_fa": "نمک پاش ثابت" }, + { "id": "وانت آتشنشانی", "name_fa": "وانت آتشنشانی" }, + { "id": "وانت تک کابین", "name_fa": "وانت تک کابین" }, + { "id": "وانت تک کابین بیابانی", "name_fa": "وانت تک کابین بیابانی" }, + { "id": "وانت تک کابین شهری", "name_fa": "وانت تک کابین شهری" }, + { "id": "وانت دو کابین شهری", "name_fa": "وانت دو کابین شهری" }, + { "id": "وانت دوکابین بیابانی", "name_fa": "وانت دوکابین بیابانی" }, + { "id": "ون", "name_fa": "ون" }, + { "id": "ویبراتور بتون", "name_fa": "ویبراتور بتون" }, + { "id": "پمپ کف کش", "name_fa": "پمپ کف کش" }, + { "id": "تراک میکسر", "name_fa": "تراک میکسر" }, + { "id": "ترانس جوش", "name_fa": "ترانس جوش" }, + { "id": "تجهیزات ثابت", "name_fa": "تجهیزات ثابت" }, + { "id": "دریل واگن", "name_fa": "دریل واگن" }, + { "id": "کامیون سرویس سیار", "name_fa": "کامیون سرویس سیار" }, + { "id": "میکسر آب نمک", "name_fa": "میکسر آب نمک" } +]; \ No newline at end of file From 28af2066966fd5163cf4d74d38d2595c77cb0abd Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Wed, 3 Sep 2025 15:41:15 +0330 Subject: [PATCH 07/10] formating --- .../Create/Forms/CreateFormContent.jsx | 2 +- .../RowActions/Allocate/index.jsx | 7 +- .../GetItemInfo/MissionsDialog/index.jsx | 4 +- .../Create/Forms/GetItemInfo/index.jsx | 28 +-- .../roadItems/operator/OperatorList.jsx | 4 +- .../roadItems/supervisor/SupervisorList.jsx | 8 +- .../roadMissions/control/ControlList.jsx | 3 +- .../Form/GetDateTime/MissionDates/index.jsx | 144 +++++------ .../Form/GetDateTime/MissionDates/index.jsx | 21 +- .../roadMissions/operator/OperatorList.jsx | 6 +- src/core/components/MuiDatePicker.jsx | 13 +- src/core/utils/machineTypes.js | 236 +++++++++--------- src/core/utils/makeDateTime.js | 2 +- 13 files changed, 243 insertions(+), 235 deletions(-) diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx index b5e2105..7476478 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx @@ -176,7 +176,7 @@ const CreateFormContent = ({ setOpen, onSubmit, is_gasht = false }) => { if (!is_gasht) { result[`activity_time`] = format(new Date(result.activity_time), "HH:mm"); - result.mission_id = result.mission_id.id + result.mission_id = result.mission_id.id; } else { delete result.activity_date; delete result.activity_time; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx index 6fb60b0..bb44050 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/MissionsList/RowActions/Allocate/index.jsx @@ -9,7 +9,12 @@ const Allocate = ({ row, setMission, setOpenDialog }) => { return ( <> - diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx index dbc6856..e3efea4 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/MissionsDialog/index.jsx @@ -30,9 +30,7 @@ const MissionsDialog = ({ setMission, mode }) => { > - {open && ( - - )} + {open && } ); diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/index.jsx index 48e1ce2..6aab3ec 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/index.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo/index.jsx @@ -21,28 +21,22 @@ const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, err render={({ field: { onChange, value }, fieldState: { error } }) => { return value ? ( - - + + - onChange(m)} mode={"edit"} /> + onChange(m)} mode={"edit"} /> - {error ? error.message : null} + {error ? error.message : null} ) : ( - onChange(m)} /> - {error ? error.message : null} + onChange(m)} /> + {error ? error.message : null} - ) + ); }} /> - + - + {!is_gasht ? ( @@ -109,7 +103,7 @@ const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, err )} - + ); }; -export default GetItemInfo; \ No newline at end of file +export default GetItemInfo; diff --git a/src/components/dashboard/roadItems/operator/OperatorList.jsx b/src/components/dashboard/roadItems/operator/OperatorList.jsx index f4a7648..7f862e4 100644 --- a/src/components/dashboard/roadItems/operator/OperatorList.jsx +++ b/src/components/dashboard/roadItems/operator/OperatorList.jsx @@ -129,8 +129,8 @@ const OperatorList = () => { props.dependencyFieldValue.value === "" ? "empty" : loadingSubItemsList - ? "loading" - : props.filterParameters.value + ? "loading" + : props.filterParameters.value } columnSelectOption={getColumnSelectOptions} /> diff --git a/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx b/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx index 0efcb18..75005b7 100644 --- a/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx +++ b/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx @@ -127,8 +127,8 @@ const SupervisorList = () => { props.dependencyFieldValue?.value === "" ? "empty" : loadingEdaratList - ? "loading" - : props.filterParameters.value + ? "loading" + : props.filterParameters.value } columnSelectOption={getColumnSelectOptions} /> @@ -227,8 +227,8 @@ const SupervisorList = () => { props.dependencyFieldValue.value === "" ? "empty" : loadingSubItemsList - ? "loading" - : props.filterParameters.value + ? "loading" + : props.filterParameters.value } columnSelectOption={getColumnSelectOptions} /> diff --git a/src/components/dashboard/roadMissions/control/ControlList.jsx b/src/components/dashboard/roadMissions/control/ControlList.jsx index bb631ab..be2443d 100644 --- a/src/components/dashboard/roadMissions/control/ControlList.jsx +++ b/src/components/dashboard/roadMissions/control/ControlList.jsx @@ -103,7 +103,8 @@ const ControlList = () => { }, }, { - accessorFn: (row) => row.start_time ? moment(row.start_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, + accessorFn: (row) => + row.start_time ? moment(row.start_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, header: "تاریخ خروج", id: "start_time", enableColumnFilter: true, diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx index 2f6dc34..8414a10 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx @@ -15,103 +15,105 @@ const MissionDates = ({ control }) => { const endDateTime = makeDateTime(end_date, end_time); const now = new Date(); - return type && ( - <> - - { - return ( - field.onChange(value || [])} - helperText={error ? error.message : null} - /> - ); - }} - /> - - {type == 1 && ( + return ( + type && ( + <> { return ( - field.onChange(value || null)} + disableFuture={false} + minDate={now} + maxDate={end_date ?? null} + placeholder={"تاریخ شروع ماموریت را وارد کنید"} + label={"تاریخ شروع ماموریت"} + setFieldValue={(name, value) => field.onChange(value || [])} helperText={error ? error.message : null} /> ); }} /> - )} - - { - return ( - field.onChange(value || [])} - helperText={error ? error.message : null} - /> - ); - }} - /> - - {type == 1 && ( + {type == 1 && ( + + { + return ( + field.onChange(value || null)} + helperText={error ? error.message : null} + /> + ); + }} + /> + + )} { return ( - field.onChange(value || null)} + disableFuture={false} + minDate={start_date ? start_date : now} + placeholder={"تاریخ پایان ماموریت را وارد کنید"} + label={"تاریخ پایان ماموریت"} + setFieldValue={(name, value) => field.onChange(value || [])} helperText={error ? error.message : null} /> ); }} /> - )} - + {type == 1 && ( + + { + return ( + field.onChange(value || null)} + helperText={error ? error.message : null} + /> + ); + }} + /> + + )} + + ) ); }; export default MissionDates; diff --git a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx index 5062e90..c002df3 100644 --- a/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx +++ b/src/components/dashboard/roadMissions/operator/Actions/CreateWithoutProcess/Form/GetDateTime/MissionDates/index.jsx @@ -47,10 +47,9 @@ const MissionDates = ({ control }) => { views={["hours", "minutes"]} maxTime={ endDateTime && - start_date && - end_date && - new Date(start_date).toDateString() === - new Date(end_date).toDateString() + start_date && + end_date && + new Date(start_date).toDateString() === new Date(end_date).toDateString() ? endDateTime : null } @@ -95,18 +94,14 @@ const MissionDates = ({ control }) => { views={["hours", "minutes"]} minTime={ startDateTime && - end_date && - start_date && - new Date(start_date).toDateString() === - new Date(end_date).toDateString() + end_date && + start_date && + new Date(start_date).toDateString() === new Date(end_date).toDateString() ? startDateTime : null } maxTime={ - end_date && - new Date(end_date).toDateString() === now.toDateString() - ? now - : null + end_date && new Date(end_date).toDateString() === now.toDateString() ? now : null } placeholder={"زمان پایان ماموریت را وارد کنید"} label={"زمان پایان ماموریت"} @@ -121,4 +116,4 @@ const MissionDates = ({ control }) => { ); }; -export default MissionDates; \ No newline at end of file +export default MissionDates; diff --git a/src/components/dashboard/roadMissions/operator/OperatorList.jsx b/src/components/dashboard/roadMissions/operator/OperatorList.jsx index 8837ea7..9625838 100644 --- a/src/components/dashboard/roadMissions/operator/OperatorList.jsx +++ b/src/components/dashboard/roadMissions/operator/OperatorList.jsx @@ -228,7 +228,8 @@ const OperatorList = () => { }, }, { - accessorFn: (row) => row.start_time ? moment(row.start_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, + accessorFn: (row) => + row.start_time ? moment(row.start_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, header: "تاریخ خروج", id: "start_time", enableColumnFilter: true, @@ -238,7 +239,8 @@ const OperatorList = () => { size: 100, }, { - accessorFn: (row) => row.finish_time ? moment(row.finish_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, + accessorFn: (row) => + row.finish_time ? moment(row.finish_time).locale("fa").format("HH:mm | yyyy/MM/DD") : null, header: "تاریخ ورود", id: "finish_time", enableColumnFilter: true, diff --git a/src/core/components/MuiDatePicker.jsx b/src/core/components/MuiDatePicker.jsx index b97bf88..7c8dddd 100644 --- a/src/core/components/MuiDatePicker.jsx +++ b/src/core/components/MuiDatePicker.jsx @@ -6,7 +6,18 @@ import { Box, FormHelperText, IconButton, InputAdornment } from "@mui/material"; import ClearIcon from "@mui/icons-material/Clear"; import moment from "jalali-moment"; -function MuiDatePicker({ value, disableFuture = true, setFieldValue, name, minDate, maxDate, helperText, placeholder, error, label }) { +function MuiDatePicker({ + value, + disableFuture = true, + setFieldValue, + name, + minDate, + maxDate, + helperText, + placeholder, + error, + label, +}) { return ( <> diff --git a/src/core/utils/machineTypes.js b/src/core/utils/machineTypes.js index 9987704..5a5ae78 100644 --- a/src/core/utils/machineTypes.js +++ b/src/core/utils/machineTypes.js @@ -1,119 +1,119 @@ export const machineType = [ - { "id": "آسفالت تراش", "name_fa": "آسفالت تراش" }, - { "id": "اتوبوس", "name_fa": "اتوبوس" }, - { "id": "اتومیکسر", "name_fa": "اتومیکسر" }, - { "id": "آمبولانس", "name_fa": "آمبولانس" }, - { "id": "اسپریدر کششی", "name_fa": "اسپریدر کششی" }, - { "id": "اسنوتراک", "name_fa": "اسنوتراک" }, - { "id": "بتونیر", "name_fa": "بتونیر" }, - { "id": "برفخور", "name_fa": "برفخور" }, - { "id": "برفخور لودری", "name_fa": "برفخور لودری" }, - { "id": "بلدوزر", "name_fa": "بلدوزر" }, - { "id": "بیل بکهو", "name_fa": "بیل بکهو" }, - { "id": "بیل مکانیکی", "name_fa": "بیل مکانیکی" }, - { "id": "بیل مکانیکی چرخ لاستیکی", "name_fa": "بیل مکانیکی چرخ لاستیکی" }, - { "id": "تانکر آبرسان", "name_fa": "تانکر آبرسان" }, - { "id": "تانکر آب", "name_fa": "تانکر آب" }, - { "id": "تانکر سوخت", "name_fa": "تانکر سوخت" }, - { "id": "تانکر قیر", "name_fa": "تانکر قیر" }, - { "id": "تراکتور", "name_fa": "تراکتور" }, - { "id": "تراگریدر", "name_fa": "تراگریدر" }, - { "id": "تریلر آبپاش", "name_fa": "تریلر آبپاش" }, - { "id": "تریلر بونکر", "name_fa": "تریلر بونکر" }, - { "id": "تریلر حمل قیر", "name_fa": "تریلر حمل قیر" }, - { "id": "تریلر سوخت رسان", "name_fa": "تریلر سوخت رسان" }, - { "id": "تریلر کارواش", "name_fa": "تریلر کارواش" }, - { "id": "تریلر کمپرسی", "name_fa": "تریلر کمپرسی" }, - { "id": "تیغ برفروب کامیونی", "name_fa": "تیغ برفروب کامیونی" }, - { "id": "تیغ برفروب لودری", "name_fa": "تیغ برفروب لودری" }, - { "id": "تیغه تراکتوری", "name_fa": "تیغه تراکتوری" }, - { "id": "جرثقیل", "name_fa": "جرثقیل" }, - { "id": "چکش هیدرولیکی", "name_fa": "چکش هیدرولیکی" }, - { "id": "رله تانک قیر", "name_fa": "رله تانک قیر" }, - { "id": "سواری بیابانی", "name_fa": "سواری بیابانی" }, - { "id": "سواری شهری", "name_fa": "سواری شهری" }, - { "id": "سنگ شکن", "name_fa": "سنگ شکن" }, - { "id": "سنگ شکن ثابت پارکر", "name_fa": "سنگ شکن ثابت پارکر" }, - { "id": "سنگ شکن سیار پارکر", "name_fa": "سنگ شکن سیار پارکر" }, - { "id": "سنگ شکن تلمیت", "name_fa": "سنگ شکن تلمیت" }, - { "id": "ضربه گیر پشت کامیونی", "name_fa": "ضربه گیر پشت کامیونی" }, - { "id": "غلتک", "name_fa": "غلتک" }, - { "id": "غلتک استاتیک", "name_fa": "غلتک استاتیک" }, - { "id": "غلتک پاچه بزی", "name_fa": "غلتک پاچه بزی" }, - { "id": "غلتک چرخ آهنی", "name_fa": "غلتک چرخ آهنی" }, - { "id": "غلتک چرخ لاستیکی", "name_fa": "غلتک چرخ لاستیکی" }, - { "id": "غلتک دستی", "name_fa": "غلتک دستی" }, - { "id": "غلتک کششی", "name_fa": "غلتک کششی" }, - { "id": "غلتک ویبره", "name_fa": "غلتک ویبره" }, - { "id": "غلطک دستی", "name_fa": "غلطک دستی" }, - { "id": "غلطک کششی", "name_fa": "غلطک کششی" }, - { "id": "فینیشر", "name_fa": "فینیشر" }, - { "id": "قیرپاش کششی", "name_fa": "قیرپاش کششی" }, - { "id": "کانتینر", "name_fa": "کانتینر" }, - { "id": "کانکس", "name_fa": "کانکس" }, - { "id": "کارخانه آسفالت", "name_fa": "کارخانه آسفالت" }, - { "id": "کارواش ثابت", "name_fa": "کارواش ثابت" }, - { "id": "کامیون آتشنشانی", "name_fa": "کامیون آتشنشانی" }, - { "id": "کامیون آب نمک پاش", "name_fa": "کامیون آب نمک پاش" }, - { "id": "کامیون آبپاش", "name_fa": "کامیون آبپاش" }, - { "id": "کامیون بالابر", "name_fa": "کامیون بالابر" }, - { "id": "کامیون باری", "name_fa": "کامیون باری" }, - { "id": "کامیون برفخور", "name_fa": "کامیون برفخور" }, - { "id": "کامیون برفروب", "name_fa": "کامیون برفروب" }, - { "id": "کامیون جاروب", "name_fa": "کامیون جاروب" }, - { "id": "کامیون جرثقیل", "name_fa": "کامیون جرثقیل" }, - { "id": "کامیون خط کش", "name_fa": "کامیون خط کش" }, - { "id": "کامیون فلاسک آسفالت", "name_fa": "کامیون فلاسک آسفالت" }, - { "id": "کامیون قیرپاش", "name_fa": "کامیون قیرپاش" }, - { "id": "کامیون کفی", "name_fa": "کامیون کفی" }, - { "id": "کامیون کمپرسی", "name_fa": "کامیون کمپرسی" }, - { "id": "کامیون کشنده", "name_fa": "کامیون کشنده" }, - { "id": "کامیون گاردریل شور", "name_fa": "کامیون گاردریل شور" }, - { "id": "کامیون میکسر", "name_fa": "کامیون میکسر" }, - { "id": "کامیون نمکپاش", "name_fa": "کامیون نمکپاش" }, - { "id": "کامیون کارواش", "name_fa": "کامیون کارواش" }, - { "id": "کامیونت", "name_fa": "کامیونت" }, - { "id": "کامیونت آتشنشانی", "name_fa": "کامیونت آتشنشانی" }, - { "id": "کامیونت بالابر", "name_fa": "کامیونت بالابر" }, - { "id": "کامیونت باری", "name_fa": "کامیونت باری" }, - { "id": "کامیونت تانکر آّب", "name_fa": "کامیونت تانکر آّب" }, - { "id": "کامیونت جرثقیل", "name_fa": "کامیونت جرثقیل" }, - { "id": "کامیونت جاروب", "name_fa": "کامیونت جاروب" }, - { "id": "کامیونت خط کش", "name_fa": "کامیونت خط کش" }, - { "id": "کامیونت سوخت رسان", "name_fa": "کامیونت سوخت رسان" }, - { "id": "کامیونت عملیات", "name_fa": "کامیونت عملیات" }, - { "id": "کامیونت کمپرسی", "name_fa": "کامیونت کمپرسی" }, - { "id": "کفی", "name_fa": "کفی" }, - { "id": "کمرشکن", "name_fa": "کمرشکن" }, - { "id": "کمپرسور", "name_fa": "کمپرسور" }, - { "id": "کوبیت ثابت", "name_fa": "کوبیت ثابت" }, - { "id": "گریدر", "name_fa": "گریدر" }, - { "id": "لکه گیر آسفالت", "name_fa": "لکه گیر آسفالت" }, - { "id": "لودر", "name_fa": "لودر" }, - { "id": "لیفتراک", "name_fa": "لیفتراک" }, - { "id": "ماسه ساز", "name_fa": "ماسه ساز" }, - { "id": "مینی بوس", "name_fa": "مینی بوس" }, - { "id": "مینی بیل", "name_fa": "مینی بیل" }, - { "id": "مینی لودر", "name_fa": "مینی لودر" }, - { "id": "مولد برق", "name_fa": "مولد برق" }, - { "id": "موتور جوش", "name_fa": "موتور جوش" }, - { "id": "موتور کارواش", "name_fa": "موتور کارواش" }, - { "id": "موتورسیکلت", "name_fa": "موتورسیکلت" }, - { "id": "نمک پاش", "name_fa": "نمک پاش" }, - { "id": "نمک پاش ثابت", "name_fa": "نمک پاش ثابت" }, - { "id": "وانت آتشنشانی", "name_fa": "وانت آتشنشانی" }, - { "id": "وانت تک کابین", "name_fa": "وانت تک کابین" }, - { "id": "وانت تک کابین بیابانی", "name_fa": "وانت تک کابین بیابانی" }, - { "id": "وانت تک کابین شهری", "name_fa": "وانت تک کابین شهری" }, - { "id": "وانت دو کابین شهری", "name_fa": "وانت دو کابین شهری" }, - { "id": "وانت دوکابین بیابانی", "name_fa": "وانت دوکابین بیابانی" }, - { "id": "ون", "name_fa": "ون" }, - { "id": "ویبراتور بتون", "name_fa": "ویبراتور بتون" }, - { "id": "پمپ کف کش", "name_fa": "پمپ کف کش" }, - { "id": "تراک میکسر", "name_fa": "تراک میکسر" }, - { "id": "ترانس جوش", "name_fa": "ترانس جوش" }, - { "id": "تجهیزات ثابت", "name_fa": "تجهیزات ثابت" }, - { "id": "دریل واگن", "name_fa": "دریل واگن" }, - { "id": "کامیون سرویس سیار", "name_fa": "کامیون سرویس سیار" }, - { "id": "میکسر آب نمک", "name_fa": "میکسر آب نمک" } -]; \ No newline at end of file + { id: "آسفالت تراش", name_fa: "آسفالت تراش" }, + { id: "اتوبوس", name_fa: "اتوبوس" }, + { id: "اتومیکسر", name_fa: "اتومیکسر" }, + { id: "آمبولانس", name_fa: "آمبولانس" }, + { id: "اسپریدر کششی", name_fa: "اسپریدر کششی" }, + { id: "اسنوتراک", name_fa: "اسنوتراک" }, + { id: "بتونیر", name_fa: "بتونیر" }, + { id: "برفخور", name_fa: "برفخور" }, + { id: "برفخور لودری", name_fa: "برفخور لودری" }, + { id: "بلدوزر", name_fa: "بلدوزر" }, + { id: "بیل بکهو", name_fa: "بیل بکهو" }, + { id: "بیل مکانیکی", name_fa: "بیل مکانیکی" }, + { id: "بیل مکانیکی چرخ لاستیکی", name_fa: "بیل مکانیکی چرخ لاستیکی" }, + { id: "تانکر آبرسان", name_fa: "تانکر آبرسان" }, + { id: "تانکر آب", name_fa: "تانکر آب" }, + { id: "تانکر سوخت", name_fa: "تانکر سوخت" }, + { id: "تانکر قیر", name_fa: "تانکر قیر" }, + { id: "تراکتور", name_fa: "تراکتور" }, + { id: "تراگریدر", name_fa: "تراگریدر" }, + { id: "تریلر آبپاش", name_fa: "تریلر آبپاش" }, + { id: "تریلر بونکر", name_fa: "تریلر بونکر" }, + { id: "تریلر حمل قیر", name_fa: "تریلر حمل قیر" }, + { id: "تریلر سوخت رسان", name_fa: "تریلر سوخت رسان" }, + { id: "تریلر کارواش", name_fa: "تریلر کارواش" }, + { id: "تریلر کمپرسی", name_fa: "تریلر کمپرسی" }, + { id: "تیغ برفروب کامیونی", name_fa: "تیغ برفروب کامیونی" }, + { id: "تیغ برفروب لودری", name_fa: "تیغ برفروب لودری" }, + { id: "تیغه تراکتوری", name_fa: "تیغه تراکتوری" }, + { id: "جرثقیل", name_fa: "جرثقیل" }, + { id: "چکش هیدرولیکی", name_fa: "چکش هیدرولیکی" }, + { id: "رله تانک قیر", name_fa: "رله تانک قیر" }, + { id: "سواری بیابانی", name_fa: "سواری بیابانی" }, + { id: "سواری شهری", name_fa: "سواری شهری" }, + { id: "سنگ شکن", name_fa: "سنگ شکن" }, + { id: "سنگ شکن ثابت پارکر", name_fa: "سنگ شکن ثابت پارکر" }, + { id: "سنگ شکن سیار پارکر", name_fa: "سنگ شکن سیار پارکر" }, + { id: "سنگ شکن تلمیت", name_fa: "سنگ شکن تلمیت" }, + { id: "ضربه گیر پشت کامیونی", name_fa: "ضربه گیر پشت کامیونی" }, + { id: "غلتک", name_fa: "غلتک" }, + { id: "غلتک استاتیک", name_fa: "غلتک استاتیک" }, + { id: "غلتک پاچه بزی", name_fa: "غلتک پاچه بزی" }, + { id: "غلتک چرخ آهنی", name_fa: "غلتک چرخ آهنی" }, + { id: "غلتک چرخ لاستیکی", name_fa: "غلتک چرخ لاستیکی" }, + { id: "غلتک دستی", name_fa: "غلتک دستی" }, + { id: "غلتک کششی", name_fa: "غلتک کششی" }, + { id: "غلتک ویبره", name_fa: "غلتک ویبره" }, + { id: "غلطک دستی", name_fa: "غلطک دستی" }, + { id: "غلطک کششی", name_fa: "غلطک کششی" }, + { id: "فینیشر", name_fa: "فینیشر" }, + { id: "قیرپاش کششی", name_fa: "قیرپاش کششی" }, + { id: "کانتینر", name_fa: "کانتینر" }, + { id: "کانکس", name_fa: "کانکس" }, + { id: "کارخانه آسفالت", name_fa: "کارخانه آسفالت" }, + { id: "کارواش ثابت", name_fa: "کارواش ثابت" }, + { id: "کامیون آتشنشانی", name_fa: "کامیون آتشنشانی" }, + { id: "کامیون آب نمک پاش", name_fa: "کامیون آب نمک پاش" }, + { id: "کامیون آبپاش", name_fa: "کامیون آبپاش" }, + { id: "کامیون بالابر", name_fa: "کامیون بالابر" }, + { id: "کامیون باری", name_fa: "کامیون باری" }, + { id: "کامیون برفخور", name_fa: "کامیون برفخور" }, + { id: "کامیون برفروب", name_fa: "کامیون برفروب" }, + { id: "کامیون جاروب", name_fa: "کامیون جاروب" }, + { id: "کامیون جرثقیل", name_fa: "کامیون جرثقیل" }, + { id: "کامیون خط کش", name_fa: "کامیون خط کش" }, + { id: "کامیون فلاسک آسفالت", name_fa: "کامیون فلاسک آسفالت" }, + { id: "کامیون قیرپاش", name_fa: "کامیون قیرپاش" }, + { id: "کامیون کفی", name_fa: "کامیون کفی" }, + { id: "کامیون کمپرسی", name_fa: "کامیون کمپرسی" }, + { id: "کامیون کشنده", name_fa: "کامیون کشنده" }, + { id: "کامیون گاردریل شور", name_fa: "کامیون گاردریل شور" }, + { id: "کامیون میکسر", name_fa: "کامیون میکسر" }, + { id: "کامیون نمکپاش", name_fa: "کامیون نمکپاش" }, + { id: "کامیون کارواش", name_fa: "کامیون کارواش" }, + { id: "کامیونت", name_fa: "کامیونت" }, + { id: "کامیونت آتشنشانی", name_fa: "کامیونت آتشنشانی" }, + { id: "کامیونت بالابر", name_fa: "کامیونت بالابر" }, + { id: "کامیونت باری", name_fa: "کامیونت باری" }, + { id: "کامیونت تانکر آّب", name_fa: "کامیونت تانکر آّب" }, + { id: "کامیونت جرثقیل", name_fa: "کامیونت جرثقیل" }, + { id: "کامیونت جاروب", name_fa: "کامیونت جاروب" }, + { id: "کامیونت خط کش", name_fa: "کامیونت خط کش" }, + { id: "کامیونت سوخت رسان", name_fa: "کامیونت سوخت رسان" }, + { id: "کامیونت عملیات", name_fa: "کامیونت عملیات" }, + { id: "کامیونت کمپرسی", name_fa: "کامیونت کمپرسی" }, + { id: "کفی", name_fa: "کفی" }, + { id: "کمرشکن", name_fa: "کمرشکن" }, + { id: "کمپرسور", name_fa: "کمپرسور" }, + { id: "کوبیت ثابت", name_fa: "کوبیت ثابت" }, + { id: "گریدر", name_fa: "گریدر" }, + { id: "لکه گیر آسفالت", name_fa: "لکه گیر آسفالت" }, + { id: "لودر", name_fa: "لودر" }, + { id: "لیفتراک", name_fa: "لیفتراک" }, + { id: "ماسه ساز", name_fa: "ماسه ساز" }, + { id: "مینی بوس", name_fa: "مینی بوس" }, + { id: "مینی بیل", name_fa: "مینی بیل" }, + { id: "مینی لودر", name_fa: "مینی لودر" }, + { id: "مولد برق", name_fa: "مولد برق" }, + { id: "موتور جوش", name_fa: "موتور جوش" }, + { id: "موتور کارواش", name_fa: "موتور کارواش" }, + { id: "موتورسیکلت", name_fa: "موتورسیکلت" }, + { id: "نمک پاش", name_fa: "نمک پاش" }, + { id: "نمک پاش ثابت", name_fa: "نمک پاش ثابت" }, + { id: "وانت آتشنشانی", name_fa: "وانت آتشنشانی" }, + { id: "وانت تک کابین", name_fa: "وانت تک کابین" }, + { id: "وانت تک کابین بیابانی", name_fa: "وانت تک کابین بیابانی" }, + { id: "وانت تک کابین شهری", name_fa: "وانت تک کابین شهری" }, + { id: "وانت دو کابین شهری", name_fa: "وانت دو کابین شهری" }, + { id: "وانت دوکابین بیابانی", name_fa: "وانت دوکابین بیابانی" }, + { id: "ون", name_fa: "ون" }, + { id: "ویبراتور بتون", name_fa: "ویبراتور بتون" }, + { id: "پمپ کف کش", name_fa: "پمپ کف کش" }, + { id: "تراک میکسر", name_fa: "تراک میکسر" }, + { id: "ترانس جوش", name_fa: "ترانس جوش" }, + { id: "تجهیزات ثابت", name_fa: "تجهیزات ثابت" }, + { id: "دریل واگن", name_fa: "دریل واگن" }, + { id: "کامیون سرویس سیار", name_fa: "کامیون سرویس سیار" }, + { id: "میکسر آب نمک", name_fa: "میکسر آب نمک" }, +]; diff --git a/src/core/utils/makeDateTime.js b/src/core/utils/makeDateTime.js index c3beb21..645a93c 100644 --- a/src/core/utils/makeDateTime.js +++ b/src/core/utils/makeDateTime.js @@ -6,4 +6,4 @@ export const makeDateTime = (date, time) => { d.setHours(t.getHours(), t.getMinutes(), 0, 0); } return d; -}; \ No newline at end of file +}; From 5ac43b6c3ba12d88cb248429246ff85e21ae00dd Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Sat, 6 Sep 2025 10:05:46 +0330 Subject: [PATCH 08/10] add mobile (#1) * add mobile * formatting --- .../Actions/Create/Form/CreateFormContent.jsx | 48 +++++++++++++++++-- .../rahdaran/Actions/Create/Form/index.jsx | 2 + .../rahdaran/Actions/Edit/EditController.jsx | 2 + .../dashboard/rahdaran/RahdaranList.jsx | 11 +++++ 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx index 74a2e76..ff8be50 100644 --- a/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx +++ b/src/components/dashboard/rahdaran/Actions/Create/Form/CreateFormContent.jsx @@ -3,16 +3,19 @@ import StyledForm from "@/core/components/StyledForm"; import validateNationalCode from "@/core/utils/nationalCodeValidation"; import { yupResolver } from "@hookform/resolvers/yup"; import { Beenhere, ExitToApp } from "@mui/icons-material"; -import { Button, DialogActions, DialogContent, Grid, Stack } from "@mui/material"; +import { Button, DialogActions, DialogContent, Grid, Stack, TextField } from "@mui/material"; import { Controller, useForm } from "react-hook-form"; import { object, string } from "yup"; const validationSchema = object({ - name: string().required("وارد کردن نام فارسی الزامیست!"), + name: string().required("وارد کردن نام و نام خانوادگی الزامیست!"), code: string() .required("لطفا کد ملی را وارد کنید!!!") .test("max", "کد ملی باید شامل 10 رقم باشد", (value) => value.toString().length === 10) .test("validation", "کد ملی صحیح نمی باشد", (value) => validateNationalCode(value)), + phone_number: string() + .matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شده و 11 رقم باشد") + .required("لطفا تلفن همراه را وارد کنید!!!"), }); const CreateFormContent = ({ setOpen, defaultValues, onSubmitBase }) => { @@ -44,10 +47,10 @@ const CreateFormContent = ({ setOpen, defaultValues, onSubmitBase }) => { { + + + + ( + { + const inputValue = event.target.value; + if (isNaN(Number(inputValue))) { + return; + } + field.onChange(inputValue); + }} + label="شماره همراه" + placeholder={"شماره همراه را وارد کنید"} + fullWidth + size="small" + error={error} + helperText={error?.message} + InputLabelProps={{ shrink: true }} + /> + )} + /> + + + diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx index 5cb292d..fbc264f 100644 --- a/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx +++ b/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx @@ -10,11 +10,13 @@ const CreateForm = ({ open, setOpen, mutate }) => { const defaultValues = { name: "", code: "", + phone_number: "", }; const onSubmit = async (result) => { const formData = new FormData(); formData.append("name", result.name); formData.append("code", result.code); + formData.append("mobile", result.phone_number); await requestServer(CREATE_RAHDARAN_ITEM, "post", { data: formData, diff --git a/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx b/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx index 61bb336..6fc5d76 100644 --- a/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx +++ b/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx @@ -10,11 +10,13 @@ const EditController = ({ rowId, mutate, setOpen, row }) => { const defaultData = { name: row.original?.name || "", code: row.original?.code || "", + phone_number: row.original?.mobile || "", }; const handleSubmit = async (result) => { const formData = new FormData(); formData.append("name", result.name); formData.append("code", result.code); + formData.append("mobile", result.phone_number); await requestServer(`${UPDATE_RAHDARAN_ITEM}/${rowId}`, "post", { data: formData, diff --git a/src/components/dashboard/rahdaran/RahdaranList.jsx b/src/components/dashboard/rahdaran/RahdaranList.jsx index 90df9e9..7fe1ffb 100644 --- a/src/components/dashboard/rahdaran/RahdaranList.jsx +++ b/src/components/dashboard/rahdaran/RahdaranList.jsx @@ -43,6 +43,17 @@ const RahdaranList = () => { grow: false, size: 100, }, + { + accessorKey: "mobile", + header: "شماره همراه", + id: "mobile", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, ], [] ); From bc74c65622851697bd09be10610a37bd6b2d39c9 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Sun, 7 Sep 2025 10:11:43 +0330 Subject: [PATCH 09/10] Feature/amirris add area tollhouse (#2) * add area * formatting * change text * add province permission --- .../CreateTollHouseContent.jsx | 41 ++++- .../Form/CreateTollHouse/MachineInfo.jsx | 12 +- .../Form/CreateTollHouse/TollHouseArea.jsx | 80 ++++++++++ .../Form/CreateTollHouse/TollHouseInfo.jsx | 6 +- .../tollHouse/Form/CreateTollHouse/index.jsx | 12 ++ .../tollHouse/Form/Edit/EditController.jsx | 11 ++ .../tollHouse/TollHouseList.jsx | 144 +++++++++--------- 7 files changed, 222 insertions(+), 84 deletions(-) create mode 100644 src/components/infrastructure/tollHouse/Form/CreateTollHouse/TollHouseArea.jsx diff --git a/src/components/infrastructure/tollHouse/Form/CreateTollHouse/CreateTollHouseContent.jsx b/src/components/infrastructure/tollHouse/Form/CreateTollHouse/CreateTollHouseContent.jsx index bb3cb1b..a19dfa5 100644 --- a/src/components/infrastructure/tollHouse/Form/CreateTollHouse/CreateTollHouseContent.jsx +++ b/src/components/infrastructure/tollHouse/Form/CreateTollHouse/CreateTollHouseContent.jsx @@ -7,13 +7,15 @@ import OtherHousesIcon from "@mui/icons-material/OtherHouses"; import LocalShippingIcon from "@mui/icons-material/LocalShipping"; import EditLocationAltIcon from "@mui/icons-material/EditLocationAlt"; import React, { useState } from "react"; -import { useForm } from "react-hook-form"; +import { Controller, useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; -import { mixed, number, object, string } from "yup"; +import { array, mixed, number, object, string } from "yup"; import TollHouseInfo from "./TollHouseInfo"; import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; import MachineInfo from "@/components/infrastructure/tollHouse/Form/CreateTollHouse/MachineInfo"; import TollHouseLocation from "@/components/infrastructure/tollHouse/Form/CreateTollHouse/TollHouseLocation"; +import { Route } from "@mui/icons-material"; +import TollHouseArea from "./TollHouseArea"; function TabPanel(props) { const { children, value, index } = props; @@ -54,6 +56,23 @@ const validationSchema = object({ return !!value; }) .required("لطفاً محل پروژه را مشخص کنید!"), + area: array() + .of( + object().shape({ + lat: number() + .typeError("عرض جغرافیایی باید یک عدد معتبر باشد") + .required("عرض جغرافیایی الزامی است") + .min(25, "عرض جغرافیایی نمی‌تواند کمتر از 25 باشد") + .max(40, "عرض جغرافیایی نمی‌تواند بیشتر از 40 باشد"), + lon: number("وارد کردن طول جغرافیایی الزامیست") + .typeError("طول جغرافیایی باید یک عدد معتبر باشد") + .required("طول جغرافیایی الزامی است") + .min(44, "طول جغرافیایی نمی‌تواند کمتر از 44 باشد") + .max(64, "طول جغرافیایی نمی‌تواند بیشتر از 64 باشد"), + }) + ) + .min(4, "حداقل باید ۴ نقطه وجود داشته باشد") + .required("محدوده الزامی است"), }); const CreateTollHouseContent = ({ setOpen, SubmitCreateTollHouse, defaultValues }) => { const [tabState, setTabState] = useState(0); @@ -137,8 +156,9 @@ const CreateTollHouseContent = ({ setOpen, SubmitCreateTollHouse, defaultValues }} > } label="اطلاعات راهدارخانه" /> - } label="ماشین آلات" /> - } label="موقعیت" /> + } label="ماشین آلات" /> + } label="موقعیت" /> + } label="محدوده" /> @@ -151,6 +171,15 @@ const CreateTollHouseContent = ({ setOpen, SubmitCreateTollHouse, defaultValues + + ( + + )} + /> + @@ -163,7 +192,7 @@ const CreateTollHouseContent = ({ setOpen, SubmitCreateTollHouse, defaultValues > {tabState === 0 ? "بستن" : "مرحله قبل"} - {tabState !== 2 && ( + {tabState !== 3 && ( + + + + + ); +}; +export default TollHouseArea; diff --git a/src/components/infrastructure/tollHouse/Form/CreateTollHouse/TollHouseInfo.jsx b/src/components/infrastructure/tollHouse/Form/CreateTollHouse/TollHouseInfo.jsx index 22e3fdc..dc56843 100644 --- a/src/components/infrastructure/tollHouse/Form/CreateTollHouse/TollHouseInfo.jsx +++ b/src/components/infrastructure/tollHouse/Form/CreateTollHouse/TollHouseInfo.jsx @@ -106,9 +106,9 @@ const TollHouseInfo = ({ control }) => { value={field.value} label="نوع" selectors={[ - { id: 0, name: "داعمی" }, - { id: 1, name: "موقت" }, - { id: 2, name: "فصلی" }, + { id: 1, name: "دائمی" }, + { id: 2, name: "موقت" }, + { id: 3, name: "فصلی" }, ]} schema={{ name: "name", value: "id" }} error={error} diff --git a/src/components/infrastructure/tollHouse/Form/CreateTollHouse/index.jsx b/src/components/infrastructure/tollHouse/Form/CreateTollHouse/index.jsx index 7dbe3d5..a9cb7cf 100644 --- a/src/components/infrastructure/tollHouse/Form/CreateTollHouse/index.jsx +++ b/src/components/infrastructure/tollHouse/Form/CreateTollHouse/index.jsx @@ -51,6 +51,12 @@ const CreateTollHouse = ({ mutate }) => { }); formData.append("lat", result.start_point.lat); formData.append("lng", result.start_point.lng); + formData.append("area[type]", "polygon"); + result.area.map((point, pointIndex) => { + formData.append(`area[coordinates][${pointIndex}][0]`, point.lat); + formData.append(`area[coordinates][${pointIndex}][1]`, point.lon); + }); + await requestServer(`${CREATE_TOLL_HOUSE}`, "post", { data: formData, }) @@ -83,6 +89,12 @@ const CreateTollHouse = ({ mutate }) => { overview_files_4: null, overview_files_5: null, start_point: "", + area: [ + { lat: "", lon: "" }, + { lat: "", lon: "" }, + { lat: "", lon: "" }, + { lat: "", lon: "" }, + ], }; return ( <> diff --git a/src/components/infrastructure/tollHouse/Form/Edit/EditController.jsx b/src/components/infrastructure/tollHouse/Form/Edit/EditController.jsx index a9d4281..58b108b 100644 --- a/src/components/infrastructure/tollHouse/Form/Edit/EditController.jsx +++ b/src/components/infrastructure/tollHouse/Form/Edit/EditController.jsx @@ -47,6 +47,12 @@ const EditController = ({ rowId, mutate, setOpenEditDialog }) => { overview_files_3: tollHouseItemDetails?.files[2]?.path || null, overview_files_4: tollHouseItemDetails?.files[3]?.path || null, overview_files_5: tollHouseItemDetails?.files[4]?.path || null, + area: tollHouseItemDetails?.area?.coordinates.map(([lat, lon]) => ({ lat, lon })) || [ + { lat: "", lon: "" }, + { lat: "", lon: "" }, + { lat: "", lon: "" }, + { lat: "", lon: "" }, + ], }; const HandleSubmit = async (result) => { const fields = [ @@ -79,6 +85,11 @@ const EditController = ({ rowId, mutate, setOpenEditDialog }) => { } formData.append("lat", result.start_point.lat); formData.append("lng", result.start_point.lng); + formData.append("area[type]", "polygon"); + result.area.map((point, pointIndex) => { + formData.append(`area[coordinates][${pointIndex}][0]`, point.lat); + formData.append(`area[coordinates][${pointIndex}][1]`, point.lon); + }); await requestServer(`${UPDATE_TOLL_HOUSE_ITEM}/${rowId}`, "post", { data: formData, diff --git a/src/components/infrastructure/tollHouse/TollHouseList.jsx b/src/components/infrastructure/tollHouse/TollHouseList.jsx index 113dcbc..4ef1674 100644 --- a/src/components/infrastructure/tollHouse/TollHouseList.jsx +++ b/src/components/infrastructure/tollHouse/TollHouseList.jsx @@ -12,6 +12,7 @@ import useEdaratLists from "@/lib/hooks/useEdaratLists"; import { usePermissions } from "@/lib/hooks/usePermissions"; import LocationForm from "./RowActions/LocationForm"; import ImageDialog from "./RowActions/ImageForm"; +import { useAuth } from "@/lib/contexts/auth"; const statusOptions = [ { value: "", label: "همه وضعیت ها" }, @@ -21,14 +22,51 @@ const statusOptions = [ const typeOptions = [ { value: "", label: "همه نوع ها" }, { value: 0, label: "فصلی" }, - { value: 1, label: "داعمی" }, + { value: 1, label: "دائمی" }, { value: 2, label: "موقت" }, ]; const TollHouseList = () => { const { data: userPermissions } = usePermissions(); - const hasProvincePermission = userPermissions.some((item) => ["add-tollhouse"].includes(item)); + const hasCountryPermission = userPermissions?.includes("show-tollhouse"); + const { user } = useAuth(); const columns = useMemo(() => { + const provinceColumn = { + 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_name}, + }; return [ { accessorKey: "id", @@ -64,42 +102,7 @@ const TollHouseList = () => { 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_name}, - }, + ...(hasCountryPermission ? [provinceColumn] : []), { accessorKey: "city_id", header: "شهرستان", // Office @@ -107,17 +110,19 @@ const TollHouseList = () => { enableColumnFilter: true, datatype: "numeric", filterMode: "equals", - dependencyId: "province_id", + dependencyId: hasCountryPermission ? "province_id" : null, grow: false, size: 120, ColumnSelectComponent: (props) => { const { edaratList, loadingEdaratList, errorEdaratList } = useEdaratLists( - props.dependencyFieldValue.value + hasCountryPermission ? props.dependencyFieldValue.value : user.province_id + ); + const [prevDependency, setPrevDependency] = useState( + hasCountryPermission ? props.dependencyFieldValue.value : user.province_id ); - const [prevDependency, setPrevDependency] = useState(props.dependencyFieldValue.value); const getColumnSelectOptions = useMemo(() => { - if (props.dependencyFieldValue.value === "") { + if (hasCountryPermission && props.dependencyFieldValue.value === "") { return [{ value: "empty", label: "ابتدا استان را انتخاب کنید" }]; } if (loadingEdaratList) { @@ -135,10 +140,11 @@ const TollHouseList = () => { ]; }, [edaratList, loadingEdaratList, errorEdaratList]); useEffect(() => { + if (hasCountryPermission) return; if (prevDependency === props.dependencyFieldValue?.value) return; props.handleChange({ ...props.filterParameters, value: "" }); setPrevDependency(props.dependencyFieldValue?.value); - }, [props.dependencyFieldValue?.value]); + }, [props.dependencyFieldValue?.value, hasCountryPermission]); return ( { return {row.original.type_fa}; }, }, + { + header: "موقعیت", // Location + 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: ({ renderedCellValue, row }) => { + return ( + + + + ); + }, + }, { accessorKey: "phone", header: "تلفن راهدارخانه", @@ -352,31 +383,6 @@ const TollHouseList = () => { }, ], }, - { - header: "موقعیت", // Location - 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: ({ renderedCellValue, row }) => { - return ( - - - - ); - }, - }, { accessorFn: (row) => moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"), header: "تاریخ ثبت", @@ -402,7 +408,7 @@ const TollHouseList = () => { sorting={[{ id: "id", desc: true }]} TableToolbar={Toolbar} enableRowActions - positionActionsColumn={"last"} + positionActionsColumn={"first"} RowActions={RowActions} /> From 1fb24dbb6831695d2ca5672730a11e939f22584a Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Sun, 7 Sep 2025 10:12:53 +0330 Subject: [PATCH 10/10] change version to 1.7.3 --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 37aa8cf..1328a44 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ HOST="rms.witel.ir" -NEXT_PUBLIC_VERSION="1.7.0" +NEXT_PUBLIC_VERSION="1.7.3" NEXT_PUBLIC_API_URL="https://rms.witel.ir" NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map" \ No newline at end of file