diff --git a/src/app/(withAuth)/dashboard/road-safety/operator/loading.jsx b/src/app/(withAuth)/dashboard/road-safety/operator/loading.jsx new file mode 100644 index 0000000..4535a8d --- /dev/null +++ b/src/app/(withAuth)/dashboard/road-safety/operator/loading.jsx @@ -0,0 +1,7 @@ +"use client"; +import PageLoading from "@/core/components/PageLoading"; + +const Loading = () => { + return ; +}; +export default Loading; diff --git a/src/app/(withAuth)/dashboard/road-safety/operator/page.js b/src/app/(withAuth)/dashboard/road-safety/operator/page.js new file mode 100644 index 0000000..468d2d6 --- /dev/null +++ b/src/app/(withAuth)/dashboard/road-safety/operator/page.js @@ -0,0 +1,20 @@ +import WithPermission from "@/core/middlewares/withPermission"; +import OperatorPage from "@/components/dashboard/roadSafety/operator"; +// import ActivityCodeLog from "@/core/components/ActivityCodeLog"; + +const Page = () => { + return ( + + + {/**/} + + ); +}; + +export default Page; diff --git a/src/components/dashboard/roadSafety/operator/ExcelPrint/index.jsx b/src/components/dashboard/roadSafety/operator/ExcelPrint/index.jsx new file mode 100644 index 0000000..2970e57 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/ExcelPrint/index.jsx @@ -0,0 +1,74 @@ +import { Button, CircularProgress, IconButton, useMediaQuery } from "@mui/material"; +import { useMemo, useState } from "react"; +import moment from "jalali-moment"; +import FileSaver from "file-saver"; +import DescriptionIcon from "@mui/icons-material/Description"; +import useRequest from "@/lib/hooks/useRequest"; +import { useTheme } from "@emotion/react"; +import DataTableFilterDataStructure from "@/core/utils/DataTableFilterDataStructure"; +import isArrayEmpty from "@/core/utils/isArrayEmpty"; +import { EXPORT_OPERATOR_ROAD_SAFETY } from "@/core/utils/routes"; + +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_OPERATOR_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/operator/Form/StepOne/CreateFormContent.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/CreateFormContent.jsx new file mode 100644 index 0000000..3ff2907 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/CreateFormContent.jsx @@ -0,0 +1,154 @@ +import React, { useState } from "react"; +import { useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { mixed, number, object, string } from "yup"; +import { Box, Button, DialogActions, DialogContent, Tab, Tabs } from "@mui/material"; +import StyledForm from "@/core/components/StyledForm"; +import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; +import FileCopyIcon from "@mui/icons-material/FileCopy"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight"; +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import useRequest from "@/lib/hooks/useRequest"; +import GetItemInfo from "./GetItemInfo"; +import GetSubItemInfo from "./GetSubItemInfo"; +import { format } from "date-fns"; +import { FIRST_STEP_STORE } from "@/core/utils/routes"; + +function TabPanel(props) { + const { children, value, index } = props; + return ( + + ); +} + +const validationSchema = object({ + recognize_picture: mixed().nullable().required("لطفا عکس فعالیت را بارگذاری کنید!"), + info_id: number().required("نوع آیتم را مشخص کنید!"), + axis_type_id: number().required("نوع محور را مشخص کنید!"), + start_point: mixed() + .test("start-point-required", "لطفاً نقطه شروع را مشخص کنید!", function (value) { + return !!value; // چک می‌کند که مقدار موجود است + }) + .required("لطفاً نقطه فعالیت را مشخص کنید!"), + activity_time: string().required("لطفا زمان فعالیت را انتخاب کنید!"), + activity_date: string().required("لطفا تاریخ فعالیت را انتخاب کنید!"), +}); + +const CreateFormContent = ({ setOpen, mutate }) => { + const requestServer = useRequest({ notificationSuccess: true }); + const [itemsList, setItemsList] = useState(); + const defaultValues = { + info_id: null, + axis_type_id: null, + recognize_picture: null, + activity_date: "", + activity_time: "", + start_point: "", + }; + + const [tabState, setTabState] = useState(0); + const handleClose = () => { + setOpen(false); + }; + const handleChangeTab = (event, newValue) => { + setTabState(newValue); + }; + + const handlePrev = () => { + if (tabState === 2) { + const fieldsToReset = ["recognize_picture", "activity_time", "activity_date", "start_point"]; + fieldsToReset.forEach((field) => resetField(field)); + } + if (tabState === 0) { + handleClose(); + } else { + setTabState(tabState - 1); + } + }; + const { + control, + handleSubmit, + resetField, + setValue, + formState: { errors, isSubmitting }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + }); + const onSubmitBase = async (data) => { + const startPoint = `${data.start_point.lat},${data.start_point.lng}`; + const formData = new FormData(); + formData.append("activity_date", data.activity_date); + formData.append("activity_time", format(new Date(data.activity_time), "HH:mm")); + formData.append("info_id", data.info_id); + formData.append("axis_type_id", data.axis_type_id); + formData.append("recognize_picture", data.recognize_picture); + formData.append("point", startPoint); + await requestServer(FIRST_STEP_STORE, "post", { + data: formData, + }) + .then((response) => { + mutate(); + setOpen(false); + }) + .catch((error) => {}); + }; + + return ( + + + } label="انتخاب آیتم" /> + } label="اطلاعات مورد مشاهده شده" /> + + + + + + + + + + + + + + {tabState === 1 && ( + + )} + + + ); +}; +export default CreateFormContent; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepOne/GetItemInfo.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/GetItemInfo.jsx new file mode 100644 index 0000000..da3c533 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/GetItemInfo.jsx @@ -0,0 +1,63 @@ +import React from "react"; +import { Card, CardActionArea, Grid, LinearProgress, Typography } from "@mui/material"; +import Image from "next/image"; +import { Controller } from "react-hook-form"; +import useSafetyAndPrivacyGetItems from "@/lib/hooks/useSafetyAndPrivacyGetItems"; + +const GetItemInfo = ({ setItemsList, setTabState, control }) => { + const { itemsList, loadingItemsList, errorItemsList } = useSafetyAndPrivacyGetItems(); + + return ( + <> + {errorItemsList ? ( + + خطا در دریافت لیست آیتم ها + + ) : loadingItemsList ? ( + + ) : ( + + ( + <> + {itemsList.map((item) => ( + + { + field.onChange(item.id); + setItemsList(item); + setTabState(1); + }} + > + + {item.name} + + + + ))} + + )} + /> + + )} + + ); +}; +export default GetItemInfo; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepOne/GetSubItemInfo.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/GetSubItemInfo.jsx new file mode 100644 index 0000000..9a6ae21 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/GetSubItemInfo.jsx @@ -0,0 +1,129 @@ +import { Box, Chip, Divider, Grid, Stack, Typography } from "@mui/material"; +import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; +import ImageUpload from "./ImageUpload"; +import { Controller, useWatch } from "react-hook-form"; +import MapInfoOneMarker from "@/core/components/MapInfoOneMarker"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import MuiTimePicker from "@/core/components/MuiTimePicker"; +import SelectBox from "@/core/components/SelectBox"; + +const GetSubItemInfo = ({ itemsList, control, setValue, errors }) => { + const StartPoint = useWatch({ control, name: "start_point" }); + return ( + + + + + + } + label={ + + آیتم انتخاب ‌شده + + } + /> + + + + {itemsList?.name || "هیچ آیتمی انتخاب نشده است"} + + + + + + + + ( + + )} + /> + + + + + + + { + return ( + field.onChange(value || [])} + helperText={error ? error.message : null} + /> + ); + }} + name={"activity_date"} + /> + + + { + return ( + field.onChange(value || null)} + helperText={error ? error.message : null} + /> + ); + }} + name={"activity_time"} + /> + + + ( + + )} + /> + + + + + + + + ); +}; +export default GetSubItemInfo; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepOne/ImageUpload.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/ImageUpload.jsx new file mode 100644 index 0000000..5186a4b --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/ImageUpload.jsx @@ -0,0 +1,77 @@ +import { FormControl, FormHelperText } from "@mui/material"; +import UploadSystem from "@/core/components/UploadSystem"; +import React, { useEffect, useState } from "react"; + +const ImageUpload = ({ name, value, onChange, error, title }) => { + const [beforeImg, setBeforeImg] = useState(value ? value : null); + const [beforeFileType, setBeforeFileType] = useState(value ? "image/" : null); + const [beforeFileName, setBeforeFileName] = useState(null); + const [showBeforeImage, setShowBeforeImage] = useState(!value); + + useEffect(() => { + if (value) { + setShowBeforeImage(false); + if (typeof value === "string") { + setBeforeImg(value); + setBeforeFileType("image/"); + } else if (value instanceof File) { + setBeforeImg(URL.createObjectURL(value)); + setBeforeFileType(value.type); + } + } + }, [value]); + + const handleFileChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const fileType = event.target?.files?.[0].type; + const fileName = event.target?.files?.[0].name; + setBeforeImg(URL.createObjectURL(uploadedFile)); + setBeforeFileType(fileType); + setBeforeFileName(fileName); + onChange(uploadedFile); + setShowBeforeImage(false); + } + }; + + return ( + + + {title} + + + {error ? error.message : null} + + ); +}; +export default ImageUpload; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepOne/OperatorCreateForm.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/OperatorCreateForm.jsx new file mode 100644 index 0000000..44b2828 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/OperatorCreateForm.jsx @@ -0,0 +1,26 @@ +"use client"; +import { Dialog, IconButton } from "@mui/material"; +import CreateFormContent from "./CreateFormContent"; +import CloseIcon from "@mui/icons-material/Close"; + +const OperatorCreateForm = ({ open, setOpen, mutate }) => { + return ( + + setOpen(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + {open && } + + ); +}; +export default OperatorCreateForm; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepOne/index.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/index.jsx new file mode 100644 index 0000000..e390936 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/index.jsx @@ -0,0 +1,36 @@ +import { Button, IconButton, useMediaQuery } from "@mui/material"; +import { AddCircle } from "@mui/icons-material"; +import { useTheme } from "@emotion/react"; +import { useState } from "react"; +import OperatorCreateForm from "./OperatorCreateForm"; + +const StepOne = ({ mutate }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const [open, setOpen] = useState(false); + + const handleOpen = () => { + setOpen(true); + }; + return ( + <> + {isMobile ? ( + + + + ) : ( + + )} + + + ); +}; +export default StepOne; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepThree/ImageUpload.jsx b/src/components/dashboard/roadSafety/operator/Form/StepThree/ImageUpload.jsx new file mode 100644 index 0000000..5186a4b --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepThree/ImageUpload.jsx @@ -0,0 +1,77 @@ +import { FormControl, FormHelperText } from "@mui/material"; +import UploadSystem from "@/core/components/UploadSystem"; +import React, { useEffect, useState } from "react"; + +const ImageUpload = ({ name, value, onChange, error, title }) => { + const [beforeImg, setBeforeImg] = useState(value ? value : null); + const [beforeFileType, setBeforeFileType] = useState(value ? "image/" : null); + const [beforeFileName, setBeforeFileName] = useState(null); + const [showBeforeImage, setShowBeforeImage] = useState(!value); + + useEffect(() => { + if (value) { + setShowBeforeImage(false); + if (typeof value === "string") { + setBeforeImg(value); + setBeforeFileType("image/"); + } else if (value instanceof File) { + setBeforeImg(URL.createObjectURL(value)); + setBeforeFileType(value.type); + } + } + }, [value]); + + const handleFileChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const fileType = event.target?.files?.[0].type; + const fileName = event.target?.files?.[0].name; + setBeforeImg(URL.createObjectURL(uploadedFile)); + setBeforeFileType(fileType); + setBeforeFileName(fileName); + onChange(uploadedFile); + setShowBeforeImage(false); + } + }; + + return ( + + + {title} + + + {error ? error.message : null} + + ); +}; +export default ImageUpload; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepThree/StepThreeContent.jsx b/src/components/dashboard/roadSafety/operator/Form/StepThree/StepThreeContent.jsx new file mode 100644 index 0000000..c0902c3 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepThree/StepThreeContent.jsx @@ -0,0 +1,69 @@ +import { Button, DialogActions, DialogContent, Stack } from "@mui/material"; +import { Controller, useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import StyledForm from "@/core/components/StyledForm"; +import { mixed, object } from "yup"; +import ImageUpload from "./ImageUpload"; +import useRequest from "@/lib/hooks/useRequest"; +import { THIRD_STEP_STORE } from "@/core/utils/routes"; + +const StepThreeContent = ({ setOpen, mutate, rowId }) => { + const requestServer = useRequest({ notificationSuccess: true }); + const defaultValues = { + action_picture: null, + }; + const validationSchema = object({ + action_picture: mixed().nullable().required("لطفا عکس اقدام را بارگذاری کنید!"), + }); + const { + control, + handleSubmit, + formState: { isSubmitting, errors }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + }); + const onSubmit = async (data) => { + const formData = new FormData(); + formData.append("action_picture", data.action_picture); + await requestServer(`${THIRD_STEP_STORE}/${rowId}`, "post", { + data: formData, + }) + .then((response) => { + mutate(); + setOpen(false); + }) + .catch((error) => {}); + }; + return ( + + + + ( + + )} + /> + + + + + + + + ); +}; +export default StepThreeContent; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepThree/index.jsx b/src/components/dashboard/roadSafety/operator/Form/StepThree/index.jsx new file mode 100644 index 0000000..a2bb0ad --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepThree/index.jsx @@ -0,0 +1,32 @@ +import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import StepThreeContent from "./StepThreeContent"; +import AddPhotoAlternateIcon from "@mui/icons-material/AddPhotoAlternate"; +const StepThree = ({ mutate, rowId }) => { + const [open, setOpen] = useState(false); + return ( + <> + + setOpen(true)}> + + + + setOpen(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"} + fullWidth + > + بارگذاری تصویر اقدام + + + + ); +}; +export default StepThree; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepTwo/ShowDocuments.jsx b/src/components/dashboard/roadSafety/operator/Form/StepTwo/ShowDocuments.jsx new file mode 100644 index 0000000..93958c8 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepTwo/ShowDocuments.jsx @@ -0,0 +1,37 @@ +import { Box, Card, IconButton, Stack, Typography } from "@mui/material"; +import DeleteIcon from "@mui/icons-material/Delete"; +import React from "react"; +import MinorCrashIcon from "@mui/icons-material/MinorCrash"; + +const ShowDocuments = ({ deleteDamageItem, selectedDamageItem }) => { + return ( + + + + + + {selectedDamageItem.name} + + + + + + deleteDamageItem(selectedDamageItem.name)}> + + + + + ); +}; +export default ShowDocuments; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepTwo/StepTwoContent.jsx b/src/components/dashboard/roadSafety/operator/Form/StepTwo/StepTwoContent.jsx new file mode 100644 index 0000000..b21be85 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepTwo/StepTwoContent.jsx @@ -0,0 +1,129 @@ +import { Box, Button, Chip, DialogActions, DialogContent, Divider, Fade, Grid, Stack, Typography } from "@mui/material"; +import { useEffect, useState } from "react"; +import { Controller, useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { mixed, object } from "yup"; +import ShowDocuments from "./ShowDocuments"; +import StyledForm from "@/core/components/StyledForm"; +import { SECOND_STEP_STORE } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; + +const StepTwoContent = ({ setOpenStepTwoDialog, mutate, rowId }) => { + const requestServer = useRequest({ notificationSuccess: true }); + const [selectedDamageItemList, setSelectedDamageItemList] = useState([]); + const defaultValues = { + judiciary_document: null, + }; + const validationSchema = object({ + judiciary_document: mixed().test("is-array", "لطفا حداقل یک فایل بارگذاری کنید!", (value) => { + return Array.isArray(value) && value.length > 0; + }), + }); + const { + control, + handleSubmit, + setValue, + formState: { isSubmitting, errors }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + }); + + const handleCreateDamage = (files) => { + setSelectedDamageItemList((prev) => { + const newFiles = files.filter((file) => !prev.some((item) => item.name === file.name)); + return [...prev, ...newFiles]; + }); + }; + useEffect(() => { + setValue("judiciary_document", selectedDamageItemList); + }, [selectedDamageItemList]); + + 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)); + await requestServer(`${SECOND_STEP_STORE}/${rowId}`, "post", { + data: formData, + }) + .then((response) => { + mutate(); + setOpenStepTwoDialog(false); + }) + .catch((error) => {}); + }; + return ( + + + + ( + <> + + {error && {error.message}} + + )} + /> + + + + + {selectedDamageItemList.length === 0 && ( + + + فایل موردنظر را بارگذاری کنید. + + + )} + + + {selectedDamageItemList.length !== 0 && + selectedDamageItemList.map((selectedDamageItem, index) => ( + + + + ))} + + + + + + + + + ); +}; +export default StepTwoContent; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepTwo/index.jsx b/src/components/dashboard/roadSafety/operator/Form/StepTwo/index.jsx new file mode 100644 index 0000000..2308d02 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/StepTwo/index.jsx @@ -0,0 +1,33 @@ +import UploadFileIcon from "@mui/icons-material/UploadFile"; +import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import StepTwoContent from "./StepTwoContent"; + +const StepTwo = ({ mutate, rowId }) => { + const [openStepTwoDialog, setOpenStepTwoDialog] = useState(false); + return ( + <> + + setOpenStepTwoDialog(true)}> + + + + setOpenStepTwoDialog(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"} + fullWidth + > + بارگذاری مستندات قضایی + + + + ); +}; +export default StepTwo; diff --git a/src/components/dashboard/roadSafety/operator/OperatorList.jsx b/src/components/dashboard/roadSafety/operator/OperatorList.jsx new file mode 100644 index 0000000..5efb488 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/OperatorList.jsx @@ -0,0 +1,426 @@ +"use client"; +import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency"; +import DataTableWithAuth from "@/core/components/DataTableWithAuth"; +import { Box, Stack } from "@mui/material"; +import moment from "jalali-moment"; +import { useEffect, useMemo, useState } from "react"; +import RowActions from "./RowActions"; +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 { GET_SAFETY_AND_PRIVACY } from "@/core/utils/routes"; +import RecognizePictureDialog from "./RowActions/RecognizePictureDialog"; +import ActionPictureDialog from "./RowActions/ActionPictureDialog"; +import JudiciaryDocumentDialog from "./RowActions/JudiciaryDocumentDialog"; +import LocationForm from "./RowActions/LocationForm"; + +const OperatorList = () => { + const { data: userPermissions } = usePermissions(); + const hasCountryPermission = userPermissions?.includes("show-fast-react"); + const { user } = useAuth(); + const statusOptions = [ + { value: "", label: "همه وضعیت ها" }, + { value: 1, label: "گام اول (شناسایی)" }, + { value: 2, label: "گام دوم (مستندات قضایی)" }, + { value: 3, label: "گام سوم (برخورد)" }, + ]; + const axisOptions = [ + { value: "", label: "همه محور ها" }, + { value: 1, label: "آزادراه" }, + { value: 2, label: "بزرگراه" }, + { value: 3, label: "اصلی" }, + { value: 4, label: "فرعی" }, + { value: 5, label: "روستایی" }, + ]; + + const columns = useMemo(() => { + const dynamicColumns = { + header: "استان", + id: "province_id", + enableColumnFilter: true, + datatype: "numeric", + filterMode: "equals", + grow: false, + size: 130, + ColumnSelectComponent: (props) => { + const { provinces, errorProvinces, loadingProvinces } = useProvinces(); + const getColumnSelectOptions = useMemo(() => { + if (loadingProvinces) { + return [{ value: "loading", label: "در حال بارگذاری..." }]; + } + if (errorProvinces) { + return [{ value: "error", label: "خطا در بارگذاری" }]; + } + return [ + { value: "", label: "کل کشور" }, + ...provinces.map((province) => ({ + value: province.id, + label: province.name_fa, + })), + ]; + }, [provinces, errorProvinces, loadingProvinces]); + return ( + + ); + }, + Cell: ({ row }) => <>{row.original.province_fa}, + }; + return [ + { + accessorKey: "id", + header: "کد یکتا", + id: "id", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + ...(hasCountryPermission ? [dynamicColumns] : []), + { + 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: ({ 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: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + 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 ( + + + + ); + }, + }, + ], + }, + { + 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 ( + + + + ); + }, + }, + { + 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: "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_picture_document_upload_date ? ( + moment(row.action_picture_document_upload_date) + .locale("fa") + .format("HH:mm | yyyy/MM/DD") + ) : ( + <>بدون تاریخ + ), + header: "تاریخ اقدام", + id: "action_picture_document_upload_date", + enableColumnFilter: true, + datatype: "date", + filterMode: "between", + grow: false, + size: 100, + }, + ], + }, + { + 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: "step", + 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.step_fa}, + }, + ]; + }, []); + + return ( + <> + + + + + ); +}; +export default OperatorList; diff --git a/src/components/dashboard/roadSafety/operator/RowActions/ActionPictureDialog/ActionPictureContent.jsx b/src/components/dashboard/roadSafety/operator/RowActions/ActionPictureDialog/ActionPictureContent.jsx new file mode 100644 index 0000000..f27255b --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/ActionPictureDialog/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/ActionPictureDialog/index.jsx new file mode 100644 index 0000000..4c2911c --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/DeleteDialog/DeleteContent.jsx b/src/components/dashboard/roadSafety/operator/RowActions/DeleteDialog/DeleteContent.jsx new file mode 100644 index 0000000..7a83c08 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/RowActions/DeleteDialog/DeleteContent.jsx @@ -0,0 +1,40 @@ +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") + .then(() => { + mutate(); + setOpenDeleteDialog(false); + setSubmitting(false); + }) + .catch(() => { + setSubmitting(false); + }); + }; + return ( + <> + + + آیا از حذف فعالیت اطمینان دارید؟ + + + + + + + + ); +}; + +export default DeleteContent; diff --git a/src/components/dashboard/roadSafety/operator/RowActions/DeleteDialog/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/DeleteDialog/index.jsx new file mode 100644 index 0000000..596cf9a --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentContent.jsx b/src/components/dashboard/roadSafety/operator/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentContent.jsx new file mode 100644 index 0000000..95a3f1e --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentController.jsx b/src/components/dashboard/roadSafety/operator/RowActions/JudiciaryDocumentDialog/JudiciaryDocumentController.jsx new file mode 100644 index 0000000..0773130 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/JudiciaryDocumentDialog/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/JudiciaryDocumentDialog/index.jsx new file mode 100644 index 0000000..0ff10cc --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/LocationForm/LocationFormContent.jsx b/src/components/dashboard/roadSafety/operator/RowActions/LocationForm/LocationFormContent.jsx new file mode 100644 index 0000000..14b3db3 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/LocationForm/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/LocationForm/index.jsx new file mode 100644 index 0000000..d614215 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/RecognizePictureDialog/RecognizePictureContent.jsx b/src/components/dashboard/roadSafety/operator/RowActions/RecognizePictureDialog/RecognizePictureContent.jsx new file mode 100644 index 0000000..39dbdcf --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/RecognizePictureDialog/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/RecognizePictureDialog/index.jsx new file mode 100644 index 0000000..72ef4ea --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/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/operator/RowActions/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/index.jsx new file mode 100644 index 0000000..1a9fb7c --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/RowActions/index.jsx @@ -0,0 +1,15 @@ +import { Box } from "@mui/material"; +import DeleteForm from "./DeleteDialog"; +import StepTwo from "../Form/StepTwo"; +import StepThree from "../Form/StepThree"; + +const RowActions = ({ row, mutate }) => { + return ( + + {row.original?.step === 1 && } + {row.original?.step === 2 && } + + + ); +}; +export default RowActions; diff --git a/src/components/dashboard/roadSafety/operator/Toolbar.jsx b/src/components/dashboard/roadSafety/operator/Toolbar.jsx new file mode 100644 index 0000000..2dd0b65 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Toolbar.jsx @@ -0,0 +1,16 @@ +import { Stack } from "@mui/material"; +import StepOne from "./Form/StepOne"; +import PrintExcel from "./ExcelPrint"; +import { usePermissions } from "@/lib/hooks/usePermissions"; + +const Toolbar = ({ table, filterData, mutate }) => { + const { data: userPermissions } = usePermissions(); + const hasCreatePermission = userPermissions?.includes("add-safety-and-privacy"); + return ( + + + {hasCreatePermission && } + + ); +}; +export default Toolbar; diff --git a/src/components/dashboard/roadSafety/operator/index.jsx b/src/components/dashboard/roadSafety/operator/index.jsx new file mode 100644 index 0000000..a2b328c --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/index.jsx @@ -0,0 +1,14 @@ +"use client"; +import PageTitle from "@/core/components/PageTitle"; +import { Stack } from "@mui/material"; +import OperatorList from "./OperatorList"; + +const OperatorPage = () => { + return ( + + + + + ); +}; +export default OperatorPage; diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index 2b00efb..98d8bd6 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -312,7 +312,7 @@ export const pageMenu = [ id: "safetyAndPrivacyManagmentOparationCartable", label: "کارتابل", type: "page", - route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/operator/cartable", + route: "/dashboard/road-safety/operator", permissions: [ "show-safety-and-privacy-operator-cartable", "show-safety-and-privacy-operator-cartable-province", diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 13da8ae..b224b3a 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -129,5 +129,13 @@ 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 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 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"; diff --git a/src/lib/hooks/useSafetyAndPrivacyGetItems.js b/src/lib/hooks/useSafetyAndPrivacyGetItems.js new file mode 100644 index 0000000..d97dbbf --- /dev/null +++ b/src/lib/hooks/useSafetyAndPrivacyGetItems.js @@ -0,0 +1,30 @@ +import { useEffect, useState } from "react"; +import useRequest from "@/lib/hooks/useRequest"; +import { GET_SAFETY_AND_PRIVACY_ITEM } from "@/core/utils/routes"; + +const useSafetyAndPrivacyGetItems = () => { + const requestServer = useRequest(); + const [itemsList, setItemsList] = useState([]); + const [loadingItemsList, setLoadingItemsList] = useState(true); + const [errorItemsList, setErrorItemsList] = useState(null); + + useEffect(() => { + const fetchItems = async () => { + try { + const response = await requestServer(`${GET_SAFETY_AND_PRIVACY_ITEM}`); + setItemsList(response.data.data); + setLoadingItemsList(false); + setErrorItemsList(false); + } catch (e) { + setErrorItemsList(e); + setLoadingItemsList(false); + } + }; + + fetchItems(); + }, []); + + return { itemsList, loadingItemsList, errorItemsList }; +}; + +export default useSafetyAndPrivacyGetItems;