work on patrol form instead sending request

This commit is contained in:
2025-01-06 13:08:47 +03:30
parent 6a7677ec5c
commit 6371630380
18 changed files with 539 additions and 335 deletions

View File

@@ -1,10 +1,9 @@
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { array, mixed, number, object, string } from "yup";
import { useTheme } from "@emotion/react";
import useRequest from "@/lib/hooks/useRequest";
import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material";
import React, {useState} from "react";
import {useForm} from "react-hook-form";
import {yupResolver} from "@hookform/resolvers/yup";
import {array, mixed, number, object, string} from "yup";
import {useTheme} from "@emotion/react";
import {Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery} from "@mui/material";
import StyledForm from "@/core/components/StyledForm";
import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile";
import FileCopyIcon from "@mui/icons-material/FileCopy";
@@ -15,10 +14,9 @@ import BeenhereIcon from "@mui/icons-material/Beenhere";
import GetItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemsForm";
import GetSubItemsForm from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetSubItemsForm";
import GetItemInfo from "@/components/dashboard/roadItems/operator/Actions/Create/Forms/GetItemInfo";
import { CREATE_ROAD_ITEMS } from "@/core/utils/routes";
function TabPanel(props) {
const { children, value, index } = props;
const {children, value, index} = props;
return (
<div role="tabpanel" hidden={value !== index}>
{value === index && <Box>{children}</Box>}
@@ -26,31 +24,32 @@ function TabPanel(props) {
);
}
const defaultValues = {
item_id: null,
sub_item_id: null,
amount: "",
activity_time: "",
activity_date: "",
before_image: null,
after_image: null,
cmms_machines: null,
rahdaran_id: null,
start_point: "",
end_point: "",
};
const validationSchema = object({
item_id: number().required("نوع آیتم را مشخص کنید!"),
sub_item_id: number().required("موضوع مشاهده شده را مشخص کنید!"),
amount: string().required("وارد کردن مقدار الزامیست!"),
cmms_machines: array().required("وارد کردن کد خودرو الزامیست!"),
rahdaran_id: array().required("وارد کردن کد راهداران الزامیست!").min(1, "حداقل یک کد راهدار باید وارد شود!"), // بررسی حداقل یک آیتم,
activity_time: string().required("لطفا زمان فعالیت را انتخاب کنید!"),
activity_date: string().required("لطفاً تاریخ شروع فعالیت را انتخاب کنید!"),
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; // در غیر این صورت مقدار فیلد باید وجود داشته باشد
}),
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;
@@ -60,7 +59,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;
@@ -73,7 +72,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; // چک می‌کند که مقدار موجود است
@@ -82,7 +81,20 @@ const validationSchema = object({
}),
});
const CreateFormContent = ({ setOpen, onSubmit }) => {
const CreateFormContent = ({setOpen, onSubmit, is_gasht = false}) => {
const defaultValues = {
item_id: null,
sub_item_id: null,
amount: "",
before_image: null,
after_image: null,
cmms_machines: null,
rahdaran_id: null,
start_point: "",
end_point: "",
...(!is_gasht && {activity_time: "", activity_date: ""}),
};
const [tabState, setTabState] = useState(0);
const [itemsList, setItemsList] = useState();
const [subItemsList, setSubItemsList] = useState([]);
@@ -126,15 +138,15 @@ const CreateFormContent = ({ setOpen, onSubmit }) => {
handleSubmit,
setValue,
resetField,
formState: { errors, isSubmitting },
formState: {errors, isSubmitting},
} = useForm({
defaultValues,
resolver: yupResolver(validationSchema),
mode: "onBlur",
context: { subItemsList },
context: {subItemsList, is_gasht},
});
const onSubmitBase = (data) => {
let result = { ...data };
let result = {...data};
if (result.before_image === null) {
delete result.before_image;
@@ -180,9 +192,10 @@ const CreateFormContent = ({ setOpen, onSubmit }) => {
},
});
};
console.log(errors)
return (
<StyledForm onSubmit={handleSubmit(onSubmitBase)}>
<StyledForm onSubmit={handleSubmit(onSubmitBase)} id="road_items">
<Tabs
allowScrollButtonsMobile
value={tabState}
@@ -195,12 +208,12 @@ const CreateFormContent = ({ setOpen, onSubmit }) => {
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}
@@ -229,17 +242,18 @@ const CreateFormContent = ({ setOpen, onSubmit }) => {
register={register}
watch={watch}
getValues={getValues}
is_gasht={is_gasht}
/>
</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>
@@ -249,7 +263,8 @@ const CreateFormContent = ({ setOpen, onSubmit }) => {
size="large"
disabled={isSubmitting}
type={"submit"}
endIcon={<BeenhereIcon />}
form="road_items"
endIcon={<BeenhereIcon/>}
>
{isSubmitting ? "در حال ثبت فعالیت" : "ثبت فعالیت"}
</Button>

View File

@@ -1,20 +1,20 @@
import { Stack, TextField, Grid } 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 }) => {
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, err
<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, err
<Stack>
<Controller
control={control}
render={({ field, fieldState: { error } }) => {
render={({field, fieldState: {error}}) => {
return (
<RahdarCode
rahdarsCode={field.value || []}
@@ -75,38 +75,40 @@ const GetItemInfo = ({ register, itemsList, subItemsList, control, setValue, err
</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>
<Stack>
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<MuiDatePicker
name="activity_date"
error={errors.activity_date ? errors.activity_date.message : null}
value={watch("activity_date")}
placeholder={"تاریخ شروع فعالیت"}
setFieldValue={setValue}
helperText={errors.activity_date ? errors.activity_date.message : null}
/>
{!is_gasht ? (
<Stack>
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<MuiDatePicker
name="activity_date"
error={errors.activity_date ? errors.activity_date.message : null}
value={watch("activity_date")}
placeholder={"تاریخ شروع فعالیت"}
setFieldValue={setValue}
helperText={errors.activity_date ? errors.activity_date.message : null}
/>
</Grid>
<Grid item xs={12} md={6}>
<MuiTimePicker
value={watch("activity_time")}
name="activity_time"
error={errors.activity_time ? errors.activity_time.message : null}
placeholder={"زمان فعالیت"}
setFieldValue={setValue}
helperText={errors.activity_time ? errors.activity_time.message : null}
/>
</Grid>
</Grid>
<Grid item xs={12} md={6}>
<MuiTimePicker
value={watch("activity_time")}
name="activity_time"
error={errors.activity_time ? errors.activity_time.message : null}
placeholder={"زمان فعالیت"}
setFieldValue={setValue}
helperText={errors.activity_time ? errors.activity_time.message : null}
/>
</Grid>
</Grid>
</Stack>
</Stack>
) : 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>

View File

@@ -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);
@@ -15,15 +15,31 @@ const ImageUpload = ({ control, setValue, errors, getValues, beforeImage = null,
const [showAfterImage, setShowAfterImage] = useState(!afterImage);
useEffect(() => {
if (getValues("before_image")) {
const beforeImage = getValues("before_image");
const afterImage = getValues("after_image");
if (beforeImage) {
setShowBeforeImage(false);
setBeforeImg(getValues("before_image"));
setBeforeFileType("image/");
if (typeof beforeImage === "string") {
setBeforeImg(beforeImage);
setBeforeFileType("image/");
} else if (beforeImage instanceof File) {
setBeforeImg(URL.createObjectURL(beforeImage));
setBeforeFileType(beforeImage.type);
}
}
if (getValues("after_image")) {
if (afterImage) {
setShowAfterImage(false);
setAfterImg(getValues("after_image"));
setAfterFileType("image/");
if (typeof afterImage === "string") {
setAfterImg(afterImage);
setAfterFileType("image/");
} else if (afterImage instanceof File) {
setAfterImg(URL.createObjectURL(afterImage));
setAfterFileType(afterImage.type);
}
}
}, [getValues]);
@@ -57,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}
@@ -68,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
@@ -93,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}
@@ -104,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

View File

@@ -14,21 +14,34 @@ const EditFormContent = ({setOpenEditDialog, onSubmit, defaultData}) => {
start_point: defaultData?.start_point || {lat: "", lng: ""},
end_point: defaultData?.end_point || {lat: "", lng: ""},
cmms_machines: defaultData?.cmms_machines || null,
rahdaran_id: defaultData?.rahdaran || null,
rahdaran_id: defaultData?.rahdaran_id || null,
};
const onSubmitBase = (data) => {
let result = {...data};
(result.before_image === null || result.before_image === defaultValues.before_image) &&
delete result.before_image;
(result.after_image === null || result.after_image === defaultValues.after_image) && delete result.after_image;
if (subItem.needs_end_point !== 1) {
if (result.before_image === null) {
delete result.before_image;
delete data.before_image;
}
if (result.after_image === null) {
delete result.after_image;
delete data.after_image;
}
if (result.end_point === "") {
delete result.end_point;
delete data.end_point;
} else {
result.end_point = `${result.end_point.lat},${result.end_point.lng}`;
}
result.start_point = `${result.start_point.lat},${result.start_point.lng}`;
if (result.start_point === "") {
delete result.start_point;
delete data.start_point;
} else {
result.start_point = `${result.start_point.lat},${result.start_point.lng}`;
}
result.rahdaran_id.forEach((rahdar, index) => {
result[`rahdaran_id[${index}]`] = rahdar.id;
@@ -45,8 +58,10 @@ const EditFormContent = ({setOpenEditDialog, onSubmit, defaultData}) => {
data: {
...data,
item_name: subItem.item_str,
sub_item_name: subItemsList.name,
unit_fa: subItemsList.unit,
sub_item_name: subItem.name,
unit_fa: subItem.unit,
item_id: subItem.item,
sub_item_id: subItem.sub_item,
},
});
};

View File

@@ -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,22 +58,23 @@ const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, set
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)}>
<DialogContent sx={{ overflowY: "auto", maxHeight: "70vh" }}>
<StyledForm onSubmit={handleSubmit(onSubmitBase)} id="edit_road_items">
<DialogContent sx={{overflowY: "auto", maxHeight: "70vh"}}>
<Stack spacing={2}>
<Stack>
{subItem.needs_image === 1 ? (
<ImageUpload
afterImage={defaultData?.afterImage}
beforeImage={defaultData?.beforeImage}
afterImage={defaultData?.after_image}
beforeImage={defaultData?.before_image}
getValues={getValues}
setValue={setValue}
control={control}
@@ -110,7 +111,7 @@ const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, set
<Stack>
<Controller
control={control}
render={({ field, fieldState: { error } }) => {
render={({field, fieldState: {error}}) => {
return (
<CarCode
carCode={field.value || []}
@@ -127,7 +128,7 @@ const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, set
<Stack>
<Controller
control={control}
render={({ field, fieldState: { error } }) => {
render={({field, fieldState: {error}}) => {
return (
<RahdarCode
rahdarsCode={field.value || []}
@@ -161,7 +162,8 @@ const EditFormCreate = ({ defaultData, subItem, onSubmitBase, defaultValues, set
<Button onClick={() => setOpenEditDialog(false)} variant="outlined" color="primary" autoFocus>
بستن
</Button>
<Button disabled={isSubmitting} type={"submit"} variant="contained" color="primary">
<Button form="edit_road_items" disabled={isSubmitting} type={"submit"} variant="contained"
color="primary">
{isSubmitting ? "در حال ویرایش" : "ویرایش"}
</Button>
</DialogActions>