From a3f1096dbd7b42a7cbecc859eefb091b2f6136ef Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Sat, 15 Mar 2025 08:08:57 +0000 Subject: [PATCH] Resolve #86c2grd6k "Feature/road safety edit" --- .../(withAuth)/dashboard/permissions/page.js | 2 +- .../dashboard/user-activities/page.js | 2 +- .../Form/EditAxisType/EditFormContent.jsx | 102 ++++++++++++++++++ .../Form/EditAxisType/OperatorEditForm.jsx | 26 +++++ .../operator/Form/EditAxisType/index.jsx | 19 ++++ .../Form/StepOne/CreateFormContent.jsx | 2 +- .../operator/Form/StepOne/GetSubItemInfo.jsx | 4 +- .../roadSafety/operator/OperatorList.jsx | 62 +++++++---- .../roadSafety/operator/RowActions/index.jsx | 22 ++-- .../report/Search/SearchReportField.jsx | 10 +- .../report/Search/SelectAxisType.jsx | 45 ++++++++ .../report/Search/SelectProvince.jsx | 6 +- .../dashboard/roadSafety/report/index.jsx | 13 +-- src/core/utils/pageMenu.js | 4 +- src/core/utils/routes.js | 1 + 15 files changed, 276 insertions(+), 44 deletions(-) create mode 100644 src/components/dashboard/roadSafety/operator/Form/EditAxisType/EditFormContent.jsx create mode 100644 src/components/dashboard/roadSafety/operator/Form/EditAxisType/OperatorEditForm.jsx create mode 100644 src/components/dashboard/roadSafety/operator/Form/EditAxisType/index.jsx create mode 100644 src/components/dashboard/roadSafety/report/Search/SelectAxisType.jsx diff --git a/src/app/(withAuth)/dashboard/permissions/page.js b/src/app/(withAuth)/dashboard/permissions/page.js index 8a825a5..1dcd0b2 100644 --- a/src/app/(withAuth)/dashboard/permissions/page.js +++ b/src/app/(withAuth)/dashboard/permissions/page.js @@ -5,7 +5,7 @@ export const metadata = { }; const Page = () => { return ( - + ); diff --git a/src/app/(withAuth)/dashboard/user-activities/page.js b/src/app/(withAuth)/dashboard/user-activities/page.js index 64f91e7..c671c77 100644 --- a/src/app/(withAuth)/dashboard/user-activities/page.js +++ b/src/app/(withAuth)/dashboard/user-activities/page.js @@ -5,7 +5,7 @@ export const metadata = { }; const Page = () => { return ( - + ); diff --git a/src/components/dashboard/roadSafety/operator/Form/EditAxisType/EditFormContent.jsx b/src/components/dashboard/roadSafety/operator/Form/EditAxisType/EditFormContent.jsx new file mode 100644 index 0000000..a76342b --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/EditAxisType/EditFormContent.jsx @@ -0,0 +1,102 @@ +import SelectBox from "@/core/components/SelectBox"; +import StyledForm from "@/core/components/StyledForm"; +import { UPDATE_SAFETY_AND_PRIVACY } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { yupResolver } from "@hookform/resolvers/yup"; +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import { Button, DialogActions, DialogContent, Grid, Stack } from "@mui/material"; +import { Controller, useForm } from "react-hook-form"; +import { object, string } from "yup"; + +const validationSchema = object({ + axis_type_id: string().required("نوع محور را مشخص کنید!"), +}); + +const EditFormContent = ({ setOpen, mutate, row }) => { + const requestServer = useRequest({ notificationSuccess: true }); + const defaultValues = { + axis_type_id: row.original.axis_type_id || "", + }; + + const handleClose = () => { + setOpen(false); + }; + + const { + control, + handleSubmit, + formState: { isSubmitting }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + }); + const onSubmitBase = async (data) => { + const formData = new FormData(); + formData.append("axis_type_id", data.axis_type_id); + await requestServer(`${UPDATE_SAFETY_AND_PRIVACY}/${row.original.id}`, "post", { + data: formData, + }) + .then((response) => { + mutate(); + setOpen(false); + }) + .catch((error) => {}); + }; + + return ( + + + + + + ( + + )} + /> + + + + + + + + + + ); +}; +export default EditFormContent; diff --git a/src/components/dashboard/roadSafety/operator/Form/EditAxisType/OperatorEditForm.jsx b/src/components/dashboard/roadSafety/operator/Form/EditAxisType/OperatorEditForm.jsx new file mode 100644 index 0000000..34e66e3 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/EditAxisType/OperatorEditForm.jsx @@ -0,0 +1,26 @@ +import { Dialog, DialogTitle, IconButton } from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; +import EditFormContent from "./EditFormContent"; + +const OperatorEditForm = ({ open, setOpen, mutate, row }) => { + return ( + + setOpen(false)} + sx={(theme) => ({ + position: "absolute", + right: 8, + top: 8, + zIndex: 50, + color: theme.palette.grey[500], + })} + > + + + ویرایش محور + {open && } + + ); +}; +export default OperatorEditForm; diff --git a/src/components/dashboard/roadSafety/operator/Form/EditAxisType/index.jsx b/src/components/dashboard/roadSafety/operator/Form/EditAxisType/index.jsx new file mode 100644 index 0000000..7e99d16 --- /dev/null +++ b/src/components/dashboard/roadSafety/operator/Form/EditAxisType/index.jsx @@ -0,0 +1,19 @@ +import { Dialog, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; +import EditIcon from "@mui/icons-material/Edit"; +import OperatorEditForm from "./OperatorEditForm"; + +const EditAxisType = ({ row, mutate }) => { + const [openEditDialog, setOpenEditDialog] = useState(false); + return ( + <> + + setOpenEditDialog(true)}> + + + + + + ); +}; +export default EditAxisType; diff --git a/src/components/dashboard/roadSafety/operator/Form/StepOne/CreateFormContent.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/CreateFormContent.jsx index ca96b6e..6c49683 100644 --- a/src/components/dashboard/roadSafety/operator/Form/StepOne/CreateFormContent.jsx +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/CreateFormContent.jsx @@ -113,7 +113,7 @@ const CreateFormContent = ({ setOpen, mutate }) => { backgroundColor: "#efefef", }} > - } label="انتخاب آیتم" /> + } label="انتخاب مورد" /> } label="اطلاعات مورد مشاهده شده" /> diff --git a/src/components/dashboard/roadSafety/operator/Form/StepOne/GetSubItemInfo.jsx b/src/components/dashboard/roadSafety/operator/Form/StepOne/GetSubItemInfo.jsx index 9a6ae21..a6e3f5e 100644 --- a/src/components/dashboard/roadSafety/operator/Form/StepOne/GetSubItemInfo.jsx +++ b/src/components/dashboard/roadSafety/operator/Form/StepOne/GetSubItemInfo.jsx @@ -19,7 +19,7 @@ const GetSubItemInfo = ({ itemsList, control, setValue, errors }) => { icon={} label={ - آیتم انتخاب ‌شده + مورد انتخاب ‌شده } /> @@ -40,7 +40,7 @@ const GetSubItemInfo = ({ itemsList, control, setValue, errors }) => { render={({ field, fieldState: { error } }) => ( { const { data: userPermissions } = usePermissions(); @@ -153,15 +154,40 @@ const OperatorList = () => { columns: [ { accessorKey: "info_id", - header: "موضوع مشاهده شده", + header: "مورد مشاهده شده", id: "info_id", enableColumnFilter: true, - datatype: "text", + datatype: "numeric", filterMode: "equals", - sortDescFirst: false, - columnFilterModeOptions: ["equals", "contains"], 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}, }, { @@ -208,10 +234,20 @@ const OperatorList = () => { ); }, }, + { + 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: "گام اول", + header: "گام اول (شناسایی)", id: "stepOne", enableColumnFilter: false, enableSorting: false, @@ -265,7 +301,7 @@ const OperatorList = () => { ], }, { - header: "گام دوم", + header: "گام دوم (مستندات قضایی)", id: "stepTwo", enableColumnFilter: false, enableSorting: false, @@ -322,7 +358,7 @@ const OperatorList = () => { ], }, { - header: "گام سوم", + header: "گام سوم (برخورد)", id: "stepThree", enableColumnFilter: false, enableSorting: false, @@ -367,7 +403,7 @@ const OperatorList = () => { ) : ( <>- ), - header: "تاریخ اقدام", + header: "تاریخ ثبت اقدام", id: "action_picture_document_upload_date", enableColumnFilter: true, datatype: "date", @@ -377,16 +413,6 @@ const OperatorList = () => { }, ], }, - { - 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", diff --git a/src/components/dashboard/roadSafety/operator/RowActions/index.jsx b/src/components/dashboard/roadSafety/operator/RowActions/index.jsx index e5be7ee..85a7f23 100644 --- a/src/components/dashboard/roadSafety/operator/RowActions/index.jsx +++ b/src/components/dashboard/roadSafety/operator/RowActions/index.jsx @@ -1,16 +1,26 @@ -import { Box } from "@mui/material"; -import DeleteForm from "./DeleteDialog"; -import StepTwo from "../Form/StepTwo"; -import StepThree from "../Form/StepThree"; import { usePermissions } from "@/lib/hooks/usePermissions"; +import { Box } from "@mui/material"; +import EditAxisType from "../Form/EditAxisType"; +import StepThree from "../Form/StepThree"; +import StepTwo from "../Form/StepTwo"; +import DeleteForm from "./DeleteDialog"; 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 ( - {row.original?.step === 1 && } - {row.original?.step === 2 && } + {hasUpdatePermission && row.original?.axis_type_id == null && } + {hasEdarateShahriPermission && ( + <> + {row.original?.step === 1 && } + {row.original?.step === 2 && } + + )} {hasDeletePermission && } ); diff --git a/src/components/dashboard/roadSafety/report/Search/SearchReportField.jsx b/src/components/dashboard/roadSafety/report/Search/SearchReportField.jsx index ab8442c..606e08c 100644 --- a/src/components/dashboard/roadSafety/report/Search/SearchReportField.jsx +++ b/src/components/dashboard/roadSafety/report/Search/SearchReportField.jsx @@ -5,14 +5,15 @@ import FromDateController from "./FromDateController"; import ToDateController from "./ToDateController"; import SelectProvince from "./SelectProvince"; import { Controller } from "react-hook-form"; +import SelectAxisType from "./SelectAxisType"; const SearchReportField = ({ control, hasProvincesPermission }) => { return ( - + - + {hasProvincesPermission && ( @@ -20,7 +21,10 @@ const SearchReportField = ({ control, hasProvincesPermission }) => { )} - + + + + { + return ( + ( + + نوع محور + + {error && {error.message}} + + )} + /> + ); +}; +export default SelectAxisType; diff --git a/src/components/dashboard/roadSafety/report/Search/SelectProvince.jsx b/src/components/dashboard/roadSafety/report/Search/SelectProvince.jsx index b1d8a39..2b24d67 100644 --- a/src/components/dashboard/roadSafety/report/Search/SelectProvince.jsx +++ b/src/components/dashboard/roadSafety/report/Search/SelectProvince.jsx @@ -1,8 +1,6 @@ -import { Controller } from "react-hook-form"; -import MuiDatePicker from "@/core/components/MuiDatePicker"; -import React from "react"; -import { FormControl, FormHelperText, InputLabel, LinearProgress, MenuItem, Select, Typography } from "@mui/material"; import useProvinces from "@/lib/hooks/useProvince"; +import { FormControl, FormHelperText, InputLabel, MenuItem, Select } from "@mui/material"; +import { Controller } from "react-hook-form"; const SelectProvince = ({ control }) => { const { provinces, loadingProvinces, errorProvinces } = useProvinces(); diff --git a/src/components/dashboard/roadSafety/report/index.jsx b/src/components/dashboard/roadSafety/report/index.jsx index 549e008..cafa140 100644 --- a/src/components/dashboard/roadSafety/report/index.jsx +++ b/src/components/dashboard/roadSafety/report/index.jsx @@ -18,20 +18,17 @@ const ReportPage = () => { const { data: userPermissions } = usePermissions(); const { user } = useAuth(); const requestServer = useRequest(); - const hasProvincesPermission = userPermissions.some((item) => - [ - "show-safety-and-privacy-operator-cartable-province", - "show-safety-and-privacy-operator-cartable-edarate-shahri", - ].includes(item) - ); + const hasProvincesPermission = userPermissions.includes("show-safety-and-privacy-operator-cartable"); const defaultValues = { from_date: moment(new Date()).format("YYYY-MM-DD"), date_to: moment(new Date()).format("YYYY-MM-DD"), province_id: hasProvincesPermission ? "-1" : user.province_id, + axis_type_id: "-1", }; const defaultFilter = [ { value: `${defaultValues.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${defaultValues.axis_type_id}`, datatype: "numeric", id: "axis_type_id", fn: "equals" }, { value: `${defaultValues.from_date}`, datatype: "date", id: "from_date", fn: "between" }, { value: `${defaultValues.date_to}`, datatype: "date", id: "date_to", fn: "between" }, ]; @@ -41,8 +38,11 @@ const ReportPage = () => { const params = new URLSearchParams(); params.set("from_date", `${data.from_date}`); params.set("date_to", `${data.date_to}`); + if (data.axis_type_id != "-1") params.set("axis_type_id", `${data.axis_type_id}`); + setSpecialFilter([ { value: `${data.province_id}`, datatype: "numeric", id: "province_id", fn: "equals" }, + { value: `${data.axis_type_id}`, datatype: "numeric", id: "axis_type_id", fn: "equals" }, { value: `${data.from_date}`, datatype: "date", id: "from_date", fn: "between" }, { value: `${data.date_to}`, datatype: "date", id: "date_to", fn: "between" }, ]); @@ -118,6 +118,7 @@ const ReportPage = () => { .matches(/^\d{4}-\d{2}-\d{2}$/, "تاریخ ثبت الزامی است!") .test("is-valid-date", "تاریخ ثبت معتبر نیست!", (value) => moment(value, "YYYY-MM-DD", true).isValid()), province_id: yup.string().nullable(), + axis_type_id: yup.string().nullable(), }); const { control, handleSubmit } = useForm({ diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index 5be659e..3465345 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -494,7 +494,7 @@ export const pageMenu = [ type: "page", route: "/dashboard/permissions", icon: , - permissions: ["show-permissions-page"], + permissions: ["manage-permissions"], }, { id: "userActivities", @@ -502,7 +502,7 @@ export const pageMenu = [ type: "page", route: "/dashboard/user-activities", icon: , - permissions: ["show-user-activities-page"], + permissions: ["manage-log-list"], }, { id: "CarDetails", diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 36947c4..4953100 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -136,6 +136,7 @@ export const GET_SAFETY_AND_PRIVACY_ITEM = api + "/api/v3/safety_and_privacy/sub 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";