formatting
This commit is contained in:
@@ -1,9 +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 {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";
|
||||
@@ -16,7 +16,7 @@ import GetSubItemsForm from "@/components/dashboard/roadItems/operator/Actions/C
|
||||
import GetItemInfo from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo";
|
||||
|
||||
function TabPanel(props) {
|
||||
const {children, value, index} = props;
|
||||
const { children, value, index } = props;
|
||||
return (
|
||||
<div role="tabpanel" hidden={value !== index}>
|
||||
{value === index && <Box>{children}</Box>}
|
||||
@@ -30,26 +30,28 @@ const validationSchema = object({
|
||||
amount: string().required("وارد کردن مقدار الزامیست!"),
|
||||
cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"),
|
||||
rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), // بررسی حداقل یک آیتم,
|
||||
activity_time: string()
|
||||
.test("activity-time-conditional", "لطفا زمان فعالیت را انتخاب کنید!", function (value) {
|
||||
const {is_gasht} = this.options.context; // دسترسی به context
|
||||
activity_time: string().test("activity-time-conditional", "لطفا زمان فعالیت را انتخاب کنید!", function (value) {
|
||||
const { is_gasht } = this.options.context; // دسترسی به context
|
||||
if (is_gasht) {
|
||||
return true; // اگر is_gasht true باشد، این فیلد نیاز به اعتبارسنجی ندارد
|
||||
}
|
||||
return !!value; // در غیر این صورت مقدار فیلد باید وجود داشته باشد
|
||||
}),
|
||||
activity_date: string().test(
|
||||
"activity-date-conditional",
|
||||
"لطفاً تاریخ شروع فعالیت را انتخاب کنید!",
|
||||
function (value) {
|
||||
const { is_gasht } = this.options.context; // دسترسی به context
|
||||
if (is_gasht) {
|
||||
return true; // اگر is_gasht true باشد، این فیلد نیاز به اعتبارسنجی ندارد
|
||||
}
|
||||
return !!value; // در غیر این صورت مقدار فیلد باید وجود داشته باشد
|
||||
}),
|
||||
activity_date: string()
|
||||
.test("activity-date-conditional", "لطفاً تاریخ شروع فعالیت را انتخاب کنید!", function (value) {
|
||||
const {is_gasht} = this.options.context; // دسترسی به context
|
||||
if (is_gasht) {
|
||||
return true; // اگر is_gasht true باشد، این فیلد نیاز به اعتبارسنجی ندارد
|
||||
}
|
||||
return !!value; // در غیر این صورت مقدار فیلد باید وجود داشته باشد
|
||||
}),
|
||||
}
|
||||
),
|
||||
before_image: mixed()
|
||||
.nullable()
|
||||
.test("before-image-required", "لطفا عکس قبل از اقدام را بارگذاری کنید!", function (value) {
|
||||
const {subItemsList} = this.options.context;
|
||||
const { subItemsList } = this.options.context;
|
||||
const needsImage = subItemsList?.needs_image === 1;
|
||||
if (needsImage) {
|
||||
return !!value;
|
||||
@@ -59,7 +61,7 @@ const validationSchema = object({
|
||||
after_image: mixed()
|
||||
.nullable()
|
||||
.test("after-image-required", "لطفا عکس بعد از اقدام را بارگذاری کنید!", function (value) {
|
||||
const {subItemsList} = this.options.context;
|
||||
const { subItemsList } = this.options.context;
|
||||
const needsImage = subItemsList?.needs_image === 1;
|
||||
if (needsImage) {
|
||||
return !!value;
|
||||
@@ -72,7 +74,7 @@ const validationSchema = object({
|
||||
})
|
||||
.required("لطفاً نقطه شروع را مشخص کنید!"),
|
||||
end_point: mixed().test("end-point-required", "لطفاً نقطه پایان را مشخص کنید!", function (value) {
|
||||
const {subItemsList} = this.options.context;
|
||||
const { subItemsList } = this.options.context;
|
||||
const needsEndPoint = subItemsList?.needs_end_point === 1;
|
||||
if (needsEndPoint) {
|
||||
return !!value; // چک میکند که مقدار موجود است
|
||||
@@ -81,7 +83,7 @@ const validationSchema = object({
|
||||
}),
|
||||
});
|
||||
|
||||
const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
|
||||
const CreateFormContent = ({ setOpen, onSubmit, is_gasht = false }) => {
|
||||
const defaultValues = {
|
||||
item_id: null,
|
||||
sub_item_id: null,
|
||||
@@ -92,7 +94,7 @@ const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
|
||||
rahdaran_id: null,
|
||||
start_point: "",
|
||||
end_point: "",
|
||||
...(!is_gasht && {activity_time: "", activity_date: ""}),
|
||||
...(!is_gasht && { activity_time: "", activity_date: "" }),
|
||||
};
|
||||
|
||||
const [tabState, setTabState] = useState(0);
|
||||
@@ -138,15 +140,15 @@ const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
|
||||
handleSubmit,
|
||||
setValue,
|
||||
resetField,
|
||||
formState: {errors, isSubmitting},
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm({
|
||||
defaultValues,
|
||||
resolver: yupResolver(validationSchema),
|
||||
mode: "onBlur",
|
||||
context: {subItemsList, is_gasht},
|
||||
context: { subItemsList, is_gasht },
|
||||
});
|
||||
const onSubmitBase = (data) => {
|
||||
let result = {...data};
|
||||
let result = { ...data };
|
||||
|
||||
if (result.before_image === null) {
|
||||
delete result.before_image;
|
||||
@@ -192,7 +194,7 @@ const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
console.log(errors)
|
||||
console.log(errors);
|
||||
|
||||
return (
|
||||
<StyledForm onSubmit={handleSubmit(onSubmitBase)} id="road_items">
|
||||
@@ -208,12 +210,12 @@ const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
|
||||
backgroundColor: "#efefef",
|
||||
}}
|
||||
>
|
||||
<Tab icon={<InsertDriveFileIcon/>} label="انتخاب آیتم"/>
|
||||
<Tab disabled={tabState === 0} icon={<FileCopyIcon/>} label="انتخاب موضوع مشاهده شده"/>
|
||||
<Tab disabled={tabState === 0 || tabState === 1} icon={<InfoIcon/>} label="اطلاعات فعالیت"/>
|
||||
<Tab icon={<InsertDriveFileIcon />} label="انتخاب آیتم" />
|
||||
<Tab disabled={tabState === 0} icon={<FileCopyIcon />} label="انتخاب موضوع مشاهده شده" />
|
||||
<Tab disabled={tabState === 0 || tabState === 1} icon={<InfoIcon />} label="اطلاعات فعالیت" />
|
||||
</Tabs>
|
||||
<DialogContent dividers sx={{overflowY: "auto", maxHeight: "70vh"}}>
|
||||
<Box sx={{flex: 1}}>
|
||||
<DialogContent dividers sx={{ overflowY: "auto", maxHeight: "70vh" }}>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<TabPanel value={tabState} index={0}>
|
||||
<GetItemsForm
|
||||
setItemsList={setItemsList}
|
||||
@@ -247,13 +249,13 @@ const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
|
||||
</TabPanel>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{alignItems: "center", justifyContent: "center"}}>
|
||||
<DialogActions sx={{ alignItems: "center", justifyContent: "center" }}>
|
||||
<Button
|
||||
onClick={handlePrev}
|
||||
variant="outlined"
|
||||
color="error"
|
||||
size="large"
|
||||
startIcon={tabState === 0 ? <ExitToAppIcon/> : <KeyboardDoubleArrowRightIcon/>}
|
||||
startIcon={tabState === 0 ? <ExitToAppIcon /> : <KeyboardDoubleArrowRightIcon />}
|
||||
>
|
||||
{tabState === 0 ? "بستن" : "مرحله قبل"}
|
||||
</Button>
|
||||
@@ -264,7 +266,7 @@ const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
|
||||
disabled={isSubmitting}
|
||||
type={"submit"}
|
||||
form="road_items"
|
||||
endIcon={<BeenhereIcon/>}
|
||||
endIcon={<BeenhereIcon />}
|
||||
>
|
||||
{isSubmitting ? "در حال ثبت فعالیت" : "ثبت فعالیت"}
|
||||
</Button>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import {Grid, Stack} from "@mui/material";
|
||||
import { Grid, Stack } from "@mui/material";
|
||||
import ImageUpload from "./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 {Controller} from "react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
import CarCode from "@/core/components/CarCode";
|
||||
import RahdarCode from "@/core/components/RahdarCode";
|
||||
import PreviousStatesInfo from "./PreviousStatesInfo";
|
||||
import NumberField from "@/core/components/NumberField";
|
||||
|
||||
const GetItemInfo = ({register, itemsList, subItemsList, control, setValue, errors, watch, getValues, is_gasht}) => {
|
||||
const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, errors, watch, getValues, is_gasht }) => {
|
||||
return (
|
||||
<Stack spacing={2}>
|
||||
<Stack>
|
||||
<PreviousStatesInfo itemsList={itemsList} subItemsList={subItemsList}/>
|
||||
<PreviousStatesInfo itemsList={itemsList} subItemsList={subItemsList} />
|
||||
</Stack>
|
||||
<Stack>
|
||||
<NumberField
|
||||
@@ -45,7 +45,7 @@ const GetItemInfo = ({register, itemsList, subItemsList, control, setValue, erro
|
||||
<Stack>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({field, fieldState: {error}}) => {
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<CarCode
|
||||
carCode={field.value || []}
|
||||
@@ -61,7 +61,7 @@ const GetItemInfo = ({register, itemsList, subItemsList, control, setValue, erro
|
||||
<Stack>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({field, fieldState: {error}}) => {
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<RahdarCode
|
||||
rahdarsCode={field.value || []}
|
||||
@@ -75,7 +75,7 @@ const GetItemInfo = ({register, itemsList, subItemsList, control, setValue, erro
|
||||
</Stack>
|
||||
<Stack>
|
||||
{subItemsList.needs_image ? (
|
||||
<ImageUpload setValue={setValue} control={control} errors={errors} getValues={getValues}/>
|
||||
<ImageUpload setValue={setValue} control={control} errors={errors} getValues={getValues} />
|
||||
) : null}
|
||||
</Stack>
|
||||
{!is_gasht ? (
|
||||
@@ -106,9 +106,9 @@ const GetItemInfo = ({register, itemsList, subItemsList, control, setValue, erro
|
||||
) : null}
|
||||
<Stack>
|
||||
{subItemsList?.needs_end_point === 1 ? (
|
||||
<MapInfoTwoMarker setValue={setValue} errors={errors}/>
|
||||
<MapInfoTwoMarker setValue={setValue} errors={errors} />
|
||||
) : (
|
||||
<MapInfoOneMarker setValue={setValue} errors={errors}/>
|
||||
<MapInfoOneMarker setValue={setValue} errors={errors} />
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {FormControl, FormHelperText, Grid} from "@mui/material";
|
||||
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";
|
||||
import { Controller } from "react-hook-form";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
const ImageUpload = ({control, setValue, errors, getValues, beforeImage = null, afterImage = null}) => {
|
||||
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);
|
||||
@@ -73,7 +73,7 @@ const ImageUpload = ({control, setValue, errors, getValues, beforeImage = null,
|
||||
<Controller
|
||||
name="before_image"
|
||||
control={control}
|
||||
render={({field: {value, onChange}}) => {
|
||||
render={({ field: { value, onChange } }) => {
|
||||
return (
|
||||
<FormControl
|
||||
error={errors.before_image}
|
||||
@@ -84,7 +84,7 @@ const ImageUpload = ({control, setValue, errors, getValues, beforeImage = null,
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<FormHelperText sx={{fontSize: "large"}} id="before_image">
|
||||
<FormHelperText sx={{ fontSize: "large" }} id="before_image">
|
||||
عکس قبل از اقدام
|
||||
</FormHelperText>
|
||||
<UploadSystem
|
||||
@@ -109,7 +109,7 @@ const ImageUpload = ({control, setValue, errors, getValues, beforeImage = null,
|
||||
<Controller
|
||||
name="after_image"
|
||||
control={control}
|
||||
render={({field: {value, onChange}}) => {
|
||||
render={({ field: { value, onChange } }) => {
|
||||
return (
|
||||
<FormControl
|
||||
error={errors.before_image}
|
||||
@@ -120,7 +120,7 @@ const ImageUpload = ({control, setValue, errors, getValues, beforeImage = null,
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<FormHelperText sx={{fontSize: "large"}} id="before_image">
|
||||
<FormHelperText sx={{ fontSize: "large" }} id="before_image">
|
||||
عکس بعد از اقدام
|
||||
</FormHelperText>
|
||||
<UploadSystem
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import {LinearProgress, Typography} from "@mui/material";
|
||||
import { LinearProgress, Typography } from "@mui/material";
|
||||
import React from "react";
|
||||
import useRoadItemGetISubtems from "@/lib/hooks/useRoadItemGetISubtems";
|
||||
import EditFormCreate from "@/components/dashboard/roadItems/operator/RowActions/EditForm/EditFormCreate";
|
||||
|
||||
const EditFormContent = ({setOpenEditDialog, onSubmit, defaultData}) => {
|
||||
const {subItemsList, loadingSubItemsList, errorSubItemsList} = useRoadItemGetISubtems(defaultData?.item_id);
|
||||
const EditFormContent = ({ setOpenEditDialog, onSubmit, defaultData }) => {
|
||||
const { subItemsList, loadingSubItemsList, errorSubItemsList } = useRoadItemGetISubtems(defaultData?.item_id);
|
||||
const subItem = subItemsList.find((SubItem) => SubItem.sub_item === defaultData?.sub_item_id);
|
||||
|
||||
const defaultValues = {
|
||||
before_image: defaultData?.before_image || null,
|
||||
after_image: defaultData?.after_image || null,
|
||||
amount: defaultData?.amount || null,
|
||||
start_point: defaultData?.start_point || {lat: "", lng: ""},
|
||||
end_point: defaultData?.end_point || {lat: "", lng: ""},
|
||||
start_point: defaultData?.start_point || { lat: "", lng: "" },
|
||||
end_point: defaultData?.end_point || { lat: "", lng: "" },
|
||||
cmms_machines: defaultData?.cmms_machines || null,
|
||||
rahdaran_id: defaultData?.rahdaran_id || null,
|
||||
};
|
||||
|
||||
const onSubmitBase = (data) => {
|
||||
let result = {...data};
|
||||
let result = { ...data };
|
||||
if (result.before_image === null) {
|
||||
delete result.before_image;
|
||||
delete data.before_image;
|
||||
@@ -73,7 +73,7 @@ const EditFormContent = ({setOpenEditDialog, onSubmit, defaultData}) => {
|
||||
خطا در دریافت اطلاعات!!!
|
||||
</Typography>
|
||||
) : loadingSubItemsList ? (
|
||||
<LinearProgress/>
|
||||
<LinearProgress />
|
||||
) : (
|
||||
<EditFormCreate
|
||||
onSubmitBase={onSubmitBase}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import {Button, DialogActions, DialogContent, Stack} from "@mui/material";
|
||||
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 { 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";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { array, mixed, object, string } from "yup";
|
||||
|
||||
const validationSchema = object({
|
||||
amount: string().required("وارد کردن مقدار الزامیست!"),
|
||||
@@ -18,7 +18,7 @@ const validationSchema = object({
|
||||
before_image: mixed()
|
||||
.nullable()
|
||||
.test("before-image-required", "لطفا عکس قبل از اقدام را بارگذاری کنید!", function (value) {
|
||||
const {subItem} = this.options.context;
|
||||
const { subItem } = this.options.context;
|
||||
const needsImage = subItem?.needs_image === 1;
|
||||
if (needsImage) {
|
||||
return !!value;
|
||||
@@ -28,7 +28,7 @@ const validationSchema = object({
|
||||
after_image: mixed()
|
||||
.nullable()
|
||||
.test("after-image-required", "لطفا عکس بعد از اقدام را بارگذاری کنید!", function (value) {
|
||||
const {subItem} = this.options.context;
|
||||
const { subItem } = this.options.context;
|
||||
const needsImage = subItem?.needs_image === 1;
|
||||
if (needsImage) {
|
||||
return !!value;
|
||||
@@ -41,7 +41,7 @@ const validationSchema = object({
|
||||
})
|
||||
.required("لطفاً نقطه شروع را مشخص کنید!"),
|
||||
end_point: mixed().test("end-point-required", "لطفاً نقطه پایان را مشخص کنید!", function (value) {
|
||||
const {subItem} = this.options.context;
|
||||
const { subItem } = this.options.context;
|
||||
const needsEndPoint = subItem?.needs_end_point === 1;
|
||||
if (needsEndPoint) {
|
||||
return !!value;
|
||||
@@ -50,7 +50,7 @@ const validationSchema = object({
|
||||
}),
|
||||
});
|
||||
|
||||
const EditFormCreate = ({defaultData, subItem, onSubmitBase, defaultValues, setOpenEditDialog}) => {
|
||||
const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, setOpenEditDialog }) => {
|
||||
const {
|
||||
control,
|
||||
getValues,
|
||||
@@ -58,17 +58,17 @@ const EditFormCreate = ({defaultData, subItem, onSubmitBase, defaultValues, setO
|
||||
register,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: {errors, isSubmitting},
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm({
|
||||
defaultValues,
|
||||
resolver: yupResolver(validationSchema),
|
||||
mode: "onBlur",
|
||||
context: {subItem},
|
||||
context: { subItem },
|
||||
});
|
||||
|
||||
return (
|
||||
<StyledForm onSubmit={handleSubmit(onSubmitBase)} id="edit_road_items">
|
||||
<DialogContent sx={{overflowY: "auto", maxHeight: "70vh"}}>
|
||||
<DialogContent sx={{ overflowY: "auto", maxHeight: "70vh" }}>
|
||||
<Stack spacing={2}>
|
||||
<Stack>
|
||||
{subItem.needs_image === 1 ? (
|
||||
@@ -111,7 +111,7 @@ const EditFormCreate = ({defaultData, subItem, onSubmitBase, defaultValues, setO
|
||||
<Stack>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({field, fieldState: {error}}) => {
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<CarCode
|
||||
carCode={field.value || []}
|
||||
@@ -128,7 +128,7 @@ const EditFormCreate = ({defaultData, subItem, onSubmitBase, defaultValues, setO
|
||||
<Stack>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({field, fieldState: {error}}) => {
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<RahdarCode
|
||||
rahdarsCode={field.value || []}
|
||||
@@ -162,8 +162,13 @@ const EditFormCreate = ({defaultData, subItem, onSubmitBase, defaultValues, setO
|
||||
<Button onClick={() => setOpenEditDialog(false)} variant="outlined" color="primary" autoFocus>
|
||||
بستن
|
||||
</Button>
|
||||
<Button form="edit_road_items" disabled={isSubmitting} type={"submit"} variant="contained"
|
||||
color="primary">
|
||||
<Button
|
||||
form="edit_road_items"
|
||||
disabled={isSubmitting}
|
||||
type={"submit"}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
>
|
||||
{isSubmitting ? "در حال ویرایش" : "ویرایش"}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"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 { 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 OperatorCreate = ({ mutate }) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
const [open, setOpen] = useState(false);
|
||||
@@ -19,14 +19,14 @@ const OperatorCreate = ({mutate}) => {
|
||||
<>
|
||||
{isMobile ? (
|
||||
<IconButton aria-label="ثبت اقدام جدید" color="primary" onClick={handleOpen}>
|
||||
<AddCircle sx={{fontSize: "25px"}}/>
|
||||
<AddCircle sx={{ fontSize: "25px" }} />
|
||||
</IconButton>
|
||||
) : (
|
||||
<Button variant="contained" color="primary" startIcon={<AddCircle/>} onClick={handleOpen}>
|
||||
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleOpen}>
|
||||
ثبت اقدام
|
||||
</Button>
|
||||
)}
|
||||
{open && <CreatePatrol open={open} setOpen={setOpen} mutate={mutate}/>}
|
||||
{open && <CreatePatrol open={open} setOpen={setOpen} mutate={mutate} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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_ROAD_PATROL_OPERATOR_LIST} from "@/core/utils/routes";
|
||||
import { EXPORT_ROAD_PATROL_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,23 +20,22 @@ 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_ROAD_PATROL_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);
|
||||
});
|
||||
@@ -47,8 +46,8 @@ const PrintExcel = ({table, filterData}) => {
|
||||
color="primary"
|
||||
variant="contained"
|
||||
disabled={loading}
|
||||
sx={{textTransform: "unset", alignSelf: "center"}}
|
||||
startIcon={loading ? <CircularProgress size={18} color="inherit"/> : <DescriptionIcon/>}
|
||||
sx={{ textTransform: "unset", alignSelf: "center" }}
|
||||
startIcon={loading ? <CircularProgress size={18} color="inherit" /> : <DescriptionIcon />}
|
||||
onClick={clickHandler}
|
||||
>
|
||||
خروجی اکسل
|
||||
|
||||
@@ -13,44 +13,40 @@ import {
|
||||
Divider,
|
||||
IconButton,
|
||||
Stack,
|
||||
Typography
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import HandymanIcon from '@mui/icons-material/Handyman';
|
||||
import HandymanIcon from "@mui/icons-material/Handyman";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import DirectionsCarIcon from '@mui/icons-material/DirectionsCar';
|
||||
import PersonIcon from '@mui/icons-material/Person';
|
||||
import DesignServicesIcon from '@mui/icons-material/DesignServices';
|
||||
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
|
||||
import PersonIcon from "@mui/icons-material/Person";
|
||||
import DesignServicesIcon from "@mui/icons-material/DesignServices";
|
||||
import EditActionDuringPatrol from "./EditActionDuringPatrol";
|
||||
|
||||
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
|
||||
loading: () => <MapLoading/>,
|
||||
loading: () => <MapLoading />,
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const ActionInfo = ({action, setActionsList, index, deleteAction}) => {
|
||||
const ActionInfo = ({ action, setActionsList, index, deleteAction }) => {
|
||||
return (
|
||||
<Card sx={{maxWidth: 300}}>
|
||||
<Card sx={{ maxWidth: 300 }}>
|
||||
<CardHeader
|
||||
avatar={
|
||||
<HandymanIcon color="primary" sx={{width: "30px", height: "30px"}}/>
|
||||
}
|
||||
title={<Typography sx={{fontSize: "14px", fontWeight: 500}}>{action.data.item_name}</Typography>}
|
||||
avatar={<HandymanIcon color="primary" sx={{ width: "30px", height: "30px" }} />}
|
||||
title={<Typography sx={{ fontSize: "14px", fontWeight: 500 }}>{action.data.item_name}</Typography>}
|
||||
subheader={action.data.sub_item_name}
|
||||
/>
|
||||
<CardContent>
|
||||
<Stack sx={{gap: 1}}>
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 1}}>
|
||||
<DesignServicesIcon/>
|
||||
<Typography variant="button">
|
||||
میزان فعالیت انجام شده:
|
||||
</Typography>
|
||||
<Stack sx={{ gap: 1 }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||||
<DesignServicesIcon />
|
||||
<Typography variant="button">میزان فعالیت انجام شده:</Typography>
|
||||
<Typography variant="button">
|
||||
{action.data.amount}({action.data.unit_fa})
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box>
|
||||
<Divider sx={{mb: 1}}>
|
||||
<Chip size="small" label="خودرو ها" icon={<DirectionsCarIcon/>}/>
|
||||
<Divider sx={{ mb: 1 }}>
|
||||
<Chip size="small" label="خودرو ها" icon={<DirectionsCarIcon />} />
|
||||
</Divider>
|
||||
<Stack>
|
||||
{action.data.cmms_machines.map((cmms_machine, index) => (
|
||||
@@ -61,8 +57,8 @@ const ActionInfo = ({action, setActionsList, index, deleteAction}) => {
|
||||
</Stack>
|
||||
</Box>
|
||||
<Box>
|
||||
<Divider sx={{mb: 1}}>
|
||||
<Chip size="small" label="راهداران" icon={<PersonIcon/>}/>
|
||||
<Divider sx={{ mb: 1 }}>
|
||||
<Chip size="small" label="راهداران" icon={<PersonIcon />} />
|
||||
</Divider>
|
||||
<Stack>
|
||||
{action.data.rahdaran_id.map((rahdar, index) => (
|
||||
@@ -77,13 +73,13 @@ const ActionInfo = ({action, setActionsList, index, deleteAction}) => {
|
||||
<CardActions disableSpacing>
|
||||
<Box>
|
||||
<IconButton aria-label="حذف فعالیت" color="error" onClick={deleteAction}>
|
||||
<DeleteIcon/>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
<EditActionDuringPatrol action={action} index={index} setActionsList={setActionsList}/>
|
||||
<EditActionDuringPatrol action={action} index={index} setActionsList={setActionsList} />
|
||||
</Box>
|
||||
</CardActions>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default ActionInfo;
|
||||
export default ActionInfo;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import {Box, Button, Divider, Grid, Typography} from "@mui/material";
|
||||
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||
import React, {useState} from "react";
|
||||
import { Box, Button, Divider, Grid, Typography } from "@mui/material";
|
||||
import AddCircleIcon from "@mui/icons-material/AddCircle";
|
||||
import React, { useState } from "react";
|
||||
import ModalActionsDuringPatrol from "./ModalActionsDuringPatrol";
|
||||
import ActionInfo from "./ActionInfo";
|
||||
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
|
||||
|
||||
const ActionsDuringPatrol = ({setValue, tabState, setTabState}) => {
|
||||
const ActionsDuringPatrol = ({ setValue, tabState, setTabState }) => {
|
||||
const [ActionsList, setActionsList] = useState([]);
|
||||
const [open, setOpen] = useState(false);
|
||||
const handleOpen = () => {
|
||||
@@ -20,29 +20,37 @@ const ActionsDuringPatrol = ({setValue, tabState, setTabState}) => {
|
||||
|
||||
const SubmitActionDuringPatrol = () => {
|
||||
setTabState(tabState + 1);
|
||||
const resultItems = ActionsList.map(item => item.result);
|
||||
const resultItems = ActionsList.map((item) => item.result);
|
||||
console.log("resultItems", resultItems);
|
||||
setValue("observed_items", resultItems);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Typography variant="h6">لیست اقدامات حین گشت</Typography>
|
||||
<Button onClick={handleOpen} startIcon={<AddCircleIcon/>} variant="outlined"
|
||||
sx={{mb: 1, alignSelf: "end"}}>
|
||||
<Button
|
||||
onClick={handleOpen}
|
||||
startIcon={<AddCircleIcon />}
|
||||
variant="outlined"
|
||||
sx={{ mb: 1, alignSelf: "end" }}
|
||||
>
|
||||
ثبت اقدام
|
||||
</Button>
|
||||
<ModalActionsDuringPatrol open={open} setOpen={setOpen} setActionsList={setActionsList}/>
|
||||
<ModalActionsDuringPatrol open={open} setOpen={setOpen} setActionsList={setActionsList} />
|
||||
</Box>
|
||||
<Divider/>
|
||||
{ActionsList.length !== 0 ?
|
||||
<Grid container spacing={2} sx={{
|
||||
p: 1,
|
||||
mt: 1,
|
||||
maxHeight: "300px",
|
||||
overflowY: "auto",
|
||||
}}>
|
||||
<Divider />
|
||||
{ActionsList.length !== 0 ? (
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
sx={{
|
||||
p: 1,
|
||||
mt: 1,
|
||||
maxHeight: "300px",
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
{ActionsList.map((action, index) => (
|
||||
<Grid key={index} item xs={12} sm={6} lg={4}>
|
||||
<ActionInfo
|
||||
@@ -54,18 +62,23 @@ const ActionsDuringPatrol = ({setValue, tabState, setTabState}) => {
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
:
|
||||
<Box sx={{my: 5, width: "100%", textAlign: "center"}}>
|
||||
<Typography variant="h6" sx={{letterSpacing: "2px", color: "#606060"}}>
|
||||
) : (
|
||||
<Box sx={{ my: 5, width: "100%", textAlign: "center" }}>
|
||||
<Typography variant="h6" sx={{ letterSpacing: "2px", color: "#606060" }}>
|
||||
فعالیتی ثبت نکرده اید
|
||||
</Typography>
|
||||
</Box>
|
||||
}
|
||||
)}
|
||||
<Box>
|
||||
<Box sx={{display: "flex", gap: 1, justifyContent: "center"}}>
|
||||
<Button variant="contained" color="primary" onClick={SubmitActionDuringPatrol}
|
||||
disabled={ActionsList === []}
|
||||
endIcon={<KeyboardDoubleArrowLeftIcon/>} sx={{mt: 2}}>
|
||||
<Box sx={{ display: "flex", gap: 1, justifyContent: "center" }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={SubmitActionDuringPatrol}
|
||||
disabled={ActionsList === []}
|
||||
endIcon={<KeyboardDoubleArrowLeftIcon />}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
نهایی کردن درخواست
|
||||
</Button>
|
||||
</Box>
|
||||
@@ -74,4 +87,4 @@ const ActionsDuringPatrol = ({setValue, tabState, setTabState}) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ActionsDuringPatrol;
|
||||
export default ActionsDuringPatrol;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import React, {useEffect, useState} from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -12,17 +12,17 @@ import {
|
||||
OutlinedInput,
|
||||
Slide,
|
||||
Stack,
|
||||
Typography
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import BeenhereIcon from "@mui/icons-material/Beenhere";
|
||||
import ForwardToInboxIcon from "@mui/icons-material/ForwardToInbox";
|
||||
import {formatCounter} from "@/core/utils/formatCounter";
|
||||
import { formatCounter } from "@/core/utils/formatCounter";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import {GET_OTP_TOKEN} from "@/core/utils/routes";
|
||||
import { GET_OTP_TOKEN } from "@/core/utils/routes";
|
||||
import moment from "jalali-moment";
|
||||
|
||||
const CompeleteRequest = ({watch, isSubmitting, setValue, register}) => {
|
||||
const requestServer = useRequest({auth: true});
|
||||
const CompeleteRequest = ({ watch, isSubmitting, setValue, register }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [delayPerRequest, setDelayPerRequest] = useState(false);
|
||||
const [phoneNumber, setPhoneNumber] = useState("");
|
||||
const [validPhone, setValidPhone] = useState(false);
|
||||
@@ -32,7 +32,7 @@ const CompeleteRequest = ({watch, isSubmitting, setValue, register}) => {
|
||||
const [readyToVerify, setReadyToVerify] = useState(false);
|
||||
|
||||
const handleNumericInput = (e) => {
|
||||
e.target.value = e.target.value.replace(/[^0-9]/g, '');
|
||||
e.target.value = e.target.value.replace(/[^0-9]/g, "");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -55,7 +55,7 @@ const CompeleteRequest = ({watch, isSubmitting, setValue, register}) => {
|
||||
}
|
||||
if (delayPerRequest && counter > 0) {
|
||||
const timer = setInterval(() => {
|
||||
setCounter(prevCounter => prevCounter - 1);
|
||||
setCounter((prevCounter) => prevCounter - 1);
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(timer);
|
||||
@@ -69,82 +69,89 @@ const CompeleteRequest = ({watch, isSubmitting, setValue, register}) => {
|
||||
setOtpSended(true);
|
||||
setDelayPerRequest(true);
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Stack>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Box>
|
||||
<Typography sx={{color: "#777777", fontWeight: 500}}
|
||||
variant="body1">{moment(watch("start_time")).locale("fa").format("YYYY/MM/DD | HH:mm")}</Typography>
|
||||
<Typography sx={{ color: "#777777", fontWeight: 500 }} variant="body1">
|
||||
{moment(watch("start_time")).locale("fa").format("YYYY/MM/DD | HH:mm")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography sx={{color: "#777777", fontWeight: 500}}
|
||||
variant="body1">{moment(watch("end_time")).locale("fa").format("YYYY/MM/DD | HH:mm")}</Typography>
|
||||
<Typography sx={{ color: "#777777", fontWeight: 500 }} variant="body1">
|
||||
{moment(watch("end_time")).locale("fa").format("YYYY/MM/DD | HH:mm")}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
<Grid container spacing={2} sx={{alignItems: "start", my: 1}}>
|
||||
<Grid item xs={12} lg={6} sx={{display: "flex", alignItems: "center"}}>
|
||||
<Chip label="مدت زمان روشن بودن خودرو"/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Grid container spacing={2} sx={{ alignItems: "start", my: 1 }}>
|
||||
<Grid item xs={12} lg={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip label="مدت زمان روشن بودن خودرو" />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("vehicle_runtime")}</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={6} sx={{display: "flex", alignItems: "center"}}>
|
||||
<Chip label="میزان سوخت مصرفی"/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Grid item xs={12} lg={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip label="میزان سوخت مصرفی" />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("fuel_consumption")}</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={6} sx={{display: "flex", alignItems: "center"}}>
|
||||
<Chip label="تعداد نقاط توقف"/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Grid item xs={12} lg={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip label="تعداد نقاط توقف" />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("stop_points").length}</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={6} sx={{display: "flex", alignItems: "center"}}>
|
||||
<Chip label="مسافت پیموده شده"/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Grid item xs={12} lg={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip label="مسافت پیموده شده" />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("distance")}</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={6} sx={{display: "flex", alignItems: "center"}}>
|
||||
<Chip label="تعداد فعالیت های حین گشت"/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Grid item xs={12} lg={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip label="تعداد فعالیت های حین گشت" />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("observed_items").length}</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={3} sx={{alignItems: "start", my: 2}}>
|
||||
<Grid container spacing={3} sx={{ alignItems: "start", my: 2 }}>
|
||||
<Grid item xs={12} lg={6}>
|
||||
<Divider><Chip label="خودرو گشت"/></Divider>
|
||||
<Box sx={{display: "flex", alignItems: "center", my: 1}}>
|
||||
<Divider>
|
||||
<Chip label="خودرو گشت" />
|
||||
</Divider>
|
||||
<Box sx={{ display: "flex", alignItems: "center", my: 1 }}>
|
||||
<Typography>کد</Typography>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("road_patrol_machines_id.machine_code")}</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", my: 1}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", my: 1 }}>
|
||||
<Typography>نام</Typography>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("road_patrol_machines_id.car_name")}</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", my: 1}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", my: 1 }}>
|
||||
<Typography>پلاک</Typography>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>{watch("road_patrol_machines_id.plak_number")}</Typography>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={6}>
|
||||
<Divider><Chip label="راهدار / راهداران حاضر در گشت"/></Divider>
|
||||
<Divider>
|
||||
<Chip label="راهدار / راهداران حاضر در گشت" />
|
||||
</Divider>
|
||||
{watch("road_patrol_rahdaran_id")?.map((rahdar, index) => (
|
||||
<Box sx={{display: "flex", alignItems: "center", my: 1}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", my: 1 }}>
|
||||
<Typography>نام و کد راهدار</Typography>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography>{rahdar.name} | {rahdar.code}</Typography>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography>
|
||||
{rahdar.name} | {rahdar.code}
|
||||
</Typography>
|
||||
</Box>
|
||||
))}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Box sx={{display: "flex", gap: 2, my: 2, justifyContent: "space-around"}}>
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 2}}>
|
||||
<Box sx={{ display: "flex", gap: 2, my: 2, justifyContent: "space-around" }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||
<FormControl size="small" fullWidth variant="outlined">
|
||||
<InputLabel htmlFor="phone_number">شماره تلفن مامور گشت</InputLabel>
|
||||
<OutlinedInput
|
||||
@@ -160,14 +167,18 @@ const CompeleteRequest = ({watch, isSubmitting, setValue, register}) => {
|
||||
onInput={handleNumericInput}
|
||||
type="text"
|
||||
inputProps={{
|
||||
maxLength: 11
|
||||
maxLength: 11,
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<Button onClick={sendOtp} disabled={!validPhone || delayPerRequest} variant="contained"
|
||||
color="success"
|
||||
sx={{textWrap: "nowrap", px: 4}}
|
||||
endIcon={<ForwardToInboxIcon/>}>
|
||||
<Button
|
||||
onClick={sendOtp}
|
||||
disabled={!validPhone || delayPerRequest}
|
||||
variant="contained"
|
||||
color="success"
|
||||
sx={{ textWrap: "nowrap", px: 4 }}
|
||||
endIcon={<ForwardToInboxIcon />}
|
||||
>
|
||||
{delayPerRequest ? formatCounter(counter) : "دریافت کد"}
|
||||
</Button>
|
||||
</Box>
|
||||
@@ -207,7 +218,7 @@ const CompeleteRequest = ({watch, isSubmitting, setValue, register}) => {
|
||||
disabled={isSubmitting}
|
||||
type={"submit"}
|
||||
form="patrol_form"
|
||||
endIcon={<BeenhereIcon/>}
|
||||
endIcon={<BeenhereIcon />}
|
||||
>
|
||||
{isSubmitting ? "در حال ثبت فعالیت" : "ثبت فعالیت"}
|
||||
</Button>
|
||||
@@ -215,4 +226,4 @@ const CompeleteRequest = ({watch, isSubmitting, setValue, register}) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default CompeleteRequest;
|
||||
export default CompeleteRequest;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import React, {useState} from "react";
|
||||
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 { 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: () => <MapLoading/>,
|
||||
loading: () => <MapLoading />,
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const EditActionDuringPatrol = ({action, index, setActionsList}) => {
|
||||
const EditActionDuringPatrol = ({ action, index, setActionsList }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const handleOpen = () => {
|
||||
@@ -35,7 +35,7 @@ const EditActionDuringPatrol = ({action, index, setActionsList}) => {
|
||||
return (
|
||||
<>
|
||||
<IconButton aria-label="ویرایش فعالیت" color="primary" onClick={handleOpen}>
|
||||
<EditIcon/>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
<Dialog
|
||||
maxWidth="sm"
|
||||
@@ -48,10 +48,10 @@ const EditActionDuringPatrol = ({action, index, setActionsList}) => {
|
||||
}}
|
||||
>
|
||||
<DialogTitle>ویرایش اطلاعات</DialogTitle>
|
||||
<EditFormContent setOpenEditDialog={setOpen} onSubmit={HandleSubmit} defaultData={action.data}/>
|
||||
<EditFormContent setOpenEditDialog={setOpen} onSubmit={HandleSubmit} defaultData={action.data} />
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditActionDuringPatrol;
|
||||
export default EditActionDuringPatrol;
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import CreateFormContent from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/CreateFormContent";
|
||||
import {Dialog} from "@mui/material";
|
||||
|
||||
const ModalActionsDuringPatrol = ({open, setOpen, setActionsList}) => {
|
||||
import { Dialog } from "@mui/material";
|
||||
|
||||
const ModalActionsDuringPatrol = ({ open, setOpen, setActionsList }) => {
|
||||
const HandleSubmit = async (data) => {
|
||||
setActionsList((prev) => [...prev, data]);
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} fullWidth maxWidth="sm">
|
||||
<CreateFormContent setOpen={setOpen} onSubmit={HandleSubmit} is_gasht={true}/>
|
||||
<CreateFormContent setOpen={setOpen} onSubmit={HandleSubmit} is_gasht={true} />
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
export default ModalActionsDuringPatrol;
|
||||
};
|
||||
export default ModalActionsDuringPatrol;
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
"use client";
|
||||
|
||||
import {Box, Button, Chip, Divider, IconButton, InputAdornment, Stack} from "@mui/material";
|
||||
import React, {useEffect, useState} from "react";
|
||||
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';
|
||||
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 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 {Controller} from "react-hook-form";
|
||||
import {GET_FMS_DATA} from "@/core/utils/routes";
|
||||
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: () => <MapLoading/>,
|
||||
loading: () => <MapLoading />,
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const PatrolDetail = ({control, watch, setValue, tabState, setTabState}) => {
|
||||
const requestServer = useRequest({notificationSuccess: true});
|
||||
const [patrolResultStatus, setPatrolResultStatus] = 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 [patrolData, setPatrolData] = useState(null);
|
||||
|
||||
@@ -35,18 +35,19 @@ const PatrolDetail = ({control, watch, setValue, tabState, setTabState}) => {
|
||||
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) => {
|
||||
});
|
||||
}
|
||||
})
|
||||
.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(() => {
|
||||
const roadPatrolMachinesId = watch("road_patrol_machines_id");
|
||||
@@ -64,14 +65,14 @@ const PatrolDetail = ({control, watch, setValue, tabState, setTabState}) => {
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
my: 3
|
||||
my: 3,
|
||||
}}
|
||||
>
|
||||
<Box sx={{display: "flex", flexDirection: {xs: "column", lg: "row"}, gap: 2}}>
|
||||
<Stack sx={{minWidth: "200px"}}>
|
||||
<Box sx={{ display: "flex", flexDirection: { xs: "column", lg: "row" }, gap: 2 }}>
|
||||
<Stack sx={{ minWidth: "200px" }}>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({field, fieldState: {error}}) => {
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<CarCode
|
||||
carCode={field.value}
|
||||
@@ -83,103 +84,120 @@ const PatrolDetail = ({control, watch, setValue, tabState, setTabState}) => {
|
||||
name={"road_patrol_machines_id"}
|
||||
/>
|
||||
</Stack>
|
||||
<Box sx={{display: "flex", gap: 2}}>
|
||||
<Box sx={{ display: "flex", gap: 2 }}>
|
||||
<LocalizationProvider
|
||||
dateAdapter={AdapterDateFnsJalali}
|
||||
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
|
||||
>
|
||||
<MobileDateTimePicker value={watch("start_time") ? new Date(watch("start_time")) : null}
|
||||
ampm={false}
|
||||
name="تاریخ و ساعت شروع گشت"
|
||||
closeOnSelect
|
||||
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");
|
||||
setValue("start_time", formattedDate);
|
||||
}}
|
||||
slotProps={{
|
||||
textField: {
|
||||
size: "small",
|
||||
placeholder: "تاریخ و ساعت شروع گشت",
|
||||
InputProps: {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
setValue("start_time", "");
|
||||
}}
|
||||
sx={{
|
||||
color: "#bfbfbf",
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||
color: "#363434",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ClearIcon/>
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
},
|
||||
},
|
||||
}} label="تاریخ و ساعت شروع گشت"
|
||||
<MobileDateTimePicker
|
||||
value={watch("start_time") ? new Date(watch("start_time")) : null}
|
||||
ampm={false}
|
||||
name="تاریخ و ساعت شروع گشت"
|
||||
closeOnSelect
|
||||
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");
|
||||
setValue("start_time", formattedDate);
|
||||
}}
|
||||
slotProps={{
|
||||
textField: {
|
||||
size: "small",
|
||||
placeholder: "تاریخ و ساعت شروع گشت",
|
||||
InputProps: {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
setValue("start_time", "");
|
||||
}}
|
||||
sx={{
|
||||
color: "#bfbfbf",
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||
color: "#363434",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ClearIcon />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
},
|
||||
},
|
||||
}}
|
||||
label="تاریخ و ساعت شروع گشت"
|
||||
/>
|
||||
<MobileDateTimePicker
|
||||
value={watch("end_time") ? new Date(watch("end_time")) : null}
|
||||
ampm={false}
|
||||
name="تاریخ و ساعت پایان گشت"
|
||||
closeOnSelect
|
||||
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");
|
||||
setValue("end_time", formattedDate);
|
||||
}}
|
||||
slotProps={{
|
||||
textField: {
|
||||
size: "small",
|
||||
placeholder: "تاریخ و ساعت پایان گشت",
|
||||
InputProps: {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
setValue("end_time", "");
|
||||
}}
|
||||
sx={{
|
||||
color: "#bfbfbf",
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||
color: "#363434",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ClearIcon />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
},
|
||||
},
|
||||
}}
|
||||
label="تاریخ و ساعت پایان گشت"
|
||||
/>
|
||||
<MobileDateTimePicker value={watch("end_time") ? new Date(watch("end_time")) : null}
|
||||
ampm={false}
|
||||
name="تاریخ و ساعت پایان گشت"
|
||||
closeOnSelect
|
||||
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");
|
||||
setValue("end_time", formattedDate);
|
||||
}}
|
||||
slotProps={{
|
||||
textField: {
|
||||
size: "small",
|
||||
placeholder: "تاریخ و ساعت پایان گشت",
|
||||
InputProps: {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
setValue("end_time", "");
|
||||
}}
|
||||
sx={{
|
||||
color: "#bfbfbf",
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||
color: "#363434",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ClearIcon/>
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
},
|
||||
},
|
||||
}} label="تاریخ و ساعت پایان گشت"/>
|
||||
</LocalizationProvider>
|
||||
</Box>
|
||||
<Button variant="contained" onClick={requestPatrolInfo} color="success" disabled={!readyToRequest}
|
||||
endIcon={<SearchIcon/>}>درخواست
|
||||
اطلاعات</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={requestPatrolInfo}
|
||||
color="success"
|
||||
disabled={!readyToRequest}
|
||||
endIcon={<SearchIcon />}
|
||||
>
|
||||
درخواست اطلاعات
|
||||
</Button>
|
||||
</Box>
|
||||
<Divider sx={{my: 2, width: "100%"}}>
|
||||
<Chip color="success" label="مشخصات گشت"/>
|
||||
<Divider sx={{ my: 2, width: "100%" }}>
|
||||
<Chip color="success" label="مشخصات گشت" />
|
||||
</Divider>
|
||||
{patrolResultStatus === 0 ?
|
||||
<PatrolDetailInfo patrolData={patrolData} tabState={tabState} setTabState={setTabState}
|
||||
setValue={setValue}/> :
|
||||
<PatrolResultCodeErrors ResultCode={patrolResultStatus}/>}
|
||||
{patrolResultStatus === 0 ? (
|
||||
<PatrolDetailInfo
|
||||
patrolData={patrolData}
|
||||
tabState={tabState}
|
||||
setTabState={setTabState}
|
||||
setValue={setValue}
|
||||
/>
|
||||
) : (
|
||||
<PatrolResultCodeErrors ResultCode={patrolResultStatus} />
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default PatrolDetail;
|
||||
export default PatrolDetail;
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import {Box, Button, Card, CardActions, CardContent, Chip, Divider, Slide, Stack, Typography} from "@mui/material";
|
||||
import React, {useEffect} from "react";
|
||||
import { Box, Button, Card, CardActions, CardContent, Chip, Divider, Slide, Stack, Typography } from "@mui/material";
|
||||
import React, { useEffect } 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 ElectricCarIcon from '@mui/icons-material/ElectricCar';
|
||||
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 ElectricCarIcon from "@mui/icons-material/ElectricCar";
|
||||
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
|
||||
import QrCode2Icon from '@mui/icons-material/QrCode2';
|
||||
import QrCode2Icon from "@mui/icons-material/QrCode2";
|
||||
import moment from "jalali-moment";
|
||||
import PatrolMapFeatures from "./PatrolMapFeatures";
|
||||
import {useMap} from "react-leaflet";
|
||||
import { useMap } from "react-leaflet";
|
||||
|
||||
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
|
||||
loading: () => <MapLoading/>,
|
||||
loading: () => <MapLoading />,
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const MapItemViewBound = ({patrolData, bound}) => {
|
||||
const MapItemViewBound = ({ patrolData, bound }) => {
|
||||
const map = useMap();
|
||||
|
||||
useEffect(() => {
|
||||
if (bound.length !== 0) {
|
||||
map.fitBounds(bound,
|
||||
{paddingTopLeft: [16, 16], paddingBottomRight: [16, 130]}
|
||||
);
|
||||
map.fitBounds(bound, { paddingTopLeft: [16, 16], paddingBottomRight: [16, 130] });
|
||||
}
|
||||
}, [bound]);
|
||||
|
||||
@@ -37,102 +35,103 @@ const MapItemViewBound = ({patrolData, bound}) => {
|
||||
<>
|
||||
{patrolData.stopPoints.map((stopPoint, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<PatrolMapFeatures stopPoint={stopPoint}/>
|
||||
<PatrolMapFeatures stopPoint={stopPoint} />
|
||||
</React.Fragment>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const PatrolDetailInfo = ({patrolData, tabState, setTabState, setValue}) => {
|
||||
const bound = patrolData.stopPoints.map(point => [point.latitude, point.longitude]);
|
||||
const PatrolDetailInfo = ({ patrolData, tabState, setTabState, setValue }) => {
|
||||
const bound = patrolData.stopPoints.map((point) => [point.latitude, point.longitude]);
|
||||
|
||||
const SendPatrolInfo = () => {
|
||||
setValue("vehicle_runtime", patrolData.accOnDuration)
|
||||
setValue("fuel_consumption", patrolData.fuelConsumption)
|
||||
setValue("distance", patrolData.mileage)
|
||||
setValue("stop_points", patrolData.stopPoints)
|
||||
setTabState(tabState + 1)
|
||||
}
|
||||
setValue("vehicle_runtime", patrolData.accOnDuration);
|
||||
setValue("fuel_consumption", patrolData.fuelConsumption);
|
||||
setValue("distance", patrolData.mileage);
|
||||
setValue("stop_points", patrolData.stopPoints);
|
||||
setTabState(tabState + 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<Slide in={true} sx={{width: "100%"}}>
|
||||
<Slide in={true} sx={{ width: "100%" }}>
|
||||
<Card>
|
||||
<CardContent
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: {xs: "column", lg: "row"},
|
||||
flexDirection: { xs: "column", lg: "row" },
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
gap: {xs: 2, lg: 0},
|
||||
}}>
|
||||
<Stack sx={{minWidth: {xs: "100%", lg: "300px"}, gap: 2}}>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="مدت زمان روشن بودن خودرو" icon={<ElectricCarIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
gap: { xs: 2, lg: 0 },
|
||||
}}
|
||||
>
|
||||
<Stack sx={{ minWidth: { xs: "100%", lg: "300px" }, gap: 2 }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="مدت زمان روشن بودن خودرو" icon={<ElectricCarIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{Math.floor(patrolData.accOnDuration / 60)} دقیقه
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="نام خودرو" icon={<DirectionsCarFilledIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="نام خودرو" icon={<DirectionsCarFilledIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{patrolData.roadPatrolMachinesId.car_name}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="کد خودرو" icon={<QrCode2Icon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="کد خودرو" icon={<QrCode2Icon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{patrolData.roadPatrolMachinesId.machine_code}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="پلاک خودرو" icon={<DirectionsCarFilledIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="پلاک خودرو" icon={<DirectionsCarFilledIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{patrolData.roadPatrolMachinesId.plak_number}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="زمان شروع گشت" icon={<QueryBuilderIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="زمان شروع گشت" icon={<QueryBuilderIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{moment(patrolData.start_time).locale("fa").format("HH:mm | YYYY/MM/DD")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="زمان پایان گشت" icon={<WatchLaterIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="زمان پایان گشت" icon={<WatchLaterIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{moment(patrolData.end_time).locale("fa").format("HH:mm | YYYY/MM/DD")}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="مسافت" icon={<AddRoadIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="مسافت" icon={<AddRoadIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{(patrolData.mileage / 1000).toFixed(1)} کیلومتر
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="میزان مصرف سوخت" icon={<LocalGasStationIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="میزان مصرف سوخت" icon={<LocalGasStationIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{Math.round(patrolData.fuelConsumption * 10) / 10} لیتر
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Chip size="small" label="تعداد توقف در مسیر" icon={<ShareLocationIcon/>}/>
|
||||
<Divider sx={{flex: 1, mx: 2}}/>
|
||||
<Typography sx={{fontSize: "13px", fontWeight: 400}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Chip size="small" label="تعداد توقف در مسیر" icon={<ShareLocationIcon />} />
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography sx={{ fontSize: "13px", fontWeight: 400 }}>
|
||||
{patrolData.stopPoints.length} مورد
|
||||
</Typography>
|
||||
</Box>
|
||||
</Stack>
|
||||
<Divider orientation="vertical" flexItem/>
|
||||
<Stack spacing={1} sx={{height: "300px", width: {xs: "100%", lg: "350px"}}}>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<Stack spacing={1} sx={{ height: "300px", width: { xs: "100%", lg: "350px" } }}>
|
||||
<Box
|
||||
sx={{
|
||||
p: 1,
|
||||
@@ -151,16 +150,21 @@ const PatrolDetailInfo = ({patrolData, tabState, setTabState, setValue}) => {
|
||||
}}
|
||||
>
|
||||
<MapLayer position={bound}>
|
||||
<MapItemViewBound patrolData={patrolData} bound={bound}/>
|
||||
<MapItemViewBound patrolData={patrolData} bound={bound} />
|
||||
</MapLayer>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</CardContent>
|
||||
<CardActions sx={{alignItems: "center", justifyContent: "center"}}>
|
||||
<Box sx={{display: "flex", gap: 1}}>
|
||||
<Button variant="contained" color="primary" onClick={SendPatrolInfo}
|
||||
endIcon={<KeyboardDoubleArrowLeftIcon/>} sx={{mt: 2}}>
|
||||
<CardActions sx={{ alignItems: "center", justifyContent: "center" }}>
|
||||
<Box sx={{ display: "flex", gap: 1 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={SendPatrolInfo}
|
||||
endIcon={<KeyboardDoubleArrowLeftIcon />}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
تایید اطلاعات و رفتن به مرحله بعد
|
||||
</Button>
|
||||
</Box>
|
||||
@@ -170,4 +174,4 @@ const PatrolDetailInfo = ({patrolData, tabState, setTabState, setValue}) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PatrolDetailInfo;
|
||||
export default PatrolDetailInfo;
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import {Box, DialogContent, Tab, Tabs, useMediaQuery} from "@mui/material";
|
||||
import {useTheme} from "@emotion/react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
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 { Box, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
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 PatrolDetail from "./PatrolDetail";
|
||||
import SuperVisorsDetail from "./SuperVisorsDetail";
|
||||
import ActionsDuringPatrol from "./ActionsDurigPatrol";
|
||||
import {useForm} from "react-hook-form";
|
||||
import { useForm } from "react-hook-form";
|
||||
import StyledForm from "@/core/components/StyledForm";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import CompeleteRequest from "./CompeleteRequest";
|
||||
|
||||
function TabPanel(props) {
|
||||
const {children, value, index} = props;
|
||||
const { children, value, index } = props;
|
||||
|
||||
return (
|
||||
<div role="tabpanel" hidden={value !== index}>
|
||||
@@ -37,11 +37,11 @@ const defaultValues = {
|
||||
distance: "",
|
||||
observed_items: null,
|
||||
phone_number: "",
|
||||
otp_token: ""
|
||||
otp_token: "",
|
||||
};
|
||||
|
||||
const PatrolForms = ({mutate, setOpen}) => {
|
||||
const requestServer = useRequest({notificationSuccess: true});
|
||||
const PatrolForms = ({ mutate, setOpen }) => {
|
||||
const requestServer = useRequest({ notificationSuccess: true });
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
|
||||
const [tabState, setTabState] = useState(0);
|
||||
@@ -65,14 +65,14 @@ const PatrolForms = ({mutate, setOpen}) => {
|
||||
handleSubmit,
|
||||
setValue,
|
||||
resetField,
|
||||
formState: {isSubmitting},
|
||||
formState: { isSubmitting },
|
||||
} = useForm({
|
||||
defaultValues,
|
||||
mode: "onBlur"
|
||||
mode: "onBlur",
|
||||
});
|
||||
|
||||
const onSubmit = async (data) => {
|
||||
console.log("data", data)
|
||||
console.log("data", data);
|
||||
// const formData = new FormData();
|
||||
// data.road_patrol_rahdaran_id.forEach((rahdar, index) => formData.append(`road_patrol_rahdaran_id[${index}]`, rahdar.id));
|
||||
// formData.append(`road_patrol_machines_id[0]`, data.road_patrol_machines_id.id)
|
||||
@@ -109,7 +109,6 @@ const PatrolForms = ({mutate, setOpen}) => {
|
||||
// } else {
|
||||
// console.log("error phone number")
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -126,13 +125,13 @@ const PatrolForms = ({mutate, setOpen}) => {
|
||||
backgroundColor: "#efefef",
|
||||
}}
|
||||
>
|
||||
<Tab disabled={!(activeUpTo >= 0)} icon={<TaxiAlertIcon/>} label="مشخصات گشت"></Tab>
|
||||
<Tab disabled={!(activeUpTo >= 1)} icon={<EngineeringIcon/>} label="مشخصات راهداران"></Tab>
|
||||
<Tab disabled={!(activeUpTo >= 2)} icon={<HandymanIcon/>} label="اقدامات حین گشت"></Tab>
|
||||
<Tab disabled={!(activeUpTo >= 3)} icon={<VerifiedIcon/>} label="تکمیل درخواست"></Tab>
|
||||
<Tab disabled={!(activeUpTo >= 0)} icon={<TaxiAlertIcon />} label="مشخصات گشت"></Tab>
|
||||
<Tab disabled={!(activeUpTo >= 1)} icon={<EngineeringIcon />} label="مشخصات راهداران"></Tab>
|
||||
<Tab disabled={!(activeUpTo >= 2)} icon={<HandymanIcon />} label="اقدامات حین گشت"></Tab>
|
||||
<Tab disabled={!(activeUpTo >= 3)} icon={<VerifiedIcon />} label="تکمیل درخواست"></Tab>
|
||||
</Tabs>
|
||||
<DialogContent dividers sx={{display: "flex"}}>
|
||||
<Box sx={{flex: 1}}>
|
||||
<DialogContent dividers sx={{ display: "flex" }}>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<TabPanel value={tabState} index={0}>
|
||||
<PatrolDetail
|
||||
control={control}
|
||||
@@ -148,7 +147,8 @@ const PatrolForms = ({mutate, setOpen}) => {
|
||||
setValue={setValue}
|
||||
watch={watch}
|
||||
tabState={tabState}
|
||||
setTabState={setTabState}/>
|
||||
setTabState={setTabState}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel value={tabState} index={2}>
|
||||
<ActionsDuringPatrol
|
||||
@@ -168,8 +168,8 @@ const PatrolForms = ({mutate, setOpen}) => {
|
||||
</TabPanel>
|
||||
</Box>
|
||||
{!isMobile && (
|
||||
<Box sx={{display: "flex", alignItems: "center"}}>
|
||||
<PatrolTimeLine tabState={tabState}/>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<PatrolTimeLine tabState={tabState} />
|
||||
</Box>
|
||||
)}
|
||||
</DialogContent>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import {Typography} from "@mui/material";
|
||||
import React, {useRef} from "react";
|
||||
import {Marker, Popup} from "react-leaflet";
|
||||
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 PatrolMapFeatures = ({ stopPoint }) => {
|
||||
const position = [stopPoint.latitude, stopPoint.longitude];
|
||||
const mapPatrolMarker = useRef();
|
||||
const createCustomIcon = (size, iconUrl) => {
|
||||
@@ -18,21 +18,21 @@ const PatrolMapFeatures = ({stopPoint}) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Marker ref={mapPatrolMarker}
|
||||
icon={L.icon({
|
||||
iconUrl: AzmayeshIcon.src,
|
||||
iconSize: [35, 35],
|
||||
iconAnchor: [35 / 2, 35],
|
||||
popupAnchor: [0, -35],
|
||||
})}
|
||||
position={position}
|
||||
<Marker
|
||||
ref={mapPatrolMarker}
|
||||
icon={L.icon({
|
||||
iconUrl: AzmayeshIcon.src,
|
||||
iconSize: [35, 35],
|
||||
iconAnchor: [35 / 2, 35],
|
||||
popupAnchor: [0, -35],
|
||||
})}
|
||||
position={position}
|
||||
>
|
||||
<Popup>
|
||||
<Typography variant="button">مدت زمان
|
||||
توقف: {stopPoint.duration} ثانیه</Typography>
|
||||
<Typography variant="button">مدت زمان توقف: {stopPoint.duration} ثانیه</Typography>
|
||||
</Popup>
|
||||
</Marker>
|
||||
);
|
||||
};
|
||||
|
||||
export default PatrolMapFeatures;
|
||||
export default PatrolMapFeatures;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import {Box, Typography} from "@mui/material";
|
||||
import { Box, Typography } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
const PatrolResultCodeErrors = ({ResultCode}) => {
|
||||
const PatrolResultCodeErrors = ({ ResultCode }) => {
|
||||
const errorMessages = {
|
||||
[-1]: "نام کاربری یا کلمه عبور صحیح نمیباشد",
|
||||
[-2]: "ردیاب به خودرو انتخابی متصل نیست",
|
||||
@@ -14,12 +14,12 @@ const PatrolResultCodeErrors = ({ResultCode}) => {
|
||||
const message = errorMessages[ResultCode] || "ابتدا اطلاعات بالا را تکمیل نمایید";
|
||||
|
||||
return (
|
||||
<Box sx={{my: 5}}>
|
||||
<Typography variant="h6" sx={{letterSpacing: "2px", color: ResultCode ? "error.main" : "#606060"}}>
|
||||
<Box sx={{ my: 5 }}>
|
||||
<Typography variant="h6" sx={{ letterSpacing: "2px", color: ResultCode ? "error.main" : "#606060" }}>
|
||||
{message}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default PatrolResultCodeErrors;
|
||||
export default PatrolResultCodeErrors;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import {Box, CircularProgress, Typography} from "@mui/material";
|
||||
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 { Box, CircularProgress, Typography } from "@mui/material";
|
||||
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 {
|
||||
Timeline,
|
||||
TimelineConnector,
|
||||
@@ -15,83 +15,99 @@ import {
|
||||
TimelineSeparator,
|
||||
} from "@mui/lab";
|
||||
|
||||
const PatrolTimeLine = ({tabState}) => {
|
||||
const PatrolTimeLine = ({ tabState }) => {
|
||||
return (
|
||||
<Box sx={{display: "flex", alignItems: "center"}}>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Timeline
|
||||
position="right"
|
||||
sx={{
|
||||
[`& .${timelineItemClasses.root}:before`]: {flex: 0, padding: 0},
|
||||
[`& .${timelineItemClasses.root}:before`]: { flex: 0, padding: 0 },
|
||||
}}
|
||||
>
|
||||
<TimelineItem>
|
||||
<TimelineSeparator>
|
||||
<TimelineConnector/>
|
||||
<TimelineDot sx={{backgroundColor: "#fff"}}>
|
||||
{tabState === 0 ? <CircularProgress size="23px"/> : <TaxiAlertIcon
|
||||
color={tabState > 0 ? "success" : "error"}
|
||||
sx={{width: "1.5rem", height: "1.5rem"}}
|
||||
/>}
|
||||
<TimelineConnector />
|
||||
<TimelineDot sx={{ backgroundColor: "#fff" }}>
|
||||
{tabState === 0 ? (
|
||||
<CircularProgress size="23px" />
|
||||
) : (
|
||||
<TaxiAlertIcon
|
||||
color={tabState > 0 ? "success" : "error"}
|
||||
sx={{ width: "1.5rem", height: "1.5rem" }}
|
||||
/>
|
||||
)}
|
||||
</TimelineDot>
|
||||
<TimelineConnector/>
|
||||
<TimelineConnector />
|
||||
</TimelineSeparator>
|
||||
<TimelineContent sx={{py: "12px", px: 2}}>
|
||||
<TimelineContent sx={{ py: "12px", px: 2 }}>
|
||||
<Typography variant="h6">مشخصات گشت</Typography>
|
||||
<Typography variant="caption" sx={{color: "#606060"}}>
|
||||
<Typography variant="caption" sx={{ color: "#606060" }}>
|
||||
تایید اطلاعات اولیه گشت
|
||||
</Typography>
|
||||
</TimelineContent>
|
||||
</TimelineItem>
|
||||
<TimelineItem>
|
||||
<TimelineSeparator>
|
||||
<TimelineConnector/>
|
||||
<TimelineDot sx={{backgroundColor: "#fff"}}>
|
||||
{tabState === 1 ? <CircularProgress size="23px"/> : <EngineeringIcon
|
||||
color={tabState > 1 ? "success" : "error"}
|
||||
sx={{width: "1.5rem", height: "1.5rem"}}
|
||||
/>}
|
||||
<TimelineConnector />
|
||||
<TimelineDot sx={{ backgroundColor: "#fff" }}>
|
||||
{tabState === 1 ? (
|
||||
<CircularProgress size="23px" />
|
||||
) : (
|
||||
<EngineeringIcon
|
||||
color={tabState > 1 ? "success" : "error"}
|
||||
sx={{ width: "1.5rem", height: "1.5rem" }}
|
||||
/>
|
||||
)}
|
||||
</TimelineDot>
|
||||
<TimelineConnector/>
|
||||
<TimelineConnector />
|
||||
</TimelineSeparator>
|
||||
<TimelineContent sx={{py: "12px", px: 2}}>
|
||||
<TimelineContent sx={{ py: "12px", px: 2 }}>
|
||||
<Typography variant="h6">مشخصات راهداران</Typography>
|
||||
<Typography variant="caption" sx={{color: "#606060"}}>
|
||||
<Typography variant="caption" sx={{ color: "#606060" }}>
|
||||
راهدار / راهداران حاضر در گشت
|
||||
</Typography>
|
||||
</TimelineContent>
|
||||
</TimelineItem>
|
||||
<TimelineItem>
|
||||
<TimelineSeparator>
|
||||
<TimelineConnector/>
|
||||
<TimelineDot sx={{backgroundColor: "#fff"}}>
|
||||
{tabState === 2 ? <CircularProgress size="23px"/> : <HandymanIcon
|
||||
color={tabState > 2 ? "success" : "error"}
|
||||
sx={{width: "1.5rem", height: "1.5rem"}}
|
||||
/>}
|
||||
<TimelineConnector />
|
||||
<TimelineDot sx={{ backgroundColor: "#fff" }}>
|
||||
{tabState === 2 ? (
|
||||
<CircularProgress size="23px" />
|
||||
) : (
|
||||
<HandymanIcon
|
||||
color={tabState > 2 ? "success" : "error"}
|
||||
sx={{ width: "1.5rem", height: "1.5rem" }}
|
||||
/>
|
||||
)}
|
||||
</TimelineDot>
|
||||
<TimelineConnector/>
|
||||
<TimelineConnector />
|
||||
</TimelineSeparator>
|
||||
<TimelineContent sx={{py: "12px", px: 2}}>
|
||||
<TimelineContent sx={{ py: "12px", px: 2 }}>
|
||||
<Typography variant="h6">اقدامات حین گشت</Typography>
|
||||
<Typography variant="caption" sx={{color: "#606060"}}>
|
||||
<Typography variant="caption" sx={{ color: "#606060" }}>
|
||||
ثبت فعالیت های صورت گرفته حین گشت
|
||||
</Typography>
|
||||
</TimelineContent>
|
||||
</TimelineItem>
|
||||
<TimelineItem>
|
||||
<TimelineSeparator>
|
||||
<TimelineConnector/>
|
||||
<TimelineDot sx={{backgroundColor: "#fff"}}>
|
||||
{tabState === 3 ? <CircularProgress size="23px"/> : <VerifiedIcon
|
||||
color={tabState > 3 ? "success" : "error"}
|
||||
sx={{width: "1.5rem", height: "1.5rem"}}
|
||||
/>}
|
||||
<TimelineConnector />
|
||||
<TimelineDot sx={{ backgroundColor: "#fff" }}>
|
||||
{tabState === 3 ? (
|
||||
<CircularProgress size="23px" />
|
||||
) : (
|
||||
<VerifiedIcon
|
||||
color={tabState > 3 ? "success" : "error"}
|
||||
sx={{ width: "1.5rem", height: "1.5rem" }}
|
||||
/>
|
||||
)}
|
||||
</TimelineDot>
|
||||
<TimelineConnector/>
|
||||
<TimelineConnector />
|
||||
</TimelineSeparator>
|
||||
<TimelineContent sx={{py: "12px", px: 2}}>
|
||||
<TimelineContent sx={{ py: "12px", px: 2 }}>
|
||||
<Typography variant="h6">تکمیل درخواست</Typography>
|
||||
<Typography variant="caption" sx={{color: "#606060"}}>
|
||||
<Typography variant="caption" sx={{ color: "#606060" }}>
|
||||
تکمیل درخواست و ثبت نهایی
|
||||
</Typography>
|
||||
</TimelineContent>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import {Box, Button, FormControl, InputLabel, OutlinedInput} from "@mui/material";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import ForwardToInboxIcon from '@mui/icons-material/ForwardToInbox';
|
||||
import { Box, Button, FormControl, InputLabel, OutlinedInput } from "@mui/material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import ForwardToInboxIcon from "@mui/icons-material/ForwardToInbox";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import {GET_OTP_TOKEN, VERIFY_OTP} from "@/core/utils/routes";
|
||||
import {formatCounter} from "@/core/utils/formatCounter";
|
||||
import { GET_OTP_TOKEN, VERIFY_OTP } from "@/core/utils/routes";
|
||||
import { formatCounter } from "@/core/utils/formatCounter";
|
||||
|
||||
const PhoneValidation = ({tabState, setTabState}) => {
|
||||
const requestServer = useRequest({auth: true});
|
||||
const PhoneValidation = ({ tabState, setTabState }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [phoneNumber, setPhoneNumber] = useState("");
|
||||
const [verificationCode, setVerificationCode] = useState("");
|
||||
const [validPhone, setValidPhone] = useState(false);
|
||||
@@ -18,7 +18,7 @@ const PhoneValidation = ({tabState, setTabState}) => {
|
||||
const [readyToVerify, setReadyToVerify] = useState(false);
|
||||
|
||||
const handleNumericInput = (e) => {
|
||||
e.target.value = e.target.value.replace(/[^0-9]/g, '');
|
||||
e.target.value = e.target.value.replace(/[^0-9]/g, "");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -41,7 +41,7 @@ const PhoneValidation = ({tabState, setTabState}) => {
|
||||
}
|
||||
if (delayPerRequest && counter > 0) {
|
||||
const timer = setInterval(() => {
|
||||
setCounter(prevCounter => prevCounter - 1);
|
||||
setCounter((prevCounter) => prevCounter - 1);
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(timer);
|
||||
@@ -51,10 +51,8 @@ const PhoneValidation = ({tabState, setTabState}) => {
|
||||
const sendOtp = () => {
|
||||
if (!validPhone) return false;
|
||||
requestServer(`${GET_OTP_TOKEN}?phone_number=${phoneNumber}`, "get")
|
||||
.then((response) => {
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
.then((response) => {})
|
||||
.catch(() => {});
|
||||
//////////**** (mohammad) this part should keep in success but for now we go next level ****////////////
|
||||
setOtpSended(true);
|
||||
setDelayPerRequest(true);
|
||||
@@ -65,25 +63,25 @@ const PhoneValidation = ({tabState, setTabState}) => {
|
||||
formData.append("phone_number", phoneNumber);
|
||||
formData.append("verification_code", verificationCode);
|
||||
|
||||
setTabState(tabState + 1)
|
||||
setTabState(tabState + 1);
|
||||
requestServer(VERIFY_OTP, "post", {
|
||||
data: formData,
|
||||
})
|
||||
.then(() => {
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
}
|
||||
.then(() => {})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
my: 3
|
||||
}}>
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 2, width: {xs: "100%", sm: "70%"}}}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
my: 3,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2, width: { xs: "100%", sm: "70%" } }}>
|
||||
<FormControl size="small" fullWidth variant="outlined">
|
||||
<InputLabel htmlFor="phone_number">شماره تلفن مامور گشت</InputLabel>
|
||||
<OutlinedInput
|
||||
@@ -98,19 +96,23 @@ const PhoneValidation = ({tabState, setTabState}) => {
|
||||
onInput={handleNumericInput}
|
||||
type="text"
|
||||
inputProps={{
|
||||
maxLength: 11
|
||||
maxLength: 11,
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<Button onClick={sendOtp} disabled={!validPhone || delayPerRequest} variant="contained" color="success"
|
||||
sx={{width: "200px", height: "37px"}}
|
||||
endIcon={<ForwardToInboxIcon/>}>
|
||||
<Button
|
||||
onClick={sendOtp}
|
||||
disabled={!validPhone || delayPerRequest}
|
||||
variant="contained"
|
||||
color="success"
|
||||
sx={{ width: "200px", height: "37px" }}
|
||||
endIcon={<ForwardToInboxIcon />}
|
||||
>
|
||||
{delayPerRequest ? formatCounter(counter) : "دریافت کد"}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default PhoneValidation;
|
||||
export default PhoneValidation;
|
||||
|
||||
@@ -1,30 +1,38 @@
|
||||
"use client";
|
||||
|
||||
import {Box, Card, IconButton, Stack, Typography} from "@mui/material";
|
||||
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import { Box, Card, IconButton, Stack, Typography } from "@mui/material";
|
||||
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import React from "react";
|
||||
|
||||
const SuperVisorInfo = ({superVisor, deleteSuperVisor}) => {
|
||||
const SuperVisorInfo = ({ superVisor, deleteSuperVisor }) => {
|
||||
return (
|
||||
<Card elevation={3} sx={{
|
||||
display: "flex", alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
px: 1, py: 1,
|
||||
}}>
|
||||
<Box sx={{display: "flex"}}>
|
||||
<AccountCircleIcon color="primary" sx={{width: "50px", height: "50px"}}/>
|
||||
<Stack sx={{ml: 1, justifyContent: "center"}}>
|
||||
<Typography variant="body1"
|
||||
sx={{letterSpacing: "1px", fontWeight: 500}}>{superVisor.name}</Typography>
|
||||
<Card
|
||||
elevation={3}
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
px: 1,
|
||||
py: 1,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<AccountCircleIcon color="primary" sx={{ width: "50px", height: "50px" }} />
|
||||
<Stack sx={{ ml: 1, justifyContent: "center" }}>
|
||||
<Typography variant="body1" sx={{ letterSpacing: "1px", fontWeight: 500 }}>
|
||||
{superVisor.name}
|
||||
</Typography>
|
||||
<Typography variant="caption">کد راهدار: {superVisor.code}</Typography>
|
||||
</Stack>
|
||||
</Box>
|
||||
<Box>
|
||||
<IconButton color="error" onClick={() => deleteSuperVisor(superVisor.id)}><DeleteIcon/></IconButton>
|
||||
<IconButton color="error" onClick={() => deleteSuperVisor(superVisor.id)}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default SuperVisorInfo;
|
||||
export default SuperVisorInfo;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
"use client";
|
||||
|
||||
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 { 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";
|
||||
import { Controller } from "react-hook-form";
|
||||
|
||||
const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) => {
|
||||
const SuperVisorsDetail = ({ control, watch, setValue, tabState, setTabState }) => {
|
||||
const [SuperVisorList, setSuperVisorList] = useState([]);
|
||||
const [readyToRequest, setReadyToRequest] = useState(false);
|
||||
|
||||
@@ -17,7 +17,7 @@ const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) =>
|
||||
setSuperVisorList((prev) => [...prev, watch("road_patrol_rahdaran_id")]);
|
||||
setReadyToRequest(false);
|
||||
setValue("road_patrol_rahdaran_id", null);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteSuperVisor = (id) => {
|
||||
setSuperVisorList((prev) => prev.filter((superVisor) => superVisor.id !== id));
|
||||
@@ -30,7 +30,7 @@ const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) =>
|
||||
const SendSuperVisor = () => {
|
||||
setValue("road_patrol_rahdaran_id", SuperVisorList);
|
||||
setTabState(tabState + 1);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -39,16 +39,19 @@ const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) =>
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
my: 3
|
||||
my: 3,
|
||||
}}
|
||||
>
|
||||
<Grid container sx={{display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||
<Grid item xs={6}
|
||||
sx={{display: "flex", alignItems: "center", flexDirection: {xs: "column", lg: "row"}, gap: 2}}>
|
||||
<Stack sx={{minWidth: "250px"}}>
|
||||
<Grid container sx={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
|
||||
<Grid
|
||||
item
|
||||
xs={6}
|
||||
sx={{ display: "flex", alignItems: "center", flexDirection: { xs: "column", lg: "row" }, gap: 2 }}
|
||||
>
|
||||
<Stack sx={{ minWidth: "250px" }}>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({field, fieldState: {error}}) => {
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<RahdarCode
|
||||
rahdarsCode={field.value}
|
||||
@@ -61,33 +64,36 @@ const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) =>
|
||||
name={"road_patrol_rahdaran_id"}
|
||||
/>
|
||||
</Stack>
|
||||
<Button variant="contained" onClick={requestPatrolInfo}
|
||||
color="success"
|
||||
sx={{textWrap: "nowrap", px: 3}}
|
||||
disabled={!readyToRequest}
|
||||
endIcon={<SaveAltIcon/>}
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={requestPatrolInfo}
|
||||
color="success"
|
||||
sx={{ textWrap: "nowrap", px: 3 }}
|
||||
disabled={!readyToRequest}
|
||||
endIcon={<SaveAltIcon />}
|
||||
>
|
||||
ثبت راهدار
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Divider sx={{my: 2, width: "100%"}}>
|
||||
<Chip color="success" variant="outlined" label="لیست راهداران انتخاب شده"/>
|
||||
<Divider sx={{ my: 2, width: "100%" }}>
|
||||
<Chip color="success" variant="outlined" label="لیست راهداران انتخاب شده" />
|
||||
</Divider>
|
||||
{SuperVisorList.length !== 0 ? (
|
||||
<>
|
||||
<Grid container spacing={2} sx={{
|
||||
p: 1,
|
||||
mt: 1,
|
||||
maxHeight: "300px",
|
||||
overflowY: "auto",
|
||||
}}>
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
sx={{
|
||||
p: 1,
|
||||
mt: 1,
|
||||
maxHeight: "300px",
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
{SuperVisorList.map((superVisor) => (
|
||||
<Grid key={superVisor.id} item xs={12} sm={6} lg={4}>
|
||||
<SuperVisorInfo
|
||||
superVisor={superVisor}
|
||||
deleteSuperVisor={deleteSuperVisor}
|
||||
/>
|
||||
<SuperVisorInfo superVisor={superVisor} deleteSuperVisor={deleteSuperVisor} />
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
@@ -103,8 +109,8 @@ const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) =>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="error"
|
||||
startIcon={<KeyboardDoubleArrowRightIcon/>}
|
||||
sx={{mt: 2}}
|
||||
startIcon={<KeyboardDoubleArrowRightIcon />}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
بازگشت
|
||||
</Button>
|
||||
@@ -112,16 +118,16 @@ const SuperVisorsDetail = ({control, watch, setValue, tabState, setTabState}) =>
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={SendSuperVisor}
|
||||
endIcon={<KeyboardDoubleArrowLeftIcon/>}
|
||||
sx={{mt: 2}}
|
||||
endIcon={<KeyboardDoubleArrowLeftIcon />}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
تایید اطلاعات و رفتن به مرحله بعد
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
) : (
|
||||
<Box sx={{my: 5, width: "100%", textAlign: "center"}}>
|
||||
<Typography variant="h6" sx={{letterSpacing: "2px", color: "#606060"}}>
|
||||
<Box sx={{ my: 5, width: "100%", textAlign: "center" }}>
|
||||
<Typography variant="h6" sx={{ letterSpacing: "2px", color: "#606060" }}>
|
||||
ابتدا اطلاعات بالا را تکمیل نمایید
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import {Dialog} from "@mui/material";
|
||||
import { Dialog } from "@mui/material";
|
||||
import PatrolForms from "./PatrolForms";
|
||||
|
||||
const CreatePatrol = ({open, setOpen, mutate}) => {
|
||||
const CreatePatrol = ({ open, setOpen, mutate }) => {
|
||||
return (
|
||||
<Dialog open={open} fullWidth maxWidth="lg">
|
||||
<PatrolForms
|
||||
setOpen={setOpen}
|
||||
mutate={mutate}
|
||||
/>
|
||||
<PatrolForms setOpen={setOpen} mutate={mutate} />
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import PrintExcel from "./ExcelPrint";
|
||||
import OperatorCreate from "./Actions/Create";
|
||||
import {Box} from "@mui/material";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
const Toolbar = ({table, filterData, mutate}) => {
|
||||
const Toolbar = ({ table, filterData, mutate }) => {
|
||||
return (
|
||||
<Box sx={{display: "flex", gap: 1}}>
|
||||
<OperatorCreate table={table} mutate={mutate}/>
|
||||
<PrintExcel table={table} filterData={filterData}/>
|
||||
<Box sx={{ display: "flex", gap: 1 }}>
|
||||
<OperatorCreate table={table} mutate={mutate} />
|
||||
<PrintExcel table={table} filterData={filterData} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
import PageTitle from "@/core/components/PageTitle";
|
||||
import {Stack} from "@mui/material";
|
||||
import { Stack } from "@mui/material";
|
||||
import OperatorList from "./OperatorList";
|
||||
|
||||
const OperatorPage = () => {
|
||||
return (
|
||||
<Stack spacing={1}>
|
||||
<PageTitle title={"عملیات"}/>
|
||||
<OperatorList/>
|
||||
<PageTitle title={"عملیات"} />
|
||||
<OperatorList />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
import PageTitle from "@/core/components/PageTitle";
|
||||
import {Stack} from "@mui/material";
|
||||
import { Stack } from "@mui/material";
|
||||
import SuperviserList from "./SupervisorList";
|
||||
|
||||
const SupervisorPage = () => {
|
||||
return (
|
||||
<Stack spacing={1}>
|
||||
<PageTitle title={"ارزیابی"}/>
|
||||
<SuperviserList/>
|
||||
<PageTitle title={"ارزیابی"} />
|
||||
<SuperviserList />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const formatCounter = (counter) => {
|
||||
const minutes = Math.floor(counter / 60).toString().padStart(2, '0');
|
||||
const seconds = (counter % 60).toString().padStart(2, '0');
|
||||
const minutes = Math.floor(counter / 60)
|
||||
.toString()
|
||||
.padStart(2, "0");
|
||||
const seconds = (counter % 60).toString().padStart(2, "0");
|
||||
return `${minutes}:${seconds}`;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ export const pageMenu = [
|
||||
label: "پیشخوان",
|
||||
type: "page",
|
||||
route: "/dashboard",
|
||||
icon: <SpaceDashboardIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <SpaceDashboardIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["all"],
|
||||
},
|
||||
{
|
||||
@@ -36,14 +36,14 @@ export const pageMenu = [
|
||||
label: "مدیریت کاربران",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management",
|
||||
icon: <GroupsIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <GroupsIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["full-user-management", "limited-user-management"],
|
||||
},
|
||||
{
|
||||
id: "projectsManagment",
|
||||
label: "پروژه های راهداری",
|
||||
type: "menu",
|
||||
icon: <AccountTreeIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AccountTreeIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
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: <GavelIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <GavelIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
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: <BallotIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <BallotIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["all"],
|
||||
},
|
||||
{
|
||||
@@ -67,7 +67,7 @@ export const pageMenu = [
|
||||
label: "پروژه های پیشنهادی",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal",
|
||||
icon: <AssistantIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssistantIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
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: <AdminPanelSettingsIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AdminPanelSettingsIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
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: <MapIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <MapIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["all"],
|
||||
},
|
||||
],
|
||||
@@ -92,7 +92,7 @@ export const pageMenu = [
|
||||
id: "roadItemManagment",
|
||||
label: "فعالیت های روزانه",
|
||||
type: "menu",
|
||||
icon: <FactCheckIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <FactCheckIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_items.total"],
|
||||
Subitems: [
|
||||
@@ -100,7 +100,7 @@ export const pageMenu = [
|
||||
id: "roadItemManagmentSupervisor",
|
||||
label: "ارزیابی",
|
||||
type: "menu",
|
||||
icon: <SpeedIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_items.supervise_cnt"],
|
||||
Subitems: [
|
||||
@@ -120,7 +120,7 @@ export const pageMenu = [
|
||||
id: "roadItemManagmentOparation",
|
||||
label: "عملیات",
|
||||
type: "menu",
|
||||
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_items.operation_cnt"],
|
||||
Subitems: [
|
||||
@@ -138,7 +138,7 @@ export const pageMenu = [
|
||||
label: "پراکندگی بر روی نقشه",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items",
|
||||
icon: <MapIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <MapIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: [
|
||||
"show-road-item-supervise-cartable",
|
||||
"show-road-item-supervise-cartable-province",
|
||||
@@ -150,7 +150,7 @@ export const pageMenu = [
|
||||
label: "گزارش ها",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report",
|
||||
icon: <AssessmentIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssessmentIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: [
|
||||
"show-road-item-supervise-cartable",
|
||||
"show-road-item-supervise-cartable-province",
|
||||
@@ -163,7 +163,7 @@ export const pageMenu = [
|
||||
id: "roadPatrolManagment",
|
||||
label: "گشت راهداری و ترابری",
|
||||
type: "menu",
|
||||
icon: <FireTruckIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <FireTruckIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_patrols.total"],
|
||||
Subitems: [
|
||||
@@ -171,7 +171,7 @@ export const pageMenu = [
|
||||
id: "roadPatrolManagmentSupervisor",
|
||||
label: "ارزیابی",
|
||||
type: "menu",
|
||||
icon: <SpeedIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_patrols.supervise_cnt"],
|
||||
Subitems: [
|
||||
@@ -191,7 +191,7 @@ export const pageMenu = [
|
||||
id: "roadPatrolManagmentOparation",
|
||||
label: "عملیات",
|
||||
type: "menu",
|
||||
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_patrols.operation_cnt"],
|
||||
Subitems: [
|
||||
@@ -209,7 +209,7 @@ export const pageMenu = [
|
||||
label: "پراکندگی بر روی نقشه",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols",
|
||||
icon: <MapIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <MapIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: [
|
||||
"add-road-patrol",
|
||||
"show-road-patrol-supervise-cartable",
|
||||
@@ -221,7 +221,7 @@ export const pageMenu = [
|
||||
label: "گزارش ها",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report",
|
||||
icon: <AssessmentIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssessmentIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: [
|
||||
"add-road-patrol",
|
||||
"show-road-patrol-supervise-cartable",
|
||||
@@ -234,7 +234,7 @@ export const pageMenu = [
|
||||
id: "inquiryPrivacyManagment",
|
||||
label: "استعلام حریم راه",
|
||||
type: "menu",
|
||||
icon: <DoorbellIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <DoorbellIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
Subitems: [
|
||||
{
|
||||
@@ -271,7 +271,7 @@ export const pageMenu = [
|
||||
id: "safetyAndPrivacyManagment",
|
||||
label: "نگهداری حریم راه",
|
||||
type: "menu",
|
||||
icon: <RouteIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <RouteIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["safety_and_privacy.step_one", "safety_and_privacy.step_two"],
|
||||
Subitems: [
|
||||
@@ -279,7 +279,7 @@ export const pageMenu = [
|
||||
id: "safetyAndPrivacyManagmentOparation",
|
||||
label: "عملیات",
|
||||
type: "menu",
|
||||
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
Subitems: [
|
||||
{
|
||||
@@ -307,7 +307,7 @@ export const pageMenu = [
|
||||
label: "پراکندگی بر روی نقشه",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy",
|
||||
icon: <MapIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <MapIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: [
|
||||
"show-safety-and-privacy-operator-cartable",
|
||||
"show-safety-and-privacy-operator-cartable-province",
|
||||
@@ -320,7 +320,7 @@ export const pageMenu = [
|
||||
label: "گزارش ها",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report",
|
||||
icon: <AssessmentIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssessmentIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: [
|
||||
"show-safety-and-privacy-operator-cartable",
|
||||
"show-safety-and-privacy-operator-cartable-province",
|
||||
@@ -334,7 +334,7 @@ export const pageMenu = [
|
||||
id: "roadObservationsManagment",
|
||||
label: "واکنش سریع",
|
||||
type: "menu",
|
||||
icon: <ElectricBoltIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <ElectricBoltIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_observations.total"],
|
||||
Subitems: [
|
||||
@@ -342,7 +342,7 @@ export const pageMenu = [
|
||||
id: "roadObservationsManagmentSupervisor",
|
||||
label: "ارزیابی",
|
||||
type: "menu",
|
||||
icon: <SpeedIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_observations.supervise_cnt"],
|
||||
Subitems: [
|
||||
@@ -360,14 +360,14 @@ export const pageMenu = [
|
||||
label: "رسیدگی به شکایات",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations",
|
||||
icon: <AssignmentLateIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssignmentLateIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["show-fast-react", "show-fast-react-province", "show-fast-react-edarate-shahri"],
|
||||
},
|
||||
{
|
||||
id: "roadObservationsManagmentOparation",
|
||||
label: "عملیات",
|
||||
type: "menu",
|
||||
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
badges: ["road_observations.operation_cnt"],
|
||||
Subitems: [
|
||||
@@ -385,7 +385,7 @@ export const pageMenu = [
|
||||
label: "پراکندگی بر روی نقشه",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations",
|
||||
icon: <MapIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <MapIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["all"],
|
||||
},
|
||||
{
|
||||
@@ -393,7 +393,7 @@ export const pageMenu = [
|
||||
label: "گزارش ها",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index",
|
||||
icon: <AssessmentIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssessmentIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["all"],
|
||||
},
|
||||
],
|
||||
@@ -402,7 +402,7 @@ export const pageMenu = [
|
||||
id: "winterCampManagment",
|
||||
label: "قرارگاه زمستانی",
|
||||
type: "menu",
|
||||
icon: <CottageIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <CottageIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
Subitems: [
|
||||
{
|
||||
@@ -410,7 +410,7 @@ export const pageMenu = [
|
||||
label: "محور های انسدادی",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp",
|
||||
icon: <LineAxisIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <LineAxisIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["show-camp", "show-camp-province"],
|
||||
},
|
||||
{
|
||||
@@ -418,7 +418,7 @@ export const pageMenu = [
|
||||
label: "محور های حلقه اول",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp",
|
||||
icon: <LineAxisIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <LineAxisIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["show-camp", "show-camp-province"],
|
||||
},
|
||||
{
|
||||
@@ -426,7 +426,7 @@ export const pageMenu = [
|
||||
label: "گزارش ها",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew",
|
||||
icon: <AssessmentIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssessmentIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["show-camp", "show-camp-province"],
|
||||
},
|
||||
],
|
||||
@@ -435,14 +435,14 @@ export const pageMenu = [
|
||||
id: "receiptManagment",
|
||||
label: "خسارات وارده بر ابنیه فنی و تاسیسات راه",
|
||||
type: "menu",
|
||||
icon: <GppMaybeIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <GppMaybeIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
Subitems: [
|
||||
{
|
||||
id: "receiptManagmentOparation",
|
||||
label: "عملیات",
|
||||
type: "menu",
|
||||
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
hasSubitems: true,
|
||||
Subitems: [
|
||||
{
|
||||
@@ -459,7 +459,7 @@ export const pageMenu = [
|
||||
label: "گزارش ها",
|
||||
type: "page",
|
||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report",
|
||||
icon: <AssessmentIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <AssessmentIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["all"],
|
||||
},
|
||||
],
|
||||
@@ -469,7 +469,7 @@ export const pageMenu = [
|
||||
label: "آزمایشات (OPTS)",
|
||||
type: "page",
|
||||
route: "/dashboard/azmayesh",
|
||||
icon: <ScienceIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <ScienceIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["azmayesh-management"],
|
||||
},
|
||||
{
|
||||
@@ -477,7 +477,7 @@ export const pageMenu = [
|
||||
label: "نوع آزمایشات",
|
||||
type: "page",
|
||||
route: "/dashboard/azmayesh_type",
|
||||
icon: <BiotechIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <BiotechIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: ["azmayesh-type-management"],
|
||||
},
|
||||
{
|
||||
@@ -485,7 +485,7 @@ export const pageMenu = [
|
||||
label: "اطلاعات خودرو",
|
||||
type: "page",
|
||||
route: "/dashboard/car-details",
|
||||
icon: <DriveEtaIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||
icon: <DriveEtaIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||
permissions: [""],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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: {},
|
||||
@@ -14,7 +14,7 @@ const defaultOptions = {
|
||||
};
|
||||
|
||||
const useRequest = (initOptions) => {
|
||||
const {logout} = useAuth();
|
||||
const { logout } = useAuth();
|
||||
|
||||
const _options = Object.assign({}, defaultOptions, initOptions);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user