Merge branch 'feature/show_car_details' into 'develop'
Feature/show car details See merge request witel-front-end/rms!34
This commit is contained in:
7
src/app/(withAuth)/dashboard/car-details/page.js
Normal file
7
src/app/(withAuth)/dashboard/car-details/page.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import TestPage from "@/components/dashboard/carDetails";
|
||||||
|
|
||||||
|
const Page = () => {
|
||||||
|
return <TestPage />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
187
src/components/dashboard/carDetails/CarDetailsContent.jsx
Normal file
187
src/components/dashboard/carDetails/CarDetailsContent.jsx
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
import {
|
||||||
|
Button, Collapse,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent, Grid,
|
||||||
|
Stack, TextField
|
||||||
|
} from "@mui/material";
|
||||||
|
import MuiDatePicker from "@/core/components/MuiDatePicker";
|
||||||
|
import {useFormik} from "formik";
|
||||||
|
import moment from "jalali-moment";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import {useState} from "react";
|
||||||
|
import ApplicantRequestDetail from "@/core/components/ApplicantRequestDetail";
|
||||||
|
import DetailMap from "@/core/components/ApplicantRequestDetail/DetailMap";
|
||||||
|
import FlyToPolyline from "@/core/components/ApplicantRequestDetail/FlyToPolyline";
|
||||||
|
import {MapContainer} from "react-leaflet";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import MapLoading from "@/core/components/MapLayer/Loading";
|
||||||
|
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
|
||||||
|
loading: () => <MapLoading />,
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const fakeData = {
|
||||||
|
id: 1,
|
||||||
|
shomareh_darkhast: "2124",
|
||||||
|
ostan: "ostan",
|
||||||
|
shahr: "shahr",
|
||||||
|
shahrestan: "shahrestan",
|
||||||
|
bakhsh: "bakhsh",
|
||||||
|
roosta: "roosta",
|
||||||
|
tarikh_darkhast: "tarikh_darkhast",
|
||||||
|
sazman: "sazman",
|
||||||
|
masahat_zamin: "masahat_zamin",
|
||||||
|
masahat_tarh: "masahat_tarh",
|
||||||
|
gorooh_tarh: "gorooh_tarh",
|
||||||
|
onvane_tarh: "onvane_tarh",
|
||||||
|
address: "کرج - فلان جا - جنب پاساژ - نزدیک اونجا - اونور خیابون - زیر رو گذر - روی زیر گذر",
|
||||||
|
file_mosavab: "file",
|
||||||
|
polyline: [
|
||||||
|
[35.6892, 51.3890],
|
||||||
|
[35.7074, 51.3929],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const CarDetailsContent = ({setOpenCarDialog}) => {
|
||||||
|
const [openCarDetailContent, setOpenCarDetailContent] = useState(false)
|
||||||
|
const initialValues = {
|
||||||
|
start_date: "",
|
||||||
|
end_date: "",
|
||||||
|
vehicle_code: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
start_date: Yup.string().required("تاریخ شروع الزامیست!!!"),
|
||||||
|
end_date: Yup.string().test(
|
||||||
|
"is-greater",
|
||||||
|
"تاریخ اتمام نمیتواند کمتر از تاریخ شروع باشد",
|
||||||
|
function (value) {
|
||||||
|
const {start_date} = this.parent; // Access other field values
|
||||||
|
if (!value || !start_date) return true; // Skip validation if either field is empty
|
||||||
|
return moment(value, "YYYY/MM/DD").isSameOrAfter(
|
||||||
|
moment(start_date, "YYYY/MM/DD")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
).required("تاریخ اتمام الزامیست!!!"),
|
||||||
|
vehicle_code: Yup.mixed()
|
||||||
|
.test("is-number", "کد خودرو باید عدد باشد!!!", (value) => !isNaN(value))
|
||||||
|
.test("positive", "کد خودرو باید مثبت باشد!!!", (value) => value >= 0)
|
||||||
|
.required("کد خودرو الزامیست!!!"),
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSubmit = async (values, props) => {
|
||||||
|
props.setSubmitting(true);
|
||||||
|
setOpenCarDetailContent(true)
|
||||||
|
console.log(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
const formik = useFormik({
|
||||||
|
initialValues,
|
||||||
|
validationSchema,
|
||||||
|
onSubmit: handleSubmit,
|
||||||
|
});
|
||||||
|
console.log(formik.errors)
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DialogContent>
|
||||||
|
<Stack spacing={2} sx={{my: 2}}>
|
||||||
|
<Stack direction={"row"} spacing={2} sx={{my: 2}}>
|
||||||
|
<MuiDatePicker
|
||||||
|
formik={formik}
|
||||||
|
value={formik.values.start_date}
|
||||||
|
name={"start_date"}
|
||||||
|
error={formik.errors.start_date}
|
||||||
|
helperText={formik.touched.start_date && formik.errors.start_date}
|
||||||
|
touched={formik.touched.start_date}
|
||||||
|
onBlur={formik.handleBlur("start_date")}
|
||||||
|
/>
|
||||||
|
<MuiDatePicker
|
||||||
|
formik={formik}
|
||||||
|
name={"end_date"}
|
||||||
|
disabled={formik.values.start_date === ""}
|
||||||
|
value={formik.values.end_date}
|
||||||
|
error={formik.errors.end_date}
|
||||||
|
helperText={formik.touched.end_date && formik.errors.end_date}
|
||||||
|
touched={formik.touched.end_date}
|
||||||
|
onBlur={formik.handleBlur("end_date")}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
name="vehicle_code"
|
||||||
|
label={"کد خودرو"}
|
||||||
|
type="text"
|
||||||
|
inputProps={{
|
||||||
|
inputMode: "number",
|
||||||
|
min: 0,
|
||||||
|
pattern: "[0-9]*",
|
||||||
|
}}
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.vehicle_code}
|
||||||
|
onChange={(event) => {
|
||||||
|
if (!isNaN(event.target.value)) {
|
||||||
|
formik.setFieldValue("vehicle_code", event.target.value);
|
||||||
|
} else {
|
||||||
|
formik.setFieldValue("vehicle_code", formik.values.vehicle_code);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
size={"small"}
|
||||||
|
error={formik.touched.vehicle_code && Boolean(formik.errors.vehicle_code)}
|
||||||
|
helperText={formik.touched.vehicle_code && formik.errors.vehicle_code}
|
||||||
|
onBlur={formik.handleBlur("vehicle_code")}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack>
|
||||||
|
<Button variant={"contained"} color={"primary"}
|
||||||
|
onClick={formik.handleSubmit}>
|
||||||
|
نمایش اطلاعات
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12} sm={4}>
|
||||||
|
<Stack direction="column" sx={{height : "100%", justifyContent: "start", alignItems: "center"}} spacing={5}>
|
||||||
|
<TextField
|
||||||
|
name="vehicle_code"
|
||||||
|
label={"مصرف سوخت خودرو"}
|
||||||
|
disabled
|
||||||
|
variant="outlined"
|
||||||
|
value={"5 لیتر"}
|
||||||
|
size={"small"}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
name="vehicle_code"
|
||||||
|
label={"مسافت پیموده شده"}
|
||||||
|
disabled
|
||||||
|
variant="outlined"
|
||||||
|
value={"54 کیلومتر"}
|
||||||
|
size={"small"}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
name="vehicle_code"
|
||||||
|
label={"زمان روشن بودن خودرو"}
|
||||||
|
disabled
|
||||||
|
variant="outlined"
|
||||||
|
value={"3 ساعت"}
|
||||||
|
size={"small"}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={8}>
|
||||||
|
<MapLayer style={{ height: "400px", width: "100%" }}>
|
||||||
|
{/*<FlyToPolyline polyline={fakeData.polyline} />*/}
|
||||||
|
</MapLayer>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant={"outlined"} color={"warning"} onClick={() => setOpenCarDialog(false)}>
|
||||||
|
بستن
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CarDetailsContent;
|
||||||
45
src/components/dashboard/carDetails/index.jsx
Normal file
45
src/components/dashboard/carDetails/index.jsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
"use client";
|
||||||
|
import PageTitle from "@/core/components/PageTitle";
|
||||||
|
import {Dialog, DialogTitle, IconButton, Stack, Tooltip} from "@mui/material";
|
||||||
|
import {useState} from "react";
|
||||||
|
import DriveEtaIcon from "@mui/icons-material/DriveEta";
|
||||||
|
import CarDetailsContent from "@/components/dashboard/carDetails/CarDetailsContent";
|
||||||
|
|
||||||
|
const TestPage = () => {
|
||||||
|
const [openCarDialog, setOpenCarDialog] = useState(false)
|
||||||
|
return (
|
||||||
|
<Stack spacing={1}>
|
||||||
|
<PageTitle title={"نمایش اطلاعات خودرو"} />
|
||||||
|
<>
|
||||||
|
<Tooltip title="نمایش اطلاعات خودرو">
|
||||||
|
<IconButton
|
||||||
|
color="primary"
|
||||||
|
onClick={() => {
|
||||||
|
setOpenCarDialog(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DriveEtaIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<Dialog
|
||||||
|
onClose={()=>setOpenCarDialog(false)}
|
||||||
|
fullWidth
|
||||||
|
open={openCarDialog}
|
||||||
|
PaperProps={{
|
||||||
|
sx: {
|
||||||
|
transition: "all .3s",
|
||||||
|
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
maxWidth={"lg"}
|
||||||
|
>
|
||||||
|
<DialogTitle>
|
||||||
|
نمایش اطلاعات خودرو
|
||||||
|
</DialogTitle>
|
||||||
|
<CarDetailsContent setOpenCarDialog={setOpenCarDialog} />
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default TestPage;
|
||||||
21
src/core/components/ApplicantRequestDetail/FlyToPolyline.jsx
Normal file
21
src/core/components/ApplicantRequestDetail/FlyToPolyline.jsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Polyline, useMap } from "react-leaflet";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
const purpleOptions = { color: "purple" };
|
||||||
|
|
||||||
|
const FlyToPolyline = ({ polyline }) => {
|
||||||
|
const map = useMap();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map) {
|
||||||
|
const leafletPolyline = L.polyline(polyline); // Create a Leaflet polyline
|
||||||
|
const bounds = leafletPolyline.getBounds(); // Get bounds from the polyline
|
||||||
|
map.flyToBounds(bounds, { padding: [50, 50] }); // Fly to the polyline bounds
|
||||||
|
}
|
||||||
|
}, [map, polyline]);
|
||||||
|
|
||||||
|
return <Polyline pathOptions={purpleOptions} positions={polyline} />; // Render the polyline
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FlyToPolyline;
|
||||||
61
src/core/components/MuiDatePicker.jsx
Normal file
61
src/core/components/MuiDatePicker.jsx
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { LocalizationProvider, MobileDateTimePicker } from "@mui/x-date-pickers";
|
||||||
|
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
|
||||||
|
import moment from "jalali-moment";
|
||||||
|
import { faIR } from "@mui/x-date-pickers/locales";
|
||||||
|
import {Box, IconButton, FormControl, FormHelperText, InputAdornment, Stack} from "@mui/material";
|
||||||
|
import ClearIcon from "@mui/icons-material/Clear";
|
||||||
|
|
||||||
|
export default function PickerWithButtonField({
|
||||||
|
formik,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
error,
|
||||||
|
touched,
|
||||||
|
disabled,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<FormControl variant="outlined" fullWidth size="small" error={!!error}>
|
||||||
|
<Stack sx={{width : "100%"}} direction={"row"}>
|
||||||
|
<LocalizationProvider
|
||||||
|
dateAdapter={AdapterDateFnsJalali}
|
||||||
|
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
|
||||||
|
>
|
||||||
|
<MobileDateTimePicker
|
||||||
|
ampm={false}
|
||||||
|
disableFuture
|
||||||
|
value={value ? new Date(value) : null}
|
||||||
|
onChange={(newValue) => {
|
||||||
|
const formattedDate = moment(newValue).locale("en").format("YYYY-MM-DD HH:mm");
|
||||||
|
formik.setFieldValue(name, formattedDate);
|
||||||
|
}}
|
||||||
|
slotProps={{
|
||||||
|
textField: {
|
||||||
|
placeholder: name === "start_date"
|
||||||
|
? "تاریخ شروع را وارد کنید"
|
||||||
|
: "تاریخ اتمام را وارد کنید",
|
||||||
|
variant: "outlined",
|
||||||
|
disabled,
|
||||||
|
fullWidth: true,
|
||||||
|
error: !!error,
|
||||||
|
helperText : touched && error ,
|
||||||
|
size: "small", // Ensure that the TextField is small
|
||||||
|
InputProps: {
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton
|
||||||
|
size="small" // Set size="small" for IconButton
|
||||||
|
onClick={() => formik.setFieldValue(name, null)}
|
||||||
|
>
|
||||||
|
<ClearIcon />
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</Stack>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ import ReportIcon from "@mui/icons-material/Report";
|
|||||||
import AssignmentLateIcon from "@mui/icons-material/AssignmentLate";
|
import AssignmentLateIcon from "@mui/icons-material/AssignmentLate";
|
||||||
import LineAxisIcon from "@mui/icons-material/LineAxis";
|
import LineAxisIcon from "@mui/icons-material/LineAxis";
|
||||||
import ScienceIcon from "@mui/icons-material/Science";
|
import ScienceIcon from "@mui/icons-material/Science";
|
||||||
|
import DriveEtaIcon from '@mui/icons-material/DriveEta';
|
||||||
import BiotechIcon from "@mui/icons-material/Biotech";
|
import BiotechIcon from "@mui/icons-material/Biotech";
|
||||||
|
|
||||||
export const pageMenu = [
|
export const pageMenu = [
|
||||||
@@ -493,4 +494,12 @@ export const pageMenu = [
|
|||||||
icon: <BiotechIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <BiotechIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||||
permissions: ["azmayesh-type-management"],
|
permissions: ["azmayesh-type-management"],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "CarDetails",
|
||||||
|
label: "اطلاعات خودرو",
|
||||||
|
type: "page",
|
||||||
|
route: "/dashboard/car-details",
|
||||||
|
icon: <DriveEtaIcon sx={{ width: "inherit", height: "inherit" }} />,
|
||||||
|
permissions: ["all"],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user