From bc3db055b1d8c04ae455b49ff1803c3614d49602 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 4 Jan 2025 18:33:55 +0330 Subject: [PATCH] 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"} + /> +