diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/azmayesh/loading.jsx b/src/app/(withAuth)/(dashboardLayout)/dashboard/azmayesh/loading.jsx deleted file mode 100644 index 4535a8d..0000000 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/azmayesh/loading.jsx +++ /dev/null @@ -1,7 +0,0 @@ -"use client"; -import PageLoading from "@/core/components/PageLoading"; - -const Loading = () => { - return ; -}; -export default Loading; diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/azmayesh_type/loading.jsx b/src/app/(withAuth)/(dashboardLayout)/dashboard/azmayesh_type/loading.jsx deleted file mode 100644 index 4535a8d..0000000 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/azmayesh_type/loading.jsx +++ /dev/null @@ -1,7 +0,0 @@ -"use client"; -import PageLoading from "@/core/components/PageLoading"; - -const Loading = () => { - return ; -}; -export default Loading; diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-patrols/operator/loading.jsx b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-patrols/operator/loading.jsx deleted file mode 100644 index 4535a8d..0000000 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-patrols/operator/loading.jsx +++ /dev/null @@ -1,7 +0,0 @@ -"use client"; -import PageLoading from "@/core/components/PageLoading"; - -const Loading = () => { - return ; -}; -export default Loading; diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-patrols/supervisor/loading.jsx b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-patrols/supervisor/loading.jsx deleted file mode 100644 index 4535a8d..0000000 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-patrols/supervisor/loading.jsx +++ /dev/null @@ -1,7 +0,0 @@ -"use client"; -import PageLoading from "@/core/components/PageLoading"; - -const Loading = () => { - return ; -}; -export default Loading; diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/operator/loading.jsx b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/operator/loading.jsx deleted file mode 100644 index 4535a8d..0000000 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/operator/loading.jsx +++ /dev/null @@ -1,7 +0,0 @@ -"use client"; -import PageLoading from "@/core/components/PageLoading"; - -const Loading = () => { - return ; -}; -export default Loading; diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/operator/page.js b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/operator/page.js index 3ce87a7..ecf5a33 100644 --- a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/operator/page.js +++ b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/operator/page.js @@ -6,13 +6,7 @@ export const metadata = { }; const Page = () => { return ( - + {/**/} diff --git a/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/supervisor/page.js b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/supervisor/page.js new file mode 100644 index 0000000..6ef1822 --- /dev/null +++ b/src/app/(withAuth)/(dashboardLayout)/dashboard/road-safety/supervisor/page.js @@ -0,0 +1,21 @@ +import SupervisorPage from "@/components/dashboard/roadSafety/supervisor"; +import WithPermission from "@/core/middlewares/withPermission"; +// import ActivityCodeLog from "@/core/components/ActivityCodeLog"; +export const metadata = { + title: "کارتابل ارزیابی نگهداری حریم", +}; +const Page = () => { + return ( + + + {/**/} + + ); +}; + +export default Page; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepTwo/StepTwoContent.jsx b/src/components/dashboard/roadSafety/operator/Form/StepTwo/StepTwoContent.jsx index c9ab104..e9d5a6e 100644 --- a/src/components/dashboard/roadSafety/operator/Form/StepTwo/StepTwoContent.jsx +++ b/src/components/dashboard/roadSafety/operator/Form/StepTwo/StepTwoContent.jsx @@ -1,8 +1,23 @@ -import { Box, Button, Chip, DialogActions, DialogContent, Divider, Fade, Grid, Stack, Typography } from "@mui/material"; +import { + Box, + Button, + Chip, + DialogActions, + DialogContent, + Divider, + Fade, + FormControlLabel, + Grid, + Radio, + RadioGroup, + Stack, + TextField, + Typography, +} from "@mui/material"; import { useEffect, useState } from "react"; -import { Controller, useForm } from "react-hook-form"; +import { Controller, useForm, useWatch } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; -import { mixed, object } from "yup"; +import { mixed, object, string } from "yup"; import ShowDocuments from "./ShowDocuments"; import StyledForm from "@/core/components/StyledForm"; import { SECOND_STEP_STORE } from "@/core/utils/routes"; @@ -12,24 +27,35 @@ const StepTwoContent = ({ setOpenStepTwoDialog, mutate, rowId }) => { const requestServer = useRequest({ notificationSuccess: true }); const [selectedDamageItemList, setSelectedDamageItemList] = useState([]); const defaultValues = { + need_judiciary: "0", + operator_description: "", judiciary_document: null, }; const validationSchema = object({ - judiciary_document: mixed().test("is-array", "لطفا حداقل یک فایل بارگذاری کنید!", (value) => { - return Array.isArray(value) && value.length > 0; + judiciary_document: mixed().when("need_judiciary", { + is: "1", + then: (schema) => + schema.test("is-array", "لطفا حداقل یک فایل بارگذاری کنید!", (value) => { + return Array.isArray(value) && value.length > 0; + }), + otherwise: (schema) => schema.notRequired(), + }), + operator_description: string().when("need_judiciary", { + is: "0", + then: (schema) => schema.required("لطفا توضیحات را وارد کنید!"), + otherwise: (schema) => schema.notRequired(), }), }); const { control, handleSubmit, setValue, - formState: { isSubmitting, errors }, + formState: { isSubmitting }, } = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "all", }); - const handleCreateDamage = (files) => { setSelectedDamageItemList((prev) => { const newFiles = files.filter((file) => !prev.some((item) => item.name === file.name)); @@ -40,12 +66,19 @@ const StepTwoContent = ({ setOpenStepTwoDialog, mutate, rowId }) => { setValue("judiciary_document", selectedDamageItemList); }, [selectedDamageItemList]); + const need_judiciary = useWatch({ control, name: "need_judiciary" }); + const deleteDamageItem = (name) => { setSelectedDamageItemList((prev) => prev.filter((documentItem) => documentItem.name !== name)); }; const onSubmit = async (data) => { const formData = new FormData(); - data.judiciary_document.map((item, index) => formData.append(`judiciary_document[${index}]`, item)); + formData.append(`need_judiciary`, data.need_judiciary); + if (data.need_judiciary == 1) { + data.judiciary_document.map((item, index) => formData.append(`judiciary_document[${index}]`, item)); + } else { + formData.append(`operator_description`, data.operator_description); + } await requestServer(`${SECOND_STEP_STORE}/${rowId}`, "post", { data: formData, hasSidebarUpdate: true, @@ -58,69 +91,108 @@ const StepTwoContent = ({ setOpenStepTwoDialog, mutate, rowId }) => { }; return ( - - - ( - <> - - {error && {error.message}} - + + ( + <> + + } label="بدون مستندات قضایی" /> + } label="دارای مستندات قضایی" /> + + + )} + /> + {need_judiciary == 1 ? ( + <> + + ( + <> + + {error && {error.message}} + + )} + /> + + + + + {selectedDamageItemList.length === 0 && ( + + + فایل موردنظر را بارگذاری کنید. + + )} - /> - - - - - {selectedDamageItemList.length === 0 && ( - - - فایل موردنظر را بارگذاری کنید. - - + + + {selectedDamageItemList.length !== 0 && + selectedDamageItemList.map((selectedDamageItem, index) => ( + + + + ))} + + + + ) : ( + + ( + + )} + /> + )} - - - {selectedDamageItemList.length !== 0 && - selectedDamageItemList.map((selectedDamageItem, index) => ( - - - - ))} - - + + + + ); +}; + +export default FinishContent; diff --git a/src/components/dashboard/roadSafety/operator/RowActions/FinishForm/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/FinishForm/index.jsx new file mode 100644 index 0000000..a4340d7 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/RowActions/FinishForm/index.jsx @@ -0,0 +1,29 @@ +import DoneAllIcon from "@mui/icons-material/DoneAll"; +import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import FinishContent from "./FinishContent"; +const FinishForm = ({ rowId, mutate }) => { + const [openFinishDialog, setOpenFinishDialog] = useState(false); + return ( + <> + + setOpenFinishDialog(true)}> + + + + + خاتمه فرایند + + + + ); +}; +export default FinishForm; diff --git a/src/components/dashboard/roadSafety/operator/RowActions/OperatorDescriptionForm/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/OperatorDescriptionForm/index.jsx new file mode 100644 index 0000000..9a59745 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/RowActions/OperatorDescriptionForm/index.jsx @@ -0,0 +1,51 @@ +import { Dialog, DialogContent, DialogTitle, IconButton, Tooltip, Typography, Card, CardContent } from "@mui/material"; +import { useState } from "react"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import CloseIcon from "@mui/icons-material/Close"; + +const OperatorDescriptionForm = ({ description }) => { + const [openOfficerDescriptionDialog, setOpenOfficerDescriptionDialog] = useState(false); + + return ( + <> + + setOpenOfficerDescriptionDialog(true)}> + + + + setOpenOfficerDescriptionDialog(false)} + PaperProps={{ + sx: { + transition: "all .3s", + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + borderRadius: 2, + padding: 1, + }, + }} + maxWidth="sm" + fullWidth + dir="rtl" + > + + + توضیحات کارشناس + + setOpenOfficerDescriptionDialog(false)} size="small"> + + + + + + + {description || "هیچ توضیحی موجود نیست"} + + + + + + ); +}; + +export default OperatorDescriptionForm; diff --git a/src/components/dashboard/roadSafety/operator/RowActions/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/index.jsx index 85a7f23..8b3344b 100644 --- a/src/components/dashboard/roadSafety/operator/RowActions/index.jsx +++ b/src/components/dashboard/roadSafety/operator/RowActions/index.jsx @@ -4,21 +4,20 @@ import EditAxisType from "../Form/EditAxisType"; import StepThree from "../Form/StepThree"; import StepTwo from "../Form/StepTwo"; import DeleteForm from "./DeleteDialog"; +import FinishForm from "./FinishForm"; const RowActions = ({ row, mutate }) => { const { data: userPermissions } = usePermissions(); const hasDeletePermission = userPermissions?.includes("delete-safety-and-privacy"); const hasUpdatePermission = userPermissions?.includes("update-safety-and-privacy"); - const hasEdarateShahriPermission = userPermissions?.includes( - "show-safety-and-privacy-operator-cartable-edarate-shahri" - ); return ( {hasUpdatePermission && row.original?.axis_type_id == null && } - {hasEdarateShahriPermission && ( + {!row.original.is_finished && ( <> {row.original?.step === 1 && } {row.original?.step === 2 && } + )} {hasDeletePermission && } diff --git a/src/components/dashboard/roadSafety/supervisor/ExcelPrint/index.jsx b/src/components/dashboard/roadSafety/supervisor/ExcelPrint/index.jsx new file mode 100644 index 0000000..d66215e --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/ExcelPrint/index.jsx @@ -0,0 +1,74 @@ +import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; +import isArrayEmpty from "@/core/utils/isArrayEmpty"; +import { EXPORT_SUPERVISOR_ROAD_SAFETY } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { useTheme } from "@emotion/react"; +import DescriptionIcon from "@mui/icons-material/Description"; +import { Button, CircularProgress, IconButton, useMediaQuery } from "@mui/material"; +import FileSaver from "file-saver"; +import moment from "jalali-moment"; +import { useMemo, useState } from "react"; + +const PrintExcel = ({ table, filterData }) => { + const [loading, setLoading] = useState(false); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const requestServer = useRequest(); + const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { + if (filter.value && (!Array.isArray(filter.value) || filter.value.some((item) => item.trim() !== ""))) { + acc.push({ id: key, value: filter.value }); + } + return acc; + }, []); + + const filterParams = useMemo(() => { + const params = new URLSearchParams(); + if (activeFilters.length > 0) { + activeFilters.map((filter, index) => { + const filteredFilterData = DataTableFilterDataStructure(filterData, isArrayEmpty); + params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); + }); + } else { + params.set("filters", JSON.stringify([])); + } + return params; + }, [activeFilters]); + + const clickHandler = () => { + setLoading(true); + requestServer(`${EXPORT_SUPERVISOR_ROAD_SAFETY}?${filterParams}`, "get", { + requestOptions: { responseType: "blob" }, + }) + .then((response) => { + const filename = `خروجی کارتابل ارزیابی نگهداری حریم تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; + FileSaver.saveAs(response.data, filename); + }) + .catch(() => {}) + .finally(() => { + setLoading(false); + }); + }; + + return ( + <> + {isMobile ? ( + + + + ) : ( + + )} + + ); +}; +export default PrintExcel; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/ActionPictureDialog/ActionPictureContent.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/ActionPictureDialog/ActionPictureContent.jsx new file mode 100644 index 0000000..f27255b --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/ActionPictureDialog/ActionPictureContent.jsx @@ -0,0 +1,44 @@ +import { Box, Stack, Typography, useTheme } from "@mui/material"; +import Image from "next/image"; + +const ActionPictureContent = ({ image, title }) => { + const theme = useTheme(); + return ( + + + {title} + + + Image + + + ); +}; +export default ActionPictureContent; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/ActionPictureDialog/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/ActionPictureDialog/index.jsx new file mode 100644 index 0000000..4c2911c --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/ActionPictureDialog/index.jsx @@ -0,0 +1,40 @@ +import PhotoLibraryIcon from "@mui/icons-material/PhotoLibrary"; +import { Button, Dialog, DialogActions, DialogContent, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import ActionPictureContent from "./ActionPictureContent"; + +const ActionPictureDialog = ({ image }) => { + const [openImageDialog, setOpenImageDialog] = useState(false); + + return ( + <> + + setOpenImageDialog(true)}> + + + + setOpenImageDialog(false)} + PaperProps={{ + sx: { + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + }, + }} + maxWidth={"sm"} + scroll="paper" + > + + + + + + + + + ); +}; +export default ActionPictureDialog; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/ConfirmForm/ConfirmContent.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/ConfirmForm/ConfirmContent.jsx new file mode 100644 index 0000000..847e242 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/ConfirmForm/ConfirmContent.jsx @@ -0,0 +1,70 @@ +import { CONFIRM_ROAD_SAFETY_BY_SUPERVISOR } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { Button, DialogActions, DialogContent, Stack, TextField } from "@mui/material"; +import { useForm } from "react-hook-form"; + +const ConfirmContent = ({ rowId, mutate, setOpenConfirmDialog }) => { + const requestServer = useRequest({ notificationSuccess: true }); + + const { + register, + handleSubmit, + formState: { isSubmitting }, + } = useForm({ + defaultValues: { + supervisor_description: "", + }, + }); + + const onSubmit = async (data) => { + const formData = new FormData(); + data.supervisor_description !== "" && formData.append("supervisor_description", data.supervisor_description); + requestServer(`${CONFIRM_ROAD_SAFETY_BY_SUPERVISOR}/${rowId}`, "post", { + data: formData, + hasSidebarUpdate: true, + }) + .then(() => { + mutate(); + setOpenConfirmDialog(false); + }) + .catch(() => {}); + }; + + return ( + <> + + + + + + + + + + + + + ); +}; + +export default ConfirmContent; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/ConfirmForm/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/ConfirmForm/index.jsx new file mode 100644 index 0000000..d9aafa0 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/ConfirmForm/index.jsx @@ -0,0 +1,29 @@ +import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import ConfirmContent from "./ConfirmContent"; +import DoneIcon from "@mui/icons-material/Done"; +const ConfirmForm = ({ rowId, mutate }) => { + const [openConfirmDialog, setOpenConfirmDialog] = useState(false); + return ( + <> + + setOpenConfirmDialog(true)}> + + + + + تایید فعالیت + + + + ); +}; +export default ConfirmForm; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/DeleteDialog/DeleteContent.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/DeleteDialog/DeleteContent.jsx new file mode 100644 index 0000000..bb88f78 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/DeleteDialog/DeleteContent.jsx @@ -0,0 +1,42 @@ +import { Button, DialogActions, DialogContent, Stack, Typography } from "@mui/material"; +import React, { useState } from "react"; +import useRequest from "@/lib/hooks/useRequest"; +import { DELETE_SAFETY_AND_PRIVACY } 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_SAFETY_AND_PRIVACY}/${rowId}`, "delete", { + hasSidebarUpdate: true, + }) + .then(() => { + mutate(); + setOpenDeleteDialog(false); + setSubmitting(false); + }) + .catch(() => { + setSubmitting(false); + }); + }; + return ( + <> + + + آیا از حذف فعالیت اطمینان دارید؟ + + + + + + + + ); +}; + +export default DeleteContent; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/DeleteDialog/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/DeleteDialog/index.jsx new file mode 100644 index 0000000..596cf9a --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/DeleteDialog/index.jsx @@ -0,0 +1,32 @@ +import DeleteIcon from "@mui/icons-material/Delete"; +import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import DeleteContent from "./DeleteContent"; +const DeleteForm = ({ rowId, mutate }) => { + const [openDeleteDialog, setOpenDeleteDialog] = useState(false); + + return ( + <> + + setOpenDeleteDialog(true)}> + + + + setOpenDeleteDialog(false)} + PaperProps={{ + sx: { + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + }, + }} + dir="rtl" + maxWidth={"md"} + > + حذف فعالیت + + + + ); +}; +export default DeleteForm; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/DescriptionForm/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/DescriptionForm/index.jsx new file mode 100644 index 0000000..91b135a --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/DescriptionForm/index.jsx @@ -0,0 +1,51 @@ +import { Dialog, DialogContent, DialogTitle, IconButton, Tooltip, Typography, Card, CardContent } from "@mui/material"; +import { useState } from "react"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import CloseIcon from "@mui/icons-material/Close"; + +const DescriptionForm = ({ description }) => { + const [openOfficerDescriptionDialog, setOpenOfficerDescriptionDialog] = useState(false); + + return ( + <> + + setOpenOfficerDescriptionDialog(true)}> + + + + setOpenOfficerDescriptionDialog(false)} + PaperProps={{ + sx: { + transition: "all .3s", + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + borderRadius: 2, + padding: 1, + }, + }} + maxWidth="sm" + fullWidth + dir="rtl" + > + + + توضیحات ناظر + + setOpenOfficerDescriptionDialog(false)} size="small"> + + + + + + + {description || "هیچ توضیحی موجود نیست"} + + + + + + ); +}; + +export default DescriptionForm; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/FinishDescriptionForm/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/FinishDescriptionForm/index.jsx new file mode 100644 index 0000000..6178ae8 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/FinishDescriptionForm/index.jsx @@ -0,0 +1,51 @@ +import { Dialog, DialogContent, DialogTitle, IconButton, Tooltip, Typography, Card, CardContent } from "@mui/material"; +import { useState } from "react"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import CloseIcon from "@mui/icons-material/Close"; + +const FinishDescriptionForm = ({ description }) => { + const [openOfficerDescriptionDialog, setOpenOfficerDescriptionDialog] = useState(false); + + return ( + <> + + setOpenOfficerDescriptionDialog(true)}> + + + + setOpenOfficerDescriptionDialog(false)} + PaperProps={{ + sx: { + transition: "all .3s", + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + borderRadius: 2, + padding: 1, + }, + }} + maxWidth="sm" + fullWidth + dir="rtl" + > + + + علت خاتمه فرایند + + setOpenOfficerDescriptionDialog(false)} size="small"> + + + + + + + {description || "هیچ توضیحی موجود نیست"} + + + + + + ); +}; + +export default FinishDescriptionForm; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentContent.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentContent.jsx new file mode 100644 index 0000000..95a3f1e --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentContent.jsx @@ -0,0 +1,43 @@ +import { Box, Button, Chip, Divider, Grid, Typography } from "@mui/material"; +import DownloadIcon from "@mui/icons-material/Download"; +import ArticleIcon from "@mui/icons-material/Article"; + +const JudiciaryDocumentContent = ({ judiciaryDocumentDetails }) => { + return ( + + {judiciaryDocumentDetails.map((judiciaryDocument, index) => { + return ( + + + } + label={ + + مستندات قضایی {index + 1} + + } + /> + + + + + ); + })} + + ); +}; +export default JudiciaryDocumentContent; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentController.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentController.jsx new file mode 100644 index 0000000..0773130 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentController.jsx @@ -0,0 +1,35 @@ +import { useEffect, useState } from "react"; +import useRequest from "@/lib/hooks/useRequest"; +import DialogLoading from "@/core/components/DialogLoading"; +import JudiciaryDocumentContent from "./JudiciaryDocumentContent"; +import { DESERIALIZE_JUDICIARY_DOCUMENT } from "@/core/utils/routes"; +import { Typography } from "@mui/material"; + +const JudiciaryDocumentController = ({ rowId }) => { + const requestServer = useRequest(); + const [judiciaryDocumentDetails, setJudiciaryDocumentDetails] = useState([]); + const [judiciaryDocumentDetailsLoading, setJudiciaryDocumentDetailsLoading] = useState(false); + useEffect(() => { + setJudiciaryDocumentDetailsLoading(true); + requestServer(`${DESERIALIZE_JUDICIARY_DOCUMENT}/${rowId}`, "get") + .then((response) => { + setJudiciaryDocumentDetails(response.data.data); + setJudiciaryDocumentDetailsLoading(false); + }) + .catch((e) => { + setJudiciaryDocumentDetailsLoading(false); + }); + }, [rowId]); + return ( + <> + {judiciaryDocumentDetailsLoading ? ( + + ) : judiciaryDocumentDetails.length > 0 ? ( + + ) : ( + بدون مستندات + )} + + ); +}; +export default JudiciaryDocumentController; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/index.jsx new file mode 100644 index 0000000..575d4c5 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/JudiciaryDocumentDialog/index.jsx @@ -0,0 +1,40 @@ +import { Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import ArticleIcon from "@mui/icons-material/Article"; +import React, { useState } from "react"; +import JudiciaryDocumentController from "./JudiciaryDocumentController"; + +const JudiciaryDocumentDialog = ({ rowId }) => { + const [openJudiciaryDocumentDialog, setOpenJudiciaryDocumentDialog] = useState(false); + return ( + <> + + setOpenJudiciaryDocumentDialog(true)}> + + + + setOpenJudiciaryDocumentDialog(false)} + PaperProps={{ + sx: { + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + }, + }} + dir="rtl" + maxWidth={"sm"} + fullWidth + > + مشاهده مستندات قضایی + + + + + + + + + ); +}; +export default JudiciaryDocumentDialog; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/LocationForm/LocationFormContent.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/LocationForm/LocationFormContent.jsx new file mode 100644 index 0000000..14b3db3 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/LocationForm/LocationFormContent.jsx @@ -0,0 +1,35 @@ +"use client"; +import { Box, Button, DialogActions, DialogContent, Stack } from "@mui/material"; +import React from "react"; +import dynamic from "next/dynamic"; +import MapLoading from "@/core/components/MapLayer/Loading"; +import ShowLocationMarker from "@/core/components/ShowLocationMarker"; +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); + +const LocationFormContent = ({ setOpenLocationDialog, start_lat, start_lng, end_lat, end_lng }) => { + return ( + <> + + + + + + + + + + + + ); +}; +export default LocationFormContent; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/LocationForm/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/LocationForm/index.jsx new file mode 100644 index 0000000..d614215 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/LocationForm/index.jsx @@ -0,0 +1,40 @@ +import React, { useState } from "react"; +import { Tooltip, IconButton, Dialog, DialogTitle } from "@mui/material"; +import ExploreIcon from "@mui/icons-material/Explore"; +import LocationFormContent from "./LocationFormContent"; +const LocationForm = ({ start_lat, start_lng, end_lat, end_lng }) => { + const [openLocationDialog, setOpenLocationDialog] = useState(false); + + return ( + <> + + setOpenLocationDialog(true)}> + + + + setOpenLocationDialog(false)} + PaperProps={{ + sx: { + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + }, + }} + dir="rtl" + maxWidth={"md"} + > + موقعیت + {openLocationDialog && ( + + )} + + + ); +}; +export default LocationForm; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/OperatorDescriptionForm/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/OperatorDescriptionForm/index.jsx new file mode 100644 index 0000000..9a59745 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/OperatorDescriptionForm/index.jsx @@ -0,0 +1,51 @@ +import { Dialog, DialogContent, DialogTitle, IconButton, Tooltip, Typography, Card, CardContent } from "@mui/material"; +import { useState } from "react"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import CloseIcon from "@mui/icons-material/Close"; + +const OperatorDescriptionForm = ({ description }) => { + const [openOfficerDescriptionDialog, setOpenOfficerDescriptionDialog] = useState(false); + + return ( + <> + + setOpenOfficerDescriptionDialog(true)}> + + + + setOpenOfficerDescriptionDialog(false)} + PaperProps={{ + sx: { + transition: "all .3s", + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + borderRadius: 2, + padding: 1, + }, + }} + maxWidth="sm" + fullWidth + dir="rtl" + > + + + توضیحات کارشناس + + setOpenOfficerDescriptionDialog(false)} size="small"> + + + + + + + {description || "هیچ توضیحی موجود نیست"} + + + + + + ); +}; + +export default OperatorDescriptionForm; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/RecognizePictureDialog/RecognizePictureContent.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/RecognizePictureDialog/RecognizePictureContent.jsx new file mode 100644 index 0000000..39dbdcf --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/RecognizePictureDialog/RecognizePictureContent.jsx @@ -0,0 +1,44 @@ +import { Box, Stack, Typography, useTheme } from "@mui/material"; +import Image from "next/image"; + +const RecognizePictureContent = ({ image, title }) => { + const theme = useTheme(); + return ( + + + {title} + + + Image + + + ); +}; +export default RecognizePictureContent; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/RecognizePictureDialog/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/RecognizePictureDialog/index.jsx new file mode 100644 index 0000000..72ef4ea --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/RecognizePictureDialog/index.jsx @@ -0,0 +1,40 @@ +import PhotoLibraryIcon from "@mui/icons-material/PhotoLibrary"; +import { Button, Dialog, DialogActions, DialogContent, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import RecognizePictureContent from "./RecognizePictureContent"; + +const RecognizePictureDialog = ({ image }) => { + const [openImageDialog, setOpenImageDialog] = useState(false); + + return ( + <> + + setOpenImageDialog(true)}> + + + + setOpenImageDialog(false)} + PaperProps={{ + sx: { + boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px", + }, + }} + maxWidth={"sm"} + scroll="paper" + > + + + + + + + + + ); +}; +export default RecognizePictureDialog; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/RejectForm/RejectContent.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/RejectForm/RejectContent.jsx new file mode 100644 index 0000000..bed259d --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/RejectForm/RejectContent.jsx @@ -0,0 +1,83 @@ +import { REJECT_ROAD_SAFETY_BY_SUPERVISOR } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Button, DialogActions, DialogContent, Stack, TextField } from "@mui/material"; +import { useForm } from "react-hook-form"; +import * as Yup from "yup"; + +const RejectContent = ({ rowId, mutate, setOpenRejectDialog }) => { + const requestServer = useRequest({ notificationSuccess: true }); + + const validationSchema = Yup.object().shape({ + supervisor_description: Yup.string().required("لطفاً توضیحات را وارد کنید."), + }); + + const { + register, + handleSubmit, + formState: { errors, isSubmitting }, + reset, + } = useForm({ + defaultValues: { + supervisor_description: "", + }, + resolver: yupResolver(validationSchema), + mode: "all", + }); + + const onSubmit = async (data) => { + const formData = new FormData(); + formData.append("supervisor_description", data.supervisor_description); + await requestServer(`${REJECT_ROAD_SAFETY_BY_SUPERVISOR}/${rowId}`, "post", { + data: formData, + hasSidebarUpdate: true, + }) + .then(() => { + mutate(); + setOpenRejectDialog(false); + }) + .catch(() => {}) + .finally(() => { + reset(); + }); + }; + + return ( + <> + + + + + + + + + + + + + ); +}; +export default RejectContent; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/RejectForm/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/RejectForm/index.jsx new file mode 100644 index 0000000..2f08152 --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/RejectForm/index.jsx @@ -0,0 +1,29 @@ +import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import RejectContent from "./RejectContent"; +import ClearIcon from "@mui/icons-material/Clear"; +const RejectForm = ({ rowId, mutate }) => { + const [openRejectDialog, setOpenRejectDialog] = useState(false); + return ( + <> + + setOpenRejectDialog(true)}> + + + + + عدم تایید فعالیت + + + + ); +}; +export default RejectForm; diff --git a/src/components/dashboard/roadSafety/supervisor/RowActions/index.jsx b/src/components/dashboard/roadSafety/supervisor/RowActions/index.jsx new file mode 100644 index 0000000..1deca9d --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/RowActions/index.jsx @@ -0,0 +1,22 @@ +import { usePermissions } from "@/lib/hooks/usePermissions"; +import { Box } from "@mui/material"; +import ConfirmForm from "./ConfirmForm"; +import DeleteForm from "./DeleteDialog"; +import RejectForm from "./RejectForm"; + +const RowActions = ({ row, mutate }) => { + const { data: userPermissions } = usePermissions(); + const hasDeletePermission = userPermissions?.includes("delete-safety-and-privacy"); + return ( + + {row.original.is_finished == 1 && row.original.status === 0 && ( + <> + + + + )} + {hasDeletePermission && } + + ); +}; +export default RowActions; diff --git a/src/components/dashboard/roadSafety/supervisor/SupervisorList.jsx b/src/components/dashboard/roadSafety/supervisor/SupervisorList.jsx new file mode 100644 index 0000000..c0acffd --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/SupervisorList.jsx @@ -0,0 +1,606 @@ +"use client"; +import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency"; +import DataTableWithAuth from "@/core/components/DataTableWithAuth"; +import { GET_SAFETY_AND_PRIVACY_SUPERVISOR } from "@/core/utils/routes"; +import useSafetyAndPrivacyGetItems from "@/lib/hooks/useSafetyAndPrivacyGetItems"; +import { Box, Stack } from "@mui/material"; +import moment from "jalali-moment"; +import { useEffect, useMemo, useState } from "react"; +import RowActions from "./RowActions"; +import ActionPictureDialog from "./RowActions/ActionPictureDialog"; +import DescriptionForm from "./RowActions/DescriptionForm"; +import FinishDescriptionForm from "./RowActions/FinishDescriptionForm"; +import JudiciaryDocumentDialog from "./RowActions/JudiciaryDocumentDialog"; +import LocationForm from "./RowActions/LocationForm"; +import OperatorDescriptionForm from "./RowActions/OperatorDescriptionForm"; +import RecognizePictureDialog from "./RowActions/RecognizePictureDialog"; +import Toolbar from "./Toolbar"; +import { usePermissions } from "@/lib/hooks/usePermissions"; +import { useAuth } from "@/lib/contexts/auth"; +import useProvinces from "@/lib/hooks/useProvince"; +import useEdaratLists from "@/lib/hooks/useEdaratLists"; +import BlinkingCell from "@/core/components/BlinkingCell"; + +const stepOptions = [ + { value: "", label: "همه گام ها" }, + { value: 1, label: "گام اول (شناسایی)" }, + { value: 2, label: "گام دوم (مستندات قضایی)" }, + { value: 3, label: "گام سوم (برخورد)" }, +]; +const statusOptions = [ + { value: "", label: "همه وضعیت ها" }, + { value: 0, label: "درحال بررسی" }, + { value: 1, label: "تایید" }, + { value: 2, label: "عدم تایید" }, +]; +const finishOptions = [ + { value: "", label: "همه موارد" }, + { value: 0, label: "در جریان" }, + { value: 1, label: "خاتمه یافته" }, +]; +const axisOptions = [ + { value: "", label: "همه محور ها" }, + { value: 1, label: "آزادراه" }, + { value: 2, label: "بزرگراه" }, + { value: 3, label: "اصلی" }, + { value: 4, label: "فرعی" }, + { value: 5, label: "روستایی" }, +]; +const SupervisorList = () => { + const { data: userPermissions } = usePermissions(); + const hasCountryPermission = userPermissions?.includes("show-safety-and-privacy-operator-cartable"); + const { user } = useAuth(); + + const columns = useMemo(() => { + const provinceColumn = { + header: "استان", + id: "province_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 130, + ColumnSelectComponent: (props) => { + const { provinces, errorProvinces, loadingProvinces } = useProvinces(); + const getColumnSelectOptions = useMemo(() => { + if (loadingProvinces) { + return [{ value: "loading", label: "در حال بارگذاری..." }]; + } + if (errorProvinces) { + return [{ value: "error", label: "خطا در بارگذاری" }]; + } + return [ + { value: "", label: "کل کشور" }, + ...provinces.map((province) => ({ + value: province.id, + label: province.name_fa, + })), + ]; + }, [provinces, errorProvinces, loadingProvinces]); + return ( + + ); + }, + Cell: ({ renderedCellValue, row }) => <>{row.original.province_fa}, + }; + return [ + { + accessorKey: "id", + header: "کد یکتا", + id: "id", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + Cell: ({ row }) => ( + + ), + }, + ...(hasCountryPermission ? [provinceColumn] : []), + { + header: "اداره", + id: "edare_shahri_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + dependencyId: hasCountryPermission ? "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: ({ renderedCellValue, row }) => <>{row.original.edare_shahri_name}, + }, + { + header: "اطلاعات فعالیت", + id: "info", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 50, + columns: [ + { + accessorKey: "info_id", + header: "مورد مشاهده شده", + id: "info_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 100, + ColumnSelectComponent: (props) => { + const { itemsList, loadingItemsList, errorItemsList } = useSafetyAndPrivacyGetItems(); + + const getColumnSelectOptions = useMemo(() => { + if (loadingItemsList) { + return [{ value: "loading", label: "در حال بارگذاری..." }]; + } + if (errorItemsList) { + return [{ value: "error", label: "خطا در بارگذاری" }]; + } + return [ + { value: "", label: "همه موارد" }, + ...itemsList.map((item) => ({ + value: item.id, + label: item.name, + })), + ]; + }, [itemsList, loadingItemsList, errorItemsList]); + + return ( + + ); + }, + Cell: ({ row }) => <>{row.original.info_fa}, + }, + { + accessorKey: "axis_type_id", + header: "نوع محور", + id: "axis_type_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + sortDescFirst: true, + grow: false, + size: 100, + columnSelectOption: () => { + return axisOptions.map((status) => ({ + value: status.value, + label: status.label, + })); + }, + Cell: ({ row }) => (row.original?.axis_type_name ? <>{row.original.axis_type_name} : <>-), + }, + { + accessorKey: "location", + header: "موقعیت", + id: "location", + enableColumnFilter: false, + enableSorting: false, + datatype: "array", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ row }) => { + return ( + + + + ); + }, + }, + { + accessorFn: (row) => moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"), + header: "تاریخ ثبت", + id: "created_at", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + ], + }, + { + header: "وضعیت فعالیت", + id: "allstatus", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 50, + columns: [ + { + header: "وضعیت گام ها", + id: "step", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + sortDescFirst: true, + grow: false, + size: 100, + columnSelectOption: () => { + return stepOptions.map((status) => ({ + value: status.value, + label: status.label, + })); + }, + Cell: ({ row }) => <>{row.original.step_fa}, + }, + { + header: "وضعیت فرایند", + id: "is_finished", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + sortDescFirst: true, + grow: false, + size: 100, + columnSelectOption: () => { + return finishOptions.map((status) => ({ + value: status.value, + label: status.label, + })); + }, + Cell: ({ row }) => ( + <> + {row.original.is_finished == 1 + ? "خاتمه یافته" + : row.original.is_finished == 0 + ? "در جریان" + : "-"} + + ), + }, + { + header: "علت خاتمه فرایند", + id: "finished_description", + enableColumnFilter: false, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ row }) => + row.original.final_description ? ( + + + + ) : ( + "-" + ), + }, + { + header: "وضعیت نظارت", + id: "status", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + sortDescFirst: true, + grow: false, + size: 100, + columnSelectOption: () => { + return statusOptions.map((status) => ({ + value: status.value, + label: status.label, + })); + }, + Cell: ({ row }) => <>{row.original.status_fa || "-"}, + }, + { + header: "توضیحات ناظر", + id: "supervisor_description", + enableColumnFilter: false, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ row }) => + row.original.supervisor_description ? ( + + + + ) : ( + "-" + ), + }, + ], + }, + { + header: "گام اول (شناسایی)", + id: "stepOne", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 50, + columns: [ + { + accessorKey: "recognize_picture", + header: "تصویر بازدید", + id: "recognize_picture", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue }) => { + return renderedCellValue ? ( + + + + ) : ( + <>- + ); + }, + }, + { + accessorFn: (row) => + row.activity_date_time ? ( + moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD") + ) : ( + <>- + ), + header: "تاریخ بازدید", + id: "activity_date_time", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + ], + }, + { + header: "گام دوم (مستندات قضایی)", + id: "stepTwo", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 50, + columns: [ + { + header: "مستندات قضایی", + id: "judiciary_document", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ row }) => { + return ( + + {row.original.judiciary_document_upload_date !== "0000-00-00 00:00:00" && + row.original.judiciary_document_upload_date ? ( + + ) : ( + <>- + )} + + ); + }, + }, + { + accessorFn: (row) => { + const date = row.judiciary_document_upload_date; + if (!date || date === "0000-00-00 00:00:00") { + return <>-; + } + return moment(date, "YYYY-MM-DD HH:mm:ss").locale("fa").format("HH:mm | yyyy/MM/DD"); + }, + + header: "تاریخ بارگذاری مستندات", + id: "judiciary_document_upload_date", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + { + header: "توضیحات کارشناس", + id: "operator_description", + enableColumnFilter: false, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ row }) => + row.original.operator_description ? ( + + + + ) : ( + "-" + ), + }, + ], + }, + { + header: "گام سوم (برخورد)", + id: "stepThree", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 50, + columns: [ + { + accessorKey: "action_picture", + header: "تصویر اقدام", + id: "action_picture", + enableColumnFilter: false, + enableSorting: false, + datatype: "text", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue }) => { + return renderedCellValue ? ( + + + + ) : ( + <>- + ); + }, + }, + { + accessorFn: (row) => + row.action_date ? ( + moment(row.action_date).locale("fa").format("HH:mm | yyyy/MM/DD") + ) : ( + <>- + ), + header: "تاریخ اقدام", + id: "action_date", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + ], + }, + ]; + }, []); + + return ( + <> + + + + + ); +}; +export default SupervisorList; diff --git a/src/components/dashboard/roadSafety/supervisor/Toolbar.jsx b/src/components/dashboard/roadSafety/supervisor/Toolbar.jsx new file mode 100644 index 0000000..88f55fb --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/Toolbar.jsx @@ -0,0 +1,11 @@ +import { Stack } from "@mui/material"; +import PrintExcel from "./ExcelPrint"; + +const Toolbar = ({ table, filterData, mutate }) => { + return ( + + + + ); +}; +export default Toolbar; diff --git a/src/components/dashboard/roadSafety/supervisor/index.jsx b/src/components/dashboard/roadSafety/supervisor/index.jsx new file mode 100644 index 0000000..356487f --- /dev/null +++ b/src/components/dashboard/roadSafety/supervisor/index.jsx @@ -0,0 +1,14 @@ +"use client"; +import PageTitle from "@/core/components/PageTitle"; +import { Stack } from "@mui/material"; +import SupervisorList from "./SupervisorList"; + +const SupervisorPage = () => { + return ( + + + + + ); +}; +export default SupervisorPage; diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index a4e1d31..c6bc66c 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -291,10 +291,31 @@ export const pageMenu = [ icon: , hasSubitems: true, badges: [ + { key: "safetyAndPrivacy.supervise_cnt" }, { key: "safetyAndPrivacy.step_one", color: "warning" }, { key: "safetyAndPrivacy.step_two", color: "error" }, ], Subitems: [ + { + id: "safetyAndPrivacyManagmentSupervisor", + label: "ارزیابی", + type: "menu", + icon: , + hasSubitems: true, + badges: [{ key: "safetyAndPrivacy.supervise_cnt" }], + Subitems: [ + { + id: "safetyAndPrivacyManagmentSupervisorCartable", + label: "کارتابل", + type: "page", + route: "/dashboard/road-safety/supervisor", + permissions: [ + "show-safety-and-privacy-operator-cartable", + "show-safety-and-privacy-operator-cartable-province", + ], + }, + ], + }, { id: "safetyAndPrivacyManagmentOparation", label: "عملیات", @@ -311,11 +332,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: "/dashboard/road-safety/operator", - permissions: [ - "show-safety-and-privacy-operator-cartable", - "show-safety-and-privacy-operator-cartable-province", - "show-safety-and-privacy-operator-cartable-edarate-shahri", - ], + permissions: ["show-safety-and-privacy-operator-cartable-edarate-shahri"], }, ], }, diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 4fd9f13..ab33deb 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -130,15 +130,22 @@ export const EXPORT_FAST_REACT_OPERATOR_LIST = api + "/api/v3/road_observations/ export const EXPORT_FAST_REACT_COMPLAINT_LIST = api + "/api/v3/road_observations/complaints_report"; // road safety -export const GET_SAFETY_AND_PRIVACY = api + "/api/v3/safety_and_privacy"; -export const DELETE_SAFETY_AND_PRIVACY = api + "/api/v3/safety_and_privacy"; +export const GET_SAFETY_AND_PRIVACY_OPERATOR = api + "/api/v3/safety_and_privacy/operator"; +export const DELETE_SAFETY_AND_PRIVACY = api + "/api/v3/safety_and_privacy/operator"; +export const FIRST_STEP_STORE = api + "/api/v3/safety_and_privacy/operator/first_step_store"; +export const SECOND_STEP_STORE = api + "/api/v3/safety_and_privacy/operator/second_step_store"; +export const THIRD_STEP_STORE = api + "/api/v3/safety_and_privacy/operator/third_step_store"; +export const UPDATE_SAFETY_AND_PRIVACY = api + "/api/v3/safety_and_privacy/operator"; +export const FINISH_ROAD_SAFETY_BY_SUPERVISOR = api + "/api/v3/safety_and_privacy/operator/finish"; +export const EXPORT_OPERATOR_ROAD_SAFETY = api + "/api/v3/safety_and_privacy/operator/excel_report"; + +export const GET_SAFETY_AND_PRIVACY_SUPERVISOR = api + "/api/v3/safety_and_privacy/supervisor"; +export const EXPORT_SUPERVISOR_ROAD_SAFETY = api + "/api/v3/safety_and_privacy/supervisor/excel_report"; +export const CONFIRM_ROAD_SAFETY_BY_SUPERVISOR = api + "/api/v3/safety_and_privacy/supervisor/confirm"; +export const REJECT_ROAD_SAFETY_BY_SUPERVISOR = api + "/api/v3/safety_and_privacy/supervisor/reject"; + export const DESERIALIZE_JUDICIARY_DOCUMENT = api + "/api/v3/safety_and_privacy/deserialize"; export const GET_SAFETY_AND_PRIVACY_ITEM = api + "/api/v3/safety_and_privacy/sub_items"; -export const FIRST_STEP_STORE = api + "/api/v3/safety_and_privacy/first_step_store"; -export const SECOND_STEP_STORE = api + "/api/v3/safety_and_privacy/second_step_store"; -export const THIRD_STEP_STORE = api + "/api/v3/safety_and_privacy/third_step_store"; -export const UPDATE_SAFETY_AND_PRIVACY = api + "/api/v3/safety_and_privacy"; -export const EXPORT_OPERATOR_ROAD_SAFETY = api + "/api/v3/safety_and_privacy/excel_report"; export const GET_ROAD_SAFETY_PROVINCE_ACTIVITY_REPORT = api + "/api/v3/safety_and_privacy_report/country_activity"; export const GET_ROAD_SAFETY_CITY_ACTIVITY_REPORT = api + "/api/v3/safety_and_privacy_report/province_activity"; export const GET_ROAD_SAFETY_REPORT_MAP = api + "/api/v3/safety_and_privacy/map";