From c3d7375e2be0ef5af64607b53bea314a02e40256 Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Sat, 11 Oct 2025 13:36:59 +0330 Subject: [PATCH] add continue mission --- .../MapControlPolygon/DrawBound/index.jsx | 129 +++++++++ .../Form/Area/MapControlPolygon/index.jsx | 116 ++++++++ .../MapControlPolyline/DrawBound/index.jsx | 129 +++++++++ .../Form/Area/MapControlPolyline/index.jsx | 116 ++++++++ .../Dialog/Form/Area/OldBoundLayer/index.jsx | 30 ++ .../Form/Area/SelectBoundType/index.jsx | 25 ++ .../AddController/Dialog/Form/Area/index.jsx | 56 ++++ .../Form/GetDateTime/MissionDates/index.jsx | 60 ++++ .../Dialog/Form/GetDateTime/index.jsx | 83 ++++++ .../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 ++ .../Dialog/Form/GetItemInfo/index.jsx | 153 ++++++++++ .../Dialog/Form/Verify/index.jsx | 130 +++++++++ .../Add/AddController/Dialog/Form/index.jsx | 102 +++++++ .../Add/AddController/Dialog/index.jsx | 83 ++++++ .../RowActions/Add/AddController/index.jsx | 52 ++++ .../operator/RowActions/Add/index.jsx | 47 +++ .../RowActions/Edit/EditController/index.jsx | 4 +- .../operator/RowActions/index.jsx | 6 + src/core/utils/routes.js | 1 + 23 files changed, 1695 insertions(+), 2 deletions(-) create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolygon/DrawBound/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolygon/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolyline/DrawBound/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolyline/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/OldBoundLayer/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/SelectBoundType/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetDateTime/MissionDates/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetDateTime/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Verify/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/index.jsx create mode 100644 src/components/dashboard/roadMissions/operator/RowActions/Add/index.jsx diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolygon/DrawBound/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolygon/DrawBound/index.jsx new file mode 100644 index 0000000..a2134c5 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolygon/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolygon/index.jsx new file mode 100644 index 0000000..186a0b6 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolyline/DrawBound/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolyline/DrawBound/index.jsx new file mode 100644 index 0000000..682be24 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolyline/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/MapControlPolyline/index.jsx new file mode 100644 index 0000000..edd6cac --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/Area/OldBoundLayer/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/OldBoundLayer/index.jsx new file mode 100644 index 0000000..1f74ad5 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/OldBoundLayer/index.jsx @@ -0,0 +1,30 @@ +import { useEffect } from "react"; +import { Polygon, Polyline, useMap } from "react-leaflet"; + +const OldBoundLayer = ({ bound }) => { + const map = useMap(); + + const safeFitBounds = (coordinates) => { + if (!map) return; + try { + const latLngs = coordinates; + map.fitBounds(latLngs, { + paddingTopLeft: [70, 70], + paddingBottomRight: [70, 70], + }); + } catch (e) { + console.warn("fitBounds failed:", e); + } + }; + + useEffect(() => { + safeFitBounds(bound.coordinates); + }, []); + + return bound.type == "polygon" ? ( + + ) : ( + + ); +}; +export default OldBoundLayer; diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/SelectBoundType/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/SelectBoundType/index.jsx new file mode 100644 index 0000000..a69a0ba --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/Area/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/index.jsx new file mode 100644 index 0000000..fdbd268 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Area/index.jsx @@ -0,0 +1,56 @@ +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"; +import OldBoundLayer from "./OldBoundLayer"; +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); + +const Area = ({ allData, setAllData, handlePrev, setTabState, oldBound }) => { + 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/RowActions/Add/AddController/Dialog/Form/GetDateTime/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetDateTime/MissionDates/index.jsx new file mode 100644 index 0000000..7de1570 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetDateTime/MissionDates/index.jsx @@ -0,0 +1,60 @@ +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import MuiTimePicker from "@/core/components/MuiTimePicker"; +import { Grid } from "@mui/material"; +import { Controller, useWatch } from "react-hook-form"; + +const MissionDates = ({ control }) => { + const type = useWatch({ control, name: "type" }); + const now = new Date(); + + return ( + type && ( + <> + + { + return ( + 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/RowActions/Add/AddController/Dialog/Form/GetDateTime/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetDateTime/index.jsx new file mode 100644 index 0000000..42c977f --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetDateTime/index.jsx @@ -0,0 +1,83 @@ +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 { Alert, 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({ + type: string().required("نوع ماموریت را مشخص کنید!"), + end_date: string().required("تاریخ پایان ماموریت را مشخص کنید!"), + end_time: string().when("type", { + is: "1", + then: (schema) => schema.required("زمان پایان ماموریت را مشخص کنید!"), + otherwise: (schema) => schema.notRequired(), + }), +}); + +const GetDateTime = ({ allData, setAllData, handlePrev, setTabState }) => { + const defaultValues = { + type: allData.type, + 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/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx new file mode 100644 index 0000000..1e7e881 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx new file mode 100644 index 0000000..3d0b958 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx new file mode 100644 index 0000000..82a0472 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/Dialog/index.jsx new file mode 100644 index 0000000..013f73f --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/FastReactCode/index.jsx new file mode 100644 index 0000000..1545046 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/GetItemInfo/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/GetItemInfo/index.jsx new file mode 100644 index 0000000..3b3b513 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/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/RowActions/Add/AddController/Dialog/Form/Verify/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Verify/index.jsx new file mode 100644 index 0000000..9e33b27 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/Verify/index.jsx @@ -0,0 +1,130 @@ +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 "../../../../../../Actions/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/RowActions/Add/AddController/Dialog/Form/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/index.jsx new file mode 100644 index 0000000..42f2c36 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/Form/index.jsx @@ -0,0 +1,102 @@ +import { AccessTime, InsertDriveFile, 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 Verify from "./Verify"; + +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, oldBound }) => { + 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="بررسی نهایی" /> + + + { + 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/RowActions/Add/AddController/Dialog/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/index.jsx new file mode 100644 index 0000000..440c4e9 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/Dialog/index.jsx @@ -0,0 +1,83 @@ +import { REQUEST_MISSION_CONTINUE_MISSION } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import moment from "jalali-moment"; +import { useState } from "react"; +import CreateForm from "./Form"; + +const DialogAdd = ({ mutate, setOpen, oldBound, rahdaran, machine, row }) => { + const [submitting, setSubmitting] = useState(false); + const requestServer = useRequest({ notificationSuccess: 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_CONTINUE_MISSION}/${row.original.id}`, "post", { + data: { + ...(result.rahdaran.length != 0 ? { rahdaran: result.rahdaran.map((r) => r.id) } : {}), + machines: [result.machine.id], + driver: result.driver.id, + zone: result.region, + type: result.type, + ...(result.type == 1 + ? { + end_date: `${result.end_date} ${moment(result.end_time).format("HH:mm")}`, + } + : { + end_date: result.end_date, + }), + end_point: result.end_point, + area: { + type: result.bound_type, + coordinates: area, + }, + category_id: result.category_id, + explanation: result.explanation, + ...(result.category_id == 3 + ? { + road_observed_id: result.road_observed_id, + } + : {}), + }, + hasSidebarUpdate: true, + }) + .then((response) => { + mutate(); + setOpen(false); + }) + .catch((error) => {}) + .finally(() => { + setSubmitting(false); + }); + }; + + return ( + !r.is_driver), + bound_type: "polygon", + type: "", + end_date: "", + end_time: null, + end_point: "", + region: "", + machine: machine, + driver: rahdaran.find((r) => r.is_driver), + }} + oldBound={oldBound} + submitForm={submitForm} + submitting={submitting} + open={open} + setOpen={setOpen} + mutate={mutate} + /> + ); +}; +export default DialogAdd; diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/index.jsx new file mode 100644 index 0000000..63caea6 --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/AddController/index.jsx @@ -0,0 +1,52 @@ +import DialogLoading from "@/core/components/DialogLoading"; +import { GET_MACHINES_BY_ID, GET_RAHDARAN_BY_ID } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import L from "leaflet"; +import { useEffect, useMemo, useState } from "react"; +import DialogAdd from "./Dialog"; + +const AddController = ({ row, mutate, setOpenAddDialog }) => { + const [rahdaran, setRahdaran] = useState(null); + const [rahdaranLoading, setRahdaranLoading] = useState(true); + const [machine, setMachine] = useState(null); + const [machineLoading, setMachineLoading] = useState(true); + const requestServer = useRequest(); + + useEffect(() => { + setRahdaranLoading(true); + requestServer(`${GET_RAHDARAN_BY_ID}/${row.original.id}`, "get") + .then((response) => { + setRahdaran(response.data.data); + setRahdaranLoading(false); + }) + .catch((e) => { + setRahdaranLoading(false); + }); + }, [row.original.id]); + + useEffect(() => { + setMachineLoading(true); + requestServer(`${GET_MACHINES_BY_ID}/${row.original.id}`, "get") + .then((response) => { + setMachine(response.data.data[0]); + setMachineLoading(false); + }) + .catch((e) => { + setMachineLoading(false); + }); + }, [row.original.id]); + + return rahdaranLoading || machineLoading ? ( + + ) : ( + + ); +}; +export default AddController; diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Add/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Add/index.jsx new file mode 100644 index 0000000..e743a0e --- /dev/null +++ b/src/components/dashboard/roadMissions/operator/RowActions/Add/index.jsx @@ -0,0 +1,47 @@ +import { Add, Close } from "@mui/icons-material"; +import { Dialog, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import AddController from "./AddController"; + +const AddDialog = ({ row, mutate }) => { + const [openAddDialog, setOpenAddDialog] = useState(false); + + return ( + <> + + { + setOpenAddDialog(true); + }} + > + + + + + setOpenAddDialog(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + {openAddDialog && ( + + )} + + + ); +}; +export default AddDialog; diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Edit/EditController/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Edit/EditController/index.jsx index 1fdda15..bfc214a 100644 --- a/src/components/dashboard/roadMissions/operator/RowActions/Edit/EditController/index.jsx +++ b/src/components/dashboard/roadMissions/operator/RowActions/Edit/EditController/index.jsx @@ -16,7 +16,7 @@ const EditController = ({ row, mutate, openEditDialog, setOpenEditDialog }) => { ); const [submitting, setSubmitting] = useState(false); const [rahdaran, setRahdaran] = useState(null); - const [rahdaranLoading, setRahdaranLoading] = useState(false); + const [rahdaranLoading, setRahdaranLoading] = useState(true); const requestServer = useRequest(); useEffect(() => { @@ -87,7 +87,7 @@ const EditController = ({ row, mutate, openEditDialog, setOpenEditDialog }) => { explanation: row.original.explanation, category_id: row.original.category_id, road_observed_id: row.original.category_id == 3 ? row.original.road_observed[0].id : "", - rahdaran: rahdaran, + rahdaran: rahdaran.filter((r) => !r.isDriver), requested_machines: row.original.requested_machines, bound: bound, bound_type: row.original.area.type, diff --git a/src/components/dashboard/roadMissions/operator/RowActions/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/index.jsx index b5659da..38e6f9d 100644 --- a/src/components/dashboard/roadMissions/operator/RowActions/index.jsx +++ b/src/components/dashboard/roadMissions/operator/RowActions/index.jsx @@ -2,6 +2,7 @@ import { Box } from "@mui/material"; import Edit from "./Edit"; import Delete from "./Delete"; import { useAuth } from "@/lib/contexts/auth"; +import Add from "./Add"; const RowActions = ({ row, mutate }) => { const { user } = useAuth(); @@ -14,6 +15,11 @@ const RowActions = ({ row, mutate }) => { )} + {row.original.state_id == 3 && user.id == row.original.user_id && ( + <> + + + )} ); }; diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index bd25977..1ddf8dc 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -217,6 +217,7 @@ export const GET_ROAD_MISSIONS_TRANSPORTATION_LIST = api + "/api/v3/missions/tra export const GET_ROAD_MISSIONS_CONTROL_LIST = api + "/api/v3/missions/control_unit"; export const REQUEST_MISSION = api + "/api/v3/missions/request_portal"; export const REQUEST_MISSION_WITHOUT_PROCESS = api + "/api/v3/missions/request_portal/no_process"; +export const REQUEST_MISSION_CONTINUE_MISSION = api + "/api/v3/missions/request_portal/continue"; export const UPDATE_REQUEST_MISSION = api + "/api/v3/missions/request_portal"; export const DELETE_REQUEST_MISSION = api + "/api/v3/missions/request_portal"; export const GET_RAHDARAN_BY_ID = api + "/api/v3/missions/details/rahdaran";