diff --git a/.env.example b/.env.example
index 07cc628..bc22b8a 100644
--- a/.env.example
+++ b/.env.example
@@ -1,4 +1,4 @@
HOST="rms.witel.ir"
-NEXT_PUBLIC_VERSION="1.4.3"
+NEXT_PUBLIC_VERSION="1.5.0"
NEXT_PUBLIC_API_URL="https://rms.witel.ir"
NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map"
\ No newline at end of file
diff --git a/package.json b/package.json
index 45edef7..a4532cb 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
"react-leaflet": "^4.2.1",
"react-leaflet-draw": "^0.20.4",
"react-leaflet-markercluster": "^4.2.1",
+ "react-qr-code": "^2.0.18",
"react-toastify": "^10.0.5",
"sass": "^1.75.0",
"sharp": "^0.33.4",
diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/rahdaran/page.js b/src/app/(withAuth)/(dashboardLayout)/dashboard/rahdaran/page.js
new file mode 100644
index 0000000..67311d9
--- /dev/null
+++ b/src/app/(withAuth)/(dashboardLayout)/dashboard/rahdaran/page.js
@@ -0,0 +1,10 @@
+import RahdaranTablePage from "@/components/dashboard/rahdaran";
+import WithPermission from "@/core/middlewares/withPermission";
+
+export default function page() {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-missions/operator/page.js b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-missions/operator/page.js
index a788616..417937a 100644
--- a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-missions/operator/page.js
+++ b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-missions/operator/page.js
@@ -7,7 +7,13 @@ export const metadata = {
const Page = () => {
return (
<>
-
+
{/* */}
diff --git a/src/assets/scss/map-styles.scss b/src/assets/scss/map-styles.scss
index 44a88a0..cabcd68 100644
--- a/src/assets/scss/map-styles.scss
+++ b/src/assets/scss/map-styles.scss
@@ -15,6 +15,7 @@
.leaflet-draw-tooltip {
margin-left: 0;
margin-right: 20px;
+ font-family: IRANSansFaNum;
}
.leaflet-draw-tooltip::before {
border-left: 6px solid black;
diff --git a/src/components/dashboard/damages/operator/Form/CreateFactor/CreateFactorContent.jsx b/src/components/dashboard/damages/operator/Form/CreateFactor/CreateFactorContent.jsx
index b538199..fe8380b 100644
--- a/src/components/dashboard/damages/operator/Form/CreateFactor/CreateFactorContent.jsx
+++ b/src/components/dashboard/damages/operator/Form/CreateFactor/CreateFactorContent.jsx
@@ -17,6 +17,7 @@ import {
Typography,
} from "@mui/material";
import { useReducer, useState } from "react";
+import QRCode from "react-qr-code";
const initialState = {
submittingCreateFactor: false,
@@ -147,15 +148,53 @@ const CreateFactorContent = ({ row, mutate, rowId, setOpenCreateFactorDialog })
ریال
- {!factorCreated && (
+ {factorCreated ? (
+
+
+
+ {row.original.is_foreign ? (
+ <>
+
+ میتوانید برای پرداخت، بارکد را اسکن کنید
+
+ >
+ ) : (
+ <>
+
+ لینک پرداخت به شماره همراه مورد نظر ارسال شد
+
+
+ همچنین میتوانید برای پرداخت، بارکد را اسکن کنید
+
+ >
+ )}
+
+
+
+
+
+
+ ) : (
پس از صدور فاکتور، امکان ویرایش مبالغ بیمه و داغی وجود نخواهد داشت
-
- لینک پرداخت فاکتور به شماره {row.original?.driver_phone_number} ارسال می شود.
-
+ {!row.original.is_foreign && (
+
+ لینک پرداخت فاکتور به شماره {row.original?.driver_phone_number} ارسال می شود.
+
+ )}
)}
@@ -172,15 +211,17 @@ const CreateFactorContent = ({ row, mutate, rowId, setOpenCreateFactorDialog })
>
بستن
-
+ {!row.original.is_foreign && (
+
+ )}
+
+
+ >
+ );
+};
+export default CreateFormContent;
diff --git a/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx b/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx
new file mode 100644
index 0000000..5cb292d
--- /dev/null
+++ b/src/components/dashboard/rahdaran/Actions/Create/Form/index.jsx
@@ -0,0 +1,57 @@
+import { Dialog, DialogTitle, IconButton } from "@mui/material";
+import CreateFormContent from "./CreateFormContent";
+import CloseIcon from "@mui/icons-material/Close";
+import useRequest from "@/lib/hooks/useRequest";
+import { CREATE_RAHDARAN_ITEM } from "@/core/utils/routes";
+import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
+
+const CreateForm = ({ open, setOpen, mutate }) => {
+ const requestServer = useRequest({ notificationSuccess: true });
+ const defaultValues = {
+ name: "",
+ code: "",
+ };
+ const onSubmit = async (result) => {
+ const formData = new FormData();
+ formData.append("name", result.name);
+ formData.append("code", result.code);
+
+ await requestServer(CREATE_RAHDARAN_ITEM, "post", {
+ data: formData,
+ })
+ .then(() => {
+ mutate();
+ setOpen(false);
+ })
+ .catch(() => {});
+ };
+ return (
+
+ );
+};
+export default CreateForm;
diff --git a/src/components/dashboard/rahdaran/Actions/Create/index.jsx b/src/components/dashboard/rahdaran/Actions/Create/index.jsx
new file mode 100644
index 0000000..8417fd5
--- /dev/null
+++ b/src/components/dashboard/rahdaran/Actions/Create/index.jsx
@@ -0,0 +1,36 @@
+import { AddCircle } from "@mui/icons-material";
+import { Button, IconButton, useMediaQuery, useTheme } from "@mui/material";
+import CreateForm from "./Form";
+import { useState } from "react";
+
+const CreateRahdar = ({ mutate }) => {
+ const theme = useTheme();
+ const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
+ const [open, setOpen] = useState(false);
+
+ const handleOpen = () => {
+ setOpen(true);
+ };
+
+ return (
+ <>
+ {isMobile ? (
+
+
+
+ ) : (
+ }
+ onClick={handleOpen}
+ >
+ ثبت راهدار
+
+ )}
+
+ >
+ );
+};
+export default CreateRahdar;
diff --git a/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx b/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx
new file mode 100644
index 0000000..61bb336
--- /dev/null
+++ b/src/components/dashboard/rahdaran/Actions/Edit/EditController.jsx
@@ -0,0 +1,37 @@
+import { UPDATE_RAHDARAN_ITEM } from "@/core/utils/routes";
+import useRequest from "@/lib/hooks/useRequest";
+import { DialogTitle } from "@mui/material";
+import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
+import CreateFormContent from "../Create/Form/CreateFormContent";
+
+const EditController = ({ rowId, mutate, setOpen, row }) => {
+ const requestServer = useRequest({ notificationSuccess: true });
+
+ const defaultData = {
+ name: row.original?.name || "",
+ code: row.original?.code || "",
+ };
+ const handleSubmit = async (result) => {
+ const formData = new FormData();
+ formData.append("name", result.name);
+ formData.append("code", result.code);
+
+ await requestServer(`${UPDATE_RAHDARAN_ITEM}/${rowId}`, "post", {
+ data: formData,
+ })
+ .then(() => {
+ mutate();
+ setOpen(false);
+ })
+ .catch(() => {});
+ };
+ return (
+ <>
+
+ ویرایش راهدار
+
+
+ >
+ );
+};
+export default EditController;
diff --git a/src/components/dashboard/rahdaran/Actions/Edit/index.jsx b/src/components/dashboard/rahdaran/Actions/Edit/index.jsx
new file mode 100644
index 0000000..2a47c4c
--- /dev/null
+++ b/src/components/dashboard/rahdaran/Actions/Edit/index.jsx
@@ -0,0 +1,51 @@
+import BorderColorIcon from "@mui/icons-material/BorderColor";
+import CloseIcon from "@mui/icons-material/Close";
+import { Dialog, IconButton, Tooltip } from "@mui/material";
+import { useState } from "react";
+import EditController from "./EditController";
+
+const EditRahdar = ({ mutate, row, rowId }) => {
+ const [open, setOpen] = useState(false);
+
+ return (
+ <>
+
+ {
+ setOpen(true);
+ }}
+ >
+
+
+
+
+ >
+ );
+};
+export default EditRahdar;
diff --git a/src/components/dashboard/rahdaran/RahdaranList.jsx b/src/components/dashboard/rahdaran/RahdaranList.jsx
new file mode 100644
index 0000000..90df9e9
--- /dev/null
+++ b/src/components/dashboard/rahdaran/RahdaranList.jsx
@@ -0,0 +1,69 @@
+"use client";
+import DataTableWithAuth from "@/core/components/DataTableWithAuth";
+import { GET_RAHDARAN_TABLE_LIST } from "@/core/utils/routes";
+import { Box } from "@mui/material";
+import { useMemo } from "react";
+import RowActions from "./RowActions";
+import Toolbar from "./Toolbar";
+
+const RahdaranList = () => {
+ const columns = useMemo(
+ () => [
+ {
+ accessorKey: "id",
+ header: "کد یکتا",
+ id: "id",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "equals",
+ sortDescFirst: false,
+ columnFilterModeOptions: ["equals", "contains"],
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "name",
+ header: "نام و نام خانوادگی",
+ id: "name",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "equals",
+ columnFilterModeOptions: ["equals", "contains"],
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "code",
+ header: "کد ملی",
+ id: "code",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "equals",
+ columnFilterModeOptions: ["equals", "contains"],
+ grow: false,
+ size: 100,
+ },
+ ],
+ []
+ );
+
+ return (
+ <>
+
+
+
+ >
+ );
+};
+export default RahdaranList;
diff --git a/src/components/dashboard/rahdaran/RowActions/DeleteDialog/DeleteContent.jsx b/src/components/dashboard/rahdaran/RowActions/DeleteDialog/DeleteContent.jsx
new file mode 100644
index 0000000..ef1c300
--- /dev/null
+++ b/src/components/dashboard/rahdaran/RowActions/DeleteDialog/DeleteContent.jsx
@@ -0,0 +1,39 @@
+import { Button, DialogActions, DialogContent, Stack, Typography } from "@mui/material";
+import React, { useState } from "react";
+import useRequest from "@/lib/hooks/useRequest";
+import { DELETE_RAHDARAN_ITEM } from "@/core/utils/routes";
+
+const DeleteContent = ({ rowId, mutate, setOpenDeleteDialog }) => {
+ const [submitting, setSubmitting] = useState(false);
+ const requestServer = useRequest({ notificationSuccess: true });
+ const handleClick = () => {
+ setSubmitting(true);
+ requestServer(`${DELETE_RAHDARAN_ITEM}/${rowId}`, "delete")
+ .then(() => {
+ mutate();
+ setSubmitting(false);
+ setOpenDeleteDialog(false);
+ })
+ .catch(() => {
+ setSubmitting(false);
+ });
+ };
+ return (
+ <>
+
+
+ آیا از حذف راهدار اطمینان دارید؟
+
+
+
+ setOpenDeleteDialog(false)} variant="outlined" color="secondary">
+ خیر !
+
+
+ {submitting ? "درحال حذف..." : "بله اطمینان دارم"}
+
+
+ >
+ );
+};
+export default DeleteContent;
diff --git a/src/components/dashboard/rahdaran/RowActions/DeleteDialog/index.jsx b/src/components/dashboard/rahdaran/RowActions/DeleteDialog/index.jsx
new file mode 100644
index 0000000..3cf143b
--- /dev/null
+++ b/src/components/dashboard/rahdaran/RowActions/DeleteDialog/index.jsx
@@ -0,0 +1,34 @@
+import DeleteIcon from "@mui/icons-material/Delete";
+import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material";
+import { useState } from "react";
+import DeleteContent from "./DeleteContent";
+const DeleteDialog = ({ rowId, mutate }) => {
+ const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
+
+ return (
+ <>
+
+ setOpenDeleteDialog(true)}>
+
+
+
+
+ >
+ );
+};
+export default DeleteDialog;
diff --git a/src/components/dashboard/rahdaran/RowActions/index.jsx b/src/components/dashboard/rahdaran/RowActions/index.jsx
new file mode 100644
index 0000000..88602aa
--- /dev/null
+++ b/src/components/dashboard/rahdaran/RowActions/index.jsx
@@ -0,0 +1,12 @@
+import { Box } from "@mui/material";
+import EditRahdar from "../Actions/Edit";
+import DeleteDialog from "./DeleteDialog";
+const RowActions = ({ row, mutate }) => {
+ return (
+
+
+
+
+ );
+};
+export default RowActions;
diff --git a/src/components/dashboard/rahdaran/Toolbar.jsx b/src/components/dashboard/rahdaran/Toolbar.jsx
new file mode 100644
index 0000000..18b0315
--- /dev/null
+++ b/src/components/dashboard/rahdaran/Toolbar.jsx
@@ -0,0 +1,9 @@
+import CreateRahdar from "./Actions/Create";
+const Toolbar = ({ mutate }) => {
+ return (
+ <>
+
+ >
+ );
+};
+export default Toolbar;
diff --git a/src/components/dashboard/rahdaran/index.jsx b/src/components/dashboard/rahdaran/index.jsx
new file mode 100644
index 0000000..bfcce4d
--- /dev/null
+++ b/src/components/dashboard/rahdaran/index.jsx
@@ -0,0 +1,13 @@
+import PageTitle from "@/core/components/PageTitle";
+import { Stack } from "@mui/material";
+import RahdaranList from "./RahdaranList";
+
+const RahdaranTablePage = () => {
+ return (
+
+
+
+
+ );
+};
+export default RahdaranTablePage;
diff --git a/src/components/dashboard/roadMissions/control/Actions/showArea/index.jsx b/src/components/dashboard/roadMissions/control/Actions/showArea/index.jsx
index 4232c07..be4ee7a 100644
--- a/src/components/dashboard/roadMissions/control/Actions/showArea/index.jsx
+++ b/src/components/dashboard/roadMissions/control/Actions/showArea/index.jsx
@@ -6,12 +6,15 @@ import ShowBound from "../showBound";
import L from "leaflet";
const ShowArea = ({ area }) => {
- const bound = useMemo(() => L.polygon([...area]), [area]);
+ const bound = useMemo(
+ () => (area.type == "polygon" ? L.polygon([...area.coordinates]) : L.polyline([...area.coordinates])),
+ [area]
+ );
const [openAreaDialog, setOpenAreaDialog] = useState(false);
return (
<>
-
+
setOpenAreaDialog(true)}>
@@ -33,7 +36,7 @@ const ShowArea = ({ area }) => {
>
- محدوده
+ منطقه عملیاتی
setOpenAreaDialog(false)} size="small">
diff --git a/src/components/dashboard/roadMissions/control/ControlList.jsx b/src/components/dashboard/roadMissions/control/ControlList.jsx
index 45edcdf..18e757a 100644
--- a/src/components/dashboard/roadMissions/control/ControlList.jsx
+++ b/src/components/dashboard/roadMissions/control/ControlList.jsx
@@ -4,15 +4,11 @@ import { GET_ROAD_MISSIONS_CONTROL_LIST } from "@/core/utils/routes";
import { Box, Stack } from "@mui/material";
import moment from "jalali-moment";
import { useMemo } from "react";
-import ShowArea from "./Actions/showArea";
+import MachinesDialog from "./RowActions/Machines";
import RowActions from "./RowActions";
+import RahdaranDialog from "./RowActions/Rahdaran";
const ControlList = () => {
- const typeOptions = [
- { value: 1, label: "روزانه" },
- { value: 2, label: "ساعتی" },
- ];
-
const columns = useMemo(
() => [
{
@@ -27,25 +23,10 @@ const ControlList = () => {
size: 100,
},
{
- accessorKey: "type",
- header: "نوع",
- id: "type",
- enableColumnFilter: true,
- datatype: "numeric",
- filterMode: "equals",
- sortDescFirst: true,
- grow: false,
- size: 100,
- columnSelectOption: () => {
- return typeOptions.map((type) => ({
- value: type.value,
- label: type.label,
- }));
- },
- Cell: ({ row }) => row.original.type_fa,
- },
- {
- accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ 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,
@@ -55,7 +36,10 @@ const ControlList = () => {
size: 100,
},
{
- accessorFn: (row) => moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ 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,
@@ -65,21 +49,13 @@ const ControlList = () => {
size: 100,
},
{
- accessorKey: "end_point",
- header: "مقصد",
- id: "end_point",
- enableColumnFilter: false,
- datatype: "numeric",
- filterMode: "equals",
- grow: false,
- size: 100,
- },
- {
- header: "محدوده",
- id: "area",
- enableColumnFilter: false,
- datatype: "numeric",
- filterMode: "equals",
+ header: "خودرو",
+ id: "cmmsMachines__machine_code",
+ enableColumnFilter: true,
+ datatype: "text",
+ filterMode: "contains",
+ enableSorting: false,
+ columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
muiTableBodyCellProps: {
@@ -91,14 +67,40 @@ const ControlList = () => {
},
},
},
- Cell: ({ row }) =>
- row.original.area ? (
+ 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 (
+
+
+
+ );
+ },
},
],
[]
diff --git a/src/components/dashboard/roadMissions/control/RowActions/Machines/MachinesContent.jsx b/src/components/dashboard/roadMissions/control/RowActions/Machines/MachinesContent.jsx
new file mode 100644
index 0000000..3ee5a3c
--- /dev/null
+++ b/src/components/dashboard/roadMissions/control/RowActions/Machines/MachinesContent.jsx
@@ -0,0 +1,73 @@
+import DialogLoading from "@/core/components/DialogLoading";
+import ShowPlak from "@/core/components/ShowPlak";
+import { GET_MACHINES_BY_ID } from "@/core/utils/routes";
+import useRequest from "@/lib/hooks/useRequest";
+import {
+ DialogContent,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Typography,
+} from "@mui/material";
+import { useEffect, useState } from "react";
+
+const MachinesContent = ({ rowId }) => {
+ const [loading, setLoading] = useState(true);
+ const [data, setData] = useState(null);
+ const request = useRequest();
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ setLoading(true);
+ const response = await request(`${GET_MACHINES_BY_ID}/${rowId}`);
+ setData(response.data.data);
+ } catch (error) {
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchData();
+ }, [rowId]);
+
+ return (
+ <>
+
+ {loading ? (
+
+ ) : data ? (
+
+
+
+
+ کد ماشین
+ نام خودرو
+
+
+
+ {data.map((machine) => {
+ return (
+
+ {machine.machine_code}
+ {machine.car_name}
+
+ );
+ })}
+
+
+
+ ) : (
+ اطلاعات خودرویی در سامانه یافت نشد
+ )}
+
+ >
+ );
+};
+export default MachinesContent;
diff --git a/src/components/dashboard/roadMissions/control/RowActions/Machines/index.jsx b/src/components/dashboard/roadMissions/control/RowActions/Machines/index.jsx
new file mode 100644
index 0000000..395b276
--- /dev/null
+++ b/src/components/dashboard/roadMissions/control/RowActions/Machines/index.jsx
@@ -0,0 +1,38 @@
+import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
+import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
+import { useState } from "react";
+import MachinesContent from "./MachinesContent";
+
+const MachinesDialog = ({ rowId }) => {
+ const [openMachinesDialog, setOpenMachinesDialog] = useState(false);
+ return (
+ <>
+
+ setOpenMachinesDialog(true)}>
+
+
+
+
+ >
+ );
+};
+export default MachinesDialog;
diff --git a/src/components/dashboard/roadMissions/control/RowActions/Rahdaran/RahdaranContent.jsx b/src/components/dashboard/roadMissions/control/RowActions/Rahdaran/RahdaranContent.jsx
new file mode 100644
index 0000000..46001aa
--- /dev/null
+++ b/src/components/dashboard/roadMissions/control/RowActions/Rahdaran/RahdaranContent.jsx
@@ -0,0 +1,74 @@
+import DialogLoading from "@/core/components/DialogLoading";
+import { GET_RAHDARAN_BY_ID } from "@/core/utils/routes";
+import useRequest from "@/lib/hooks/useRequest";
+import {
+ DialogContent,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Typography,
+} from "@mui/material";
+import { useEffect, useState } from "react";
+
+const RahdaranContent = ({ rowId }) => {
+ const [loading, setLoading] = useState(true);
+ const [data, setData] = useState(null);
+ const request = useRequest();
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ setLoading(true);
+ const response = await request(`${GET_RAHDARAN_BY_ID}/${rowId}`);
+ setData(response.data.data);
+ } catch (error) {
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchData();
+ }, [rowId]);
+
+ return (
+ <>
+
+ {loading ? (
+
+ ) : data ? (
+
+
+
+
+ کد ملی
+ نام
+ نقش
+
+
+
+ {data.map((rahdar) => {
+ return (
+
+ {rahdar.code}
+ {rahdar.name}
+ {rahdar.is_driver ? "راننده" : "همراه"}
+
+ );
+ })}
+
+
+
+ ) : (
+ اطلاعات راهداران در سامانه یافت نشد
+ )}
+
+ >
+ );
+};
+export default RahdaranContent;
diff --git a/src/components/dashboard/roadMissions/control/RowActions/Rahdaran/index.jsx b/src/components/dashboard/roadMissions/control/RowActions/Rahdaran/index.jsx
new file mode 100644
index 0000000..b27009d
--- /dev/null
+++ b/src/components/dashboard/roadMissions/control/RowActions/Rahdaran/index.jsx
@@ -0,0 +1,38 @@
+import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
+import GroupsIcon from "@mui/icons-material/Groups";
+import { useState } from "react";
+import RahdaranContent from "./RahdaranContent";
+
+const RahdaranDialog = ({ rowId }) => {
+ const [openRahdaranDialog, setOpenRahdaranDialog] = useState(false);
+ return (
+ <>
+
+ setOpenRahdaranDialog(true)}>
+
+
+
+
+ >
+ );
+};
+export default RahdaranDialog;
diff --git a/src/components/dashboard/roadMissions/control/RowActions/StartMission/StartMissionContent.jsx b/src/components/dashboard/roadMissions/control/RowActions/StartMission/StartMissionContent.jsx
index 6aa5e78..c7f516d 100644
--- a/src/components/dashboard/roadMissions/control/RowActions/StartMission/StartMissionContent.jsx
+++ b/src/components/dashboard/roadMissions/control/RowActions/StartMission/StartMissionContent.jsx
@@ -1,38 +1,87 @@
+import LtrTextField from "@/core/components/LtrTextField";
import { START_MISSION } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
+import { yupResolver } from "@hookform/resolvers/yup";
import { Button, DialogActions, DialogContent, Stack, Typography } from "@mui/material";
-import { useState } from "react";
+import { Controller, useForm } from "react-hook-form";
+import { object, string } from "yup";
const StartMissionContent = ({ rowId, mutate, setOpenStartMissionDialog }) => {
- const [submitting, setSubmitting] = useState(false);
const requestServer = useRequest({ notificationSuccess: true });
- const handleClick = () => {
- setSubmitting(true);
+
+ const validationSchema = object().shape({
+ code: string().length(6, "کد خروج باید 6 رقم باشد").required("لطفاً کد خروج را وارد کنید."),
+ });
+
+ const {
+ control,
+ handleSubmit,
+ formState: { isSubmitting },
+ } = useForm({
+ defaultValues: {
+ code: "",
+ },
+ resolver: yupResolver(validationSchema),
+ mode: "all",
+ });
+
+ const onSubmit = (values) => {
requestServer(`${START_MISSION}/${rowId}`, "post", {
+ data: {
+ code: values.code,
+ },
hasSidebarUpdate: true,
})
.then(() => {
mutate();
setOpenStartMissionDialog(false);
- setSubmitting(false);
})
- .catch(() => {
- setSubmitting(false);
- });
+ .catch(() => {});
};
+
return (
<>
-
+
آیا از خروج خودرو و شروع ماموریت اطمینان دارید؟
+
+ (
+ {
+ if (isNaN(Number(e.target.value))) return;
+ e.target.value.length <= 6 ? field.onChange(e.target.value) : null;
+ }}
+ type="tel"
+ autoComplete="off"
+ fullWidth
+ variant="outlined"
+ InputLabelProps={{ shrink: true }}
+ />
+ )}
+ />
+
- setOpenStartMissionDialog(false)} variant="outlined" color="secondary">
+ setOpenStartMissionDialog(false)}
+ variant="outlined"
+ color="secondary"
+ disabled={isSubmitting}
+ >
خیر !
-
- {submitting ? "درحال ثبت..." : "بله اطمینان دارم"}
+
+ {isSubmitting ? "درحال ثبت..." : "بله اطمینان دارم"}
>
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControl/DrawBound/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolygon/DrawBound/index.jsx
similarity index 90%
rename from src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControl/DrawBound/index.jsx
rename to src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolygon/DrawBound/index.jsx
index 639f8fb..a2134c5 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControl/DrawBound/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolygon/DrawBound/index.jsx
@@ -1,116 +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 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();
- safeFlyToBounds(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;
+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/Create/Form/Area/MapControl/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolygon/index.jsx
similarity index 93%
rename from src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControl/index.jsx
rename to src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolygon/index.jsx
index bdd1c97..186a0b6 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControl/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolygon/index.jsx
@@ -1,116 +1,116 @@
-import { Box, Button, Stack, Typography } from "@mui/material";
-import DrawBound from "./DrawBound";
-import { Delete, Edit, Route } from "@mui/icons-material";
-import { useReducer } from "react";
-
-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 MapControl = ({ 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) => (
- button.onclick(controlDispach)}
- color={button.color}
- startIcon={button.icon}
- >
- {button.label}
-
- ))}
-
-
- >
- );
-};
-export default MapControl;
+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) => (
+ button.onclick(controlDispach)}
+ color={button.color}
+ startIcon={button.icon}
+ >
+ {button.label}
+
+ ))}
+
+
+ >
+ );
+};
+export default MapControlPolygon;
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolyline/DrawBound/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolyline/DrawBound/index.jsx
new file mode 100644
index 0000000..682be24
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/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/Create/Form/Area/MapControlPolyline/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/MapControlPolyline/index.jsx
new file mode 100644
index 0000000..edd6cac
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/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) => (
+ button.onclick(controlDispach)}
+ color={button.color}
+ startIcon={button.icon}
+ >
+ {button.label}
+
+ ))}
+
+
+ >
+ );
+};
+export default MapControlPolyline;
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/SelectBoundType/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/SelectBoundType/index.jsx
new file mode 100644
index 0000000..a69a0ba
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/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/Create/Form/Area/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/index.jsx
index aaa229c..3d666fd 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Area/index.jsx
@@ -1,8 +1,10 @@
import MapLoading from "@/core/components/MapLayer/Loading";
-import { Box, Button, DialogActions, DialogContent } from "@mui/material";
+import { Box, Button, DialogActions, DialogContent, Stack } from "@mui/material";
import dynamic from "next/dynamic";
-import MapControl from "./MapControl";
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,
@@ -10,6 +12,7 @@ const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
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 });
@@ -18,12 +21,24 @@ const Area = ({ allData, setAllData, handlePrev, setTabState }) => {
return (
<>
-
-
-
-
-
-
+
+
+
+
+
+ {boundType == "polygon" ? (
+
+ ) : (
+
+ )}
+
+
+
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/MissionDates/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx
similarity index 97%
rename from src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/MissionDates/index.jsx
rename to src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx
index 9cf2029..a2b5c07 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/MissionDates/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/MissionDates/index.jsx
@@ -1,93 +1,95 @@
-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" });
- return (
- <>
-
- {
- return (
- field.onChange(value || [])}
- helperText={error ? error.message : null}
- />
- );
- }}
- />
-
- {type == 1 && (
-
- {
- return (
- field.onChange(value || null)}
- helperText={error ? error.message : null}
- />
- );
- }}
- />
-
- )}
-
- {
- return (
- field.onChange(value || [])}
- helperText={error ? error.message : null}
- />
- );
- }}
- />
-
- {type == 1 && (
-
- {
- return (
- field.onChange(value || null)}
- helperText={error ? error.message : null}
- />
- );
- }}
- />
-
- )}
- >
- );
-};
-export default MissionDates;
+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" });
+ return (
+ <>
+
+ {
+ return (
+ field.onChange(value || [])}
+ helperText={error ? error.message : null}
+ />
+ );
+ }}
+ />
+
+ {type == 1 && (
+
+ {
+ return (
+ field.onChange(value || null)}
+ helperText={error ? error.message : null}
+ />
+ );
+ }}
+ />
+
+ )}
+
+ {
+ 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/Actions/Create/Form/GetDateTime/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/index.jsx
new file mode 100644
index 0000000..00da610
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetDateTime/index.jsx
@@ -0,0 +1,86 @@
+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({
+ type: string().required("نوع ماموریت را مشخص کنید!"),
+ start_date: string().required("تاریخ شروع ماموریت را مشخص کنید!"),
+ start_time: string().when("type", {
+ is: "1",
+ then: (schema) => schema.required("زمان شروع ماموریت را مشخص کنید!"),
+ otherwise: (schema) => schema.notRequired(),
+ }),
+ 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,
+ 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/Create/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/SelectId/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/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/Create/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/Create/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/FastReactCode/Dialog/List/RowActions/index.jsx
new file mode 100644
index 0000000..3d0b958
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/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/Create/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/FastReactCode/Dialog/List/index.jsx
new file mode 100644
index 0000000..82a0472
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/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/Create/Form/GetItemInfo/FastReactCode/Dialog/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/FastReactCode/Dialog/index.jsx
new file mode 100644
index 0000000..013f73f
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/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 === "" ? (
+ setOpenFastReactDialog(true)} variant="outlined">
+ انتخاب شکایت
+
+ ) : (
+ }
+ onDelete={() => setOpenFastReactDialog(true)}
+ />
+ )}
+
+
+ >
+ );
+});
+
+FastReactDialog.displayName = "FastReactDialog";
+
+export default FastReactDialog;
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/FastReactCode/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/FastReactCode/index.jsx
new file mode 100644
index 0000000..1545046
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/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/Create/Form/GetItemInfo/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/index.jsx
index 91dc5cf..b49ede0 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/GetItemInfo/index.jsx
@@ -1,41 +1,37 @@
import PersianTextField from "@/core/components/PersianTextField";
import SelectBox from "@/core/components/SelectBox";
import StyledForm from "@/core/components/StyledForm";
+import { machineType } from "@/core/utils/machineTypes";
+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 MissionDates from "./MissionDates";
-import moment from "jalali-moment";
+import { array, object, string } from "yup";
+import FastReactCode from "./FastReactCode";
const validationSchema = object({
- type: string().required("نوع ماموریت را مشخص کنید!"),
- start_date: string().required("تاریخ شروع ماموریت را مشخص کنید!"),
- start_time: string().when("type", {
- is: "1",
- then: (schema) => schema.required("زمان شروع ماموریت را مشخص کنید!"),
- otherwise: (schema) => schema.notRequired(),
- }),
- end_date: string().required("تاریخ پایان ماموریت را مشخص کنید!"),
- end_time: string().when("type", {
- is: "1",
- then: (schema) => schema.required("زمان شروع ماموریت را مشخص کنید!"),
- otherwise: (schema) => schema.notRequired(),
- }),
+ explanation: string().required("موضوع را مشخص کنید!"),
end_point: string().required("مقصد را مشخص کنید!"),
region: string().required("محور ماموریت را مشخص کنید!"),
+ category_id: string().required("نوع ماموریت را مشخص کنید!"),
+ requested_machines: array().min(1, "نوع خودرو را مشخص کنید!").required("نوع خودرو را مشخص کنید!"),
+ road_observed_id: string().when("category_id", {
+ is: "3",
+ then: (schema) => schema.required("کد یکتا شکایت را مشخص کنید!"),
+ otherwise: (schema) => schema.notRequired(),
+ }),
});
-const GetItemInfo = ({ types, regions, allData, setAllData, handlePrev, setTabState }) => {
+const GetItemInfo = ({ allData, setAllData, handlePrev, setTabState }) => {
const defaultValues = {
- type: allData.type,
- 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,
+ explanation: allData.explanation,
end_point: allData.end_point,
region: allData.region,
+ requested_machines: allData.requested_machines,
+ category_id: allData.category_id,
+ road_observed_id: allData.road_observed_id,
};
const { control, handleSubmit } = useForm({
@@ -58,16 +54,20 @@ const GetItemInfo = ({ types, regions, allData, setAllData, handlePrev, setTabSt
(
-
)}
/>
@@ -79,8 +79,8 @@ const GetItemInfo = ({ types, regions, allData, setAllData, handlePrev, setTabSt
render={({ field, fieldState: { error } }) => (
-
-
+
+ (
+
+ )}
+ />
+
+
+
+
+
+ (
+ field.onChange([newValue])}
+ helperText={error?.message}
+ />
+ )}
+ />
+
+
{
const defaultValues = {
@@ -38,9 +38,10 @@ const RahdaranForm = ({ setRahdaran }) => {
control={control}
render={({ field, fieldState: { error } }) => {
return (
- field.onChange(value)}
+ field.onChange(value)}
error={error}
multiple={false}
/>
@@ -56,7 +57,7 @@ const RahdaranForm = ({ setRahdaran }) => {
disabled={isSubmitting || !isValid}
startIcon={}
>
- افزودن راهدار
+ افزودن همراه
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/List/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/List/index.jsx
index 133b82c..be31897 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/List/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/List/index.jsx
@@ -33,7 +33,7 @@ const RahdaranList = ({ rahdaran, setRahdaran }) => {
{rahdar.name}
- کد راهدار:
+ کدملی:
{rahdar.code}
@@ -46,7 +46,7 @@ const RahdaranList = ({ rahdaran, setRahdaran }) => {
))}
{rahdaran.length == 0 && (
- راهداری ثبت نشده است
+ همراهی ثبت نشده است
)}
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/index.jsx
index 5e1221a..b530af4 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Rahdaran/index.jsx
@@ -17,7 +17,7 @@ const Rahdaran = ({ allData, setAllData, setTabState, handlePrev }) => {
-
+
@@ -26,8 +26,8 @@ const Rahdaran = ({ allData, setAllData, setTabState, handlePrev }) => {
{"مرحله قبلی"}
-
- {rahdaran.length == 0 ? "ثبت حداقل یک راهدار" : "مرحله بعد"}
+
+ {"مرحله بعد"}
>
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/Form/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/Form/index.jsx
deleted file mode 100644
index 7d80762..0000000
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/Form/index.jsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import LtrTextField from "@/core/components/LtrTextField";
-import SelectBox from "@/core/components/SelectBox";
-import StyledForm from "@/core/components/StyledForm";
-import { machineType } from "@/core/utils/machineTypes";
-import { yupResolver } from "@hookform/resolvers/yup";
-import { Add } from "@mui/icons-material";
-import { Button, Grid, Stack } from "@mui/material";
-import moment from "jalali-moment";
-import { Controller, useForm } from "react-hook-form";
-import { object, string } from "yup";
-
-const validationSchema = object({
- type: string().required("نوع خودرو را مشخص کنید!"),
- count: string().required("تعداد خودرو را مشخص کنید!"),
-});
-
-const RequestMachinesForm = ({ requests, setRequests }) => {
- const usedTypeIds = requests.map((r) => r.type);
- const filteredMachineTypes = machineType.filter((mt) => !usedTypeIds.includes(mt.id));
-
- const defaultValues = {
- type: "",
- count: "",
- };
-
- const { control, handleSubmit, reset } = useForm({
- defaultValues,
- resolver: yupResolver(validationSchema),
- mode: "all",
- });
-
- const submit = (data) => {
- setRequests((r) => [...r, { id: moment().valueOf(), ...data }]);
- reset();
- };
- return (
-
-
-
-
- (
-
- )}
- />
-
-
- (
- {
- if (isNaN(Number(e.target.value))) return;
- field.onChange(e.target.value);
- }}
- size="small"
- error={!!error}
- helperText={!!error && error.message}
- type="tel"
- label="تعداد خودرو"
- />
- )}
- />
-
-
- }>
- افزودن خودرو
-
-
-
-
-
- );
-};
-export default RequestMachinesForm;
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/List/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/List/index.jsx
deleted file mode 100644
index 44ce785..0000000
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/List/index.jsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { machineType } from "@/core/utils/machineTypes";
-import { Delete, FireTruck } from "@mui/icons-material";
-import { Card, Collapse, IconButton, Stack, Typography } from "@mui/material";
-import { TransitionGroup } from "react-transition-group";
-
-const RequestMachinesList = ({ requests, setRequests }) => {
- const handleRemove = (index) => {
- setRequests((prev) => prev.filter((_, i) => i !== index));
- };
-
- return (
-
-
- {requests.map((request, index) => (
-
-
-
-
-
-
- نوع خودرو:
-
- {machineType.find((t) => t.id == request.type)?.name_fa || ""}
-
-
-
- تعداد:
- {request.count}
-
-
-
- handleRemove(index)}>
-
-
-
-
- ))}
- {requests.length == 0 && (
-
- درخواستی ثبت نشده است
-
- )}
-
-
- );
-};
-export default RequestMachinesList;
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/index.jsx
deleted file mode 100644
index 28f6ed0..0000000
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/RequestMachines/index.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Box, Button, Chip, DialogActions, DialogContent, Divider } from "@mui/material";
-import { useCallback, useState } from "react";
-import RequestMachinesForm from "./Form";
-import RequestMachinesList from "./List";
-
-const RequestMachines = ({ allData, setAllData, handlePrev, setTabState }) => {
- const [requests, setRequests] = useState(allData.requested_machines);
-
- const handleNext = useCallback(() => {
- setAllData({ requested_machines: requests });
- setTabState((s) => s + 1);
- }, [requests]);
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
- {"مرحله قبلی"}
-
-
- {requests.length == 0 ? "ثبت حداقل یک درخواست" : "مرحله بعد"}
-
-
- >
- );
-};
-export default RequestMachines;
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Verify/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Verify/index.jsx
index 41a652a..57515c4 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Verify/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/Verify/index.jsx
@@ -1,16 +1,19 @@
import MapLoading from "@/core/components/MapLayer/Loading";
+import { machineType } from "@/core/utils/machineTypes";
+import { missionCategoryTypes } from "@/core/utils/missionCategoryTypes";
+import { missionRegions } from "@/core/utils/missionRegions";
+import { missionTypes } from "@/core/utils/missionTypes";
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 moment from "jalali-moment";
import ShowBound from "../../../showBound";
-import { machineType } from "@/core/utils/machineTypes";
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
loading: () => ,
ssr: false,
});
-const Verify = ({ types, regions, allData, handlePrev, submitForm, submitting }) => {
+const Verify = ({ allData, handlePrev, submitForm, submitting }) => {
const handleNext = useCallback(() => {
submitForm(allData);
}, [allData]);
@@ -30,14 +33,47 @@ const Verify = ({ types, regions, allData, handlePrev, submitForm, submitting })
- نوع ماموریت
+ موضوع ماموریت
- t.id == allData.type).name_fa} />
+
- محدوده ماموریت
+ محدوده
- r.id == allData.region).name_fa} />
+ r.id == allData.region).name_fa} />
+
+
+ نوع ماموریت
+
+ t.id == allData.category_id).name_fa}
+ />
+
+ {allData.category_id == 3 && (
+
+ کد شکایت
+
+
+
+ )}
+
+ نوع خودرو
+
+ mt.id == allData.requested_machines[0]).name_fa}
+ />
+
+
+ مقصد
+
+
+
+
+ نوع زمانبندی
+
+ t.id == allData.type).name_fa} />
تاریخ شروع ماموریت
@@ -69,37 +105,24 @@ const Verify = ({ types, regions, allData, handlePrev, submitForm, submitting })
/>
)}
-
- مقصد
-
-
-
-
+
- {allData.requested_machines.map((request) => (
-
-
- {machineType.find((mt) => mt.id == request.type).name_fa}
-
-
-
+ {allData.rahdaran.length != 0 ? (
+ allData.rahdaran.map((rahdar) => (
+
+ {rahdar.name}
+
+
+
+ ))
+ ) : (
+
+ همراهی ثبت نشده است
- ))}
-
-
-
-
-
- {allData.rahdaran.map((rahdar) => (
-
- {rahdar.name}
-
-
-
- ))}
+ )}
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/index.jsx
index 37063c2..efdaaf7 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/Form/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/Form/index.jsx
@@ -1,23 +1,12 @@
-import { Engineering, InsertDriveFile, Route, TaxiAlert, Verified } from "@mui/icons-material";
+import { AccessTime, Engineering, InsertDriveFile, Route, Verified } from "@mui/icons-material";
import { Box, Tab, Tabs } from "@mui/material";
import { useReducer, useState } from "react";
-import GetItemInfo from "./GetItemInfo";
-import RequestMachines from "./RequestMachines";
-import Rahdaran from "./Rahdaran";
import Area from "./Area";
+import GetDateTime from "./GetDateTime";
+import GetItemInfo from "./GetItemInfo";
+import Rahdaran from "./Rahdaran";
import Verify from "./Verify";
-const types = [
- { id: 1, name_fa: "ساعتی" },
- { id: 2, name_fa: "روزانه" },
-];
-
-const regions = [
- { id: 1, name_fa: "داخل شهر" },
- { id: 2, name_fa: "بیرون شهر - داخل محدوده" },
- { id: 3, name_fa: "بیرون شهر - خارج محدوده" },
-];
-
function TabPanel(props) {
const { children, value, index } = props;
return (
@@ -70,15 +59,13 @@ const CreateForm = ({ defaultValues, submitForm, setOpen, submitting }) => {
}}
>
} label="مشخصات" />
- } label="محدوده" />
- } label="خودرو ها" />
- } label="راهداران" />
+ } label="زمانبندی" />
+ } label="منطقه عملیاتی" />
+ } label="همراهان" />
} label="بررسی نهایی" />
{
dispatch({ type: "changeData", data });
@@ -88,7 +75,7 @@ const CreateForm = ({ defaultValues, submitForm, setOpen, submitting }) => {
/>
- {
dispatch({ type: "changeData", data });
@@ -98,7 +85,7 @@ const CreateForm = ({ defaultValues, submitForm, setOpen, submitting }) => {
/>
- {
dispatch({ type: "changeData", data });
@@ -118,14 +105,7 @@ const CreateForm = ({ defaultValues, submitForm, setOpen, submitting }) => {
/>
-
+
>
);
diff --git a/src/components/dashboard/roadMissions/operator/Actions/Create/index.jsx b/src/components/dashboard/roadMissions/operator/Actions/Create/index.jsx
index 236e38c..e48ab26 100644
--- a/src/components/dashboard/roadMissions/operator/Actions/Create/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/Actions/Create/index.jsx
@@ -20,25 +20,38 @@ const Create = ({ mutate }) => {
const submitForm = async (result) => {
setSubmitting(true);
const bound = result.bound.getLatLngs();
- let area = bound.map((ring) => ring.map((latlng) => [latlng.lat, latlng.lng]));
+ 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, "post", {
data: {
- area: area[0],
- rahdaran: result.rahdaran.map((r) => r.id),
+ 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) } : {}),
requested_machines: result.requested_machines,
type: result.type,
zone: result.region,
end_point: result.end_point,
...(result.type == 1
? {
- start_date: `${result.start_date} ${moment(result.start_time).format("HH:mm")}`,
- end_date: `${result.end_date} ${moment(result.end_time).format("HH:mm")}`,
- }
+ start_date: `${result.start_date} ${moment(result.start_time).format("HH:mm")}`,
+ end_date: `${result.end_date} ${moment(result.end_time).format("HH:mm")}`,
+ }
: {
- start_date: result.start_date,
- end_date: result.end_date,
- }),
+ start_date: result.start_date,
+ end_date: result.end_date,
+ }),
},
hasSidebarUpdate: true,
})
@@ -46,7 +59,7 @@ const Create = ({ mutate }) => {
mutate();
setOpen(false);
})
- .catch((error) => { })
+ .catch((error) => {})
.finally(() => {
setSubmitting(false);
});
@@ -86,9 +99,13 @@ const Create = ({ mutate }) => {
{open && (
{
- const bound = useMemo(() => L.polygon([...area]), [area]);
+ const bound = useMemo(
+ () => (area.type == "polygon" ? L.polygon([...area.coordinates]) : L.polyline([...area.coordinates])),
+ [area]
+ );
const [openAreaDialog, setOpenAreaDialog] = useState(false);
return (
<>
-
+
setOpenAreaDialog(true)}>
@@ -33,7 +36,7 @@ const ShowArea = ({ area }) => {
>
- محدوده
+ منطقه عملیاتی
setOpenAreaDialog(false)} size="small">
diff --git a/src/components/dashboard/roadMissions/operator/OperatorList.jsx b/src/components/dashboard/roadMissions/operator/OperatorList.jsx
index ae85aca..df9528e 100644
--- a/src/components/dashboard/roadMissions/operator/OperatorList.jsx
+++ b/src/components/dashboard/roadMissions/operator/OperatorList.jsx
@@ -1,17 +1,18 @@
"use client";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
+import { missionCategoryTypes } from "@/core/utils/missionCategoryTypes";
+import { missionRegions } from "@/core/utils/missionRegions";
+import { missionTypes } from "@/core/utils/missionTypes";
import { GET_ROAD_MISSIONS_OPERATOR_LIST } from "@/core/utils/routes";
import { Box, Stack } from "@mui/material";
import moment from "jalali-moment";
import { useMemo } from "react";
import ShowArea from "./Actions/showArea";
import RowActions from "./RowActions";
+import MachinesDialog from "./RowActions/Machines";
import Toolbar from "./Toolbar";
+import RahdaranDialog from "./RowActions/Rahdaran";
-const typeOptions = [
- { value: 1, label: "روزانه" },
- { value: 2, label: "ساعتی" },
-];
const OperatorList = () => {
const columns = useMemo(
() => [
@@ -27,8 +28,74 @@ const OperatorList = () => {
size: 100,
},
{
- accessorKey: "type",
+ accessorKey: "code",
+ header: "کد خروج",
+ id: "code",
+ enableColumnFilter: false,
+ datatype: "numeric",
+ filterMode: "equals",
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "state_name",
+ header: "وضعیت",
+ id: "state_name",
+ enableColumnFilter: false,
+ datatype: "numeric",
+ filterMode: "equals",
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "explanation",
+ header: "موضوع",
+ id: "explanation",
+ enableColumnFilter: false,
+ datatype: "numeric",
+ filterMode: "equals",
+ grow: false,
+ size: 100,
+ },
+ {
+ accessorKey: "category_id",
header: "نوع",
+ id: "category_id",
+ enableColumnFilter: true,
+ datatype: "numeric",
+ filterMode: "equals",
+ sortDescFirst: true,
+ grow: false,
+ size: 100,
+ columnSelectOption: () => {
+ return missionCategoryTypes.map((category) => ({
+ value: category.id,
+ label: category.name_fa,
+ }));
+ },
+ Cell: ({ row }) => row.original.category_name,
+ },
+ {
+ 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,
+ },
+ {
+ accessorKey: "type",
+ header: "نوع زمانبندی",
id: "type",
enableColumnFilter: true,
datatype: "numeric",
@@ -37,15 +104,18 @@ const OperatorList = () => {
grow: false,
size: 100,
columnSelectOption: () => {
- return typeOptions.map((type) => ({
- value: type.value,
- label: type.label,
+ return missionTypes.map((type) => ({
+ value: type.id,
+ label: type.name_fa,
}));
},
Cell: ({ row }) => row.original.type_fa,
},
{
- accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ 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,
@@ -55,7 +125,10 @@ const OperatorList = () => {
size: 100,
},
{
- accessorFn: (row) => moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ 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,
@@ -75,7 +148,7 @@ const OperatorList = () => {
size: 100,
},
{
- header: "محدوده",
+ header: "منطقه عملیاتی",
id: "area",
enableColumnFilter: false,
datatype: "numeric",
@@ -101,12 +174,66 @@ const OperatorList = () => {
),
},
{
- accessorKey: "state_name",
- header: "وضعیت",
- id: "state_name",
- enableColumnFilter: false,
- datatype: "numeric",
- filterMode: "equals",
+ 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.request_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ header: "تاریخ ثبت",
+ id: "request_date",
+ enableColumnFilter: true,
+ datatype: "date",
+ filterMode: "between",
grow: false,
size: 100,
},
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 612bac4..1fdda15 100644
--- a/src/components/dashboard/roadMissions/operator/RowActions/Edit/EditController/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/RowActions/Edit/EditController/index.jsx
@@ -7,7 +7,13 @@ import L from "leaflet";
import { GET_RAHDARAN_BY_ID, UPDATE_REQUEST_MISSION } from "@/core/utils/routes";
const EditController = ({ row, mutate, openEditDialog, setOpenEditDialog }) => {
- const bound = useMemo(() => L.polygon([...row.original.area]), [row.original.area]);
+ const bound = useMemo(
+ () =>
+ row.original.area.type == "polygon"
+ ? L.polygon([...row.original.area.coordinates])
+ : L.polyline([...row.original.area.coordinates]),
+ [row.original.area]
+ );
const [submitting, setSubmitting] = useState(false);
const [rahdaran, setRahdaran] = useState(null);
const [rahdaranLoading, setRahdaranLoading] = useState(false);
@@ -32,21 +38,31 @@ const EditController = ({ row, mutate, openEditDialog, setOpenEditDialog }) => {
await requestServer(`${UPDATE_REQUEST_MISSION}/${row.original.id}`, "post", {
data: {
- area: area[0],
- rahdaran: result.rahdaran.map((r) => r.id),
+ 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[0],
+ },
+ ...(result.rahdaran.length != 0 ? { rahdaran: result.rahdaran.map((r) => r.id) } : {}),
requested_machines: result.requested_machines,
type: result.type,
zone: result.region,
end_point: result.end_point,
...(result.type == 1
? {
- start_date: `${result.start_date} ${moment(result.start_time).format("HH:mm")}`,
- end_date: `${result.end_date} ${moment(result.end_time).format("HH:mm")}`,
- }
+ start_date: `${result.start_date} ${moment(result.start_time).format("HH:mm")}`,
+ end_date: `${result.end_date} ${moment(result.end_time).format("HH:mm")}`,
+ }
: {
- start_date: result.start_date,
- end_date: result.end_date,
- }),
+ start_date: result.start_date,
+ end_date: result.end_date,
+ }),
},
hasSidebarUpdate: true,
notificationSuccess: true,
@@ -55,7 +71,7 @@ const EditController = ({ row, mutate, openEditDialog, setOpenEditDialog }) => {
mutate();
setOpenEditDialog(false);
})
- .catch((error) => { })
+ .catch((error) => {})
.finally(() => {
setSubmitting(false);
});
@@ -68,9 +84,13 @@ const EditController = ({ row, mutate, openEditDialog, setOpenEditDialog }) => {
) : (
{
+ const [loading, setLoading] = useState(true);
+ const [data, setData] = useState(null);
+ const request = useRequest();
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ setLoading(true);
+ const response = await request(`${GET_MACHINES_BY_ID}/${rowId}`);
+ setData(response.data.data);
+ } catch (error) {
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchData();
+ }, [rowId]);
+
+ return (
+ <>
+
+ {loading ? (
+
+ ) : data ? (
+
+
+
+
+ کد ماشین
+ نام خودرو
+
+
+
+ {data.map((machine) => {
+ return (
+
+ {machine.machine_code}
+ {machine.car_name}
+
+ );
+ })}
+
+
+
+ ) : (
+ اطلاعات خودرویی در سامانه یافت نشد
+ )}
+
+ >
+ );
+};
+export default MachinesContent;
diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Machines/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Machines/index.jsx
new file mode 100644
index 0000000..395b276
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/RowActions/Machines/index.jsx
@@ -0,0 +1,38 @@
+import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
+import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
+import { useState } from "react";
+import MachinesContent from "./MachinesContent";
+
+const MachinesDialog = ({ rowId }) => {
+ const [openMachinesDialog, setOpenMachinesDialog] = useState(false);
+ return (
+ <>
+
+ setOpenMachinesDialog(true)}>
+
+
+
+
+ >
+ );
+};
+export default MachinesDialog;
diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Rahdaran/RahdaranContent.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Rahdaran/RahdaranContent.jsx
new file mode 100644
index 0000000..46001aa
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/RowActions/Rahdaran/RahdaranContent.jsx
@@ -0,0 +1,74 @@
+import DialogLoading from "@/core/components/DialogLoading";
+import { GET_RAHDARAN_BY_ID } from "@/core/utils/routes";
+import useRequest from "@/lib/hooks/useRequest";
+import {
+ DialogContent,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Typography,
+} from "@mui/material";
+import { useEffect, useState } from "react";
+
+const RahdaranContent = ({ rowId }) => {
+ const [loading, setLoading] = useState(true);
+ const [data, setData] = useState(null);
+ const request = useRequest();
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ setLoading(true);
+ const response = await request(`${GET_RAHDARAN_BY_ID}/${rowId}`);
+ setData(response.data.data);
+ } catch (error) {
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchData();
+ }, [rowId]);
+
+ return (
+ <>
+
+ {loading ? (
+
+ ) : data ? (
+
+
+
+
+ کد ملی
+ نام
+ نقش
+
+
+
+ {data.map((rahdar) => {
+ return (
+
+ {rahdar.code}
+ {rahdar.name}
+ {rahdar.is_driver ? "راننده" : "همراه"}
+
+ );
+ })}
+
+
+
+ ) : (
+ اطلاعات راهداران در سامانه یافت نشد
+ )}
+
+ >
+ );
+};
+export default RahdaranContent;
diff --git a/src/components/dashboard/roadMissions/operator/RowActions/Rahdaran/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/Rahdaran/index.jsx
new file mode 100644
index 0000000..b27009d
--- /dev/null
+++ b/src/components/dashboard/roadMissions/operator/RowActions/Rahdaran/index.jsx
@@ -0,0 +1,38 @@
+import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
+import GroupsIcon from "@mui/icons-material/Groups";
+import { useState } from "react";
+import RahdaranContent from "./RahdaranContent";
+
+const RahdaranDialog = ({ rowId }) => {
+ const [openRahdaranDialog, setOpenRahdaranDialog] = useState(false);
+ return (
+ <>
+
+ setOpenRahdaranDialog(true)}>
+
+
+
+
+ >
+ );
+};
+export default RahdaranDialog;
diff --git a/src/components/dashboard/roadMissions/operator/RowActions/index.jsx b/src/components/dashboard/roadMissions/operator/RowActions/index.jsx
index a4c3c39..b5659da 100644
--- a/src/components/dashboard/roadMissions/operator/RowActions/index.jsx
+++ b/src/components/dashboard/roadMissions/operator/RowActions/index.jsx
@@ -1,11 +1,14 @@
import { Box } from "@mui/material";
import Edit from "./Edit";
import Delete from "./Delete";
+import { useAuth } from "@/lib/contexts/auth";
const RowActions = ({ row, mutate }) => {
+ const { user } = useAuth();
+
return (
- {row.original.state_id == 5 && (
+ {row.original.state_id == 5 && user.id == row.original.user_id && (
<>
diff --git a/src/components/dashboard/roadMissions/transportation/Actions/showArea/index.jsx b/src/components/dashboard/roadMissions/transportation/Actions/showArea/index.jsx
index 4232c07..be4ee7a 100644
--- a/src/components/dashboard/roadMissions/transportation/Actions/showArea/index.jsx
+++ b/src/components/dashboard/roadMissions/transportation/Actions/showArea/index.jsx
@@ -6,12 +6,15 @@ import ShowBound from "../showBound";
import L from "leaflet";
const ShowArea = ({ area }) => {
- const bound = useMemo(() => L.polygon([...area]), [area]);
+ const bound = useMemo(
+ () => (area.type == "polygon" ? L.polygon([...area.coordinates]) : L.polyline([...area.coordinates])),
+ [area]
+ );
const [openAreaDialog, setOpenAreaDialog] = useState(false);
return (
<>
-
+
setOpenAreaDialog(true)}>
@@ -33,7 +36,7 @@ const ShowArea = ({ area }) => {
>
- محدوده
+ منطقه عملیاتی
setOpenAreaDialog(false)} size="small">
diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/DriversDialog/DriversSearch/Form/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/DriversDialog/DriversSearch/Form/index.jsx
new file mode 100644
index 0000000..93bb1d6
--- /dev/null
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/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/transportation/RowActions/Allocation/Form/DriversDialog/DriversSearch/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/DriversDialog/DriversSearch/index.jsx
new file mode 100644
index 0000000..b7136c9
--- /dev/null
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/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/transportation/RowActions/Allocation/Form/DriversDialog/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/DriversDialog/index.jsx
new file mode 100644
index 0000000..3c1d406
--- /dev/null
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/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(true)} variant="contained" fullWidth size="large">
+ انتخاب راننده
+
+ )}
+
+ >
+ );
+};
+export default DriversDialog;
diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/Allocate/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/Allocate/index.jsx
index e26344e..9718815 100644
--- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/Allocate/index.jsx
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/Allocate/index.jsx
@@ -1,13 +1,9 @@
import { Done } from "@mui/icons-material";
import { IconButton, Tooltip } from "@mui/material";
-const Allocate = ({ row, request, dispatch, setOpenMachinesDialog }) => {
+const Allocate = ({ row, setMachine, setOpenMachinesDialog }) => {
const handleClick = () => {
- dispatch({
- type: "CHANGE_MACHINE",
- id: request.id,
- machine: row.original,
- });
+ setMachine(row.original);
setOpenMachinesDialog(false);
};
diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/index.jsx
index ee1b9d2..ba0a20d 100644
--- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/index.jsx
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/RowActions/index.jsx
@@ -1,6 +1,6 @@
import Allocate from "./Allocate";
-const RowActions = ({ row, request, dispatch, setOpenMachinesDialog }) => {
- return ;
+const RowActions = ({ row, setMachine, setOpenMachinesDialog }) => {
+ return ;
};
export default RowActions;
diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/index.jsx
index fd7a643..07e8983 100644
--- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/index.jsx
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/MachineList/index.jsx
@@ -4,7 +4,7 @@ import { useMemo } from "react";
import RowActions from "./RowActions";
import { GET_MACHINES_TABLE_LIST } from "@/core/utils/routes";
-const MachinesList = ({ request, dispatch, setOpenMachinesDialog }) => {
+const MachinesList = ({ machineType, setMachine, setOpenMachinesDialog }) => {
const columns = useMemo(
() => [
{
@@ -40,6 +40,7 @@ const MachinesList = ({ request, dispatch, setOpenMachinesDialog }) => {
need_filter={true}
table_title="لیست خودرو ها"
columns={columns}
+ specialFilter={[{ value: machineType, datatype: "text", id: "car_type", fn: "equals" }]}
sorting={[{ id: "id", desc: true }]}
table_url={GET_MACHINES_TABLE_LIST}
page_name={"roadMissionsTransportation"}
@@ -47,12 +48,7 @@ const MachinesList = ({ request, dispatch, setOpenMachinesDialog }) => {
enableRowActions
positionActionsColumn={"first"}
RowActions={(props) => (
-
+
)}
/>
diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/index.jsx
index 5bdd6d8..0265264 100644
--- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/index.jsx
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/Form/MachinesDialog/index.jsx
@@ -3,7 +3,7 @@ import { Button, Dialog, IconButton } from "@mui/material";
import { useState } from "react";
import MachinesList from "./MachineList";
-const MachinesDialog = ({ request, dispatch, mode }) => {
+const MachinesDialog = ({ machineType, setMachine, mode }) => {
const [openMachinesDialog, setOpenMachinesDialog] = useState(false);
return (
<>
@@ -12,11 +12,11 @@ const MachinesDialog = ({ request, dispatch, mode }) => {
) : (
- setOpenMachinesDialog(true)} variant="outlined" size="small">
+ setOpenMachinesDialog(true)} variant="contained" fullWidth size="large">
انتخاب خودرو
)}
-
handleSubmit(requests)}
+ onClick={() => handleSubmit(machine, driver)}
variant="contained"
color="primary"
- disabled={requests.some((r) => !r.machine) || isSubmitting}
+ disabled={!machine || !driver || isSubmitting}
autoFocus
>
تایید و تخصیص
diff --git a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/index.jsx b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/index.jsx
index 58c9ae8..34dad0d 100644
--- a/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/index.jsx
+++ b/src/components/dashboard/roadMissions/transportation/RowActions/Allocation/index.jsx
@@ -8,7 +8,7 @@ const Allocation = ({ row, mutate }) => {
return (
<>
-
+
{
-
+
setOpenAllocationDialog(false)}
@@ -33,11 +33,10 @@ const Allocation = ({ row, mutate }) => {
>
- لیست خودرو های درخواستی
+ تخصیص خودرو
{openAllocationDialog && (
diff --git a/src/components/dashboard/roadMissions/transportation/TransportationList.jsx b/src/components/dashboard/roadMissions/transportation/TransportationList.jsx
index eb1f935..76a3b01 100644
--- a/src/components/dashboard/roadMissions/transportation/TransportationList.jsx
+++ b/src/components/dashboard/roadMissions/transportation/TransportationList.jsx
@@ -6,13 +6,10 @@ import moment from "jalali-moment";
import { useMemo } from "react";
import ShowArea from "./Actions/showArea";
import RowActions from "./RowActions";
+import { missionRegions } from "@/core/utils/missionRegions";
+import { missionTypes } from "@/core/utils/missionTypes";
const TransportationList = () => {
- const typeOptions = [
- { value: 1, label: "روزانه" },
- { value: 2, label: "ساعتی" },
- ];
-
const columns = useMemo(
() => [
{
@@ -26,9 +23,47 @@ const TransportationList = () => {
grow: false,
size: 100,
},
+ {
+ accessorKey: "state_name",
+ header: "وضعیت",
+ id: "state_name",
+ enableColumnFilter: false,
+ datatype: "numeric",
+ filterMode: "equals",
+ 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,
+ },
{
accessorKey: "type",
- header: "نوع",
+ header: "نوع زمانبندی",
id: "type",
enableColumnFilter: true,
datatype: "numeric",
@@ -37,15 +72,18 @@ const TransportationList = () => {
grow: false,
size: 100,
columnSelectOption: () => {
- return typeOptions.map((type) => ({
- value: type.value,
- label: type.label,
+ return missionTypes.map((type) => ({
+ value: type.id,
+ label: type.name_fa,
}));
},
Cell: ({ row }) => row.original.type_fa,
},
{
- accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ 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,
@@ -55,7 +93,10 @@ const TransportationList = () => {
size: 100,
},
{
- accessorFn: (row) => moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ 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,
@@ -75,7 +116,7 @@ const TransportationList = () => {
size: 100,
},
{
- header: "محدوده",
+ header: "منطقه عملیاتی",
id: "area",
enableColumnFilter: false,
datatype: "numeric",
@@ -100,6 +141,16 @@ const TransportationList = () => {
"-"
),
},
+ {
+ accessorFn: (row) => moment(row.request_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
+ header: "تاریخ ثبت",
+ id: "request_date",
+ enableColumnFilter: true,
+ datatype: "date",
+ filterMode: "between",
+ grow: false,
+ size: 100,
+ },
],
[]
);
diff --git a/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx b/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx
index b0f8685..47af636 100644
--- a/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx
+++ b/src/components/layouts/dashboard/headerWithLogo/HaederBottom/index.jsx
@@ -10,19 +10,20 @@ const HeaderBottom = () => {
direction="row"
justifyContent={"space-between"}
sx={{
- px: 2,
- py: 1,
+ pl: 2,
background: (theme) => theme.palette.primary2.main,
}}
spacing={2}
>
-
-
-
- theme.palette.primary2.contrastText }}>
+
+
+
+ theme.palette.primary2.contrastText }}>
سامانه جامع راهداری
- theme.palette.primary2.contrastText }}>rms.rmto.ir
+ theme.palette.primary2.contrastText }}>
+ rms.rmto.ir
+
@@ -30,13 +31,11 @@ const HeaderBottom = () => {
sx={{
p: 1,
background: "#fff",
- border: 2,
- borderColor: (theme) => theme.palette.primary.main,
- borderRadius: 2,
- borderStyle: "dashed",
+ borderTopLeftRadius: 8,
+ borderBottomLeftRadius: 8,
}}
>
-
+
diff --git a/src/components/layouts/dashboard/headerWithSidebar/index.jsx b/src/components/layouts/dashboard/headerWithSidebar/index.jsx
index d7d289f..e5c655f 100644
--- a/src/components/layouts/dashboard/headerWithSidebar/index.jsx
+++ b/src/components/layouts/dashboard/headerWithSidebar/index.jsx
@@ -9,8 +9,8 @@ import moment from "jalali-moment";
import { headerMenu } from "@/core/utils/headerMenu";
import SidebarMenu from "./Sidebar/SidebarMenu";
-const drawerWidth = 300;
-const headersHeight = 72;
+const drawerWidth = 275;
+const headersHeight = 51;
const Main = styled(Stack, { shouldForwardProp: (prop) => prop !== "open" })(({ theme, open }) => ({
flexGrow: 1,
diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js
index ce23c14..61c16cb 100644
--- a/src/core/components/DataTable/Main.js
+++ b/src/core/components/DataTable/Main.js
@@ -51,15 +51,16 @@ const DataTable_Main = (props) => {
const params = new URLSearchParams();
params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
params.set("size", pagination.pageSize);
- if (specialFilter) {
- const filteredSpecialFilterData = Object.values(specialFilter).filter(
- (filter) => !isArrayEmpty(filter.value)
- );
- params.set("filters", JSON.stringify(filteredSpecialFilterData || []));
- } else {
- const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty);
- params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData));
- }
+
+ const filteredSpecialFilterData = specialFilter
+ ? Object.values(specialFilter).filter((filter) => !isArrayEmpty(filter.value))
+ : [];
+
+ const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty);
+
+ const combinedFilters = [...filteredSpecialFilterData, ...filteredFilterData];
+
+ params.set("filters", JSON.stringify(combinedFilters));
params.set(
"sorting",
JSON.stringify(
diff --git a/src/core/components/MuiTimePicker.jsx b/src/core/components/MuiTimePicker.jsx
index 53b8f02..2323119 100644
--- a/src/core/components/MuiTimePicker.jsx
+++ b/src/core/components/MuiTimePicker.jsx
@@ -9,7 +9,18 @@ import { parseISO } from "date-fns";
const parseIfString = (val) =>
val instanceof Date ? val : typeof val === "string" && val !== "" ? parseISO(val) : null;
-function MuiTimePicker({ value, setFieldValue, name, minTime, maxTime, helperText, placeholder, error, label }) {
+function MuiTimePicker({
+ value,
+ setFieldValue,
+ views = ["hours", "minutes"],
+ name,
+ minTime,
+ maxTime,
+ helperText,
+ placeholder,
+ error,
+ label,
+}) {
// Ensure value, minTime, maxTime are Date objects
const parsedValue = parseIfString(value);
const parsedMinTime = parseIfString(minTime);
@@ -28,9 +39,10 @@ function MuiTimePicker({ value, setFieldValue, name, minTime, maxTime, helperTex
id={name}
closeOnSelect
label={label}
+ format="HH:mm"
ampm={false}
timeSteps={{ hours: 1, minutes: 5 }}
- views={["hours", "minutes"]}
+ views={views}
name={name}
onChange={(newValue) => {
setFieldValue(name, newValue);
diff --git a/src/core/components/NotificationDesign/AskForKeepData.jsx b/src/core/components/NotificationDesign/AskForKeepData.jsx
index e6fa9f3..7bedb50 100644
--- a/src/core/components/NotificationDesign/AskForKeepData.jsx
+++ b/src/core/components/NotificationDesign/AskForKeepData.jsx
@@ -13,7 +13,7 @@ function filterFalseValues(obj) {
for (const [key, value] of Object.entries(obj)) {
if (value === false) {
result[key] = false;
- } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
+ } else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
const nested = filterFalseValues(value);
if (Object.keys(nested).length > 0) {
result[key] = nested;
diff --git a/src/core/components/RahdarCode.jsx b/src/core/components/RahdarCode.jsx
index 0e77855..6344ac7 100644
--- a/src/core/components/RahdarCode.jsx
+++ b/src/core/components/RahdarCode.jsx
@@ -1,11 +1,10 @@
"use client";
+import { GET_RAHDARANS_LIST_SEARCH } from "@/core/utils/routes";
+import useRequest from "@/lib/hooks/useRequest";
import { Autocomplete, CircularProgress, TextField } from "@mui/material";
import { useEffect, useState } from "react";
-import useRequest from "@/lib/hooks/useRequest";
-import { debounce } from "@mui/material/utils";
-import { GET_RAHDARANS_LIST_SEARCH } from "@/core/utils/routes";
-const RahdarCode = ({ rahdarsCode, setRahdarsCode, error, multiple = true }) => {
+const RahdarCode = ({ title = "راهدار", rahdarsCode, setRahdarsCode, error, multiple = true }) => {
const [inputValue, setInputValue] = useState(""); // مدیریت مقدار تایپشده
const [options, setOptions] = useState([]);
const [loading, setLoading] = useState(false);
@@ -13,30 +12,27 @@ const RahdarCode = ({ rahdarsCode, setRahdarsCode, error, multiple = true }) =>
useEffect(() => {
const fetchRahdarCodes = (inputValue, controller) => {
- const debouncer = debounce((query) => {
- if ((query || "").length < 3) {
- setOptions([]);
- return;
- }
- setLoading(true);
- requestServer(`${GET_RAHDARANS_LIST_SEARCH}?code=${query}`, "get", {
- requestOptions: { signal: controller.signal },
+ if ((inputValue || "").length < 3) {
+ setOptions([]);
+ return;
+ }
+ setLoading(true);
+ requestServer(`${GET_RAHDARANS_LIST_SEARCH}?code=${inputValue}`, "get", {
+ requestOptions: { signal: controller.signal },
+ })
+ .then((response) => {
+ const combinedArray = rahdarsCode
+ ? [...rahdarsCode, ...response.data.data]
+ : [...response.data.data];
+ const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values());
+ setOptions(uniqueArray || []);
})
- .then((response) => {
- const combinedArray = rahdarsCode
- ? [...rahdarsCode, ...response.data.data]
- : [...response.data.data];
- const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values());
- setOptions(uniqueArray || []);
- })
- .catch(() => {
- setOptions([]);
- })
- .finally(() => {
- setLoading(false);
- });
- }, 500);
- debouncer(inputValue);
+ .catch(() => {
+ setOptions([]);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
};
const controller = new AbortController();
@@ -64,17 +60,17 @@ const RahdarCode = ({ rahdarsCode, setRahdarsCode, error, multiple = true }) =>
return option.code === (value?.code || value);
}}
loading={loading}
- loadingText="درحال جستجوی کد راهدار"
+ loadingText={`درحال جستجوی کد ${title}`}
noOptionsText={
- (inputValue || "").length < 3 ? "حداقل سه رقم از کد راهدار را وارد کنید" : "کد راهداری یافت نشد"
+ (inputValue || "").length < 3 ? `حداقل سه رقم کد ملی ${title} را وارد کنید` : `${title}ی یافت نشد`
}
fullWidth
renderInput={(params) => (
{
+ const [inputValue, setInputValue] = useState(""); // مدیریت مقدار تایپشده
+ const [options, setOptions] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const requestServer = useRequest();
+
+ useEffect(() => {
+ const fetchRahdarNames = (inputValue, controller) => {
+ if ((inputValue || "").length < 3) {
+ setOptions([]);
+ return;
+ }
+ setLoading(true);
+ requestServer(`${GET_RAHDARANS_LIST_SEARCH}?search=${inputValue}`, "get", {
+ requestOptions: { signal: controller.signal },
+ })
+ .then((response) => {
+ const combinedArray = rahdarsName
+ ? [...rahdarsName, ...response.data.data]
+ : [...response.data.data];
+ const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values());
+ setOptions(uniqueArray || []);
+ })
+ .catch(() => {
+ setOptions([]);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ };
+
+ const controller = new AbortController();
+ fetchRahdarNames(inputValue, controller);
+ return () => controller.abort();
+ }, [inputValue]);
+
+ return (
+ {
+ setRahdarsName(multiple ? newValue || [] : newValue || null); // مدیریت حالت چندگانه و تکگانه
+ }}
+ inputValue={inputValue} // مقدار تایپشده
+ onInputChange={(event, newInputValue) => {
+ setInputValue(newInputValue || ""); // بهروزرسانی مقدار تایپشده
+ }}
+ options={options} // گزینههای موجود
+ getOptionLabel={(option) => (typeof option === "string" ? option : `${option.code} - ${option.name}`)}
+ isOptionEqualToValue={(option, value) => {
+ if (!value) return false;
+ if (value === "") return option.code === "";
+ return option.code === (value?.code || value);
+ }}
+ loading={loading}
+ loadingText={`درحال جستجوی ${title}`}
+ noOptionsText={(inputValue || "").length < 3 ? `حداقل سه کاراکتر وارد کنید` : `${title}ی یافت نشد`}
+ fullWidth
+ renderInput={(params) => (
+
+ {loading ? : null}
+ {params.InputProps.endAdornment}
+ >
+ ),
+ }}
+ />
+ )}
+ />
+ );
+};
+export default RahdarNameOrCode;
diff --git a/src/core/utils/machineTypes.js b/src/core/utils/machineTypes.js
index 62d3642..e2188bc 100644
--- a/src/core/utils/machineTypes.js
+++ b/src/core/utils/machineTypes.js
@@ -1,4 +1,4 @@
export const machineType = [
- { id: "grader", name_fa: "گریدر" },
- { id: "loder", name_fa: "لودر" },
+ { id: "گریدر", name_fa: "گریدر" },
+ { id: "لودر", name_fa: "لودر" },
];
diff --git a/src/core/utils/missionCategoryTypes.js b/src/core/utils/missionCategoryTypes.js
new file mode 100644
index 0000000..d0711ad
--- /dev/null
+++ b/src/core/utils/missionCategoryTypes.js
@@ -0,0 +1,5 @@
+export const missionCategoryTypes = [
+ { id: 1, name_fa: "فعالیت روزانه" },
+ { id: 2, name_fa: "گشت راهداری" },
+ { id: 3, name_fa: "واکنش سریع" },
+];
diff --git a/src/core/utils/missionRegions.js b/src/core/utils/missionRegions.js
new file mode 100644
index 0000000..48896ca
--- /dev/null
+++ b/src/core/utils/missionRegions.js
@@ -0,0 +1,5 @@
+export const missionRegions = [
+ { id: 1, name_fa: "داخل شهر" },
+ { id: 2, name_fa: "بیرون شهر - داخل محدوده" },
+ { id: 3, name_fa: "بیرون شهر - خارج محدوده" },
+];
diff --git a/src/core/utils/missionTypes.js b/src/core/utils/missionTypes.js
new file mode 100644
index 0000000..3b41b88
--- /dev/null
+++ b/src/core/utils/missionTypes.js
@@ -0,0 +1,4 @@
+export const missionTypes = [
+ { id: 1, name_fa: "ساعتی" },
+ { id: 2, name_fa: "روزانه" },
+];
diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js
index 7a3c1ea..396762f 100644
--- a/src/core/utils/pageMenu.js
+++ b/src/core/utils/pageMenu.js
@@ -96,6 +96,7 @@ export const pageMenu = [
label: "ماموریت ها",
type: "menu",
icon: ,
+ badges: [{ key: "mission.total" }],
hasSubitems: true,
Subitems: [
{
@@ -103,13 +104,19 @@ export const pageMenu = [
label: "کارتابل",
type: "page",
route: "/dashboard/road-missions/operator",
- permissions: ["manage-request-portal-country", "manage-request-portal-province", "manage-request-portal-city"],
+ badges: [{ key: "mission.request_portal" }],
+ permissions: [
+ "manage-request-portal-country",
+ "manage-request-portal-province",
+ "manage-request-portal-city",
+ ],
},
{
id: "roadMissionsManagemnetNaqlie",
label: "نقلیه",
type: "page",
route: "/dashboard/road-missions/transportation",
+ badges: [{ key: "mission.transportation" }],
permissions: ["manage-transportation-unit"],
},
{
@@ -117,6 +124,7 @@ export const pageMenu = [
label: "کنترل",
type: "page",
route: "/dashboard/road-missions/control",
+ badges: [{ key: "mission.control" }],
permissions: ["manage-control-unit"],
},
],
diff --git a/src/core/utils/pageMenuDev.js b/src/core/utils/pageMenuDev.js
index 74977f9..5e0a639 100644
--- a/src/core/utils/pageMenuDev.js
+++ b/src/core/utils/pageMenuDev.js
@@ -1,28 +1,29 @@
-import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard";
-import GroupsIcon from "@mui/icons-material/Groups";
+import { Mediation } from "@mui/icons-material";
import AccountTreeIcon from "@mui/icons-material/AccountTree";
-import FactCheckIcon from "@mui/icons-material/FactCheck";
-import FireTruckIcon from "@mui/icons-material/FireTruck";
-import RouteIcon from "@mui/icons-material/Route";
-import DoorbellIcon from "@mui/icons-material/Doorbell";
-import ElectricBoltIcon from "@mui/icons-material/ElectricBolt";
-import CottageIcon from "@mui/icons-material/Cottage";
-import GppMaybeIcon from "@mui/icons-material/GppMaybe";
-import GavelIcon from "@mui/icons-material/Gavel";
-import BallotIcon from "@mui/icons-material/Ballot";
-import AssistantIcon from "@mui/icons-material/Assistant";
import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings";
-import MapIcon from "@mui/icons-material/Map";
-import SpeedIcon from "@mui/icons-material/Speed";
-import EngineeringIcon from "@mui/icons-material/Engineering";
import AssessmentIcon from "@mui/icons-material/Assessment";
import AssignmentLateIcon from "@mui/icons-material/AssignmentLate";
-import LockPersonIcon from "@mui/icons-material/LockPerson";
-import LineAxisIcon from "@mui/icons-material/LineAxis";
-import ScienceIcon from "@mui/icons-material/Science";
-import DriveEtaIcon from "@mui/icons-material/DriveEta";
+import AssistantIcon from "@mui/icons-material/Assistant";
+import BallotIcon from "@mui/icons-material/Ballot";
import BiotechIcon from "@mui/icons-material/Biotech";
-import { Mediation } from "@mui/icons-material";
+import CottageIcon from "@mui/icons-material/Cottage";
+import DoorbellIcon from "@mui/icons-material/Doorbell";
+import DriveEtaIcon from "@mui/icons-material/DriveEta";
+import ElectricBoltIcon from "@mui/icons-material/ElectricBolt";
+import EngineeringIcon from "@mui/icons-material/Engineering";
+import FactCheckIcon from "@mui/icons-material/FactCheck";
+import FireTruckIcon from "@mui/icons-material/FireTruck";
+import GavelIcon from "@mui/icons-material/Gavel";
+import GppMaybeIcon from "@mui/icons-material/GppMaybe";
+import GroupsIcon from "@mui/icons-material/Groups";
+import HandymanIcon from "@mui/icons-material/Handyman";
+import LineAxisIcon from "@mui/icons-material/LineAxis";
+import LockPersonIcon from "@mui/icons-material/LockPerson";
+import MapIcon from "@mui/icons-material/Map";
+import RouteIcon from "@mui/icons-material/Route";
+import ScienceIcon from "@mui/icons-material/Science";
+import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard";
+import SpeedIcon from "@mui/icons-material/Speed";
export const pageMenuDev = [
{
@@ -95,6 +96,7 @@ export const pageMenuDev = [
label: "ماموریت ها",
type: "menu",
icon: ,
+ badges: [{ key: "mission.total" }],
hasSubitems: true,
Subitems: [
{
@@ -102,13 +104,19 @@ export const pageMenuDev = [
label: "کارتابل",
type: "page",
route: "/dashboard/road-missions/operator",
- permissions: ["manage-request-portal-country", "manage-request-portal-province", "manage-request-portal-city"],
+ badges: [{ key: "mission.request_portal" }],
+ permissions: [
+ "manage-request-portal-country",
+ "manage-request-portal-province",
+ "manage-request-portal-city",
+ ],
},
{
id: "roadMissionsManagemnetNaqlie",
label: "نقلیه",
type: "page",
route: "/dashboard/road-missions/transportation",
+ badges: [{ key: "mission.transportation" }],
permissions: ["manage-transportation-unit"],
},
{
@@ -116,6 +124,7 @@ export const pageMenuDev = [
label: "کنترل",
type: "page",
route: "/dashboard/road-missions/control",
+ badges: [{ key: "mission.control" }],
permissions: ["manage-control-unit"],
},
],
@@ -535,6 +544,14 @@ export const pageMenuDev = [
icon: ,
permissions: ["azmayesh-type-management"],
},
+ {
+ id: "rahdaran",
+ label: "راهداران",
+ type: "page",
+ route: "/dashboard/rahdaran",
+ icon: ,
+ permissions: ["all"],
+ },
{
id: "adminManagement",
label: "مدیریت سامانه",
@@ -572,7 +589,7 @@ export const pageMenuDev = [
type: "page",
route: "/dashboard/car-details",
icon: ,
- permissions: [""],
+ permissions: ["show-rahdaran"],
},
],
},
diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js
index 741127c..3385ebc 100644
--- a/src/core/utils/routes.js
+++ b/src/core/utils/routes.js
@@ -29,57 +29,66 @@ export const ADD_AZMAYESH_TYPE = api + "/api/v3/azmayesh_types/store";
export const UPDATE_AZMAYESH_TYPE = api + "/api/v3/azmayesh_types/update";
//road patrol
-export const GET_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator_index";
-export const EXPORT_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator_report";
-export const GET_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor_index";
-export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor_report";
-export const EXPORT_PROVINCE_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrol_reports/province_activity_excel";
-export const EXPORT_COUNTRY_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrol_reports/country_activity_excel";
-export const DELETE_ROAD_PATROL_SUPERVISOR = api + "/api/v3/road_patrols/delete";
+export const GET_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator";
+export const EXPORT_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator/excel";
+export const GET_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor";
+export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor/excel";
+export const DELETE_ROAD_PATROL_SUPERVISOR = api + "/api/v3/road_patrols/operator/delete";
export const GET_CMMS_MACHINE_ROAD_PATROL = api + "/api/v3/road_patrols/machines";
export const GET_ROAD_PATROL_OPERATOR_REPORT = api + "/v2/road_patrols/operator/report";
export const GET_ROAD_PATROL_SUPERVISOR_REPORT = api + "/v2/road_patrols/operator/report";
export const GET_RAHDARAN_ROAD_POTROL = api + "/api/v3/road_patrols/rahdaran";
-export const CREATE_PATROL = api + "/api/v3/road_patrols/store";
+export const CREATE_PATROL = api + "/api/v3/road_patrols/operator/store";
export const GET_FMS_DATA = api + "/api/v3/fms_vehicle/get_activity";
export const GET_OTP_TOKEN = api + "/api/v3/otp/get_token";
-export const GET_PROVINCE_ACTIVITY_REPORT = api + "/api/v3/road_patrol_reports/country_activity";
-export const GET_CITY_ACTIVITY_REPORT = api + "/api/v3/road_patrol_reports/province_activity";
+
+export const GET_PROVINCE_ACTIVITY_REPORT = api + "/api/v3/road_patrols/report/country_activity";
+export const GET_CITY_ACTIVITY_REPORT = api + "/api/v3/road_patrols/report/province_activity";
+export const EXPORT_COUNTRY_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrols/report/country_activity_excel";
+export const EXPORT_PROVINCE_ROAD_PATROL_REPORTS = api + "/api/v3/road_patrols/report/province_activity_excel";
// road items
-export const GET_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor_index";
-export const EXPORT_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor_report";
-export const GET_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator_index";
-export const EXPORT_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator_report";
-export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_ITEM =
- api + "/api/v3/road_item_reports/province_activity_excel_per_item";
-export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_ITEM =
- api + "/api/v3/road_item_reports/country_activity_excel_per_item";
-export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
- api + "/api/v3/road_item_reports/province_activity_excel_per_sub_item";
-export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
- api + "/api/v3/road_item_reports/country_activity_excel_per_sub_item";
+export const GET_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor";
+export const EXPORT_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor/excel";
+export const GET_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator";
+export const EXPORT_ROAD_ITEMS_OPERATOR_LIST = api + "/api/v3/road_items/operator/excel";
+
export const GET_ROAD_ITEMS_ITEM = api + "/api/v3/items";
export const GET_ROAD_ITEMS_SUB_ITEM = api + "/api/v3/sub_items";
export const GET_EDARAT_LISTS = api + "/public/contents/edarate_shahri_by_province";
-export const CREATE_ROAD_ITEMS = api + "/api/v3/road_items/store";
-export const UPDATE_ROAD_ITEMS = api + "/api/v3/road_items/update";
-export const VERIFY_BY_SUPERVISOR = api + "/api/v3/road_items/verify_by_supervisor";
-export const REJECT_BY_SUPERVISOR = api + "/api/v3/road_items/verify_by_supervisor";
-export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/delete";
-export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/restore";
+
+export const CREATE_ROAD_ITEMS = api + "/api/v3/road_items/operator";
+export const UPDATE_ROAD_ITEMS = api + "/api/v3/road_items/operator";
+export const VERIFY_BY_SUPERVISOR = api + "/api/v3/road_items/supervisor/confirm";
+export const REJECT_BY_SUPERVISOR = api + "/api/v3/road_items/supervisor/reject";
+export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/operator";
+export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/supervisor/reject";
+
export const GET_CAR_LIST_SEARCH = api + "/api/v3/cmms_machines/search";
export const GET_RAHDARANS_LIST_SEARCH = api + "/api/v3/rahdaran/search";
+
export const GET_OBSERVED_GASHT_LIST = api + "/api/v3/observed_items/filter";
-export const GET_ROAD_ITEMS_REPORT_MAP = api + "/api/v3/road_item_reports/activities_on_map";
-export const GET_ROAD_ITEM = api + "/api/v3/road_item_reports/show_on_map";
-export const GET_PROVINCE_ACTIVITY_PER_ITEM = api + "/api/v3/road_item_reports/country_activity_per_item";
-export const GET_CITY_ACTIVITY_PER_ITEM = api + "/api/v3/road_item_reports/province_activity_per_item";
-export const GET_PROVINCE_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/country_activity_per_sub_item";
-export const GET_CITY_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/province_activity_per_sub_item";
-export const GET_IMAGES_ROAD_ITEM = api + "/api/v3/road_items/files";
-export const GET_CMMS_MACHINE_ROAD_ITEM = api + "/api/v3/road_items/machines";
-export const GET_RAHDARAN_ROAD_ITEM = api + "/api/v3/road_items/rahdaran";
+
+export const GET_ROAD_ITEMS_REPORT_MAP = api + "/api/v3/road_items/reports/activities_on_map";
+export const GET_ROAD_ITEM = api + "/api/v3/road_items/reports/show_on_map";
+
+export const GET_PROVINCE_ACTIVITY_PER_ITEM = api + "/api/v3/road_items/reports/country_activity_per_item";
+export const GET_CITY_ACTIVITY_PER_ITEM = api + "/api/v3/road_items/reports/province_activity_per_item";
+export const GET_PROVINCE_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_items/reports/country_activity_per_sub_item";
+export const GET_CITY_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_items/reports/province_activity_per_sub_item";
+
+export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_ITEM =
+ api + "/api/v3/road_items/reports/country_activity_excel_per_item";
+export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_ITEM =
+ api + "/api/v3/road_item/reports/province_activity_excel_per_item";
+export const EXPORT_COUNTRY_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
+ api + "/api/v3/road_items/reports/country_activity_excel_per_sub_item";
+export const EXPORT_PROVINCE_ROAD_ITEM_REPORTS_PER_SUB_ITEM =
+ api + "/api/v3/road_items/reports/province_activity_excel_per_sub_item";
+
+export const GET_IMAGES_ROAD_ITEM = api + "/api/v3/road_items/details/files";
+export const GET_CMMS_MACHINE_ROAD_ITEM = api + "/api/v3/road_items/details/machines";
+export const GET_RAHDARAN_ROAD_ITEM = api + "/api/v3/road_items/details/rahdaran";
// damage items
export const GET_RECEIPT_DAMAGE_ITEMS_LIST = api + "/api/v3/damages";
@@ -185,9 +194,16 @@ export const REQUEST_MISSION = api + "/api/v3/missions/request_portal";
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";
+export const GET_MACHINES_BY_ID = api + "/api/v3/missions/details/machines";
export const ALLOCATE_REQUEST_MISSION = api + "/api/v3/missions/transportation_unit/allocate";
export const DEALLOCATE_REQUEST_MISSION = api + "/api/v3/missions/transportation_unit/deallocate";
export const START_MISSION = api + "/api/v3/missions/control_unit/start";
export const FINISH_MISSION = api + "/api/v3/missions/control_unit/finish";
export const GET_MACHINES_TABLE_LIST = api + "/api/v3/cmms_machines";
+
+// rahdaran
+export const GET_RAHDARAN_TABLE_LIST = api + "/api/v3/rahdaran";
+export const DELETE_RAHDARAN_ITEM = api + "/api/v3/rahdaran";
+export const UPDATE_RAHDARAN_ITEM = api + "/api/v3/rahdaran";
+export const CREATE_RAHDARAN_ITEM = api + "/api/v3/rahdaran";