From 9fccf770d51d9a526199787e26dc54e4929b5da6 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sun, 15 Dec 2024 18:27:27 +0330 Subject: [PATCH 01/22] work on phone validation part and complete structure with timeline --- .../dashboard/road-patrols/operator/page.js | 2 +- .../operator/Actions/Create/index.jsx | 33 +++++ .../roadPatrols/operator/ExcelPrint/index.jsx | 26 ++-- .../Forms/CreatePatrol/PatrolForms.jsx | 80 +++++++++++ .../Forms/CreatePatrol/PatrolTimeLine.jsx | 122 ++++++++++++++++ .../Forms/CreatePatrol/PhoneValidation.jsx | 130 ++++++++++++++++++ .../operator/Forms/CreatePatrol/index.jsx | 17 +++ .../roadPatrols/operator/Toolbar.jsx | 11 +- .../dashboard/roadPatrols/operator/index.jsx | 8 +- .../roadPatrols/supervisor/SupervisorList.jsx | 28 ++-- .../roadPatrols/supervisor/index.jsx | 8 +- src/core/utils/pageMenu.js | 87 ++++++------ src/core/utils/routes.js | 1 + 13 files changed, 466 insertions(+), 87 deletions(-) create mode 100644 src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/index.jsx diff --git a/src/app/(withAuth)/dashboard/road-patrols/operator/page.js b/src/app/(withAuth)/dashboard/road-patrols/operator/page.js index 73fa9cf..ce319b9 100644 --- a/src/app/(withAuth)/dashboard/road-patrols/operator/page.js +++ b/src/app/(withAuth)/dashboard/road-patrols/operator/page.js @@ -4,7 +4,7 @@ import OperatorPage from "@/components/dashboard/roadPatrols/operator"; const Page = () => { return ( - + ); }; diff --git a/src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx b/src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx new file mode 100644 index 0000000..63347f0 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Actions/Create/index.jsx @@ -0,0 +1,33 @@ +"use client"; + +import {Button, IconButton, useMediaQuery} from "@mui/material"; +import {useTheme} from "@emotion/react"; +import {useState} from "react"; +import {AddCircle} from "@mui/icons-material"; +import CreatePatrol from "../../Forms/CreatePatrol"; + +const OperatorCreate = ({mutate}) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const [open, setOpen] = useState(false); + + const handleOpen = () => { + setOpen(true); + }; + + return ( + <> + {isMobile ? ( + + + + ) : ( + + )} + {open && } + + ); +}; +export default OperatorCreate; diff --git a/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx b/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx index 8fdc753..9148331 100644 --- a/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx +++ b/src/components/dashboard/roadPatrols/operator/ExcelPrint/index.jsx @@ -1,18 +1,18 @@ -import { Button, CircularProgress } from "@mui/material"; -import { useMemo, useState } from "react"; +import {Button, CircularProgress} 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 { EXPORT_OPERATOR_LIST } from "@/core/utils/routes"; +import {EXPORT_OPERATOR_LIST} from "@/core/utils/routes"; -const PrintExcel = ({ table, filterData }) => { +const PrintExcel = ({table, filterData}) => { const [loading, setLoading] = useState(false); const requestServer = useRequest(); const activeFilters = Object.entries(filterData).reduce((acc, [key, filter]) => { if (filter.value) { // Check if there's an active filter - acc.push({ id: key, value: filter.value }); + acc.push({id: key, value: filter.value}); } return acc; }, []); @@ -20,22 +20,23 @@ const PrintExcel = ({ table, filterData }) => { const filterParams = useMemo(() => { const params = new URLSearchParams(); activeFilters.length > 0 && - activeFilters.map((filter, index) => { - params.set(`${filter.id}`, filter.value); - }); + activeFilters.map((filter, index) => { + params.set(`${filter.id}`, filter.value); + }); return params; }, [activeFilters]); const clickHandler = () => { setLoading(true); requestServer(`${EXPORT_OPERATOR_LIST}?${filterParams}`, "get", { - requestOptions: { responseType: "blob" }, + requestOptions: {responseType: "blob"}, }) .then((response) => { const filename = `خروجی کارتابل عملیات تاریخ_${moment().format("jYYYY_jMM_jDD")}.xlsx`; FileSaver.saveAs(response.data, filename); }) - .catch(() => {}) + .catch(() => { + }) .finally(() => { setLoading(false); }); @@ -45,10 +46,9 @@ const PrintExcel = ({ table, filterData }) => { + + + + + کد پیامک شده + + + + + + + ); +}; + +export default PhoneValidation; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/index.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/index.jsx new file mode 100644 index 0000000..46eac78 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/index.jsx @@ -0,0 +1,17 @@ +"use client"; + +import {Dialog} from "@mui/material"; +import PatrolForms from "@/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms"; + +const CreatePatrol = ({open, setOpen, mutate, rowId}) => { + return ( + + + + ); +}; +export default CreatePatrol; diff --git a/src/components/dashboard/roadPatrols/operator/Toolbar.jsx b/src/components/dashboard/roadPatrols/operator/Toolbar.jsx index 32c4395..f652e04 100644 --- a/src/components/dashboard/roadPatrols/operator/Toolbar.jsx +++ b/src/components/dashboard/roadPatrols/operator/Toolbar.jsx @@ -1,10 +1,13 @@ import PrintExcel from "./ExcelPrint"; +import OperatorCreate from "./Actions/Create"; +import {Box} from "@mui/material"; -const Toolbar = ({ table, filterData }) => { +const Toolbar = ({table, filterData, mutate}) => { return ( - <> - - + + + + ); }; export default Toolbar; diff --git a/src/components/dashboard/roadPatrols/operator/index.jsx b/src/components/dashboard/roadPatrols/operator/index.jsx index 7835954..dcf34af 100644 --- a/src/components/dashboard/roadPatrols/operator/index.jsx +++ b/src/components/dashboard/roadPatrols/operator/index.jsx @@ -1,13 +1,13 @@ "use client"; import PageTitle from "@/core/components/PageTitle"; -import { Stack } from "@mui/material"; -import OperatorList from "@/components/dashboard/roadPatrols/operator/OperatorList"; +import {Stack} from "@mui/material"; +import OperatorList from "./OperatorList"; const OperatorPage = () => { return ( - - + + ); }; diff --git a/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx b/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx index d568c46..9478939 100644 --- a/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx @@ -1,15 +1,15 @@ "use client"; -import { useMemo } from "react"; -import { Box, Typography } from "@mui/material"; +import {useMemo} from "react"; +import {Box, Typography} from "@mui/material"; import DataTableWithAuth from "@/core/components/DataTableWithAuth"; import Toolbar from "./Toolbar"; -import { GET_SUPERVISOR_LIST } from "@/core/utils/routes"; +import {GET_SUPERVISOR_LIST} from "@/core/utils/routes"; import moment from "jalali-moment"; import RowActions from "./RowActions"; import useProvinces from "@/lib/hooks/useProvince"; -const OperatorList = () => { - const { provinces, errorProvinces, loadingProvinces } = useProvinces(); +const SuperviserList = () => { + const {provinces, errorProvinces, loadingProvinces} = useProvinces(); const citiesListApi = "https://rms.rmto.ir/public/contents/edarate_shahri_by_province"; const columns = useMemo( () => [ @@ -31,11 +31,11 @@ const OperatorList = () => { filterFn: "equals", columnSelectOption: () => { if (loadingProvinces) { - return [{ value: "", label: "در حال بارگذاری..." }]; + return [{value: "", label: "در حال بارگذاری..."}]; } if (errorProvinces) { - return [{ value: "", label: "خطا در بارگذاری" }]; + return [{value: "", label: "خطا در بارگذاری"}]; } return provinces.map((province) => ({ @@ -54,10 +54,10 @@ const OperatorList = () => { dependencyId: "province", columnSelectOption: (dependencyField) => { if (dependencyField.value === "") { - return [{ value: "", label: "ابتدا استان را انتخاب کنید" }]; + return [{value: "", label: "ابتدا استان را انتخاب کنید"}]; } - return [{ value: dependencyField.value, label: dependencyField.value }]; + return [{value: dependencyField.value, label: dependencyField.value}]; }, }, { @@ -95,7 +95,7 @@ const OperatorList = () => { datatype: "date", filterFn: "equals", columnFilterModeOptions: ["equals", "contains"], - Cell: ({ renderedCellValue }) => ( + Cell: ({renderedCellValue}) => ( {renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"} @@ -109,7 +109,7 @@ const OperatorList = () => { datatype: "date", filterFn: "equals", columnFilterModeOptions: ["equals", "contains"], - Cell: ({ renderedCellValue }) => ( + Cell: ({renderedCellValue}) => ( {renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"} @@ -123,7 +123,7 @@ const OperatorList = () => { datatype: "date", filterFn: "equals", columnFilterModeOptions: ["equals", "contains"], - Cell: ({ renderedCellValue }) => ( + Cell: ({renderedCellValue}) => ( {renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"} @@ -135,7 +135,7 @@ const OperatorList = () => { return ( <> - + { ); }; -export default OperatorList; +export default SuperviserList; diff --git a/src/components/dashboard/roadPatrols/supervisor/index.jsx b/src/components/dashboard/roadPatrols/supervisor/index.jsx index 3fa490b..5e2001d 100644 --- a/src/components/dashboard/roadPatrols/supervisor/index.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/index.jsx @@ -1,13 +1,13 @@ "use client"; import PageTitle from "@/core/components/PageTitle"; -import { Stack } from "@mui/material"; -import SupervisorList from "./SupervisorList"; +import {Stack} from "@mui/material"; +import SuperviserList from "./SupervisorList"; const SupervisorPage = () => { return ( - - + + ); }; diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index 6000f64..5fd062d 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -28,7 +28,7 @@ export const pageMenu = [ label: "پیشخوان", type: "page", route: "/dashboard", - icon: , + icon: , permissions: ["all"], }, { @@ -36,14 +36,14 @@ export const pageMenu = [ label: "مدیریت کاربران", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management", - icon: , + icon: , permissions: ["full-user-management", "limited-user-management"], }, { id: "projectsManagment", label: "پروژه های راهداری", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -51,7 +51,7 @@ export const pageMenu = [ label: "ثبت قرارداد و پروژه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance", - icon: , + icon: , permissions: ["show-contract", "show-contract-province"], }, { @@ -59,7 +59,7 @@ export const pageMenu = [ label: "لیست پروژه ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list", - icon: , + icon: , permissions: ["all"], }, { @@ -67,7 +67,7 @@ export const pageMenu = [ label: "پروژه های پیشنهادی", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal", - icon: , + icon: , permissions: ["show-proposal", "show-proposal-province"], }, { @@ -75,7 +75,7 @@ export const pageMenu = [ label: "درخواست نمایندگان", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers", - icon: , + icon: , permissions: ["show-lawmaker", "show-lawmaker-province"], }, { @@ -83,7 +83,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects", - icon: , + icon: , permissions: ["all"], }, ], @@ -92,7 +92,7 @@ export const pageMenu = [ id: "roadItemManagment", label: "فعالیت های روزانه", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_items.total"], Subitems: [ @@ -100,7 +100,7 @@ export const pageMenu = [ id: "roadItemManagmentSupervisor", label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_items.supervise_cnt"], Subitems: [ @@ -120,7 +120,7 @@ export const pageMenu = [ id: "roadItemManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_items.operation_cnt"], Subitems: [ @@ -145,7 +145,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items", - icon: , + icon: , permissions: [ "show-road-item-supervise-cartable", "show-road-item-supervise-cartable-province", @@ -157,7 +157,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report", - icon: , + icon: , permissions: [ "show-road-item-supervise-cartable", "show-road-item-supervise-cartable-province", @@ -170,7 +170,7 @@ export const pageMenu = [ id: "roadPatrolManagment", label: "گشت راهداری و ترابری", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_patrols.total"], Subitems: [ @@ -178,7 +178,7 @@ export const pageMenu = [ id: "roadPatrolManagmentSupervisor", label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_patrols.supervise_cnt"], Subitems: [ @@ -198,22 +198,15 @@ export const pageMenu = [ id: "roadPatrolManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_patrols.operation_cnt"], Subitems: [ - { - id: "roadPatrolManagmentOparationCreate", - label: "ثبت اقدام", - type: "page", - route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create", - permissions: ["add-road-patrol"], - }, { id: "roadPatrolManagmentOparationCartable", label: "کارتابل", type: "page", - route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable", + route: "/dashboard/road-patrols/operator", permissions: ["add-road-patrol"], }, ], @@ -223,7 +216,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols", - icon: , + icon: , permissions: [ "add-road-patrol", "show-road-patrol-supervise-cartable", @@ -235,7 +228,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report", - icon: , + icon: , permissions: [ "add-road-patrol", "show-road-patrol-supervise-cartable", @@ -248,7 +241,7 @@ export const pageMenu = [ id: "inquiryPrivacyManagment", label: "استعلام حریم راه", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -285,7 +278,7 @@ export const pageMenu = [ id: "safetyAndPrivacyManagment", label: "نگهداری حریم راه", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["safety_and_privacy.step_one", "safety_and_privacy.step_two"], Subitems: [ @@ -293,7 +286,7 @@ export const pageMenu = [ id: "safetyAndPrivacyManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -321,7 +314,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy", - icon: , + icon: , permissions: [ "show-safety-and-privacy-operator-cartable", "show-safety-and-privacy-operator-cartable-province", @@ -334,7 +327,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report", - icon: , + icon: , permissions: [ "show-safety-and-privacy-operator-cartable", "show-safety-and-privacy-operator-cartable-province", @@ -348,7 +341,7 @@ export const pageMenu = [ id: "roadObservationsManagment", label: "واکنش سریع", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_observations.total"], Subitems: [ @@ -356,7 +349,7 @@ export const pageMenu = [ id: "roadObservationsManagmentSupervisor", label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_observations.supervise_cnt"], Subitems: [ @@ -374,14 +367,14 @@ export const pageMenu = [ label: "رسیدگی به شکایات", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations", - icon: , + icon: , permissions: ["show-fast-react", "show-fast-react-province", "show-fast-react-edarate-shahri"], }, { id: "roadObservationsManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_observations.operation_cnt"], Subitems: [ @@ -399,7 +392,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations", - icon: , + icon: , permissions: ["all"], }, { @@ -407,7 +400,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index", - icon: , + icon: , permissions: ["all"], }, ], @@ -416,7 +409,7 @@ export const pageMenu = [ id: "winterCampManagment", label: "قرارگاه زمستانی", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -424,7 +417,7 @@ export const pageMenu = [ label: "محور های انسدادی", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp", - icon: , + icon: , permissions: ["show-camp", "show-camp-province"], }, { @@ -432,7 +425,7 @@ export const pageMenu = [ label: "محور های حلقه اول", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp", - icon: , + icon: , permissions: ["show-camp", "show-camp-province"], }, { @@ -440,7 +433,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew", - icon: , + icon: , permissions: ["show-camp", "show-camp-province"], }, ], @@ -449,14 +442,14 @@ export const pageMenu = [ id: "receiptManagment", label: "خسارات وارده بر ابنیه فنی و تاسیسات راه", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { id: "receiptManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -473,7 +466,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report", - icon: , + icon: , permissions: ["all"], }, ], @@ -483,7 +476,7 @@ export const pageMenu = [ label: "آزمایشات (OPTS)", type: "page", route: "/dashboard/azmayesh", - icon: , + icon: , permissions: ["azmayesh-management"], }, { @@ -491,7 +484,7 @@ export const pageMenu = [ label: "نوع آزمایشات", type: "page", route: "/dashboard/azmayesh_type", - icon: , + icon: , permissions: ["azmayesh-type-management"], }, { @@ -499,7 +492,7 @@ export const pageMenu = [ label: "اطلاعات خودرو", type: "page", route: "/dashboard/car-details", - icon: , + icon: , permissions: [""], }, ]; diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index db24fd6..c9ee515 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -31,3 +31,4 @@ export const GET_OPERATOR_LIST = "/v3/api/fake-operator-list"; export const EXPORT_OPERATOR_LIST = "https://rms.rmto.ir/v2/road_patrols/operator/cartable/report"; export const GET_SUPERVISOR_LIST = "/v3/api/fake-supervisor-list"; export const EXPORT_SUPERVISOR_LIST = "https://rms.rmto.ir/v2/road_patrols/supervisor/cartable/report"; +export const GET_OTP_TOKEN = "https://rms.rmto.ir/v2/get_otp_token"; From aedeb62849ee9542d01f056ce37268638b4fb48c Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Wed, 18 Dec 2024 11:34:21 +0330 Subject: [PATCH 02/22] work on car code --- .../Forms/CreatePatrol/PatrolDetail.jsx | 32 +++++++ .../Forms/CreatePatrol/PatrolForms.jsx | 5 +- .../Forms/CreatePatrol/PhoneValidation.jsx | 49 ++++++++--- src/core/components/CarCode.jsx | 86 +++++++++++++++++++ src/core/utils/formatCounter.js | 5 ++ src/core/utils/routes.js | 3 + src/lib/hooks/useRequest.js | 9 +- 7 files changed, 168 insertions(+), 21 deletions(-) create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx create mode 100644 src/core/components/CarCode.jsx create mode 100644 src/core/utils/formatCounter.js diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx new file mode 100644 index 0000000..38631e5 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx @@ -0,0 +1,32 @@ +"use client"; + +import {Box, Slide} from "@mui/material"; +import {useState} from "react"; +import CarCode from "@/core/components/CarCode"; + +const PatrolDetail = ({tabState, setTabState}) => { + const [patrolFounded, setPatrolFounded] = useState(false); + const [carCode, setCarCode] = useState(null); + + return ( + + + + + + + + + + ); +}; + +export default PatrolDetail; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx index 4146808..4d51f65 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx @@ -10,6 +10,7 @@ import HandymanIcon from '@mui/icons-material/Handyman'; import VerifiedIcon from '@mui/icons-material/Verified'; import PatrolTimeLine from "./PatrolTimeLine"; import PhoneValidation from "./PhoneValidation"; +import PatrolDetail from "./PatrolDetail"; function TabPanel(props) { const {children, value, index} = props; @@ -53,10 +54,10 @@ const PatrolForms = () => { - + - <>moshakhasat gasht + <>moshakhasat rahdar diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx index 0310d02..a60ba22 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx @@ -5,15 +5,18 @@ import React, {useEffect, useState} from "react"; import ForwardToInboxIcon from '@mui/icons-material/ForwardToInbox'; import QrCodeIcon from '@mui/icons-material/QrCode'; import useRequest from "@/lib/hooks/useRequest"; -import {GET_OTP_TOKEN} from "@/core/utils/routes"; +import {GET_OTP_TOKEN, VERIFY_OTP} from "@/core/utils/routes"; +import {formatCounter} from "@/core/utils/formatCounter"; -const PhoneValidation = () => { +const PhoneValidation = ({tabState, setTabState}) => { const requestServer = useRequest({auth: true}); const [phoneNumber, setPhoneNumber] = useState(""); + const [verificationCode, setVerificationCode] = useState(""); const [validPhone, setValidPhone] = useState(false); const [delayPerRequest, setDelayPerRequest] = useState(false); const [counter, setCounter] = useState(120); const [otpSended, setOtpSended] = useState(false); + const [readyToVerify, setReadyToVerify] = useState(false); const handleNumericInput = (e) => { e.target.value = e.target.value.replace(/[^0-9]/g, ''); @@ -21,18 +24,22 @@ const PhoneValidation = () => { useEffect(() => { if (phoneNumber.length === 11) { - setValidPhone(true) + setValidPhone(true); } else { - setValidPhone(false) + setValidPhone(false); } - }, [phoneNumber]); + if (verificationCode.length === 6 && phoneNumber.length === 11) { + setReadyToVerify(true); + } else { + setReadyToVerify(false); + } + }, [phoneNumber, verificationCode]); useEffect(() => { if (counter === 0) { setDelayPerRequest(false); return; } - if (delayPerRequest && counter > 0) { const timer = setInterval(() => { setCounter(prevCounter => prevCounter - 1); @@ -55,12 +62,23 @@ const PhoneValidation = () => { setDelayPerRequest(true); }; - // Format counter as MM:SS - const formatCounter = (counter) => { - const minutes = Math.floor(counter / 60).toString().padStart(2, '0'); - const seconds = (counter % 60).toString().padStart(2, '0'); - return `${minutes}:${seconds}`; - }; + const phoneRegister = () => { + const formData = new FormData(); + formData.append("phone_number", phoneNumber); + formData.append("verification_code", verificationCode); + + for (var pair of formData.entries()) { + console.log(pair[0] + ', ' + pair[1]); + } + setTabState(tabState + 1) + requestServer(VERIFY_OTP, "post", { + data: formData, + }) + .then(() => { + }) + .catch(() => { + }); + } return ( { autoComplete="off" size="small" fullWidth - type="text" + value={verificationCode} + onChange={(e) => setVerificationCode(e.target.value)} onInput={handleNumericInput} + type="text" inputProps={{ maxLength: 6, inputMode: "numeric", @@ -118,7 +138,8 @@ const PhoneValidation = () => { }} /> - diff --git a/src/core/components/CarCode.jsx b/src/core/components/CarCode.jsx new file mode 100644 index 0000000..503a826 --- /dev/null +++ b/src/core/components/CarCode.jsx @@ -0,0 +1,86 @@ +"use client"; + +import {Autocomplete, CircularProgress, TextField} from "@mui/material"; +import {useEffect, useState} from "react"; +import useRequest from "@/lib/hooks/useRequest"; +import {debounce} from "@mui/material/utils"; + +const CarCode = ({carCode, setCarCode}) => { + const [inputValue, setInputValue] = useState(''); + const [options, setOptions] = useState([]); + const [loading, setLoading] = useState(false); + const requestServer = useRequest(); + + const fetchCarCodes = (inputValue, controller) => { + const debouncer = debounce((query) => { + if (query.length < 2) { + setOptions([]); + return; + } + setLoading(true); + requestServer(`car-code/api?${query}`, "get", { + requestOptions: {signal: controller.signal} + }) + .then((response) => { + setOptions(response || []); + }) + .catch(() => { + setOptions([]); + }) + .finally(() => { + setLoading(false); + }); + }, 500) + debouncer(inputValue) + } + + useEffect(() => { + const controller = new AbortController(); + fetchCarCodes(inputValue, controller); + return () => controller.abort(); + }, [inputValue]); + + return ( + { + setCarCode(newValue); + }} + inputValue={inputValue} + onInputChange={(event, newInputValue) => { + setInputValue(newInputValue); + }} + options={options} + getOptionLabel={(option) => + typeof option === 'string' ? option : option.name || option.code + } + loading={loading} + loadingText="درحال جستجوی کد خودرو" + noOptionsText={ + inputValue.length < 2 + ? "حداقل دو رقم از کد خودرو را وارد کنید" + : "کد خودرویی یافت نشد" + } + sx={{width: 300}} + renderInput={(params) => ( + + {loading ? : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + /> + ); +}; + +export default CarCode; \ No newline at end of file diff --git a/src/core/utils/formatCounter.js b/src/core/utils/formatCounter.js new file mode 100644 index 0000000..72b021a --- /dev/null +++ b/src/core/utils/formatCounter.js @@ -0,0 +1,5 @@ +export const formatCounter = (counter) => { + const minutes = Math.floor(counter / 60).toString().padStart(2, '0'); + const seconds = (counter % 60).toString().padStart(2, '0'); + return `${minutes}:${seconds}`; +}; \ No newline at end of file diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index c9ee515..1cd95f7 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -31,4 +31,7 @@ export const GET_OPERATOR_LIST = "/v3/api/fake-operator-list"; export const EXPORT_OPERATOR_LIST = "https://rms.rmto.ir/v2/road_patrols/operator/cartable/report"; export const GET_SUPERVISOR_LIST = "/v3/api/fake-supervisor-list"; export const EXPORT_SUPERVISOR_LIST = "https://rms.rmto.ir/v2/road_patrols/supervisor/cartable/report"; + +////**** mohammad check here ****//// export const GET_OTP_TOKEN = "https://rms.rmto.ir/v2/get_otp_token"; +export const VERIFY_OTP = "https://rms.rmto.ir/v2/verify_otp"; diff --git a/src/lib/hooks/useRequest.js b/src/lib/hooks/useRequest.js index eb30a18..1efa7de 100644 --- a/src/lib/hooks/useRequest.js +++ b/src/lib/hooks/useRequest.js @@ -1,7 +1,7 @@ -import { errorResponse } from "@/core/utils/errorResponse"; -import { successRequest } from "@/core/utils/successRequest"; +import {errorResponse} from "@/core/utils/errorResponse"; +import {successRequest} from "@/core/utils/successRequest"; import axios from "axios"; -import { useAuth } from "../contexts/auth"; +import {useAuth} from "../contexts/auth"; const defaultOptions = { data: {}, @@ -16,13 +16,12 @@ const defaultOptions = { }; const useRequest = (initOptions) => { - const { logout } = useAuth(); + const {logout} = useAuth(); const _options = Object.assign({}, defaultOptions, initOptions); return async (url = "", method = "get", options) => { const mergedOptions = Object.assign({}, _options, options); - try { const response = await axios({ url, From d650e556048a256793069df50062ec0bbe89bf32 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 23 Dec 2024 12:59:19 +0330 Subject: [PATCH 03/22] working on gasht detail part --- .../Forms/CreatePatrol/PatrolDetail.jsx | 10 ++++++++-- src/core/components/MuiDatePicker.jsx | 18 +++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx index 38631e5..24d59bb 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx @@ -1,8 +1,9 @@ "use client"; -import {Box, Slide} from "@mui/material"; +import {Box, Button, Chip, Divider, Slide} from "@mui/material"; import {useState} from "react"; import CarCode from "@/core/components/CarCode"; +import SearchIcon from '@mui/icons-material/Search'; const PatrolDetail = ({tabState, setTabState}) => { const [patrolFounded, setPatrolFounded] = useState(false); @@ -18,9 +19,14 @@ const PatrolDetail = ({tabState, setTabState}) => { my: 3 }} > - + + + + + + diff --git a/src/core/components/MuiDatePicker.jsx b/src/core/components/MuiDatePicker.jsx index 1be8fdb..35bfe01 100644 --- a/src/core/components/MuiDatePicker.jsx +++ b/src/core/components/MuiDatePicker.jsx @@ -1,14 +1,14 @@ -import { LocalizationProvider, MobileDateTimePicker } from "@mui/x-date-pickers"; -import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import {LocalizationProvider, MobileDateTimePicker} from "@mui/x-date-pickers"; +import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali"; import moment from "jalali-moment"; -import { faIR } from "@mui/x-date-pickers/locales"; -import { Box, IconButton, FormControl, FormHelperText, InputAdornment, Stack } from "@mui/material"; +import {faIR} from "@mui/x-date-pickers/locales"; +import {FormControl, IconButton, InputAdornment, Stack} from "@mui/material"; import ClearIcon from "@mui/icons-material/Clear"; -export default function PickerWithButtonField({ formik, name, value, error, touched, disabled }) { +export default function PickerWithButtonField({formik, name, value, error, touched, disabled}) { return ( - + formik.setFieldValue(name, null)} > - + ), From 753c6e8076c731ee8d4a296daa42d50338fc1a87 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Wed, 25 Dec 2024 15:04:20 +0330 Subject: [PATCH 04/22] working on patrol details and do some update on timeline --- .../Forms/CreatePatrol/PatrolDetail.jsx | 247 +++++++++++++++++- .../Forms/CreatePatrol/PatrolForms.jsx | 4 +- .../Forms/CreatePatrol/PatrolTimeLine.jsx | 34 +-- src/core/utils/routes.js | 4 +- 4 files changed, 259 insertions(+), 30 deletions(-) diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx index 24d59bb..008997b 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx @@ -1,13 +1,69 @@ "use client"; -import {Box, Button, Chip, Divider, Slide} from "@mui/material"; -import {useState} from "react"; +import { + Box, + Button, + Card, + CardContent, + Chip, + Divider, + IconButton, + InputAdornment, + Slide, + Stack, + Typography +} from "@mui/material"; +import React, {useEffect, useState} from "react"; import CarCode from "@/core/components/CarCode"; import SearchIcon from '@mui/icons-material/Search'; +import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import {faIR} from "@mui/x-date-pickers/locales"; +import {LocalizationProvider, MobileDateTimePicker} from "@mui/x-date-pickers"; +import ClearIcon from "@mui/icons-material/Clear"; +import moment from "jalali-moment"; +import dynamic from "next/dynamic"; +import MapLoading from "@/core/components/MapLayer/Loading"; +import LocalGasStationIcon from '@mui/icons-material/LocalGasStation'; +import DirectionsCarFilledIcon from '@mui/icons-material/DirectionsCarFilled'; +import WatchLaterIcon from '@mui/icons-material/WatchLater'; +import AddRoadIcon from '@mui/icons-material/AddRoad'; +import ShareLocationIcon from '@mui/icons-material/ShareLocation'; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight"; + +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); const PatrolDetail = ({tabState, setTabState}) => { const [patrolFounded, setPatrolFounded] = useState(false); const [carCode, setCarCode] = useState(null); + const [dateFrom, setDateFrom] = useState(null); + const [dateTo, setDateTo] = useState(null); + const [readyToRequest, setReadyToRequest] = useState(false); + const [data, setData] = useState({ + machine_code: "12-213-21", + distance: "23", + time: "04:45", + stop: "2", + fuel_amount: "21" + }) + + const requestPatrolInfo = () => { + setPatrolFounded(true) + setReadyToRequest(false) + } + + useEffect(() => { + console.log("data", carCode?.id, dateFrom, dateTo) + if (carCode !== null && dateFrom !== null && dateTo !== null) { + setReadyToRequest(true); + } else { + setReadyToRequest(false); + } + }, [carCode, dateFrom, dateTo]); + return ( { my: 3 }} > - - - - + + + + + + + { + const date = new Date(dateFrom); + const formattedDate = moment(date).locale("en").format("YYYY-MM-DD HH:mm"); + setDateFrom(formattedDate); + }} + slotProps={{ + textField: { + size: "small", + placeholder: "تاریخ و ساعت شروع گشت", + InputProps: { + endAdornment: ( + + { + event.stopPropagation(); + setDateFrom(null); + }} + sx={{ + color: "#bfbfbf", + "&:hover": { + backgroundColor: "rgba(189, 189, 189, 0.1)", + color: "#363434", + }, + }} + > + + + + ), + }, + }, + }} label="تاریخ و ساعت شروع گشت" + /> + { + const date = new Date(dateTo); + const formattedDate = moment(date).locale("en").format("YYYY-MM-DD HH:mm"); + setDateTo(formattedDate); + }} + slotProps={{ + textField: { + size: "small", + placeholder: "تاریخ و ساعت پایان گشت", + InputProps: { + endAdornment: ( + + { + event.stopPropagation(); + setDateTo(null); + }} + sx={{ + color: "#bfbfbf", + "&:hover": { + backgroundColor: "rgba(189, 189, 189, 0.1)", + color: "#363434", + }, + }} + > + + + + ), + }, + }, + }} label="تاریخ و ساعت پایان گشت"/> + + + - + - - - - + {patrolFounded && + + + + + }/> + + + {data.machine_code} + + + + }/> + + + {data.time} + + + + }/> + + + {data.distance} + + + + }/> + + + {data.stop} + + + + }/> + + + {data.fuel_amount} + + + + + + + + + + + + + + + } + + + + ); }; diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx index 4d51f65..da6690e 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx @@ -24,7 +24,7 @@ function TabPanel(props) { const PatrolForms = () => { const theme = useTheme(); - const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const isMobile = useMediaQuery(theme.breakpoints.down("md")); const [tabState, setTabState] = useState(0); const handleChangeTab = (event, newValue) => { @@ -71,7 +71,7 @@ const PatrolForms = () => { {!isMobile && ( - + )} diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx index 5343e33..ba33a31 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx @@ -1,6 +1,6 @@ "use client"; -import {Box, Typography} from "@mui/material"; +import {Box, CircularProgress, Typography} from "@mui/material"; import TapAndPlayIcon from '@mui/icons-material/TapAndPlay'; import TaxiAlertIcon from '@mui/icons-material/TaxiAlert'; import EngineeringIcon from '@mui/icons-material/Engineering'; @@ -17,6 +17,8 @@ import { } from "@mui/lab"; const PatrolTimeLine = ({tabState}) => { + + console.log("tabState", tabState) return ( { - : 0 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} - /> + />} @@ -47,10 +49,10 @@ const PatrolTimeLine = ({tabState}) => { - : 1 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} - /> + />} @@ -65,10 +67,10 @@ const PatrolTimeLine = ({tabState}) => { - : 2 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} - /> + />} @@ -83,10 +85,10 @@ const PatrolTimeLine = ({tabState}) => { - : 3 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} - /> + />} @@ -101,10 +103,10 @@ const PatrolTimeLine = ({tabState}) => { - : 4 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} - /> + />} diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 9548f91..09719e6 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -33,6 +33,8 @@ export const GET_ROAD_PATROL_OPERATOR_LIST = "/v3/api/fake-road-patrol/operator" export const EXPORT_ROAD_PATROL_OPERATOR_LIST = "https://rms.rmto.ir/v2/road_patrols/operator/cartable/report"; export const GET_ROAD_PATROL_SUPERVISOR_LIST = "/v3/api/fake-road-patrol/supervisor"; export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = "https://rms.rmto.ir/v2/road_patrols/supervisor/cartable/report"; +export const GET_OTP_TOKEN = "fake/api"; +export const VERIFY_OTP = "fake/api"; // road items export const GET_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor_index"; @@ -48,4 +50,4 @@ export const REJECT_BY_SUPERVISOR = api + "/api/v3/road_items/verify_by_supervis export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/delete"; export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/restore"; export const GET_CAR_LIST_SEARCH = api + "/api/v3/cmms_machines/search"; -export const GET_RAHDARANS_LIST_SEARCH = api + "/api/v3/rahdaran/search"; +export const GET_RAHDARANS_LIST_SEARCH = api + "/api/v3/rahdaran/search"; \ No newline at end of file From d68e7d5e59566ce08368fe7a0b250362a6f99b7a Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 30 Dec 2024 10:38:53 +0330 Subject: [PATCH 05/22] working on partrol form part 4 --- .../Forms/CreatePatrol/PatrolDetail.jsx | 148 +++++++++--------- .../Forms/CreatePatrol/PatrolForms.jsx | 25 ++- .../Forms/CreatePatrol/PatrolTimeLine.jsx | 12 +- .../Forms/CreatePatrol/SuperVisorsDetail.jsx | 94 +++++++++++ 4 files changed, 193 insertions(+), 86 deletions(-) create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx index 008997b..aa74c7b 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx @@ -56,7 +56,6 @@ const PatrolDetail = ({tabState, setTabState}) => { } useEffect(() => { - console.log("data", carCode?.id, dateFrom, dateTo) if (carCode !== null && dateFrom !== null && dateTo !== null) { setReadyToRequest(true); } else { @@ -170,88 +169,93 @@ const PatrolDetail = ({tabState, setTabState}) => { - {patrolFounded && - - - - - }/> - - - {data.machine_code} - - - - }/> - - - {data.time} - - - - }/> - - - {data.distance} - - - - }/> - - - {data.stop} - - - - }/> - - - {data.fuel_amount} - - - - - - + {patrolFounded ? + + + + + }/> + + + {data.machine_code} + + + + }/> + + + {data.time} + + + + }/> + + + {data.distance} + + + + }/> + + + {data.stop} + + + + }/> + + + {data.fuel_amount} + + + + + - - + + + + - - - - - } + + + + : + + + ابتدا اطلاعات بالا را تکمیل نمایید + + } - diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx index da6690e..e87151b 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx @@ -2,7 +2,7 @@ import {Box, DialogContent, Tab, Tabs, useMediaQuery} from "@mui/material"; import {useTheme} from "@emotion/react"; -import React, {useState} from "react"; +import React, {useEffect, useState} from "react"; import TapAndPlayIcon from '@mui/icons-material/TapAndPlay'; import TaxiAlertIcon from '@mui/icons-material/TaxiAlert'; import EngineeringIcon from '@mui/icons-material/Engineering'; @@ -11,6 +11,7 @@ import VerifiedIcon from '@mui/icons-material/Verified'; import PatrolTimeLine from "./PatrolTimeLine"; import PhoneValidation from "./PhoneValidation"; import PatrolDetail from "./PatrolDetail"; +import SuperVisorsDetail from "@/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail"; function TabPanel(props) { const {children, value, index} = props; @@ -26,11 +27,19 @@ const PatrolForms = () => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("md")); const [tabState, setTabState] = useState(0); + const [activeUpTo, setActiveUpTo] = useState(0); const handleChangeTab = (event, newValue) => { setTabState(newValue); }; + useEffect(() => { + if (activeUpTo < tabState) { + setActiveUpTo(tabState); + } + }, [tabState]); + + return ( <> { backgroundColor: "#efefef", }} > - } label="تایید هویت"> - } label="مشخصات گشت"> - } label="مشخصات راهداران"> - } label="اقدامات حین گشت"> - } label="تکمیل درخواست"> + = 0)} icon={} label="تایید هویت"> + = 1)} icon={} label="مشخصات گشت"> + = 2)} icon={} label="مشخصات راهداران"> + = 3)} icon={} label="اقدامات حین گشت"> + = 4)} icon={} label="تکمیل درخواست"> @@ -57,10 +66,10 @@ const PatrolForms = () => { - + - <>moshakhasat rahdar + <>eghdamat heine gasht diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx index ba33a31..4bf75c1 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolTimeLine.jsx @@ -31,7 +31,7 @@ const PatrolTimeLine = ({tabState}) => { - {tabState === 0 ? : : 0 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} />} @@ -49,7 +49,7 @@ const PatrolTimeLine = ({tabState}) => { - {tabState === 1 ? : : 1 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} />} @@ -67,7 +67,7 @@ const PatrolTimeLine = ({tabState}) => { - {tabState === 2 ? : : 2 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} />} @@ -77,7 +77,7 @@ const PatrolTimeLine = ({tabState}) => { مشخصات راهداران - راهدار/راهداران حاظر در گشت + راهدار / راهداران حاظر در گشت @@ -85,7 +85,7 @@ const PatrolTimeLine = ({tabState}) => { - {tabState === 3 ? : : 3 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} />} @@ -103,7 +103,7 @@ const PatrolTimeLine = ({tabState}) => { - {tabState === 4 ? : : 4 ? "success" : "error"} sx={{width: "1.5rem", height: "1.5rem"}} />} diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx new file mode 100644 index 0000000..070bdcf --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx @@ -0,0 +1,94 @@ +"use client"; + +import {Box, Button, Card, Chip, Divider, IconButton, TextField, Typography} from "@mui/material"; +import SaveAltIcon from '@mui/icons-material/SaveAlt'; +import AccountCircleIcon from '@mui/icons-material/AccountCircle'; +import DeleteIcon from '@mui/icons-material/Delete'; +import React, {useState} from "react"; + +const SuperVisorsDetail = ({tabState, setTabState}) => { + const [patrolFounded, setPatrolFounded] = useState(false); + const [rahdarsCode, setRahdarsCode] = useState(null); + const [readyToRequest, setReadyToRequest] = useState(false); + + const requestPatrolInfo = () => { + setPatrolFounded(true) + setReadyToRequest(false) + } + + return ( + + + + {/**/} + + + + + + + + + + + + + محمد حسین + کد راهدار: 893 + + + + + + + + + + + حسین تقی + کد راهدار: 123 + + + + + + + + + ); +}; + +export default SuperVisorsDetail; \ No newline at end of file From 97e6c509f0670f030592735136ef60c3ab405654 Mon Sep 17 00:00:00 2001 From: Amin Ghasempoor Date: Mon, 30 Dec 2024 10:03:53 +0000 Subject: [PATCH 06/22] Feature/gasht cartables --- .../roadPatrols/operator/OperatorList.jsx | 27 ++++++++- .../operator/RowActions/ReportForm/index.jsx | 3 +- .../roadPatrols/operator/RowActions/index.jsx | 7 +-- .../RowActions/DeleteForm/DeleteContent.jsx | 60 +++++++++++++------ .../RowActions/OfficerDescription/index.jsx | 32 +--------- .../RowActions/ReportForm/index.jsx | 3 +- .../supervisor/RowActions/index.jsx | 4 -- .../roadPatrols/supervisor/SupervisorList.jsx | 54 ++++++++++++++++- src/core/components/MapInfoOneMarker.jsx | 28 ++++----- src/core/components/MapInfoTwoMarker.jsx | 35 +++++------ src/core/utils/routes.js | 5 +- 11 files changed, 157 insertions(+), 101 deletions(-) diff --git a/src/components/dashboard/roadPatrols/operator/OperatorList.jsx b/src/components/dashboard/roadPatrols/operator/OperatorList.jsx index a68bdcc..589ba5d 100644 --- a/src/components/dashboard/roadPatrols/operator/OperatorList.jsx +++ b/src/components/dashboard/roadPatrols/operator/OperatorList.jsx @@ -1,11 +1,12 @@ "use client"; import { useMemo } from "react"; -import { Box, Typography } from "@mui/material"; +import { Box, Stack, Typography } from "@mui/material"; import DataTableWithAuth from "@/core/components/DataTableWithAuth"; import Toolbar from "./Toolbar"; import { GET_ROAD_PATROL_OPERATOR_LIST } from "@/core/utils/routes"; import moment from "jalali-moment"; import RowActions from "./RowActions"; +import ReportForm from "./RowActions/ReportForm"; const OperatorList = () => { const columns = useMemo( @@ -81,6 +82,29 @@ const OperatorList = () => { grow: false, size: 100, }, + { + header: "گزارش مامور", + enableColumnFilter: false, + datatype: "text", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue, row }) => { + return ( + + + + ); + }, + }, ], [] ); @@ -89,7 +113,6 @@ const OperatorList = () => { <> { - const reportUrl = "https://rms.rmto.ir/v2/road_patrols/operator/report/96872"; // TODO replace id here - + const reportUrl = `https://rms.rmto.ir/v2/road_patrols/operator/report/${rowId}`; return ( { - return ( - - - - ); + return ; }; export default RowActions; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/DeleteForm/DeleteContent.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/DeleteForm/DeleteContent.jsx index 52d266c..bb9303d 100644 --- a/src/components/dashboard/roadPatrols/supervisor/RowActions/DeleteForm/DeleteContent.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/DeleteForm/DeleteContent.jsx @@ -1,9 +1,45 @@ import { Button, DialogActions, DialogContent, Stack, Typography, List, ListItem } from "@mui/material"; import useRequest from "@/lib/hooks/useRequest"; -import React from "react"; +import React, { useState } from "react"; +import { DELETE_ROAD_PATROL_SUPERVISOR } from "@/core/utils/routes"; const DeleteContent = ({ rowId, mutate, setOpenDeleteDialog }) => { - const requestServer = useRequest(); + const requestServer = useRequest({ notificationSuccess: true }); + const [submittingPartial, setSubmittingPartial] = useState(false); + const [submittingGeneral, setSubmittingGeneral] = useState(false); + const handleGeneralDelete = () => { + setSubmittingGeneral(true); + requestServer(`${DELETE_ROAD_PATROL_SUPERVISOR}/${rowId}`, "post", { + data: { + type: 2, + }, + }) + .then(() => { + mutate(); + setOpenDeleteDialog(false); + setSubmittingGeneral(false); + }) + .catch(() => { + setSubmittingGeneral(false); + }); + }; + + const handlePartialDelete = () => { + setSubmittingPartial(true); + requestServer(`${DELETE_ROAD_PATROL_SUPERVISOR}/${rowId}`, "post", { + data: { + type: 1, + }, + }) + .then(() => { + mutate(); + setOpenDeleteDialog(false); + setSubmittingPartial(false); + }) + .catch(() => { + setSubmittingPartial(false); + }); + }; return ( <> @@ -42,23 +78,11 @@ const DeleteContent = ({ rowId, mutate, setOpenDeleteDialog }) => { - - diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/OfficerDescription/index.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/OfficerDescription/index.jsx index 8b3675b..04b5946 100644 --- a/src/components/dashboard/roadPatrols/supervisor/RowActions/OfficerDescription/index.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/OfficerDescription/index.jsx @@ -1,26 +1,10 @@ import { Dialog, DialogContent, DialogTitle, IconButton, Tooltip, Typography, Card, CardContent } from "@mui/material"; import { useState } from "react"; -import useRequest from "@/lib/hooks/useRequest"; import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; import CloseIcon from "@mui/icons-material/Close"; -const OfficerDescriptionForm = ({ row }) => { +const OfficerDescriptionForm = ({ description }) => { const [openOfficerDescriptionDialog, setOpenOfficerDescriptionDialog] = useState(false); - const requestServer = useRequest(); - - const handleSubmit = () => { - // requestServer(`${RESERVE_PASSENGER_BOSS}/${rowId}`, "post", { description }) - // .then((response) => { - // setOpenOfficerDescriptionDialog(false); - // mutate(); - // }) - // .catch((error) => { - // console.error(error); - // }) - // .finally(() => { - // setIsSubmitting(false); - // }); - }; return ( <> @@ -55,18 +39,7 @@ const OfficerDescriptionForm = ({ row }) => { - - توضیحات : - - - {row.original.description || "هیچ توضیحی موجود نیست"}{" "} - {/* should replace row.original.description with the back end*/} - + {description || "هیچ توضیحی موجود نیست"} @@ -74,5 +47,4 @@ const OfficerDescriptionForm = ({ row }) => { ); }; - export default OfficerDescriptionForm; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/ReportForm/index.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/ReportForm/index.jsx index 8abb152..0319aaf 100644 --- a/src/components/dashboard/roadPatrols/supervisor/RowActions/ReportForm/index.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/ReportForm/index.jsx @@ -2,8 +2,7 @@ import { Tooltip, IconButton } from "@mui/material"; import PrintIcon from "@mui/icons-material/Print"; const ReportForm = ({ rowId }) => { - const reportUrl = "https://rms.rmto.ir/v2/road_patrols/operator/report/96872"; // TODO replace id here - + const reportUrl = `https://rms.rmto.ir/v2/road_patrols/operator/report/${rowId}`; return ( { return ( - - ); diff --git a/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx b/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx index 5d71669..d653f21 100644 --- a/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx @@ -1,15 +1,16 @@ "use client"; import { useMemo } from "react"; -import { Box, Typography } from "@mui/material"; +import { Box, Stack } from "@mui/material"; import DataTableWithAuth from "@/core/components/DataTableWithAuth"; import Toolbar from "./Toolbar"; import { GET_ROAD_PATROL_SUPERVISOR_LIST } from "@/core/utils/routes"; import moment from "jalali-moment"; import RowActions from "./RowActions"; import useProvinces from "@/lib/hooks/useProvince"; -import useRoadItemGetItems from "@/lib/hooks/useRoadItemGetItems"; import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsType/CustomSelectByDependency"; import useEdaratLists from "@/lib/hooks/useEdaratLists"; +import OfficerDescriptionForm from "./RowActions/OfficerDescription"; +import ReportForm from "./RowActions/ReportForm"; const OperatorList = () => { const columns = useMemo( @@ -151,6 +152,54 @@ const OperatorList = () => { grow: false, size: 100, }, + { + accessorKey: "description", + header: "توضیحات مامور", + id: "description", + enableColumnFilter: false, + datatype: "text", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue }) => { + return ( + + + + ); + }, + }, + { + header: "گزارش مامور", + enableColumnFilter: false, + datatype: "text", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue, row }) => { + return ( + + + + ); + }, + }, ], [] ); @@ -159,7 +208,6 @@ const OperatorList = () => { <> import("@/core/components/MapLayer"), { ssr: false, }); -const createCustomIcon = (size, iconUrl, labelText) => { +const createCustomIcon = (size, iconUrl, labelText, color) => { if (labelText) { return L.divIcon({ + className: "custom-marker", // Apply your custom CSS class html: ` -
- icon -
- ${labelText} +
+
+ ${labelText}
-
- `, - iconSize: size, - iconAnchor: [size[0] / 2, size[1]], - popupAnchor: [0, -size[1]], +
+
`, + iconSize: [100, 50], // Adjust icon size to fit your content + iconAnchor: [50, 25], // Adjust to position the marker correctly }); } @@ -45,6 +40,7 @@ const MAX_ZOOM_FOR_MARKER = 13; const MapInteraction = ({ setValue, startLat, startLng }) => { const [isMarkerLocked, setIsMarkerLocked] = useState(!!(startLat && startLng)); // وضعیت قفل مارکر const [enableSend, setEnableSend] = useState(false); + const [startIconColor, setStartIconColor] = useState(startLat ? "#1CAC66" : "#003d4f"); // رنگ آیکن شروع const [markerPosition, setMarkerPosition] = useState( startLat && startLng ? { lat: startLat, lng: startLng } : null ); @@ -79,6 +75,7 @@ const MapInteraction = ({ setValue, startLat, startLng }) => { setValue("start_point", { lat: center.lat.toString(), lng: center.lng.toString() }); setMarkerPosition({ lat: center.lat, lng: center.lng }); // به‌روزرسانی موقعیت مارکر setIsMarkerLocked(true); + setStartIconColor("#1CAC66"); } }; @@ -86,6 +83,7 @@ const MapInteraction = ({ setValue, startLat, startLng }) => { setValue("start_point", null); // حذف مقدار قبلی setIsMarkerLocked(false); // باز کردن قفل مارکر setMarkerPosition(null); // تنظیم مارکر به مرکز نقشه + setStartIconColor("#003d4f"); }; return ( @@ -93,7 +91,7 @@ const MapInteraction = ({ setValue, startLat, startLng }) => { import("@/core/components/MapLayer"), { loading: () => , ssr: false, }); -const createCustomIcon = (size, iconUrl, labelText) => { +const createCustomIcon = (size, iconUrl, labelText, color) => { if (labelText) { return L.divIcon({ + className: "custom-marker", // Apply your custom CSS class html: ` -
- icon -
- ${labelText} +
+
+ ${labelText}
-
- `, - iconSize: size, - iconAnchor: [size[0] / 2, size[1]], - popupAnchor: [0, -size[1]], +
+
`, + iconSize: [100, 50], // Adjust icon size to fit your content + iconAnchor: [50, 25], // Adjust to position the marker correctly }); } - return L.icon({ iconUrl: iconUrl, iconSize: size, @@ -48,6 +42,8 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { const [startPosition, setStartPosition] = useState(startLat && startLng ? { lat: startLat, lng: startLng } : null); const [endPosition, setEndPosition] = useState(endLat && endLng ? { lat: endLat, lng: endLng } : null); const [enableSend, setEnableSend] = useState(false); + const [startIconColor, setStartIconColor] = useState(startLat ? "#1CAC66" : "#003d4f"); // رنگ آیکن شروع + const [endIconColor, setEndIconColor] = useState(endLat ? "#D13131" : "#003d4f"); // رنگ آیکن پایان const startRef = useRef(); const endRef = useRef(); @@ -86,6 +82,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { setIsStartLocked(false); setStartPosition(null); setValue("start_point", null); + setStartIconColor("#003d4f"); }; const handleUnlockEnd = () => { @@ -95,6 +92,8 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { setStartPosition(null); setValue("end_point", ""); setValue("start_point", null); + setStartIconColor("#003d4f"); + setEndIconColor("#003d4f"); }; return ( @@ -102,7 +101,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { { if (!enableSend) return; @@ -111,6 +110,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { setValue("start_point", { lat: center.lat.toString(), lng: center.lng.toString() }); setStartPosition({ lat: center.lat, lng: center.lng }); setIsStartLocked(true); + setStartIconColor("#1CAC66"); } }, }} @@ -172,7 +172,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { { if (!enableSend) return; @@ -181,6 +181,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { setValue("end_point", { lat: center.lat.toString(), lng: center.lng.toString() }); setEndPosition({ lat: center.lat, lng: center.lng }); setIsEndLocked(true); + setEndIconColor("#D13131"); } }, }} diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index db6c244..44434f8 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -30,9 +30,10 @@ export const UPDATE_AZMAYESH_TYPE = api + "/api/v3/azmayesh_types/update"; //road patrol export const GET_ROAD_PATROL_OPERATOR_LIST = api + "/api/v3/road_patrols/operator_index"; -export const EXPORT_ROAD_PATROL_OPERATOR_LIST = "https://rms.rmto.ir/v2/road_patrols/operator/cartable/report"; +export const EXPORT_ROAD_PATROL_OPERATOR_LIST = "https://rms.witel.ir/v2/road_patrols/operator/cartable/report"; export const GET_ROAD_PATROL_SUPERVISOR_LIST = api + "/api/v3/road_patrols/supervisor_index"; -export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = "https://rms.rmto.ir/v2/road_patrols/supervisor/cartable/report"; +export const EXPORT_ROAD_PATROL_SUPERVISOR_LIST = "https://rms.witel.ir/v2/road_patrols/supervisor/cartable/report"; +export const DELETE_ROAD_PATROL_SUPERVISOR = api + "/api/v3/road_patrols/delete"; // road items export const GET_ROAD_ITEMS_SUPERVISOR_LIST = api + "/api/v3/road_items/supervisor_index"; From 7671fddc848a93b6b189dba2df5b088fd1c91a76 Mon Sep 17 00:00:00 2001 From: Amin Ghasempoor Date: Wed, 1 Jan 2025 13:25:58 +0000 Subject: [PATCH 07/22] Feature/user log entrance --- src/app/(withAuth)/dashboard/azmayesh/page.js | 2 + .../dashboard/azmayesh_type/page.js | 2 + .../dashboard/road-items/operator/page.js | 2 + .../dashboard/road-items/supervisor/page.js | 2 + .../dashboard/road-patrols/operator/page.js | 2 + .../dashboard/road-patrols/supervisor/page.js | 2 + .../Create/Forms/CreateFormContent.jsx | 61 ++++- .../Actions/Create/Forms/GetItemInfo.jsx | 16 +- .../Actions/Create/Forms/GetItemsForm.jsx | 4 +- .../Actions/Create/Forms/GetSubItemsForm.jsx | 4 +- .../Create/Forms/PreviousStatesInfo.jsx | 2 +- .../operator/Actions/Create/Forms/index.jsx | 19 +- .../ObservedGashtCreate/GashtCreate.jsx | 17 ++ .../GashtCreateContent.jsx | 116 ++++++++ .../Actions/ObservedGashtCreate/index.jsx | 38 +++ .../RowActions/EditForm/EditController.jsx | 55 ++-- .../RowActions/EditForm/EditFormContent.jsx | 255 ++++-------------- .../RowActions/EditForm/EditFormCreate.jsx | 171 ++++++++++++ .../operator/RowActions/EditForm/index.jsx | 20 +- .../dashboard/roadItems/operator/Toolbar.jsx | 2 + src/core/components/ActivityCodeLog.jsx | 30 +++ src/core/components/CarCode.jsx | 6 +- src/core/components/RahdarCode.jsx | 4 +- src/core/utils/routes.js | 3 + 24 files changed, 558 insertions(+), 277 deletions(-) create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreate.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx create mode 100644 src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx create mode 100644 src/core/components/ActivityCodeLog.jsx diff --git a/src/app/(withAuth)/dashboard/azmayesh/page.js b/src/app/(withAuth)/dashboard/azmayesh/page.js index d27371a..164a4b6 100644 --- a/src/app/(withAuth)/dashboard/azmayesh/page.js +++ b/src/app/(withAuth)/dashboard/azmayesh/page.js @@ -1,10 +1,12 @@ import AzmayeshPage from "@/components/dashboard/azmayesh"; import WithPermission from "@/core/middlewares/withPermission"; +import ActivityCodeLog from "@/core/components/ActivityCodeLog"; const Page = () => { return ( + ); }; diff --git a/src/app/(withAuth)/dashboard/azmayesh_type/page.js b/src/app/(withAuth)/dashboard/azmayesh_type/page.js index 4032594..77a604a 100644 --- a/src/app/(withAuth)/dashboard/azmayesh_type/page.js +++ b/src/app/(withAuth)/dashboard/azmayesh_type/page.js @@ -1,10 +1,12 @@ import AzmayeshTypePage from "@/components/dashboard/azmayeshType"; import WithPermission from "@/core/middlewares/withPermission"; +import ActivityCodeLog from "@/core/components/ActivityCodeLog"; const Page = () => { return ( + ); }; diff --git a/src/app/(withAuth)/dashboard/road-items/operator/page.js b/src/app/(withAuth)/dashboard/road-items/operator/page.js index 9c3d8ca..324c997 100644 --- a/src/app/(withAuth)/dashboard/road-items/operator/page.js +++ b/src/app/(withAuth)/dashboard/road-items/operator/page.js @@ -1,9 +1,11 @@ import WithPermission from "@/core/middlewares/withPermission"; import OperatorPage from "@/components/dashboard/roadItems/operator"; +import ActivityCodeLog from "@/core/components/ActivityCodeLog"; const Page = () => { return ( + ); }; diff --git a/src/app/(withAuth)/dashboard/road-items/supervisor/page.js b/src/app/(withAuth)/dashboard/road-items/supervisor/page.js index 58c47d8..2de82eb 100644 --- a/src/app/(withAuth)/dashboard/road-items/supervisor/page.js +++ b/src/app/(withAuth)/dashboard/road-items/supervisor/page.js @@ -1,11 +1,13 @@ import WithPermission from "@/core/middlewares/withPermission"; import SupervisorPage from "@/components/dashboard/roadItems/supervisor"; +import ActivityCodeLog from "@/core/components/ActivityCodeLog"; const Page = () => { return ( + ); }; diff --git a/src/app/(withAuth)/dashboard/road-patrols/operator/page.js b/src/app/(withAuth)/dashboard/road-patrols/operator/page.js index 73fa9cf..44725da 100644 --- a/src/app/(withAuth)/dashboard/road-patrols/operator/page.js +++ b/src/app/(withAuth)/dashboard/road-patrols/operator/page.js @@ -1,10 +1,12 @@ import WithPermission from "@/core/middlewares/withPermission"; import OperatorPage from "@/components/dashboard/roadPatrols/operator"; +import ActivityCodeLog from "@/core/components/ActivityCodeLog"; const Page = () => { return ( + ); }; diff --git a/src/app/(withAuth)/dashboard/road-patrols/supervisor/page.js b/src/app/(withAuth)/dashboard/road-patrols/supervisor/page.js index 1afb8c4..4093c15 100644 --- a/src/app/(withAuth)/dashboard/road-patrols/supervisor/page.js +++ b/src/app/(withAuth)/dashboard/road-patrols/supervisor/page.js @@ -1,9 +1,11 @@ import WithPermission from "@/core/middlewares/withPermission"; import SupervisorPage from "@/components/dashboard/roadPatrols/supervisor"; +import ActivityCodeLog from "@/core/components/ActivityCodeLog"; const Page = () => { return ( + ); }; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx index de60a7e..17fd595 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx @@ -27,11 +27,11 @@ function TabPanel(props) { } const defaultValues = { - itemId: null, - itemSubId: null, + item_id: null, + sub_item_id: null, amount: "", - action_date: "", - start_date: "", + activity_time: "", + activity_date: "", before_image: null, after_image: null, cmms_machines: null, @@ -40,13 +40,13 @@ const defaultValues = { end_point: "", }; const validationSchema = object({ - itemId: string().required("نوع آیتم را مشخص کنید!"), - itemSubId: string().required("موضوع مشاهده شده را مشخص کنید!"), + item_id: string().required("نوع آیتم را مشخص کنید!"), + sub_item_id: string().required("موضوع مشاهده شده را مشخص کنید!"), amount: string().required("وارد کردن مقدار الزامیست!"), cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"), rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), // بررسی حداقل یک آیتم, - action_date: string().required("لطفا زمان فعالیت را انتخاب کنید!"), - start_date: string().required("لطفاً تاریخ شروع فعالیت را انتخاب کنید!"), + activity_time: string().required("لطفا زمان فعالیت را انتخاب کنید!"), + activity_date: string().required("لطفاً تاریخ شروع فعالیت را انتخاب کنید!"), before_image: mixed() .nullable() .test("before-image-required", "لطفا عکس قبل از اقدام را بارگذاری کنید!", function (value) { @@ -82,12 +82,13 @@ const validationSchema = object({ }), }); -const CreateFormContent = ({ setOpen, mutate, onSubmit }) => { +const CreateFormContent = ({ setOpen, onSubmit }) => { const [tabState, setTabState] = useState(0); const [itemsList, setItemsList] = useState(); const [subItemsList, setSubItemsList] = useState([]); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const handleClose = () => { setOpen(false); }; @@ -100,8 +101,8 @@ const CreateFormContent = ({ setOpen, mutate, onSubmit }) => { if (tabState === 2) { const fieldsToReset = [ "amount", - "action_date", - "start_date", + "activity_time", + "activity_date", "before_image", "after_image", "cmms_machines", @@ -133,8 +134,44 @@ const CreateFormContent = ({ setOpen, mutate, onSubmit }) => { context: { subItemsList }, }); + const onSubmitBase = (data) => { + let result = { ...data }; + + result.before_image === null && delete result.before_image; + result.after_image === null && delete result.after_image; + if (result.end_point === "") { + delete result.end_point; + } else { + result.end_point = `${result.end_point.lat},${result.end_point.lng}`; + } + if (result.start_point === "") { + delete result.start_point; + } else { + result.start_point = `${result.start_point.lat},${result.start_point.lng}`; + } + + result.rahdaran_id.forEach((rahdar, index) => { + result[`rahdaran_id[${index}]`] = rahdar.id; + }); + delete result.rahdaran_id; + + result.cmms_machines.forEach((cmms_machine, index) => { + result[`machines_id[${index}]`] = cmms_machine.id; + }); + delete result.cmms_machines; + + onSubmit({ + result, + data: { + ...data, + item_name: itemsList.name, + sub_item_name: subItemsList.name, + }, + }); + }; + return ( - + diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm.jsx index 0396b71..e7daaa8 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm.jsx @@ -28,8 +28,8 @@ const GetItemsForm = ({ setValue, setItemsList, tabState, setTabState }) => { }, }} onClick={() => { - setValue("itemId", item.id); - setItemsList(item.name); + setValue("item_id", item.id); + setItemsList(item); setTabState(tabState + 1); }} > diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm.jsx index 8b36594..2a60079 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm.jsx @@ -3,7 +3,7 @@ import { Card, CardActionArea, Grid, LinearProgress, Typography } from "@mui/mat import useRoadItemGetSubItems from "@/lib/hooks/useRoadItemGetISubtems"; const GetSubItemsForm = ({ setValue, watch, setSubItemsList, tabState, setTabState }) => { - const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetSubItems(watch("itemId")); + const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetSubItems(watch("item_id")); return ( <> @@ -27,7 +27,7 @@ const GetSubItemsForm = ({ setValue, watch, setSubItemsList, tabState, setTabSta }, }} onClick={() => { - setValue("itemSubId", item.sub_item); + setValue("sub_item_id", item.sub_item); setSubItemsList(item); setTabState(tabState + 1); }} diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/PreviousStatesInfo.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/PreviousStatesInfo.jsx index 6f3cc86..9e7b7db 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/PreviousStatesInfo.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/PreviousStatesInfo.jsx @@ -18,7 +18,7 @@ const PreviousStatesInfo = ({ itemsList, subItemsList }) => { - {itemsList || "هیچ آیتمی انتخاب نشده است"} + {itemsList.name || "هیچ آیتمی انتخاب نشده است"} diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx index d47352a..3e78906 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx @@ -6,22 +6,11 @@ import useRequest from "@/lib/hooks/useRequest"; const OperatorCreateForm = ({ open, setOpen, mutate, rowId }) => { const requestServer = useRequest({ notificationSuccess: true }); - const HandleSubmit = async (data) => { - let endPoint; - let startPoint = `${data.start_point.lat},${data.start_point.lng}`; - data.end_point !== "" && (endPoint = `${data.end_point.lat},${data.end_point.lng}`); + const HandleSubmit = async ({ result }) => { const formData = new FormData(); - data.rahdaran_id.map((rahdar, index) => formData.append(`rahdaran_id[${index}]`, rahdar.id)); - formData.append("item_id", data.itemId); - formData.append("sub_item_id", data.itemSubId); - formData.append("amount", data.amount); - formData.append("activity_time", data.action_date); - formData.append("activity_date", data.start_date); - data.cmms_machines.map((machine, index) => formData.append(`machines_id[${index}]`, machine.id)); - data.before_image !== null && formData.append("before_image", data.before_image); - data.after_image !== null && formData.append("after_image", data.after_image); - data.start_point !== "" && formData.append("start_point", startPoint); - data.end_point !== "" && formData.append("end_point", endPoint); + for (const [key, value] of Object.entries(result)) { + formData.append(key, value); + } await requestServer(CREATE_ROAD_ITEMS, "post", { data: formData, }) diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreate.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreate.jsx new file mode 100644 index 0000000..1a3b3bc --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreate.jsx @@ -0,0 +1,17 @@ +import { Button, Dialog, DialogActions, DialogTitle } from "@mui/material"; +import GashtCreateContent from "./GashtCreateContent"; + +const GashtCreate = ({ open, setOpen, mutate, rowId }) => { + return ( + + جستجوی مورد مشاهده شده در گشت راهداری و ترابری + + + + + + ); +}; +export default GashtCreate; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx new file mode 100644 index 0000000..d2ff576 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx @@ -0,0 +1,116 @@ +import { Box, Button, DialogActions, DialogContent, Grid, Stack, Tab, Tabs } from "@mui/material"; +import { useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import * as yup from "yup"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; +import FileCopyIcon from "@mui/icons-material/FileCopy"; +import InfoIcon from "@mui/icons-material/Info"; +import GetItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm"; +import GetSubItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm"; +import GetItemInfo from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo"; +import ExitToAppIcon from "@mui/icons-material/ExitToApp"; +import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight"; +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import StyledForm from "@/core/components/StyledForm"; +import React from "react"; +import { TabPanel } from "@mui/lab"; + +const GashtCreateContent = ({ mutate, setOpen }) => { + const defaultValues = { + start_date: null, + end_date: null, + item_id: null, + road_patrol_id: null, + }; + + const validationSchema = yup + .object() + .shape({ + start_date: yup.string().nullable(), + end_date: yup.string().nullable(), + item_id: yup.string().nullable(), + road_patrol_id: yup.string().nullable(), + }) + .test("at-least-one", "وارد کردن مقدار ضروریست!!!", (values) => { + return (!!values.start_date && !!values.end_date) || !!values.item_id || !!values.road_patrol_id; + }); + + const { + control, + getValues, + watch, + register, + handleSubmit, + setValue, + formState: { errors, isSubmitting }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + }); + return ( + + + } label="انتخاب آیتم" /> + } label="انتخاب موضوع مشاهده شده" /> + + + + + + + + + + + + + + {tabState === 2 && ( + + )} + + + ); +}; +export default GashtCreateContent; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx new file mode 100644 index 0000000..ae14476 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx @@ -0,0 +1,38 @@ +"use client"; +import { Button, IconButton, useMediaQuery } from "@mui/material"; +import { useTheme } from "@emotion/react"; +import { useState } from "react"; +import AddRoadIcon from "@mui/icons-material/AddRoad"; +import GashtCreate from "./GashtCreate"; + +const ObservedGashtCreate = ({ mutate }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const [open, setOpen] = useState(false); + + const handleOpen = () => { + setOpen(true); + }; + + return ( + <> + {isMobile ? ( + + + + ) : ( + + )} + {open && } + + ); +}; +export default ObservedGashtCreate; diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditController.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditController.jsx index 423bb00..169170b 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditController.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditController.jsx @@ -1,29 +1,40 @@ -import { LinearProgress, Typography } from "@mui/material"; +import { Dialog, DialogTitle } from "@mui/material"; import EditFormContent from "./EditFormContent"; -import useRoadItemGetISubtems from "@/lib/hooks/useRoadItemGetISubtems"; +import { UPDATE_ROAD_ITEMS } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; -const EditController = ({ rowId, mutate, setOpenEditDialog, row }) => { - const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetISubtems(row.original?.item); - const subItem = subItemsList.find((SubItem) => SubItem.sub_item === row.original?.sub_item); +const EditController = ({ rowId, mutate, setOpenEditDialog, openEditDialog, row }) => { + const requestServer = useRequest({ notificationSuccess: true }); + + const HandleSubmit = async ({ result }) => { + const formData = new FormData(); + for (const [key, value] of Object.entries(result)) { + formData.append(key, value); + } + await requestServer(`${UPDATE_ROAD_ITEMS}/${rowId}`, "post", { + data: formData, + }) + .then((response) => { + mutate(); + setOpenEditDialog(false); + }) + .catch((error) => {}); + }; return ( - <> - {errorSubItemsList ? ( - - خطا در دریافت اطلاعات!!! - - ) : loadingSubItemsList ? ( - - ) : ( - - )} - + + ویرایش اطلاعات + + ); }; export default EditController; diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx index 92f7432..7bd5a49 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx @@ -1,215 +1,72 @@ -import { Button, DialogActions, DialogContent, Stack, TextField } from "@mui/material"; -import useRequest from "@/lib/hooks/useRequest"; -import { Controller, useForm } from "react-hook-form"; -import { yupResolver } from "@hookform/resolvers/yup"; -import { array, mixed, object, string } from "yup"; -import StyledForm from "@/core/components/StyledForm"; +import { LinearProgress, Typography } from "@mui/material"; import React from "react"; -import ImageUpload from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/ImageUpload"; -import MapInfoTwoMarker from "@/core/components/MapInfoTwoMarker"; -import MapInfoOneMarker from "@/core/components/MapInfoOneMarker"; -import { UPDATE_ROAD_ITEMS } from "@/core/utils/routes"; -import CarCode from "@/core/components/CarCode"; -import RahdarCode from "@/core/components/RahdarCode"; import useRoadItemGetISubtems from "@/lib/hooks/useRoadItemGetISubtems"; -import NumberField from "@/core/components/NumberField"; +import EditFormCreate from "@/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate"; -const validationSchema = object({ - amount: string().required("وارد کردن مقدار الزامیست!"), - cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"), - rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), - before_image: mixed() - .nullable() - .test("before-image-required", "لطفا عکس قبل از اقدام را بارگذاری کنید!", function (value) { - const { subItem } = this.options.context; - const needsImage = subItem?.needs_image === 1; - if (needsImage) { - return !!value; - } - return true; - }), - after_image: mixed() - .nullable() - .test("after-image-required", "لطفا عکس بعد از اقدام را بارگذاری کنید!", function (value) { - const { subItem } = this.options.context; - const needsImage = subItem?.needs_image === 1; - if (needsImage) { - return !!value; - } - return true; - }), - start_point: mixed() - .test("start-point-required", "لطفاً نقطه شروع را مشخص کنید!", function (value) { - return !!value; // چک می‌کند که مقدار موجود است - }) - .required("لطفاً نقطه شروع را مشخص کنید!"), - end_point: mixed().test("end-point-required", "لطفاً نقطه پایان را مشخص کنید!", function (value) { - const { subItem } = this.options.context; - const needsEndPoint = subItem?.needs_end_point === 1; - if (needsEndPoint) { - return !!value; // چک می‌کند که مقدار موجود است - } - return true; - }), -}); +const EditFormContent = ({ setOpenEditDialog, onSubmit, defaultData }) => { + const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetISubtems(defaultData?.item); + const subItem = subItemsList.find((SubItem) => SubItem.sub_item === defaultData?.sub_item); -const EditFormContent = ({ row, mutate, setOpenEditDialog, rowId, subItem }) => { const defaultValues = { - before_image: row.original?.files[0]?.full_path_for_fast_react || null, - after_image: row.original?.files[1]?.full_path_for_fast_react || null, - amount: row.original.sub_item_data || null, - start_point: { lat: row.original.start_lat || "", lng: row.original.start_lng || "" }, - end_point: { lat: row.original.end_lat || "", lng: row.original.end_lng || "" }, - cmms_machines: row.original.cmms_machines || null, - rahdaran_id: row.original.rahdaran || null, + before_image: defaultData?.files[0]?.full_path_for_fast_react || null, + after_image: defaultData?.files[1]?.full_path_for_fast_react || null, + amount: defaultData?.sub_item_data || null, + start_point: { lat: defaultData?.start_lat || "", lng: defaultData?.start_lng || "" }, + end_point: { lat: defaultData?.end_lat || "", lng: defaultData?.end_lng || "" }, + cmms_machines: defaultData?.cmms_machines || null, + rahdaran_id: defaultData?.rahdaran || null, }; - const requestServer = useRequest(); - const { - control, - getValues, - watch, - register, - handleSubmit, - setValue, - formState: { errors, isSubmitting }, - } = useForm({ - defaultValues, - resolver: yupResolver(validationSchema), - mode: "onBlur", - context: { subItem }, - }); + const onSubmitBase = (data) => { + let result = { ...data }; + (result.before_image === null || result.before_image === defaultValues.before_image) && + delete result.before_image; + (result.after_image === null || result.after_image === defaultValues.after_image) && delete result.after_image; + if (subItem.needs_end_point !== 1) { + delete result.end_point; + } else { + result.end_point = `${result.end_point.lat},${result.end_point.lng}`; + } - const onSubmit = async (data) => { - let endPoint; - let startPoint = `${data.start_point.lat},${data.start_point.lng}`; - subItem.needs_end_point === 1 && (endPoint = `${data.end_point.lat},${data.end_point.lng}`); - const formData = new FormData(); - subItem.needs_image === 1 && - data.before_image !== defaultValues.before_image && - formData.append("before_image", data.before_image); - subItem.needs_image === 1 && - data.after_image !== defaultValues.after_image && - formData.append("after_image", data.after_image); - formData.append("amount", data.amount); - data.cmms_machines.map((machine, index) => formData.append(`machines_id[${index}]`, machine.id)); - data.rahdaran_id.map((rahdar, index) => formData.append(`rahdaran_id[${index}]`, rahdar.id)); - formData.append("start_point", startPoint); - subItem.needs_end_point === 1 && formData.append("end_point", endPoint); + result.start_point = `${result.start_point.lat},${result.start_point.lng}`; - await requestServer(`${UPDATE_ROAD_ITEMS}/${rowId}`, "post", { - notificationSuccess: true, - data: formData, - }) - .then((res) => { - mutate(); - setOpenEditDialog(false); - }) - .catch((err) => {}); + result.rahdaran_id.forEach((rahdar, index) => { + result[`rahdaran_id[${index}]`] = rahdar.id; + }); + delete result.rahdaran_id; + + result.cmms_machines.forEach((cmms_machine, index) => { + result[`machines_id[${index}]`] = cmms_machine.id; + }); + delete result.cmms_machines; + + onSubmit({ + result, + data: { + ...data, + item_name: subItem.item_str, + sub_item_name: subItemsList.name, + }, + }); }; return ( <> - - - - - {subItem.needs_image === 1 ? ( - - ) : null} - - - { - if (!isNaN(event.target.value)) { - setValue("amount", event.target.value); - } else { - setValue("amount", watch("amount")); - } - }} - helperText={errors.amount ? errors.amount.message : null} - variant="outlined" - fullWidth - /> - - - { - return ( - field.onChange(value || [])} - inputValueDefault={row.original.cmms_machines} - multiple={true} - error={error} // اگر خطا وجود داشته باشد - /> - ); - }} - name={"cmms_machines"} - /> - - - { - return ( - field.onChange(value || [])} - error={error} - /> - ); - }} - name={"rahdaran_id"} - /> - - - {subItem.needs_end_point === 1 ? ( - - ) : ( - - )} - - - - - - - - + {errorSubItemsList ? ( + + خطا در دریافت اطلاعات!!! + + ) : loadingSubItemsList ? ( + + ) : ( + + )} ); }; diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx new file mode 100644 index 0000000..fef124f --- /dev/null +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx @@ -0,0 +1,171 @@ +import { Button, DialogActions, DialogContent, Stack } from "@mui/material"; +import ImageUpload from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/ImageUpload"; +import NumberField from "@/core/components/NumberField"; +import { Controller, useForm } from "react-hook-form"; +import CarCode from "@/core/components/CarCode"; +import RahdarCode from "@/core/components/RahdarCode"; +import MapInfoTwoMarker from "@/core/components/MapInfoTwoMarker"; +import MapInfoOneMarker from "@/core/components/MapInfoOneMarker"; +import StyledForm from "@/core/components/StyledForm"; +import React from "react"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { array, mixed, object, string } from "yup"; + +const validationSchema = object({ + amount: string().required("وارد کردن مقدار الزامیست!"), + cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"), + rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), + before_image: mixed() + .nullable() + .test("before-image-required", "لطفا عکس قبل از اقدام را بارگذاری کنید!", function (value) { + const { subItem } = this.options.context; + const needsImage = subItem?.needs_image === 1; + if (needsImage) { + return !!value; + } + return true; + }), + after_image: mixed() + .nullable() + .test("after-image-required", "لطفا عکس بعد از اقدام را بارگذاری کنید!", function (value) { + const { subItem } = this.options.context; + const needsImage = subItem?.needs_image === 1; + if (needsImage) { + return !!value; + } + return true; + }), + start_point: mixed() + .test("start-point-required", "لطفاً نقطه شروع را مشخص کنید!", function (value) { + return !!value; // چک می‌کند که مقدار موجود است + }) + .required("لطفاً نقطه شروع را مشخص کنید!"), + end_point: mixed().test("end-point-required", "لطفاً نقطه پایان را مشخص کنید!", function (value) { + const { subItem } = this.options.context; + const needsEndPoint = subItem?.needs_end_point === 1; + if (needsEndPoint) { + return !!value; + } + return true; + }), +}); + +const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, setOpenEditDialog }) => { + const { + control, + getValues, + watch, + register, + handleSubmit, + setValue, + formState: { errors, isSubmitting }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + context: { subItem }, + }); + return ( + + + + + {subItem.needs_image === 1 ? ( + + ) : null} + + + { + if (!isNaN(event.target.value)) { + setValue("amount", event.target.value); + } else { + setValue("amount", watch("amount")); + } + }} + helperText={errors.amount ? errors.amount.message : null} + variant="outlined" + fullWidth + /> + + + { + return ( + field.onChange(value || [])} + inputValueDefault={defaultData?.cmms_machines} + multiple={true} + error={error} // اگر خطا وجود داشته باشد + /> + ); + }} + name={"cmms_machines"} + /> + + + { + return ( + field.onChange(value || [])} + error={error} + /> + ); + }} + name={"rahdaran_id"} + /> + + + {subItem.needs_end_point === 1 ? ( + + ) : ( + + )} + + + + + + + + + ); +}; +export default EditFormCreate; diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/index.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/index.jsx index 888e166..9302918 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/EditForm/index.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/index.jsx @@ -19,19 +19,13 @@ const EditForm = ({ row, mutate, rowId }) => { - - ویرایش اطلاعات - - + ); }; diff --git a/src/components/dashboard/roadItems/operator/Toolbar.jsx b/src/components/dashboard/roadItems/operator/Toolbar.jsx index c98ae05..ae6691f 100644 --- a/src/components/dashboard/roadItems/operator/Toolbar.jsx +++ b/src/components/dashboard/roadItems/operator/Toolbar.jsx @@ -1,12 +1,14 @@ import PrintExcel from "./ExcelPrint"; import OperatorCreate from "./Actions/Create"; import { Stack } from "@mui/material"; +import ObservedGashtCreate from "./Actions/ObservedGashtCreate"; const Toolbar = ({ table, filterData, mutate }) => { return ( + {/**/} ); }; diff --git a/src/core/components/ActivityCodeLog.jsx b/src/core/components/ActivityCodeLog.jsx new file mode 100644 index 0000000..ef53b42 --- /dev/null +++ b/src/core/components/ActivityCodeLog.jsx @@ -0,0 +1,30 @@ +"use client"; +import useRequest from "@/lib/hooks/useRequest"; +import { useEffect } from "react"; +import { ACTIVITY_LOG } from "@/core/utils/routes"; + +const ActivityCodeLog = ({ activity_code }) => { + const requestServer = useRequest({ notificationShow: false }); + + useEffect(() => { + if (!activity_code) return; + + const fetchSubItems = async () => { + try { + await requestServer(ACTIVITY_LOG, "post", { + data: { + activityCode: activity_code, + }, + }); + } catch (error) { + console.error(error); // Always helpful to log the error for debugging. + } + }; + + fetchSubItems(); + }, [activity_code, requestServer]); + + return null; // Ensure the component still renders something. +}; + +export default ActivityCodeLog; diff --git a/src/core/components/CarCode.jsx b/src/core/components/CarCode.jsx index e765d24..8914acb 100644 --- a/src/core/components/CarCode.jsx +++ b/src/core/components/CarCode.jsx @@ -21,7 +21,10 @@ const CarCode = ({ carCode, setCarCode, inputValueDefault = "", error, multiple requestOptions: { signal: controller.signal }, }) .then((response) => { - setOptions(response.data.data || []); + const combinedArray = [...carCode, ...response.data.data]; + + const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values()); + setOptions(uniqueArray || []); }) .catch(() => { setOptions([]); @@ -38,7 +41,6 @@ const CarCode = ({ carCode, setCarCode, inputValueDefault = "", error, multiple fetchCarCodes(inputValue, controller); return () => controller.abort(); }, [inputValue]); - return ( requestOptions: { signal: controller.signal }, }) .then((response) => { - setOptions(response.data.data || []); + const combinedArray = [...rahdarsCode, ...response.data.data]; + const uniqueArray = Array.from(new Map(combinedArray.map((item) => [item.id, item])).values()); + setOptions(uniqueArray || []); }) .catch(() => { setOptions([]); diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 44434f8..6c26cd2 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -51,3 +51,6 @@ export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/delete"; export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/restore"; export const GET_CAR_LIST_SEARCH = api + "/api/v3/cmms_machines/search"; export const GET_RAHDARANS_LIST_SEARCH = api + "/api/v3/rahdaran/search"; + +// activity code log +export const ACTIVITY_LOG = api + "/api/v3/profile/add_activity"; From bc3db055b1d8c04ae455b49ff1803c3614d49602 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 4 Jan 2025 18:33:55 +0330 Subject: [PATCH 08/22] working on supervisor list --- .../Forms/CreatePatrol/PatrolDetail.jsx | 214 ++++++------------ .../Forms/CreatePatrol/PatrolDetailInfo.jsx | 147 ++++++++++++ .../Forms/CreatePatrol/PatrolForms.jsx | 105 +++++++-- .../Forms/CreatePatrol/PatrolMapFeatures.jsx | 38 ++++ .../CreatePatrol/PatrolResultCodeErrors.jsx | 25 ++ .../Forms/CreatePatrol/SuperVisorsDetail.jsx | 31 ++- .../operator/Forms/CreatePatrol/index.jsx | 5 +- src/core/components/CarCode.jsx | 17 +- src/core/utils/routes.js | 5 +- 9 files changed, 398 insertions(+), 189 deletions(-) create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolMapFeatures.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolResultCodeErrors.jsx diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx index d8cfee6..442640c 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx @@ -1,19 +1,6 @@ "use client"; -import { - Box, - Button, - Card, - CardActions, - CardContent, - Chip, - Divider, - IconButton, - InputAdornment, - Slide, - Stack, - Typography -} from "@mui/material"; +import {Box, Button, Chip, Divider, IconButton, InputAdornment, Stack} from "@mui/material"; import React, {useEffect, useState} from "react"; import CarCode from "@/core/components/CarCode"; import SearchIcon from '@mui/icons-material/Search'; @@ -24,46 +11,51 @@ import ClearIcon from "@mui/icons-material/Clear"; import moment from "jalali-moment"; import dynamic from "next/dynamic"; import MapLoading from "@/core/components/MapLayer/Loading"; -import LocalGasStationIcon from '@mui/icons-material/LocalGasStation'; -import DirectionsCarFilledIcon from '@mui/icons-material/DirectionsCarFilled'; -import WatchLaterIcon from '@mui/icons-material/WatchLater'; -import AddRoadIcon from '@mui/icons-material/AddRoad'; -import ShareLocationIcon from '@mui/icons-material/ShareLocation'; -import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; -import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight"; +import {Controller} from "react-hook-form"; +import {GET_FMS_DATA} from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import PatrolDetailInfo from "./PatrolDetailInfo"; +import PatrolResultCodeErrors from "./PatrolResultCodeErrors"; const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { loading: () => , ssr: false, }); -const PatrolDetail = ({tabState, setTabState}) => { - const [patrolFounded, setPatrolFounded] = useState(false); - const [carCode, setCarCode] = useState(null); - const [dateFrom, setDateFrom] = useState(null); - const [dateTo, setDateTo] = useState(null); +const PatrolDetail = ({control, watch, setValue, tabState, setTabState}) => { + const requestServer = useRequest({notificationSuccess: true}); + const [patrolResultStatus, setPatrolResultStatus] = useState(null) const [readyToRequest, setReadyToRequest] = useState(false); - const [data, setData] = useState({ - machine_code: "12-213-21", - distance: "23", - time: "04:45", - stop: "2", - fuel_amount: "21" - }) + const [patrolData, setPatrolData] = useState(null); - const requestPatrolInfo = () => { - setPatrolFounded(true) - setReadyToRequest(false) + const requestPatrolInfo = async () => { + const formData = new FormData(); + formData.append("machineCode", watch("road_patrol_machines_id").machine_code); + formData.append("startDT", moment(watch("start_time")).format("YYYY-MM-DDTHH:mm")); + formData.append("endDT", moment(watch("end_time")).format("YYYY-MM-DDTHH:mm")); + await requestServer(GET_FMS_DATA, "post", { + data: formData, + }).then((response) => { + const data = response.data.data; + setPatrolData({ + ...data, + roadPatrolMachinesId: watch("road_patrol_machines_id"), + start_time: watch("start_time"), + end_time: watch("end_time") + }); + setPatrolResultStatus(data.resultCode); + }).catch((error) => { + }); } useEffect(() => { - if (carCode !== null && dateFrom !== null && dateTo !== null) { - setReadyToRequest(true); - } else { - setReadyToRequest(false); - } - }, [carCode, dateFrom, dateTo]); + const roadPatrolMachinesId = watch("road_patrol_machines_id"); + const startTime = watch("start_time"); + const endTime = watch("end_time"); + const isReady = roadPatrolMachinesId !== null && startTime !== "" && endTime !== ""; + setReadyToRequest(isReady); + }, [watch("road_patrol_machines_id"), watch("start_time"), watch("end_time")]); return ( { }} > - - - + + { + return ( + field.onChange(value || [])} + error={error} + /> + ); + }} + name={"road_patrol_machines_id"} + /> + - { - const date = new Date(dateFrom); + maxDateTime={watch("end_time") ? new Date(watch("end_time")) : null} + onChange={(start_time) => { + const date = new Date(start_time); const formattedDate = moment(date).locale("en").format("YYYY-MM-DD HH:mm"); - setDateFrom(formattedDate); + setValue("start_time", formattedDate); }} slotProps={{ textField: { @@ -105,7 +109,7 @@ const PatrolDetail = ({tabState, setTabState}) => { size="small" onClick={(event) => { event.stopPropagation(); - setDateFrom(null); + setValue("start_time", ""); }} sx={{ color: "#bfbfbf", @@ -123,15 +127,15 @@ const PatrolDetail = ({tabState, setTabState}) => { }, }} label="تاریخ و ساعت شروع گشت" /> - { - const date = new Date(dateTo); + minDateTime={watch("start_time") ? new Date(watch("start_time")) : null} + onChange={(end_time) => { + const date = new Date(end_time); const formattedDate = moment(date).locale("en").format("YYYY-MM-DD HH:mm"); - setDateTo(formattedDate); + setValue("end_time", formattedDate); }} slotProps={{ textField: { @@ -144,7 +148,7 @@ const PatrolDetail = ({tabState, setTabState}) => { size="small" onClick={(event) => { event.stopPropagation(); - setDateTo(null); + setValue("end_time", ""); }} sx={{ color: "#bfbfbf", @@ -170,99 +174,9 @@ const PatrolDetail = ({tabState, setTabState}) => { - {patrolFounded ? - - - - - }/> - - - {data.machine_code} - - - - }/> - - - {data.time} - - - - }/> - - - {data.distance} - - - - }/> - - - {data.stop} - - - - }/> - - - {data.fuel_amount} - - - - - - - - - - - - - - - - - - - - - : - - - ابتدا اطلاعات بالا را تکمیل نمایید - - } + {patrolResultStatus === 0 ? + : + } ); }; diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx new file mode 100644 index 0000000..6ad3417 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx @@ -0,0 +1,147 @@ +"use client"; + +import {Box, Button, Card, CardActions, CardContent, Chip, Divider, Slide, Stack, Typography} from "@mui/material"; +import React from "react"; +import dynamic from "next/dynamic"; +import MapLoading from "@/core/components/MapLayer/Loading"; +import LocalGasStationIcon from '@mui/icons-material/LocalGasStation'; +import DirectionsCarFilledIcon from '@mui/icons-material/DirectionsCarFilled'; +import WatchLaterIcon from '@mui/icons-material/WatchLater'; +import QueryBuilderIcon from '@mui/icons-material/QueryBuilder'; +import AddRoadIcon from '@mui/icons-material/AddRoad'; +import ShareLocationIcon from '@mui/icons-material/ShareLocation'; +import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import QrCode2Icon from '@mui/icons-material/QrCode2'; +import moment from "jalali-moment"; +import PatrolMapFeatures from "./PatrolMapFeatures"; + +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); + +const PatrolDetailInfo = ({patrolData, tabState, setTabState}) => { + const bound = patrolData.stopPoints.map(point => [point.latitude, point.longitude]); + + return ( + + + + + + }/> + + + {Math.floor(patrolData.accOnDuration / 60)} دقیقه + + + + }/> + + + {patrolData.roadPatrolMachinesId.car_name} + + + + }/> + + + {patrolData.roadPatrolMachinesId.machine_code} + + + + }/> + + + {patrolData.roadPatrolMachinesId.plak_number} + + + + }/> + + + {moment(patrolData.start_time).locale("fa").format("HH:mm | YYYY/MM/DD")} + + + + }/> + + + {moment(patrolData.end_time).locale("fa").format("HH:mm | YYYY/MM/DD")} + + + + }/> + + + {(patrolData.mileage / 1000).toFixed(1)} کیلومتر + + + + }/> + + + {Math.round(patrolData.fuelConsumption * 10) / 10} لیتر + + + + }/> + + + {patrolData.stopPoints.length} مورد + + + + + + + + + {patrolData.stopPoints.map((stopPoint, index) => { + return ( + + + + ) + })} + + + + + + + + + + + + + ); +}; + +export default PatrolDetailInfo; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx index b8f681e..90d3c67 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx @@ -3,16 +3,19 @@ import {Box, DialogContent, Tab, Tabs, useMediaQuery} from "@mui/material"; import {useTheme} from "@emotion/react"; import React, {useEffect, useState} from "react"; -import TapAndPlayIcon from '@mui/icons-material/TapAndPlay'; import TaxiAlertIcon from '@mui/icons-material/TaxiAlert'; import EngineeringIcon from '@mui/icons-material/Engineering'; import HandymanIcon from '@mui/icons-material/Handyman'; import VerifiedIcon from '@mui/icons-material/Verified'; import PatrolTimeLine from "./PatrolTimeLine"; -import PhoneValidation from "./PhoneValidation"; import PatrolDetail from "./PatrolDetail"; import SuperVisorsDetail from "./SuperVisorsDetail"; import ActionsDuringPatrol from "./ActionsDurigPatrol"; +import {array, object, string} from "yup"; +import {useForm} from "react-hook-form"; +import {yupResolver} from "@hookform/resolvers/yup"; +import StyledForm from "@/core/components/StyledForm"; +import useRequest from "@/lib/hooks/useRequest"; function TabPanel(props) { const {children, value, index} = props; @@ -24,7 +27,32 @@ function TabPanel(props) { ); } -const PatrolForms = () => { +const defaultValues = { + road_patrol_rahdaran_id: null, + road_patrol_machines_id: null, + start_time: "", + end_time: "", + stop_points: null, + vehicle_runtime: "", + fuel_consumption: "", + distance: "", + observed_items: null +}; + +const validationSchema = object({ + road_patrol_rahdaran_id: array().required("حداقل یک راهدار باید وارد کنید!"), + road_patrol_machines_id: array().required("وارد کردن کد خودرو الزامیست!").min(1, "وارد کردن کد خودرو الزامیست!"), + start_time: string().required("لطفا زمان شروع گشت را انتخاب کنید!"), + end_time: string().required("لطفا زمان پایان گشت را انتخاب کنید!"), + stop_points: array().required("وجود نقاط توقف اجباری است!").min(1, "حداقل یک نقطه توقف باید وجود داشته باشد!"), + vehicle_runtime: string().required("وجود میزان زمان روشن بودن خودرو الزامیست!"), + fuel_consumption: string().required("وجود مقدار سوخت مصرفی الزامیست!"), + distance: string().required("وارد کردن مقدار الزامیست!"), + observed_items: array().required("وجود نقاط توقف اجباری است!").min(1, "حداقل یک نقطه توقف باید وجود داشته باشد!"), +}); + +const PatrolForms = ({mutate}) => { + const requestServer = useRequest({notificationSuccess: true}); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("md")); const [tabState, setTabState] = useState(0); @@ -40,9 +68,45 @@ const PatrolForms = () => { } }, [tabState]); + const { + control, + watch, + getValues, + register, + handleSubmit, + setValue, + resetField, + formState: {errors, isSubmitting}, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur" + }); + + const onSubmit = async (data) => { + console.log("data", data); + const formData = new FormData(); + // formData.append("road_patrol_rahdaran_id", myData); + // formData.append("road_patrol_machines_id", myData); + // formData.append("start_time", moment(new Date(myData)).format("YYYY-MM-DD")); + // formData.append("end_time", moment(new Date(myData)).format("YYYY-MM-DD")); + // formData.append("stop_points", myData); + // formData.append("vehicle_runtime", myData); + // formData.append("fuel_consumption", myData); + // formData.append("distance", myData); + // formData.append("observed_items", myData); + // try { + // await requestServer(CREATE_PATROL, "post", { + // data: formData, + // }); + // mutate(); + // handleClose(); + // } catch (error) { + // } + }; return ( - <> + { backgroundColor: "#efefef", }} > - = 0)} icon={} label="تایید هویت"> - = 1)} icon={} label="مشخصات گشت"> - = 2)} icon={} label="مشخصات راهداران"> - = 3)} icon={} label="اقدامات حین گشت"> - = 4)} icon={} label="تکمیل درخواست"> + = 0)} icon={} label="مشخصات گشت"> + = 1)} icon={} label="مشخصات راهداران"> + = 2)} icon={} label="اقدامات حین گشت"> + = 3)} icon={} label="تکمیل درخواست"> - + - + - - - - + <>taiidie @@ -85,7 +158,7 @@ const PatrolForms = () => { )} - + ); }; export default PatrolForms; diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolMapFeatures.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolMapFeatures.jsx new file mode 100644 index 0000000..a72ce56 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolMapFeatures.jsx @@ -0,0 +1,38 @@ +"use client"; + +import {Typography} from "@mui/material"; +import React, {useRef} from "react"; +import {Marker, Popup} from "react-leaflet"; +import AzmayeshIcon from "@/assets/images/examine_marker.png"; + +const PatrolMapFeatures = ({stopPoint}) => { + const position = [stopPoint.latitude, stopPoint.longitude]; + const mapPatrolMarker = useRef(); + const createCustomIcon = (size, iconUrl) => { + return L.icon({ + iconUrl: iconUrl, + iconSize: size, + iconAnchor: [size[0] / 2, size[1]], + popupAnchor: [0, -size[1]], + }); + }; + + return ( + + + مدت زمان + توقف: {stopPoint.duration} ثانیه + + + ); +}; + +export default PatrolMapFeatures; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolResultCodeErrors.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolResultCodeErrors.jsx new file mode 100644 index 0000000..c470da6 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolResultCodeErrors.jsx @@ -0,0 +1,25 @@ +"use client"; + +import {Box, Typography} from "@mui/material"; +import React from "react"; + +const PatrolResultCodeErrors = ({ResultCode}) => { + const errorMessages = { + [-1]: "نام کاربری یا کلمه عبور صحیح نمیباشد", + [-2]: "ردیاب به خودرو انتخابی متصل نیست", + [-3]: "کاربر دسترسی لازم به اطلاعات خودرو انتخابی را ندارد", + [-4]: "خطای درخواست مکرر", + }; + + const message = errorMessages[ResultCode] || "ابتدا اطلاعات بالا را تکمیل نمایید"; + + return ( + + + {message} + + + ); +}; + +export default PatrolResultCodeErrors; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx index cf53f07..5586a97 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx @@ -1,22 +1,22 @@ "use client"; -import {Box, Button, Chip, Divider, Grid, Typography} from "@mui/material"; +import {Box, Button, Chip, Divider, Grid, Stack, Typography} from "@mui/material"; import SaveAltIcon from '@mui/icons-material/SaveAlt'; import React, {useEffect, useState} from "react"; import RahdarCode from "@/core/components/RahdarCode"; import SuperVisorInfo from "@/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorInfo"; import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight"; import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; +import {Controller} from "react-hook-form"; -const SuperVisorsDetail = ({tabState, setTabState}) => { +const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) => { const [SuperVisorList, setSuperVisorList] = useState([]); - const [rahdarsCode, setRahdarsCode] = useState(null); const [readyToRequest, setReadyToRequest] = useState(false); const requestPatrolInfo = () => { - setSuperVisorList((prev) => [...prev, rahdarsCode]); + setSuperVisorList((prev) => [...prev, watch("road_patrol_rahdaran_id")]); setReadyToRequest(false); - setRahdarsCode(null); + setValue("road_patrol_rahdaran_id", null); } const deleteSuperVisor = (id) => { @@ -24,8 +24,8 @@ const SuperVisorsDetail = ({tabState, setTabState}) => { }; useEffect(() => { - setReadyToRequest(rahdarsCode != null); - }, [rahdarsCode]); + setReadyToRequest(watch("road_patrol_rahdaran_id") != null); + }, [watch("road_patrol_rahdaran_id")]); return ( { - + + { + return ( + field.onChange(value || [])} + error={error} + multiple={false} + /> + ); + }} + name={"road_patrol_rahdaran_id"} + /> + + + ); }; diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/EditActionDuringPatrol.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/EditActionDuringPatrol.jsx new file mode 100644 index 0000000..3098d06 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/EditActionDuringPatrol.jsx @@ -0,0 +1,52 @@ +"use client"; + +import React, {useState} from "react"; +import dynamic from "next/dynamic"; +import MapLoading from "@/core/components/MapLayer/Loading"; +import {Dialog, DialogTitle, IconButton} from "@mui/material"; +import EditIcon from "@mui/icons-material/Edit"; +import EditFormContent from "@/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent"; + +const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { + loading: () => , + ssr: false, +}); + +const EditActionDuringPatrol = ({action}) => { + + console.log("action", action) + + const [open, setOpen] = useState(false); + + const handleOpen = () => { + setOpen(true); + }; + + const HandleSubmit = async (data, result) => { + setActionsList((prev) => [...prev, data]); + setOpen(false); + } + + return ( + <> + + + + + ویرایش اطلاعات + + + + ); +}; + +export default EditActionDuringPatrol; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx index 6ad3417..f7b8f00 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetailInfo.jsx @@ -10,6 +10,7 @@ import WatchLaterIcon from '@mui/icons-material/WatchLater'; import QueryBuilderIcon from '@mui/icons-material/QueryBuilder'; import AddRoadIcon from '@mui/icons-material/AddRoad'; import ShareLocationIcon from '@mui/icons-material/ShareLocation'; +import ElectricCarIcon from '@mui/icons-material/ElectricCar'; import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft"; import QrCode2Icon from '@mui/icons-material/QrCode2'; import moment from "jalali-moment"; @@ -36,65 +37,65 @@ const PatrolDetailInfo = ({patrolData, tabState, setTabState}) => { }}> - }/> + }/> - + {Math.floor(patrolData.accOnDuration / 60)} دقیقه }/> - + {patrolData.roadPatrolMachinesId.car_name} }/> - + {patrolData.roadPatrolMachinesId.machine_code} }/> - + {patrolData.roadPatrolMachinesId.plak_number} }/> - + {moment(patrolData.start_time).locale("fa").format("HH:mm | YYYY/MM/DD")} }/> - + {moment(patrolData.end_time).locale("fa").format("HH:mm | YYYY/MM/DD")} }/> - + {(patrolData.mileage / 1000).toFixed(1)} کیلومتر }/> - + {Math.round(patrolData.fuelConsumption * 10) / 10} لیتر }/> - + {patrolData.stopPoints.length} مورد diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx index 90d3c67..fdafddf 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx @@ -55,7 +55,7 @@ const PatrolForms = ({mutate}) => { const requestServer = useRequest({notificationSuccess: true}); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("md")); - const [tabState, setTabState] = useState(0); + const [tabState, setTabState] = useState(2); const [activeUpTo, setActiveUpTo] = useState(0); const handleChangeTab = (event, newValue) => { diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx index 5586a97..e1b8d43 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/SuperVisorsDetail.jsx @@ -44,10 +44,11 @@ const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) => { + console.log("field.value", field.value) return ( field.onChange(value || [])} + rahdarsCode={field.value} + setRahdarsCode={(value) => field.onChange(value)} error={error} multiple={false} /> From fed5422c59ac557a305863b162003f5300b18d24 Mon Sep 17 00:00:00 2001 From: Amin Ghasempoor Date: Sun, 5 Jan 2025 09:52:54 +0000 Subject: [PATCH 13/22] Bugfix/unit pass --- .../operator/Actions/Create/Forms/CreateFormContent.jsx | 8 ++++---- .../operator/RowActions/EditForm/EditFormContent.jsx | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx index d6311e9..7f47a7d 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; -import { array, mixed, object, string } from "yup"; +import { array, mixed, number, object, string } from "yup"; import { useTheme } from "@emotion/react"; import useRequest from "@/lib/hooks/useRequest"; import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material"; @@ -40,8 +40,8 @@ const defaultValues = { end_point: "", }; const validationSchema = object({ - item_id: string().required("نوع آیتم را مشخص کنید!"), - sub_item_id: string().required("موضوع مشاهده شده را مشخص کنید!"), + item_id: number().required("نوع آیتم را مشخص کنید!"), + sub_item_id: number().required("موضوع مشاهده شده را مشخص کنید!"), amount: string().required("وارد کردن مقدار الزامیست!"), cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"), rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), // بررسی حداقل یک آیتم, @@ -133,7 +133,6 @@ const CreateFormContent = ({ setOpen, onSubmit }) => { mode: "onBlur", context: { subItemsList }, }); - const onSubmitBase = (data) => { let result = { ...data }; @@ -177,6 +176,7 @@ const CreateFormContent = ({ setOpen, onSubmit }) => { ...data, item_name: itemsList.name, sub_item_name: subItemsList.name, + unit_fa: subItemsList.unit, }, }); }; diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx index 095c706..620f052 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx @@ -46,6 +46,7 @@ const EditFormContent = ({ setOpenEditDialog, onSubmit, defaultData }) => { ...data, item_name: subItem.item_str, sub_item_name: subItemsList.name, + unit_fa: subItemsList.unit, }, }); }; From 58cd380c649f05224aa6dfe5440fbbb8e4430ef9 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Sun, 5 Jan 2025 14:22:50 +0330 Subject: [PATCH 14/22] better performance --- src/core/components/ActivityCodeLog.jsx | 34 +++++++++++++++---------- src/core/middlewares/withPermission.js | 12 +++++++-- src/lib/hooks/usePermissions.js | 2 +- src/lib/hooks/useSidebarBadge.js | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/core/components/ActivityCodeLog.jsx b/src/core/components/ActivityCodeLog.jsx index ef53b42..cf284e6 100644 --- a/src/core/components/ActivityCodeLog.jsx +++ b/src/core/components/ActivityCodeLog.jsx @@ -1,30 +1,36 @@ "use client"; + +import { useEffect, useState, memo } from "react"; import useRequest from "@/lib/hooks/useRequest"; -import { useEffect } from "react"; import { ACTIVITY_LOG } from "@/core/utils/routes"; -const ActivityCodeLog = ({ activity_code }) => { +const ActivityCodeLog = memo(({ activity_code }) => { const requestServer = useRequest({ notificationShow: false }); + const [hasLogged, setHasLogged] = useState(false); useEffect(() => { - if (!activity_code) return; + if (!activity_code || hasLogged) return; - const fetchSubItems = async () => { + const controller = new AbortController(); + + const fetchActivityLog = async () => { try { await requestServer(ACTIVITY_LOG, "post", { - data: { - activityCode: activity_code, - }, + data: { activityCode: activity_code }, + signal: controller.signal, }); - } catch (error) { - console.error(error); // Always helpful to log the error for debugging. - } + setHasLogged(true); + } catch (error) {} }; - fetchSubItems(); - }, [activity_code, requestServer]); + fetchActivityLog(); - return null; // Ensure the component still renders something. -}; + return () => { + controller.abort(); + }; + }, [activity_code, hasLogged, requestServer]); + + return null; +}); export default ActivityCodeLog; diff --git a/src/core/middlewares/withPermission.js b/src/core/middlewares/withPermission.js index c6e3661..0da81c9 100644 --- a/src/core/middlewares/withPermission.js +++ b/src/core/middlewares/withPermission.js @@ -2,16 +2,24 @@ import { Box, Typography } from "@mui/material"; import { usePermissions } from "@/lib/hooks/usePermissions"; +import { useEffect, useState } from "react"; function WithPermission({ children, permission_name }) { const { data, error, isLoading } = usePermissions(); + const [cachedData, setCachedData] = useState(null); - if (error || isLoading || !data || !permission_name) { + useEffect(() => { + if (data) { + setCachedData(data); + } + }, [data]); + + if (error || isLoading || !cachedData || !permission_name) { return null; } const hasPermission = - permission_name.includes("all") || permission_name.some((permission) => data.includes(permission)); + permission_name.includes("all") || permission_name.some((permission) => cachedData.includes(permission)); if (!hasPermission) { return ( diff --git a/src/lib/hooks/usePermissions.js b/src/lib/hooks/usePermissions.js index 004ff6d..3fb4921 100644 --- a/src/lib/hooks/usePermissions.js +++ b/src/lib/hooks/usePermissions.js @@ -14,5 +14,5 @@ export const usePermissions = () => { } }; - return useSWR(GET_PERMISSIONS_ROUTE, fetcher, { keepPreviousData: true }); + return useSWR(GET_PERMISSIONS_ROUTE, fetcher, { keepPreviousData: true, dedupingInterval: 30000 }); }; diff --git a/src/lib/hooks/useSidebarBadge.js b/src/lib/hooks/useSidebarBadge.js index 621ce55..2befed2 100644 --- a/src/lib/hooks/useSidebarBadge.js +++ b/src/lib/hooks/useSidebarBadge.js @@ -14,5 +14,5 @@ export const useSidebarBadge = () => { } }; - return useSWR(GET_SIDEBAR_BADGE_ROUTE, fetcher, { keepPreviousData: true }); + return useSWR(GET_SIDEBAR_BADGE_ROUTE, fetcher, { keepPreviousData: true, dedupingInterval: 30000 }); }; From fa79ee736fb1e5d7d6fda9c77016cf92c2c6a71c Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Mon, 6 Jan 2025 10:51:57 +0330 Subject: [PATCH 15/22] change icon size --- src/core/components/MapInfoTwoMarker.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/components/MapInfoTwoMarker.jsx b/src/core/components/MapInfoTwoMarker.jsx index daac893..5034cb7 100644 --- a/src/core/components/MapInfoTwoMarker.jsx +++ b/src/core/components/MapInfoTwoMarker.jsx @@ -23,8 +23,8 @@ const createCustomIcon = (size, iconUrl, labelText, color) => {
`, - iconSize: [100, 50], // Adjust icon size to fit your content - iconAnchor: [50, 25], // Adjust to position the marker correctly + iconSize: [50, 50], + iconAnchor: [25, 50], }); } return L.icon({ @@ -111,6 +111,7 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { setStartPosition({ lat: center.lat, lng: center.lng }); setIsStartLocked(true); setStartIconColor("#1CAC66"); + map.panBy([25, 25]) } }, }} @@ -182,6 +183,13 @@ const MapInteraction = ({ setValue, startLat, startLng, endLat, endLng }) => { setEndPosition({ lat: center.lat, lng: center.lng }); setIsEndLocked(true); setEndIconColor("#D13131"); + map.fitBounds( + [ + startPosition, + map.getCenter(), + ], + { paddingTopLeft: [16, 16], paddingBottomRight: [16, 16] } + ); } }, }} From 3f32a65cdbdad36be36339efbdd472eee078fad6 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Mon, 6 Jan 2025 10:52:39 +0330 Subject: [PATCH 16/22] change icon size --- src/core/components/MapInfoOneMarker.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/components/MapInfoOneMarker.jsx b/src/core/components/MapInfoOneMarker.jsx index e456244..a0817bf 100644 --- a/src/core/components/MapInfoOneMarker.jsx +++ b/src/core/components/MapInfoOneMarker.jsx @@ -23,8 +23,8 @@ const createCustomIcon = (size, iconUrl, labelText, color) => {
`, - iconSize: [100, 50], // Adjust icon size to fit your content - iconAnchor: [50, 25], // Adjust to position the marker correctly + iconSize: [50, 50], + iconAnchor: [25, 50], }); } From 4747802e8aad987c8d7fb17f5ce3098ede65686a Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Mon, 6 Jan 2025 10:55:51 +0330 Subject: [PATCH 17/22] change dedupingInterval to 10s --- src/lib/hooks/useSidebarBadge.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/hooks/useSidebarBadge.js b/src/lib/hooks/useSidebarBadge.js index 2befed2..29e5fed 100644 --- a/src/lib/hooks/useSidebarBadge.js +++ b/src/lib/hooks/useSidebarBadge.js @@ -14,5 +14,5 @@ export const useSidebarBadge = () => { } }; - return useSWR(GET_SIDEBAR_BADGE_ROUTE, fetcher, { keepPreviousData: true, dedupingInterval: 30000 }); + return useSWR(GET_SIDEBAR_BADGE_ROUTE, fetcher, { keepPreviousData: true, dedupingInterval: 10000 }); }; From ae9b4787c58d218bfddae96430e862abf85c5828 Mon Sep 17 00:00:00 2001 From: Amin Ghasempoor Date: Mon, 6 Jan 2025 08:53:41 +0000 Subject: [PATCH 18/22] Feature/observed gasht create --- .../Create/Forms/CreateFormContent.jsx | 9 +- .../Actions/Create/Forms/GetItemInfo.jsx | 1 - .../ObservedGashtCreate/GashtCreate.jsx | 6 - .../GashtCreateContent.jsx | 123 +++++++--- .../LocationForm/LocationFormContent.jsx | 31 +++ .../LocationForm/index.jsx | 36 +++ .../RowActions/CompleteItem.jsx | 231 ++++++++++++++++++ .../RowActions/GetItemInfo.jsx | 28 +++ .../RowActions/ImageUpload.jsx | 131 ++++++++++ .../RowActions/PreviousStatesInfo.jsx | 43 ++++ .../RowActions/SubItemForm/index.jsx | 21 ++ .../ObservedGashtCreate/RowActions/index.jsx | 11 + .../ObservedGashtCreate/SearchItemInfo.jsx | 42 ++++ .../ObservedGashtCreate/SearchItems.jsx | 96 ++++++++ .../Actions/ObservedGashtCreate/TableInfo.jsx | 115 +++++++++ .../Actions/ObservedGashtCreate/index.jsx | 6 +- .../roadItems/operator/OperatorList.jsx | 41 ++-- .../RowActions/DescriptionForm/index.jsx | 2 +- .../RowActions/EditForm/EditFormContent.jsx | 4 +- .../RowActions/EditForm/EditFormCreate.jsx | 2 +- .../LocationForm/LocationFormContent.jsx | 2 +- .../dashboard/roadItems/operator/Toolbar.jsx | 2 +- .../RowActions/DeleteForm/DeleteContent.jsx | 4 +- .../LocationForm/LocationFormContent.jsx | 2 +- .../roadItems/supervisor/SupervisorList.jsx | 14 +- .../roadPatrols/operator/OperatorList.jsx | 75 ++++-- .../MachinesCodeForm/MachinesCodeContent.jsx | 55 +++++ .../RowActions/MachinesCodeForm/index.jsx | 43 ++++ .../RahdaranForm/RahdaranContent.jsx | 48 ++++ .../RowActions/RahdaranForm/index.jsx | 38 +++ .../MachinesCodeForm/MachinesCodeContent.jsx | 55 +++++ .../RowActions/MachinesCodeForm/index.jsx | 43 ++++ .../RahdaranForm/RahdaranContent.jsx | 48 ++++ .../RowActions/RahdaranForm/index.jsx | 38 +++ .../roadPatrols/supervisor/SupervisorList.jsx | 77 ++++-- src/core/components/DataTable/Main.js | 35 +-- src/core/components/MuiDatePicker.jsx | 8 +- src/core/components/MuiTimePicker.jsx | 8 +- src/core/utils/routes.js | 1 + 39 files changed, 1427 insertions(+), 148 deletions(-) create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/LocationFormContent.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/index.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/CompleteItem.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/GetItemInfo.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/ImageUpload.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/PreviousStatesInfo.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/SubItemForm/index.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/index.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItemInfo.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItems.jsx create mode 100644 src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/TableInfo.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/MachinesCodeContent.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/index.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/RahdaranContent.jsx create mode 100644 src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/index.jsx create mode 100644 src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/MachinesCodeContent.jsx create mode 100644 src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/index.jsx create mode 100644 src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/RahdaranContent.jsx create mode 100644 src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/index.jsx diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx index 7f47a7d..db106e3 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx @@ -133,7 +133,7 @@ const CreateFormContent = ({ setOpen, onSubmit }) => { mode: "onBlur", context: { subItemsList }, }); - const onSubmitBase = (data) => { + const onSubmitBase = async (data) => { let result = { ...data }; if (result.before_image === null) { @@ -170,7 +170,7 @@ const CreateFormContent = ({ setOpen, onSubmit }) => { }); delete result.cmms_machines; - onSubmit({ + await onSubmit({ result, data: { ...data, @@ -190,7 +190,8 @@ const CreateFormContent = ({ setOpen, onSubmit }) => { variant={`${isMobile ? "scrollable" : "fullWidth"}`} sx={{ display: "flex", - justifyContent: "space-around", + justifyContent: "center", + alignItems: "center", width: "100%", backgroundColor: "#efefef", }} @@ -237,7 +238,7 @@ const CreateFormContent = ({ setOpen, onSubmit }) => { - ); }; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx index d2ff576..a37e36f 100644 --- a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/GashtCreateContent.jsx @@ -1,28 +1,46 @@ -import { Box, Button, DialogActions, DialogContent, Grid, Stack, Tab, Tabs } from "@mui/material"; +import { Box, Button, DialogActions, DialogContent, Tab, Tabs } from "@mui/material"; import { useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; -import MuiDatePicker from "@/core/components/MuiDatePicker"; import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; import FileCopyIcon from "@mui/icons-material/FileCopy"; -import InfoIcon from "@mui/icons-material/Info"; -import GetItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm"; -import GetSubItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm"; -import GetItemInfo from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo"; import ExitToAppIcon from "@mui/icons-material/ExitToApp"; import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight"; import BeenhereIcon from "@mui/icons-material/Beenhere"; import StyledForm from "@/core/components/StyledForm"; -import React from "react"; -import { TabPanel } from "@mui/lab"; +import React, { useState } from "react"; +import SearchItemInfo from "./SearchItemInfo"; +import moment from "jalali-moment"; +import GetItemInfo from "./RowActions/GetItemInfo"; + +function TabPanel(props) { + const { children, value, index } = props; + return ( + + ); +} + +const defaultValues = { + start_date: moment(new Date()).format("YYYY-MM-DD"), + end_date: moment(new Date()).format("YYYY-MM-DD"), + item_id: "", + road_patrol_id: "", +}; + +const defaultFilter = [ + { value: `${defaultValues.item_id}`, datatype: "text", id: "item_id", fn: "equals" }, + { value: `${defaultValues.road_patrol_id}`, datatype: "text", id: "road_patrol_id", fn: "equals" }, + { value: `${defaultValues.start_date}`, datatype: "date", id: "roadPatrol.start_time", fn: "equals" }, + { value: `${defaultValues.end_date}`, datatype: "date", id: "roadPatrol.end_time", fn: "equals" }, +]; const GashtCreateContent = ({ mutate, setOpen }) => { - const defaultValues = { - start_date: null, - end_date: null, - item_id: null, - road_patrol_id: null, - }; + const [tabState, setTabState] = useState(0); + const [itemInfo, setItemInfo] = useState(null); + const [submitCompleteForm, setSubmitCompleteForm] = useState(false); + const [specialFilter, setSpecialFilter] = useState(defaultFilter); const validationSchema = yup .object() @@ -36,6 +54,21 @@ const GashtCreateContent = ({ mutate, setOpen }) => { return (!!values.start_date && !!values.end_date) || !!values.item_id || !!values.road_patrol_id; }); + const handleChangeTab = (event, newValue) => { + setTabState(newValue); + }; + const handleClose = () => { + setOpen(false); + }; + + const handlePrev = () => { + if (tabState === 0) { + handleClose(); + } else { + setTabState(tabState - 1); + } + }; + const { control, getValues, @@ -49,41 +82,53 @@ const GashtCreateContent = ({ mutate, setOpen }) => { resolver: yupResolver(validationSchema), mode: "onBlur", }); + const onSearchSubmit = async (data) => { + setSpecialFilter([ + { value: `${data.item_id}`, datatype: "text", id: "item_id", fn: "equals" }, + { value: `${data.road_patrol_id}`, datatype: "text", id: "road_patrol_id", fn: "equals" }, + { value: `${data.start_date}`, datatype: "date", id: "roadPatrol.start_time", fn: "equals" }, + { value: `${data.end_date}`, datatype: "date", id: "roadPatrol.end_time", fn: "equals" }, + ]); + }; return ( - + <> - } label="انتخاب آیتم" /> - } label="انتخاب موضوع مشاهده شده" /> + } label="انتخاب مورد مشاهده شده" /> + } label="اطلاعات مورد مشاهده شده" /> - + + + - @@ -98,19 +143,21 @@ const GashtCreateContent = ({ mutate, setOpen }) => { > {tabState === 0 ? "بستن" : "مرحله قبل"} - {tabState === 2 && ( + {tabState === 1 && ( )} - + ); }; export default GashtCreateContent; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/LocationFormContent.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/LocationFormContent.jsx new file mode 100644 index 0000000..f012434 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/LocationFormContent.jsx @@ -0,0 +1,31 @@ +"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 }) => { + return ( + <> + + + + + + + + + + + + ); +}; + +export default LocationFormContent; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/index.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/index.jsx new file mode 100644 index 0000000..09df6ad --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/LocationForm/index.jsx @@ -0,0 +1,36 @@ +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 }) => { + 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"} + > + موقعیت + + + + ); +}; +export default LocationForm; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/CompleteItem.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/CompleteItem.jsx new file mode 100644 index 0000000..059aac9 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/CompleteItem.jsx @@ -0,0 +1,231 @@ +import { Button, DialogActions, Grid, Stack } from "@mui/material"; +import PreviousStatesInfo from "./PreviousStatesInfo"; +import NumberField from "@/core/components/NumberField"; +import { Controller, useForm } from "react-hook-form"; +import CarCode from "@/core/components/CarCode"; +import RahdarCode from "@/core/components/RahdarCode"; +import ImageUpload from "@/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/ImageUpload"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import MuiTimePicker from "@/core/components/MuiTimePicker"; +import MapInfoTwoMarker from "@/core/components/MapInfoTwoMarker"; +import MapInfoOneMarker from "@/core/components/MapInfoOneMarker"; +import { yupResolver } from "@hookform/resolvers/yup"; +import StyledForm from "@/core/components/StyledForm"; +import { array, mixed, number, object, string } from "yup"; +import useRequest from "@/lib/hooks/useRequest"; +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import React, { useEffect } from "react"; +import { CREATE_ROAD_ITEMS } from "@/core/utils/routes"; + +const CompleteItem = ({ subItem, itemInfo, setSubmitCompleteForm, mutate, setOpen }) => { + const requestServer = useRequest({ notificationSuccess: true }); + + const defaultValues = { + item_id: itemInfo?.item_id || null, + sub_item_id: itemInfo?.sub_item_id || null, + amount: "", + activity_time: "", + activity_date: "", + before_image: null, + after_image: null, + cmms_machines: null, + rahdaran_id: null, + start_point: { lat: itemInfo?.start_lat || "", lng: itemInfo?.start_lon || "" }, + end_point: { lat: itemInfo?.end_lat || "", lng: itemInfo?.end_lon || "" }, + }; + + const validationSchema = object({ + item_id: number().required("نوع آیتم را مشخص کنید!"), + sub_item_id: number().required("موضوع مشاهده شده را مشخص کنید!"), + amount: string().required("وارد کردن مقدار الزامیست!"), + cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"), + rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), // بررسی حداقل یک آیتم, + activity_time: string().required("لطفا زمان فعالیت را انتخاب کنید!"), + activity_date: string().required("لطفاً تاریخ شروع فعالیت را انتخاب کنید!"), + before_image: mixed() + .nullable() + .test("before-image-required", "لطفا عکس قبل از اقدام را بارگذاری کنید!", function (value) { + const { subItem } = this.options.context; + const needsImage = subItem?.needs_image === 1; + if (needsImage) { + return !!value; + } + return true; + }), + after_image: mixed() + .nullable() + .test("after-image-required", "لطفا عکس بعد از اقدام را بارگذاری کنید!", function (value) { + const { subItem } = this.options.context; + const needsImage = subItem?.needs_image === 1; + if (needsImage) { + return !!value; + } + return true; + }), + start_point: mixed() + .test("start-point-required", "لطفاً نقطه شروع را مشخص کنید!", function (value) { + return !!value; // چک می‌کند که مقدار موجود است + }) + .required("لطفاً نقطه شروع را مشخص کنید!"), + end_point: mixed().test("end-point-required", "لطفاً نقطه پایان را مشخص کنید!", function (value) { + const { subItem } = this.options.context; + const needsEndPoint = subItem?.needs_end_point === 1; + if (needsEndPoint) { + return !!value; // چک می‌کند که مقدار موجود است + } + return true; + }), + }); + + const { + control, + watch, + getValues, + register, + handleSubmit, + setValue, + resetField, + formState: { errors, isSubmitting }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + context: { subItem }, + }); + + useEffect(() => { + setSubmitCompleteForm(isSubmitting); + }, [isSubmitting]); + const onSubmit = async (data) => { + let endPoint; + let startPoint = `${data.start_point.lat},${data.start_point.lng}`; + if (subItem.needs_end_point === 1) { + endPoint = `${data.end_point.lat},${data.end_point.lng}`; + } + const formData = new FormData(); + data.after_image !== null && formData.append("after_image", data.after_image); + data.before_image !== null && formData.append("before_image", data.before_image); + subItem.needs_end_point === 1 && formData.append("end_point", endPoint); + formData.append("start_point", startPoint); + formData.append("activity_time", data.activity_time); + formData.append("activity_date", data.activity_date); + formData.append("amount", data.amount); + formData.append("item_id", data.item_id); + formData.append("sub_item_id", data.sub_item_id); + data.cmms_machines.forEach((machine, index) => formData.append(`machines_id[${index}]`, machine.id)); + data.rahdaran_id.forEach((rahdar, index) => formData.append(`rahdaran_id[${index}]`, rahdar.id)); + + await requestServer(CREATE_ROAD_ITEMS, "post", { + data: formData, + }) + .then((response) => { + mutate(); + setOpen(false); + }) + .catch((error) => {}); + }; + + return ( + + + + + + + { + if (!isNaN(event.target.value)) { + setValue("amount", event.target.value); + } else { + setValue("amount", watch("amount")); + } + }} + helperText={errors.amount ? errors.amount.message : null} + variant="outlined" + fullWidth + /> + + + { + return ( + field.onChange(value || [])} + error={error} + multiple={true} + /> + ); + }} + name={"cmms_machines"} + /> + + + { + return ( + field.onChange(value || [])} + error={error} + /> + ); + }} + name={"rahdaran_id"} + /> + + + {subItem.needs_image ? ( + + ) : null} + + + + + + + + + + + + + {subItem?.needs_end_point === 1 ? ( + + ) : ( + + )} + + + + ); +}; +export default CompleteItem; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/GetItemInfo.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/GetItemInfo.jsx new file mode 100644 index 0000000..e11fbd3 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/GetItemInfo.jsx @@ -0,0 +1,28 @@ +import { LinearProgress, Typography } from "@mui/material"; +import useRoadItemGetISubtems from "@/lib/hooks/useRoadItemGetISubtems"; +import CompleteItem from "./CompleteItem"; + +const GetItemInfo = ({ itemInfo, setSubmitCompleteForm, mutate, setOpen }) => { + const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetISubtems(itemInfo?.item_id); + const subItem = subItemsList.find((SubItem) => SubItem.sub_item === itemInfo?.sub_item_id); + return ( + <> + {loadingSubItemsList ? ( + + ) : errorSubItemsList ? ( + + خطا در دریافت اطلاعات!!! + + ) : ( + + )} + + ); +}; +export default GetItemInfo; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/ImageUpload.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/ImageUpload.jsx new file mode 100644 index 0000000..3efd1d9 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/ImageUpload.jsx @@ -0,0 +1,131 @@ +import { FormControl, FormHelperText, Grid } from "@mui/material"; +import UploadSystem from "@/core/components/UploadSystem"; +import { Controller } from "react-hook-form"; +import React, { useEffect, useState } from "react"; + +const ImageUpload = ({ control, setValue, errors, getValues, beforeImage = null, afterImage = null }) => { + const [beforeImg, setBeforeImg] = useState(beforeImage ? beforeImage : null); + const [beforeFileType, setBeforeFileType] = useState(beforeImage ? "image/" : null); + const [beforeFileName, setBeforeFileName] = useState(null); + const [showBeforeImage, setShowBeforeImage] = useState(!beforeImage); + + const [afterImg, setAfterImg] = useState(afterImage ? afterImage : null); + const [afterFileType, setAfterFileType] = useState(afterImage ? "image/" : null); + const [afterFileName, setAfterFileName] = useState(null); + const [showAfterImage, setShowAfterImage] = useState(!afterImage); + + useEffect(() => { + if (getValues("before_image")) { + setShowBeforeImage(false); + setBeforeImg(getValues("before_image")); + setBeforeFileType("image/"); + } + if (getValues("after_image")) { + setShowAfterImage(false); + setAfterImg(getValues("after_image")); + setAfterFileType("image/"); + } + }, [getValues]); + + const handleBeforeFileChange = (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); + setValue("before_image", uploadedFile); + setShowBeforeImage(false); + } + }; + const handleAfterFileChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const fileType = event.target?.files?.[0].type; + const fileName = event.target?.files?.[0].name; + setAfterImg(URL.createObjectURL(uploadedFile)); + setAfterFileType(fileType); + setAfterFileName(fileName); + setValue("after_image", uploadedFile); + setShowAfterImage(false); + } + }; + return ( + + + { + return ( + + + عکس قبل از اقدام + + + + {errors.before_image ? errors.before_image.message : null} + + + ); + }} + /> + + + { + return ( + + + عکس بعد از اقدام + + + + {errors.after_image ? errors.after_image.message : null} + + + ); + }} + /> + + + ); +}; +export default ImageUpload; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/PreviousStatesInfo.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/PreviousStatesInfo.jsx new file mode 100644 index 0000000..57c8839 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/PreviousStatesInfo.jsx @@ -0,0 +1,43 @@ +import { Box, Chip, Divider, Grid, Typography } from "@mui/material"; +import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; +import FileCopyIcon from "@mui/icons-material/FileCopy"; + +const PreviousStatesInfo = ({ itemInfo }) => { + return ( + + + + } + label={ + + آیتم انتخاب ‌شده + + } + /> + + + + {itemInfo.item_name || "هیچ آیتمی انتخاب نشده است"} + + + + + } + label={ + + موضوع مشاهده‌شده + + } + /> + + + + {itemInfo?.sub_item_name || "هیچ موضوعی انتخاب نشده است"} + + + + ); +}; +export default PreviousStatesInfo; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/SubItemForm/index.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/SubItemForm/index.jsx new file mode 100644 index 0000000..ba8a902 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/SubItemForm/index.jsx @@ -0,0 +1,21 @@ +import React from "react"; +import { Tooltip, IconButton } from "@mui/material"; +import UndoIcon from "@mui/icons-material/Undo"; +const SubItemForm = ({ row, setTabState, setItemInfo }) => { + return ( + <> + + { + setTabState(1); + setItemInfo(row.original); + }} + > + + + + + ); +}; +export default SubItemForm; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/index.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/index.jsx new file mode 100644 index 0000000..84e8a31 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/RowActions/index.jsx @@ -0,0 +1,11 @@ +import { Box } from "@mui/material"; +import SubItemForm from "./SubItemForm"; + +const RowActions = ({ row, mutate, setTabState, setItemInfo }) => { + return ( + + + + ); +}; +export default RowActions; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItemInfo.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItemInfo.jsx new file mode 100644 index 0000000..611e7d8 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItemInfo.jsx @@ -0,0 +1,42 @@ +import { LinearProgress, Typography } from "@mui/material"; +import useRoadItemGetItems from "@/lib/hooks/useRoadItemGetItems"; +import React from "react"; +import SearchItems from "./SearchItems"; +import TableInfo from "./TableInfo"; + +const SearchItemInfo = ({ + watch, + errors, + setValue, + register, + specialFilter, + setTabState, + setItemInfo, + isSubmitting, +}) => { + const { itemsList, loadingItemsList, errorItemsList } = useRoadItemGetItems(); + return ( + <> + {loadingItemsList ? ( + + ) : errorItemsList ? ( + + خطا در دریافت اطلاعات!!! + + ) : ( + <> + + + + )} + + ); +}; +export default SearchItemInfo; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItems.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItems.jsx new file mode 100644 index 0000000..775b933 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/SearchItems.jsx @@ -0,0 +1,96 @@ +import { Button, FormControl, FormHelperText, InputLabel, MenuItem, Select, Stack, TextField } from "@mui/material"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import SearchIcon from "@mui/icons-material/Search"; +import React from "react"; + +const SearchItems = ({ setValue, itemsList, watch, errors, register, isSubmitting }) => { + const disabledButton = + (!!watch("start_date") && !!watch("end_date")) || !!watch("item_id") || !!watch("road_patrol_id"); + + return ( + + + + + + + + + + آیتم فعالیت + + {/*{errors.item_id ? (*/} + {/* */} + {/* errors.item_id.message*/} + {/* */} + {/*) : null}*/} + + + + { + if (!isNaN(event.target.value)) { + setValue("road_patrol_id", event.target.value); + } else { + setValue("road_patrol_id", watch("road_patrol_id")); + } + }} + helperText={errors.road_patrol_id ? errors.road_patrol_id.message : null} + variant="outlined" + /> + + + + + + ); +}; +export default SearchItems; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/TableInfo.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/TableInfo.jsx new file mode 100644 index 0000000..c16dba4 --- /dev/null +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/TableInfo.jsx @@ -0,0 +1,115 @@ +import { useMemo } from "react"; +import { Box, Stack } from "@mui/material"; +import DataTableWithAuth from "@/core/components/DataTableWithAuth"; +import RowActions from "./RowActions"; +import { GET_OBSERVED_GASHT_LIST } from "@/core/utils/routes"; +import LocationForm from "./LocationForm"; + +const TableInfo = ({ specialFilter, setTabState, setItemInfo }) => { + const columns = useMemo( + () => [ + { + accessorKey: "road_patrol_id", + header: "کد یکتا گشت", + id: "road_patrol_id", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 50, + }, + { + accessorKey: "priority_fa", + header: "اولویت", + id: "priority_fa", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 80, + }, + { + accessorKey: "local_name", + header: "نام محلی", + id: "local_name", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "item_name", + header: "نام ایتم", + id: "item_name", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "sub_item_name", + header: "موضوع مشاهده شده", + id: "sub_item_name", + enableColumnFilter: false, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "location", + header: "موقعیت", // Location + id: "location", + enableColumnFilter: false, + enableSorting: false, + datatype: "array", + grow: false, + size: 50, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue, row }) => { + return ( + + + + ); + }, + }, + ], + [] + ); + return ( + <> + + ( + + )} + /> + + + ); +}; +export default TableInfo; diff --git a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx index ae14476..4379040 100644 --- a/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/ObservedGashtCreate/index.jsx @@ -17,7 +17,11 @@ const ObservedGashtCreate = ({ mutate }) => { return ( <> {isMobile ? ( - + ) : ( diff --git a/src/components/dashboard/roadItems/operator/OperatorList.jsx b/src/components/dashboard/roadItems/operator/OperatorList.jsx index c5cfaba..9f818e8 100644 --- a/src/components/dashboard/roadItems/operator/OperatorList.jsx +++ b/src/components/dashboard/roadItems/operator/OperatorList.jsx @@ -193,7 +193,7 @@ const OperatorList = () => { }, { accessorKey: "cmms_machines", - header: "کد خودرو", // Car ID + header: "خودرو ها", // Car ID id: "cmmsMachines__machine_code", enableColumnFilter: true, datatype: "text", @@ -241,20 +241,17 @@ const OperatorList = () => { }, }, Cell: ({ renderedCellValue }) => { - if (renderedCellValue) { - return ( - - - - ); - } - return بدون شخص; + return ( + + + + ); }, }, { - accessorFn: (row) => moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"), - header: "تاریخ ثبت", // Register Date - id: "created_at", + accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"), + header: "تاریخ فعالیت", // Start Date + id: "activity_date_time", enableColumnFilter: true, datatype: "date", filterMode: "equals", @@ -263,9 +260,9 @@ const OperatorList = () => { size: 100, }, { - accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"), - header: "تاریخ فعالیت", // Start Date - id: "activity_date_time", + accessorFn: (row) => moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"), + header: "تاریخ ثبت", // Register Date + id: "created_at", enableColumnFilter: true, datatype: "date", filterMode: "equals", @@ -296,6 +293,7 @@ const OperatorList = () => { header: "توضیحات کارشناس", // Description id: "supervisor_description", enableColumnFilter: false, + enableSorting: false, datatype: "text", filterMode: "equals", columnFilterModeOptions: ["equals", "contains"], @@ -311,11 +309,14 @@ const OperatorList = () => { }, }, Cell: ({ renderedCellValue }) => { - return ( - - - - ); + if (renderedCellValue) { + return ( + + + + ); + } + return بدون توضیحات; }, }, ], diff --git a/src/components/dashboard/roadItems/operator/RowActions/DescriptionForm/index.jsx b/src/components/dashboard/roadItems/operator/RowActions/DescriptionForm/index.jsx index 3f748c9..481e2d6 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/DescriptionForm/index.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/DescriptionForm/index.jsx @@ -37,7 +37,7 @@ const DescriptionForm = ({ description }) => { - + {description || "هیچ توضیحی موجود نیست"} diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx index 620f052..164a07a 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormContent.jsx @@ -17,7 +17,7 @@ const EditFormContent = ({ setOpenEditDialog, onSubmit, defaultData }) => { rahdaran_id: defaultData?.rahdaran || null, }; - const onSubmitBase = (data) => { + const onSubmitBase = async (data) => { let result = { ...data }; (result.before_image === null || result.before_image === defaultValues.before_image) && delete result.before_image; @@ -40,7 +40,7 @@ const EditFormContent = ({ setOpenEditDialog, onSubmit, defaultData }) => { }); delete result.cmms_machines; - onSubmit({ + await onSubmit({ result, data: { ...data, diff --git a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx index 4bd9a9c..7f2b6d8 100644 --- a/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx +++ b/src/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate.jsx @@ -158,7 +158,7 @@ const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, set - diff --git a/src/components/dashboard/roadItems/operator/Toolbar.jsx b/src/components/dashboard/roadItems/operator/Toolbar.jsx index ae6691f..d8c6fad 100644 --- a/src/components/dashboard/roadItems/operator/Toolbar.jsx +++ b/src/components/dashboard/roadItems/operator/Toolbar.jsx @@ -8,7 +8,7 @@ const Toolbar = ({ table, filterData, mutate }) => { - {/**/} + ); }; diff --git a/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/DeleteContent.jsx b/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/DeleteContent.jsx index 18198a8..485ac40 100644 --- a/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/DeleteContent.jsx +++ b/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/DeleteContent.jsx @@ -28,10 +28,10 @@ const DeleteContent = ({ rowId, mutate, setOpenDeleteDialog }) => {
- - diff --git a/src/components/dashboard/roadItems/supervisor/RowActions/LocationForm/LocationFormContent.jsx b/src/components/dashboard/roadItems/supervisor/RowActions/LocationForm/LocationFormContent.jsx index 6c17f3a..1e20921 100644 --- a/src/components/dashboard/roadItems/supervisor/RowActions/LocationForm/LocationFormContent.jsx +++ b/src/components/dashboard/roadItems/supervisor/RowActions/LocationForm/LocationFormContent.jsx @@ -25,7 +25,7 @@ const LocationFormContent = ({ setOpenLocationDialog, start_lat, start_lng, end_
- diff --git a/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx b/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx index 4f3420b..8ef88db 100644 --- a/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx +++ b/src/components/dashboard/roadItems/supervisor/SupervisorList.jsx @@ -257,7 +257,7 @@ const SupervisorList = () => { }, { accessorKey: "cmms_machines", - header: "کد خودرو", // Car ID + header: "خودرو ها", // Car ID id: "cmmsMachines__machine_code", enableColumnFilter: true, datatype: "text", @@ -316,9 +316,9 @@ const SupervisorList = () => { }, }, { - accessorFn: (row) => moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"), - header: "تاریخ ثبت", // Register Date - id: "created_at", + accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"), + header: "تاریخ فعالیت", // Start Date + id: "activity_date_time", enableColumnFilter: true, datatype: "date", filterMode: "equals", @@ -327,9 +327,9 @@ const SupervisorList = () => { size: 100, }, { - accessorFn: (row) => moment(row.activity_date_time).locale("fa").format("HH:mm | yyyy/MM/DD"), - header: "تاریخ فعالیت", // Start Date - id: "activity_date_time", + accessorFn: (row) => moment(row.created_at).locale("fa").format("HH:mm | yyyy/MM/DD"), + header: "تاریخ ثبت", // Register Date + id: "created_at", enableColumnFilter: true, datatype: "date", filterMode: "equals", diff --git a/src/components/dashboard/roadPatrols/operator/OperatorList.jsx b/src/components/dashboard/roadPatrols/operator/OperatorList.jsx index 589ba5d..c5e8d7a 100644 --- a/src/components/dashboard/roadPatrols/operator/OperatorList.jsx +++ b/src/components/dashboard/roadPatrols/operator/OperatorList.jsx @@ -7,6 +7,8 @@ import { GET_ROAD_PATROL_OPERATOR_LIST } from "@/core/utils/routes"; import moment from "jalali-moment"; import RowActions from "./RowActions"; import ReportForm from "./RowActions/ReportForm"; +import MachinesCodeDialog from "./RowActions/MachinesCodeForm"; +import RahdaranDialog from "./RowActions/RahdaranForm"; const OperatorList = () => { const columns = useMemo( @@ -23,31 +25,64 @@ const OperatorList = () => { size: 100, }, { - accessorKey: "operator_name", - header: "نام مامور", - id: "operator_name", + accessorKey: "cmms_machines", + header: "خودرو", // Car ID + id: "cmmsMachines__machine_code", enableColumnFilter: true, datatype: "text", - filterMode: "equals", + filterMode: "contains", + enableSorting: false, columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue }) => { + if (renderedCellValue) { + return ( + + + + ); + } + return کد خودرویی وجود ندارد; + }, }, { - accessorKey: "officer_phone_number", - header: "تلفن همراه", - id: "officer_phone_number", - enableColumnFilter: true, - datatype: "text", - filterMode: "equals", - columnFilterModeOptions: ["equals", "contains"], - }, - { - accessorKey: "car_id", - header: "کد خودرو", - id: "car_id", - enableColumnFilter: true, - datatype: "text", - filterMode: "equals", - columnFilterModeOptions: ["equals", "contains"], + accessorKey: "rahdaran", + header: "راهداران", + id: "rahdaran", + enableColumnFilter: false, + enableSorting: false, + datatype: "array", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue }) => { + if (renderedCellValue) { + return ( + + + + ); + } + return بدون شخص; + }, }, { accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"), diff --git a/src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/MachinesCodeContent.jsx b/src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/MachinesCodeContent.jsx new file mode 100644 index 0000000..1eef774 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/MachinesCodeContent.jsx @@ -0,0 +1,55 @@ +import { DialogContent, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material"; +import ShowPlak from "@/core/components/ShowPlak"; + +const MachinesCodeContent = ({ machinesLists }) => { + return ( + <> + + + + + + + کد ماشین + نام خودرو + پلاک + + + + {machinesLists.map((machine) => { + return ( + + {machine.machine_code} + {machine.car_name} + + {machine.plak_number ? ( + + ) : null} + + + ); + })} + +
+
+
+
+ + ); +}; +export default MachinesCodeContent; diff --git a/src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/index.jsx b/src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/index.jsx new file mode 100644 index 0000000..d8e8754 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/RowActions/MachinesCodeForm/index.jsx @@ -0,0 +1,43 @@ +import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import DirectionsCarIcon from "@mui/icons-material/DirectionsCar"; +import { useState } from "react"; +import MachinesCodeContent from "./MachinesCodeContent"; + +const MachinesCodeDialog = ({ machinesLists }) => { + const [openMachinesCodeDialog, setOpenMachinesCodeDialog] = useState(false); + return ( + <> + + setOpenMachinesCodeDialog(true)}> + + + + setOpenMachinesCodeDialog(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 MachinesCodeDialog; diff --git a/src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/RahdaranContent.jsx b/src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/RahdaranContent.jsx new file mode 100644 index 0000000..d1e9b15 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/RahdaranContent.jsx @@ -0,0 +1,48 @@ +import { DialogContent, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material"; + +const RahdaranContent = ({ rahdarLists }) => { + return ( + <> + + + + + + + کد راهدار + نام + + + + {rahdarLists.map((rahdar) => { + return ( + + {rahdar.code} + {rahdar.name} + + ); + })} + +
+
+
+
+ + ); +}; +export default RahdaranContent; diff --git a/src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/index.jsx b/src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/index.jsx new file mode 100644 index 0000000..2c73d80 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/RowActions/RahdaranForm/index.jsx @@ -0,0 +1,38 @@ +import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import GroupsIcon from "@mui/icons-material/Groups"; +import { useState } from "react"; +import RahdaranContent from "./RahdaranContent"; + +const RahdaranDialog = ({ rahdarLists }) => { + const [openRahdaranDialog, setOpenRahdaranDialog] = useState(false); + return ( + <> + + setOpenRahdaranDialog(true)}> + + + + setOpenRahdaranDialog(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 RahdaranDialog; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/MachinesCodeContent.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/MachinesCodeContent.jsx new file mode 100644 index 0000000..1eef774 --- /dev/null +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/MachinesCodeContent.jsx @@ -0,0 +1,55 @@ +import { DialogContent, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material"; +import ShowPlak from "@/core/components/ShowPlak"; + +const MachinesCodeContent = ({ machinesLists }) => { + return ( + <> + + + + + + + کد ماشین + نام خودرو + پلاک + + + + {machinesLists.map((machine) => { + return ( + + {machine.machine_code} + {machine.car_name} + + {machine.plak_number ? ( + + ) : null} + + + ); + })} + +
+
+
+
+ + ); +}; +export default MachinesCodeContent; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/index.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/index.jsx new file mode 100644 index 0000000..9696333 --- /dev/null +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/MachinesCodeForm/index.jsx @@ -0,0 +1,43 @@ +import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import DirectionsCarIcon from "@mui/icons-material/DirectionsCar"; +import { useState } from "react"; +import MachinesCodeContent from "./MachinesCodeContent"; + +const MachinesCodeDialog = ({ machinesLists }) => { + const [openMachinesCodeDialog, setOpenMachinesCodeDialog] = useState(false); + return ( + <> + + setOpenMachinesCodeDialog(true)}> + + + + setOpenMachinesCodeDialog(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 MachinesCodeDialog; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/RahdaranContent.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/RahdaranContent.jsx new file mode 100644 index 0000000..d1e9b15 --- /dev/null +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/RahdaranContent.jsx @@ -0,0 +1,48 @@ +import { DialogContent, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material"; + +const RahdaranContent = ({ rahdarLists }) => { + return ( + <> + + + + + + + کد راهدار + نام + + + + {rahdarLists.map((rahdar) => { + return ( + + {rahdar.code} + {rahdar.name} + + ); + })} + +
+
+
+
+ + ); +}; +export default RahdaranContent; diff --git a/src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/index.jsx b/src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/index.jsx new file mode 100644 index 0000000..2c73d80 --- /dev/null +++ b/src/components/dashboard/roadPatrols/supervisor/RowActions/RahdaranForm/index.jsx @@ -0,0 +1,38 @@ +import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import GroupsIcon from "@mui/icons-material/Groups"; +import { useState } from "react"; +import RahdaranContent from "./RahdaranContent"; + +const RahdaranDialog = ({ rahdarLists }) => { + const [openRahdaranDialog, setOpenRahdaranDialog] = useState(false); + return ( + <> + + setOpenRahdaranDialog(true)}> + + + + setOpenRahdaranDialog(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 RahdaranDialog; diff --git a/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx b/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx index d653f21..5ec3369 100644 --- a/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx +++ b/src/components/dashboard/roadPatrols/supervisor/SupervisorList.jsx @@ -1,6 +1,6 @@ "use client"; import { useMemo } from "react"; -import { Box, Stack } from "@mui/material"; +import {Box, Stack, Typography} from "@mui/material"; import DataTableWithAuth from "@/core/components/DataTableWithAuth"; import Toolbar from "./Toolbar"; import { GET_ROAD_PATROL_SUPERVISOR_LIST } from "@/core/utils/routes"; @@ -11,6 +11,8 @@ import CustomSelectByDependency from "@/core/components/DataTable/filter/fieldsT import useEdaratLists from "@/lib/hooks/useEdaratLists"; import OfficerDescriptionForm from "./RowActions/OfficerDescription"; import ReportForm from "./RowActions/ReportForm"; +import MachinesCodeDialog from "./RowActions/MachinesCodeForm"; +import RahdaranDialog from "./RowActions/RahdaranForm"; const OperatorList = () => { const columns = useMemo( @@ -93,31 +95,64 @@ const OperatorList = () => { Cell: ({ renderedCellValue, row }) => <>{row.original.edare_name}, }, { - accessorKey: "operator_name", - header: "نام مامور", - id: "operator_name", + accessorKey: "cmms_machines", + header: "خودرو", // Car ID + id: "cmmsMachines__machine_code", enableColumnFilter: true, datatype: "text", - filterMode: "equals", + filterMode: "contains", + enableSorting: false, columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue }) => { + if (renderedCellValue) { + return ( + + + + ); + } + return کد خودرویی وجود ندارد; + }, }, { - accessorKey: "officer_phone_number", - header: "تلفن همراه", - id: "officer_phone_number", - enableColumnFilter: true, - datatype: "text", - filterMode: "equals", - columnFilterModeOptions: ["equals", "contains"], - }, - { - accessorKey: "car_id", - header: "کد خودرو", - id: "car_id", - enableColumnFilter: true, - datatype: "text", - filterMode: "equals", - columnFilterModeOptions: ["equals", "contains"], + accessorKey: "rahdaran", + header: "راهداران", + id: "rahdaran", + enableColumnFilter: false, + enableSorting: false, + datatype: "array", + grow: false, + size: 100, + muiTableBodyCellProps: { + sx: { + borderLeft: "1px solid #e1e1e1", + py: 0, + "&:first-of-type": { + borderLeft: "unset", + }, + }, + }, + Cell: ({ renderedCellValue }) => { + if (renderedCellValue) { + return ( + + + + ); + } + return بدون شخص; + }, }, { accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"), diff --git a/src/core/components/DataTable/Main.js b/src/core/components/DataTable/Main.js index 14d8788..00d59d2 100644 --- a/src/core/components/DataTable/Main.js +++ b/src/core/components/DataTable/Main.js @@ -23,6 +23,7 @@ const DataTable_Main = (props) => { table_title, RowActions, specific_data, + specialFilter, } = props; const flatColumns = flattenArrayOfObjects(columns, "columns"); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); @@ -33,29 +34,34 @@ const DataTable_Main = (props) => { }; const fetchUrl = useMemo(() => { + const params = new URLSearchParams(); + params.set("start", `${pagination.pageIndex * pagination.pageSize}`); + params.set("size", pagination.pageSize); const isValueEmpty = (value) => { if (Array.isArray(value)) { return value.length === 0 || value.every((v) => v === ""); } return value === "" || value === null || value === undefined; }; + if (specialFilter) { + const filteredSpecialFilterData = Object.values(specialFilter).filter( + (filter) => !isValueEmpty(filter.value) + ); + params.set("filters", JSON.stringify(filteredSpecialFilterData || [])); + } else { + const filteredFilterData = Object.values(filterData) + .filter((filter) => !isValueEmpty(filter.value)) + .map(({ filterMode, id, ...rest }) => ({ + ...rest, + id: id.replace(/__/g, "."), + fn: filterMode, + })); - const filteredFilterData = Object.values(filterData) - .filter((filter) => !isValueEmpty(filter.value)) - .map(({ filterMode, id, ...rest }) => ({ - ...rest, - id: id.replace(/__/g, "."), - fn: filterMode, - })); - - const params = new URLSearchParams(); - params.set("start", `${pagination.pageIndex * pagination.pageSize}`); - params.set("size", pagination.pageSize); - params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); + params.set("filters", JSON.stringify(filteredFilterData.length === 0 ? [] : filteredFilterData)); + } params.set("sorting", JSON.stringify(sortData)); return `${table_url}?${params}`; - }, [table_url, filterData, pagination, columns, sortData]); - + }, [table_url, filterData, pagination, columns, sortData, specialFilter]); const fetcher = async (url) => { try { const response = await request(url); @@ -143,5 +149,4 @@ const DataTable_Main = (props) => { /> ); }; - export default DataTable_Main; diff --git a/src/core/components/MuiDatePicker.jsx b/src/core/components/MuiDatePicker.jsx index 78ffe58..10d5dff 100644 --- a/src/core/components/MuiDatePicker.jsx +++ b/src/core/components/MuiDatePicker.jsx @@ -59,9 +59,11 @@ function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperTex }, }} /> - - {helperText ? helperText : ""} - + {helperText ? ( + + {helperText} + + ) : null}
); diff --git a/src/core/components/MuiTimePicker.jsx b/src/core/components/MuiTimePicker.jsx index 35532fd..8aeace6 100644 --- a/src/core/components/MuiTimePicker.jsx +++ b/src/core/components/MuiTimePicker.jsx @@ -64,9 +64,11 @@ function MuiTimePicker({ value, setFieldValue, name, minTime, maxTime, helperTex }, }} /> - - {helperText ? helperText : ""} - + {helperText ? ( + + {helperText} + + ) : null}
); diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 6c26cd2..cea920d 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -51,6 +51,7 @@ export const DELETE_BY_SUPERVISOR = api + "/api/v3/road_items/delete"; export const RESTORE_BY_SUPERVISOR = api + "/api/v3/road_items/restore"; export const GET_CAR_LIST_SEARCH = api + "/api/v3/cmms_machines/search"; export const GET_RAHDARANS_LIST_SEARCH = api + "/api/v3/rahdaran/search"; +export const GET_OBSERVED_GASHT_LIST = api + "/api/v3/observed_items/filter"; // activity code log export const ACTIVITY_LOG = api + "/api/v3/profile/add_activity"; From f37e8aea5fbeb000ee4d5692f4fefb1eb7714c08 Mon Sep 17 00:00:00 2001 From: Amirhossein Mahmoodi Date: Mon, 6 Jan 2025 12:40:09 +0330 Subject: [PATCH 19/22] add secondary color --- src/core/utils/theme.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/utils/theme.js b/src/core/utils/theme.js index 85c8f68..7cde9e0 100644 --- a/src/core/utils/theme.js +++ b/src/core/utils/theme.js @@ -1,5 +1,6 @@ "use client"; import { createTheme } from "@mui/material"; +import { grey } from '@mui/material/colors'; const theme = createTheme({ direction: "rtl", @@ -16,6 +17,9 @@ const theme = createTheme({ main: "#015688", contrastText: "#fff", }, + secondary: { + main: grey[700], + } }, components: { MuiBackdrop: { From 637163038099fcb5e4fcb4e9148094f0ac27bafb Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 6 Jan 2025 13:08:47 +0330 Subject: [PATCH 20/22] work on patrol form instead sending request --- .../Create/Forms/CreateFormContent.jsx | 95 ++++---- .../Actions/Create/Forms/GetItemInfo.jsx | 66 +++--- .../Actions/Create/Forms/ImageUpload.jsx | 44 ++-- .../RowActions/EditForm/EditFormContent.jsx | 31 ++- .../RowActions/EditForm/EditFormCreate.jsx | 36 +-- .../roadPatrols/operator/ExcelPrint/index.jsx | 26 +-- .../Forms/CreatePatrol/ActionInfo.jsx | 92 +------- .../Forms/CreatePatrol/ActionsDurigPatrol.jsx | 13 +- .../Forms/CreatePatrol/CompeleteRequest.jsx | 218 ++++++++++++++++++ .../CreatePatrol/EditActionDuringPatrol.jsx | 19 +- .../CreatePatrol/ModalActionsDuringPatrol.jsx | 2 +- .../Forms/CreatePatrol/PatrolDetail.jsx | 3 +- .../Forms/CreatePatrol/PatrolDetailInfo.jsx | 45 +++- .../Forms/CreatePatrol/PatrolForms.jsx | 99 ++++---- .../Forms/CreatePatrol/PatrolTimeLine.jsx | 37 +-- .../Forms/CreatePatrol/PhoneValidation.jsx | 39 +--- .../Forms/CreatePatrol/SuperVisorsDetail.jsx | 8 +- src/core/utils/routes.js | 1 + 18 files changed, 539 insertions(+), 335 deletions(-) create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/CompeleteRequest.jsx diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx index 7f47a7d..cfb5a36 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent.jsx @@ -1,10 +1,9 @@ -import React, { useState } from "react"; -import { useForm } from "react-hook-form"; -import { yupResolver } from "@hookform/resolvers/yup"; -import { array, mixed, number, object, string } from "yup"; -import { useTheme } from "@emotion/react"; -import useRequest from "@/lib/hooks/useRequest"; -import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material"; +import React, {useState} from "react"; +import {useForm} from "react-hook-form"; +import {yupResolver} from "@hookform/resolvers/yup"; +import {array, mixed, number, object, string} from "yup"; +import {useTheme} from "@emotion/react"; +import {Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery} from "@mui/material"; import StyledForm from "@/core/components/StyledForm"; import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; import FileCopyIcon from "@mui/icons-material/FileCopy"; @@ -15,10 +14,9 @@ import BeenhereIcon from "@mui/icons-material/Beenhere"; import GetItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm"; import GetSubItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm"; import GetItemInfo from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo"; -import { CREATE_ROAD_ITEMS } from "@/core/utils/routes"; function TabPanel(props) { - const { children, value, index } = props; + const {children, value, index} = props; return (