Feature/amiriis mission new tasks

This commit is contained in:
AmirHossein Mahmoodi
2025-07-28 07:35:45 +00:00
parent fc9706bb0e
commit c6ccc39829
62 changed files with 2561 additions and 894 deletions

View File

@@ -6,12 +6,15 @@ import ShowBound from "../showBound";
import L from "leaflet";
const ShowArea = ({ area }) => {
const bound = useMemo(() => L.polygon([...area]), [area]);
const bound = useMemo(
() => (area.type == "polygon" ? L.polygon([...area.coordinates]) : L.polyline([...area.coordinates])),
[area]
);
const [openAreaDialog, setOpenAreaDialog] = useState(false);
return (
<>
<Tooltip title=حدوده">
<Tooltip title=نطقه عملیاتی">
<IconButton color="primary" onClick={() => setOpenAreaDialog(true)}>
<RemoveRedEye />
</IconButton>
@@ -33,7 +36,7 @@ const ShowArea = ({ area }) => {
>
<DialogTitle sx={{ display: "flex", justifyContent: "space-between", padding: "16px 24px" }}>
<Typography variant="body1" sx={{ fontWeight: "bold", fontSize: "large" }}>
محدوده
منطقه عملیاتی
</Typography>
<IconButton onClick={() => setOpenAreaDialog(false)} size="small">
<Close />

View File

@@ -4,15 +4,11 @@ import { GET_ROAD_MISSIONS_CONTROL_LIST } from "@/core/utils/routes";
import { Box, Stack } from "@mui/material";
import moment from "jalali-moment";
import { useMemo } from "react";
import ShowArea from "./Actions/showArea";
import MachinesDialog from "./RowActions/Machines";
import RowActions from "./RowActions";
import RahdaranDialog from "./RowActions/Rahdaran";
const ControlList = () => {
const typeOptions = [
{ value: 1, label: "روزانه" },
{ value: 2, label: "ساعتی" },
];
const columns = useMemo(
() => [
{
@@ -27,25 +23,10 @@ const ControlList = () => {
size: 100,
},
{
accessorKey: "type",
header: "نوع",
id: "type",
enableColumnFilter: true,
datatype: "numeric",
filterMode: "equals",
sortDescFirst: true,
grow: false,
size: 100,
columnSelectOption: () => {
return typeOptions.map((type) => ({
value: type.value,
label: type.label,
}));
},
Cell: ({ row }) => row.original.type_fa,
},
{
accessorFn: (row) => moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
accessorFn: (row) =>
row.type == 1
? moment(row.start_date).locale("fa").format("HH:mm | yyyy/MM/DD")
: moment(row.start_date).locale("fa").format("yyyy/MM/DD"),
header: "تاریخ شروع",
id: "start_date",
enableColumnFilter: true,
@@ -55,7 +36,10 @@ const ControlList = () => {
size: 100,
},
{
accessorFn: (row) => moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD"),
accessorFn: (row) =>
row.type == 1
? moment(row.end_date).locale("fa").format("HH:mm | yyyy/MM/DD")
: moment(row.end_date).locale("fa").format("yyyy/MM/DD"),
header: "تاریخ پایان",
id: "end_date",
enableColumnFilter: true,
@@ -65,21 +49,13 @@ const ControlList = () => {
size: 100,
},
{
accessorKey: "end_point",
header: "مقصد",
id: "end_point",
enableColumnFilter: false,
datatype: "numeric",
filterMode: "equals",
grow: false,
size: 100,
},
{
header: "محدوده",
id: "area",
enableColumnFilter: false,
datatype: "numeric",
filterMode: "equals",
header: "خودرو",
id: "cmmsMachines__machine_code",
enableColumnFilter: true,
datatype: "text",
filterMode: "contains",
enableSorting: false,
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
muiTableBodyCellProps: {
@@ -91,14 +67,40 @@ const ControlList = () => {
},
},
},
Cell: ({ row }) =>
row.original.area ? (
Cell: ({ renderedCellValue, row }) => {
return (
<Stack alignItems={"center"} justifyContent={"center"}>
<ShowArea area={row.original.area} />
<MachinesDialog rowId={row.original.id} />
</Stack>
) : (
"-"
),
);
},
},
{
header: "افراد",
id: "rahdaran__code",
enableColumnFilter: true,
enableSorting: false,
datatype: "text",
filterMode: "contains",
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
muiTableBodyCellProps: {
sx: {
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ renderedCellValue, row }) => {
return (
<Stack alignItems={"center"} justifyContent={"center"}>
<RahdaranDialog rowId={row.original.id} />
</Stack>
);
},
},
],
[]

View File

@@ -0,0 +1,73 @@
import DialogLoading from "@/core/components/DialogLoading";
import ShowPlak from "@/core/components/ShowPlak";
import { GET_MACHINES_BY_ID } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
import {
DialogContent,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography,
} from "@mui/material";
import { useEffect, useState } from "react";
const MachinesContent = ({ rowId }) => {
const [loading, setLoading] = useState(true);
const [data, setData] = useState(null);
const request = useRequest();
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await request(`${GET_MACHINES_BY_ID}/${rowId}`);
setData(response.data.data);
} catch (error) {
} finally {
setLoading(false);
}
};
fetchData();
}, [rowId]);
return (
<>
<DialogContent>
{loading ? (
<DialogLoading />
) : data ? (
<TableContainer>
<Table stickyHeader>
<TableHead>
<TableRow>
<TableCell>کد ماشین</TableCell>
<TableCell>نام خودرو</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((machine) => {
return (
<TableRow
key={machine.id}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell>{machine.machine_code}</TableCell>
<TableCell>{machine.car_name}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
) : (
<Typography textAlign={"center"}>اطلاعات خودرویی در سامانه یافت نشد</Typography>
)}
</DialogContent>
</>
);
};
export default MachinesContent;

View File

@@ -0,0 +1,38 @@
import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
import DirectionsCarIcon from "@mui/icons-material/DirectionsCar";
import { useState } from "react";
import MachinesContent from "./MachinesContent";
const MachinesDialog = ({ rowId }) => {
const [openMachinesDialog, setOpenMachinesDialog] = useState(false);
return (
<>
<Tooltip title="خودرو">
<IconButton color="primary" onClick={() => setOpenMachinesDialog(true)}>
<DirectionsCarIcon />
</IconButton>
</Tooltip>
<Dialog
fullWidth
open={openMachinesDialog}
onClose={() => setOpenMachinesDialog(false)}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
dir="rtl"
maxWidth={"sm"}
>
<DialogTitle sx={{ fontSize: "large" }}>اطلاعات خودرو</DialogTitle>
{openMachinesDialog && <MachinesContent rowId={rowId} />}
<DialogActions>
<Button onClick={() => setOpenMachinesDialog(false)} variant="outlined" color="secondary" autoFocus>
بستن
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default MachinesDialog;

View File

@@ -0,0 +1,74 @@
import DialogLoading from "@/core/components/DialogLoading";
import { GET_RAHDARAN_BY_ID } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
import {
DialogContent,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography,
} from "@mui/material";
import { useEffect, useState } from "react";
const RahdaranContent = ({ rowId }) => {
const [loading, setLoading] = useState(true);
const [data, setData] = useState(null);
const request = useRequest();
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await request(`${GET_RAHDARAN_BY_ID}/${rowId}`);
setData(response.data.data);
} catch (error) {
} finally {
setLoading(false);
}
};
fetchData();
}, [rowId]);
return (
<>
<DialogContent>
{loading ? (
<DialogLoading />
) : data ? (
<TableContainer>
<Table stickyHeader>
<TableHead>
<TableRow>
<TableCell>کد ملی</TableCell>
<TableCell>نام</TableCell>
<TableCell>نقش</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((rahdar) => {
return (
<TableRow
key={rahdar.id}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell>{rahdar.code}</TableCell>
<TableCell>{rahdar.name}</TableCell>
<TableCell>{rahdar.is_driver ? "راننده" : "همراه"}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
) : (
<Typography textAlign={"center"}>اطلاعات راهداران در سامانه یافت نشد</Typography>
)}
</DialogContent>
</>
);
};
export default RahdaranContent;

View File

@@ -0,0 +1,38 @@
import { Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip } from "@mui/material";
import GroupsIcon from "@mui/icons-material/Groups";
import { useState } from "react";
import RahdaranContent from "./RahdaranContent";
const RahdaranDialog = ({ rowId }) => {
const [openRahdaranDialog, setOpenRahdaranDialog] = useState(false);
return (
<>
<Tooltip title="افراد">
<IconButton color="primary" onClick={() => setOpenRahdaranDialog(true)}>
<GroupsIcon />
</IconButton>
</Tooltip>
<Dialog
fullWidth
open={openRahdaranDialog}
onClose={() => setOpenRahdaranDialog(false)}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
dir="rtl"
maxWidth={"sm"}
>
<DialogTitle sx={{ fontSize: "large" }}>لیست افراد</DialogTitle>
{openRahdaranDialog && <RahdaranContent rowId={rowId} />}
<DialogActions>
<Button onClick={() => setOpenRahdaranDialog(false)} variant="outlined" color="secondary" autoFocus>
بستن
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default RahdaranDialog;

View File

@@ -1,38 +1,87 @@
import LtrTextField from "@/core/components/LtrTextField";
import { START_MISSION } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
import { yupResolver } from "@hookform/resolvers/yup";
import { Button, DialogActions, DialogContent, Stack, Typography } from "@mui/material";
import { useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { object, string } from "yup";
const StartMissionContent = ({ rowId, mutate, setOpenStartMissionDialog }) => {
const [submitting, setSubmitting] = useState(false);
const requestServer = useRequest({ notificationSuccess: true });
const handleClick = () => {
setSubmitting(true);
const validationSchema = object().shape({
code: string().length(6, "کد خروج باید 6 رقم باشد").required("لطفاً کد خروج را وارد کنید."),
});
const {
control,
handleSubmit,
formState: { isSubmitting },
} = useForm({
defaultValues: {
code: "",
},
resolver: yupResolver(validationSchema),
mode: "all",
});
const onSubmit = (values) => {
requestServer(`${START_MISSION}/${rowId}`, "post", {
data: {
code: values.code,
},
hasSidebarUpdate: true,
})
.then(() => {
mutate();
setOpenStartMissionDialog(false);
setSubmitting(false);
})
.catch(() => {
setSubmitting(false);
});
.catch(() => {});
};
return (
<>
<DialogContent>
<DialogContent dividers>
<Stack alignItems="center" spacing={2}>
<Typography mt={2}>آیا از خروج خودرو و شروع ماموریت اطمینان دارید؟</Typography>
<Stack>
<Controller
control={control}
name={"code"}
render={({ field, fieldState: { error } }) => (
<LtrTextField
{...field}
label={"کد خروج"}
placeholder="xxxxxx"
error={!!error}
helperText={error?.message}
size="small"
onChange={(e) => {
if (isNaN(Number(e.target.value))) return;
e.target.value.length <= 6 ? field.onChange(e.target.value) : null;
}}
type="tel"
autoComplete="off"
fullWidth
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Stack>
</Stack>
</DialogContent>
<DialogActions sx={{ justifyContent: "center", paddingBottom: 2, width: "100%" }}>
<Button onClick={() => setOpenStartMissionDialog(false)} variant="outlined" color="secondary">
<Button
onClick={() => setOpenStartMissionDialog(false)}
variant="outlined"
color="secondary"
disabled={isSubmitting}
>
خیر !
</Button>
<Button onClick={handleClick} variant="contained" color="primary" disabled={submitting}>
{submitting ? "درحال ثبت..." : "بله اطمینان دارم"}
<Button onClick={handleSubmit(onSubmit)} variant="contained" color="primary" disabled={isSubmitting}>
{isSubmitting ? "درحال ثبت..." : "بله اطمینان دارم"}
</Button>
</DialogActions>
</>