complete design of adding new test and bundling and saving map data next step...
This commit is contained in:
7
src/app/(withAuth)/dashboard/test/page.js
Normal file
7
src/app/(withAuth)/dashboard/test/page.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import TestPage from "@/components/dashboard/test";
|
||||||
|
|
||||||
|
const Page = () => {
|
||||||
|
return <TestPage/>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
18
src/app/api/fake-tests-type/route.js
Normal file
18
src/app/api/fake-tests-type/route.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const data = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "تست نوع 1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "تست نوع 2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "تست نوع 3",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
return Response.json({data});
|
||||||
|
}
|
||||||
71
src/app/api/fake-tests/route.js
Normal file
71
src/app/api/fake-tests/route.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
const data = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
test_type_name: 1,
|
||||||
|
project_name: "نوع پروژه",
|
||||||
|
employer: "کارفرما",
|
||||||
|
consultant: "مشاور",
|
||||||
|
contractor: "پیمانکار",
|
||||||
|
applicant: "متقاضی",
|
||||||
|
work_number: "شماره کار",
|
||||||
|
request_number: "شماره درخواست",
|
||||||
|
request_date: "تاریخ درخواست",
|
||||||
|
report_date: "تاریخ گزارش"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
test_type_name: 5,
|
||||||
|
project_name: "نوع پروژه",
|
||||||
|
employer: "کارفرما",
|
||||||
|
consultant: "مشاور",
|
||||||
|
contractor: "پیمانکار",
|
||||||
|
applicant: "متقاضی",
|
||||||
|
work_number: "شماره کار",
|
||||||
|
request_number: "شماره درخواست",
|
||||||
|
request_date: "تاریخ درخواست",
|
||||||
|
report_date: "تاریخ گزارش"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
test_type_name: 2,
|
||||||
|
project_name: "نوع پروژه",
|
||||||
|
employer: "کارفرما",
|
||||||
|
consultant: "مشاور",
|
||||||
|
contractor: "پیمانکار",
|
||||||
|
applicant: "متقاضی",
|
||||||
|
work_number: "شماره کار",
|
||||||
|
request_number: "شماره درخواست",
|
||||||
|
request_date: "تاریخ درخواست",
|
||||||
|
report_date: "تاریخ گزارش"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
test_type_name: 4,
|
||||||
|
project_name: "نوع پروژه",
|
||||||
|
employer: "کارفرما",
|
||||||
|
consultant: "مشاور",
|
||||||
|
contractor: "پیمانکار",
|
||||||
|
applicant: "متقاضی",
|
||||||
|
work_number: "شماره کار",
|
||||||
|
request_number: "شماره درخواست",
|
||||||
|
request_date: "تاریخ درخواست",
|
||||||
|
report_date: "تاریخ گزارش"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
test_type_name: 3,
|
||||||
|
project_name: "نوع پروژه",
|
||||||
|
employer: "کارفرما",
|
||||||
|
consultant: "مشاور",
|
||||||
|
contractor: "پیمانکار",
|
||||||
|
applicant: "متقاضی",
|
||||||
|
work_number: "شماره کار",
|
||||||
|
request_number: "شماره درخواست",
|
||||||
|
request_date: "تاریخ درخواست",
|
||||||
|
report_date: "تاریخ گزارش"
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
return Response.json({data});
|
||||||
|
}
|
||||||
BIN
src/assets/images/examine_marker.png
Normal file
BIN
src/assets/images/examine_marker.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/images/examine_marker_active.png
Normal file
BIN
src/assets/images/examine_marker_active.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -3,8 +3,7 @@
|
|||||||
@import "react-toastify/dist/ReactToastify.css";
|
@import "react-toastify/dist/ReactToastify.css";
|
||||||
|
|
||||||
.filter-toast {
|
.filter-toast {
|
||||||
box-shadow:
|
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
|
||||||
rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
|
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
|
||||||
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
|
background-color: #d0dfe8;
|
||||||
background-color: #d0dfe8;
|
}
|
||||||
}
|
|
||||||
@@ -25,4 +25,3 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #ffeb3b;
|
color: #ffeb3b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {Marker, useMapEvents} from "react-leaflet";
|
||||||
|
import {useEffect, useRef} from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import TestIcon from "@/assets/images/examine_marker.png";
|
||||||
|
import TestActiveIcon from "@/assets/images/examine_marker_active.png";
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
FormControl,
|
||||||
|
InputAdornment,
|
||||||
|
InputLabel,
|
||||||
|
OutlinedInput,
|
||||||
|
Stack,
|
||||||
|
Tooltip,
|
||||||
|
useMediaQuery
|
||||||
|
} from "@mui/material";
|
||||||
|
import NewReleasesIcon from '@mui/icons-material/NewReleases';
|
||||||
|
import VerifiedIcon from '@mui/icons-material/Verified';
|
||||||
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
|
import {useTheme} from "@emotion/react";
|
||||||
|
|
||||||
|
const ChooseLocation = ({mapBoxData, setMapBoxData}) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
|
||||||
|
const mapTestMarker = useRef();
|
||||||
|
const defaultIconSize = [35, 35];
|
||||||
|
const createCustomIcon = (size, iconUrl) => {
|
||||||
|
return L.icon({
|
||||||
|
iconUrl: iconUrl,
|
||||||
|
iconSize: size,
|
||||||
|
iconAnchor: [size[0] / 2, size[1]],
|
||||||
|
popupAnchor: [0, -size[1]]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const map = useMapEvents({
|
||||||
|
move(e) {
|
||||||
|
if (!mapBoxData) {
|
||||||
|
mapTestMarker.current.setLatLng(e.target.getCenter());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
movestart() {
|
||||||
|
if (!mapBoxData) {
|
||||||
|
mapTestMarker.current.setIcon(createCustomIcon([45, 45], TestIcon.src));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
moveend() {
|
||||||
|
if (!mapBoxData) {
|
||||||
|
mapTestMarker.current.setIcon(createCustomIcon(defaultIconSize, TestIcon.src));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (mapTestMarker.current) {
|
||||||
|
const newIcon = mapBoxData
|
||||||
|
? createCustomIcon([45, 45], TestActiveIcon.src)
|
||||||
|
: createCustomIcon(defaultIconSize, TestIcon.src);
|
||||||
|
mapTestMarker.current.setIcon(newIcon);
|
||||||
|
}
|
||||||
|
if (mapBoxData) {
|
||||||
|
mapTestMarker.current.setLatLng(mapBoxData);
|
||||||
|
map.flyTo(mapBoxData, 14);
|
||||||
|
}
|
||||||
|
}, [mapBoxData]);
|
||||||
|
|
||||||
|
const handleMarkerClick = () => {
|
||||||
|
if (!mapBoxData) {
|
||||||
|
setMapBoxData({lat: mapTestMarker.current.getLatLng().lat, lng: mapTestMarker.current.getLatLng().lng});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditLocation = () => {
|
||||||
|
setMapBoxData(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Marker
|
||||||
|
position={map.getCenter()}
|
||||||
|
ref={mapTestMarker}
|
||||||
|
eventHandlers={{click: handleMarkerClick}}
|
||||||
|
icon={createCustomIcon(defaultIconSize, TestIcon.src)}
|
||||||
|
/>
|
||||||
|
<Box sx={{
|
||||||
|
zIndex: "400",
|
||||||
|
position: "absolute",
|
||||||
|
background: "#ffffff94",
|
||||||
|
p: 2,
|
||||||
|
borderRadius: "10px",
|
||||||
|
boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px",
|
||||||
|
bottom: "5px",
|
||||||
|
left: "10px",
|
||||||
|
right: isMobile ? "10px" : "",
|
||||||
|
}}>
|
||||||
|
<Stack sx={{gap: 2}}>
|
||||||
|
<Tooltip title="با کلیک بر روی مارکر، محل آزمایش را انتخاب کنید" arrow>
|
||||||
|
<FormControl size="small" variant="outlined">
|
||||||
|
<InputLabel sx={{color: mapBoxData ? "success.main" : ""}} htmlFor="lat">
|
||||||
|
طول جغرافیایی
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="lat"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
readOnly
|
||||||
|
sx={{
|
||||||
|
'& .MuiOutlinedInput-notchedOutline': {
|
||||||
|
borderColor: mapBoxData ? "success.main" : "",
|
||||||
|
},
|
||||||
|
color: mapBoxData ? "success.main" : ""
|
||||||
|
}}
|
||||||
|
value={mapBoxData ? `${mapBoxData.lat}` : ""}
|
||||||
|
endAdornment={
|
||||||
|
<InputAdornment position="end">
|
||||||
|
{mapBoxData ? <VerifiedIcon color="success"/> :
|
||||||
|
<NewReleasesIcon color="error"/>}
|
||||||
|
</InputAdornment>
|
||||||
|
}
|
||||||
|
label="طول جغرافیایی"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip title="با کلیک بر روی مارکر، محل آزمایش را انتخاب کنید" arrow>
|
||||||
|
<FormControl size="small" variant="outlined">
|
||||||
|
<InputLabel sx={{color: mapBoxData ? "success.main" : ""}} htmlFor="lng">
|
||||||
|
عرض جغرافیایی
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="lng"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
readOnly
|
||||||
|
sx={{
|
||||||
|
'& .MuiOutlinedInput-notchedOutline': {
|
||||||
|
borderColor: mapBoxData ? "success.main" : "",
|
||||||
|
},
|
||||||
|
color: mapBoxData ? "success.main" : ""
|
||||||
|
}}
|
||||||
|
value={mapBoxData ? `${mapBoxData.lng}` : ""}
|
||||||
|
endAdornment={
|
||||||
|
<InputAdornment position="end">
|
||||||
|
{mapBoxData ? <VerifiedIcon color="success"/> :
|
||||||
|
<NewReleasesIcon color="error"/>}
|
||||||
|
</InputAdornment>
|
||||||
|
}
|
||||||
|
label="عرض جغرافیایی"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</Tooltip>
|
||||||
|
<Button variant="contained" color="primary" disabled={!mapBoxData} startIcon={<EditIcon/>}
|
||||||
|
onClick={handleEditLocation}>ویرایش مختصات</Button>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ChooseLocation;
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {Box, Typography} from "@mui/material";
|
||||||
|
import TextSnippetIcon from '@mui/icons-material/TextSnippet';
|
||||||
|
import TravelExploreIcon from '@mui/icons-material/TravelExplore';
|
||||||
|
import {
|
||||||
|
Timeline,
|
||||||
|
TimelineConnector,
|
||||||
|
TimelineContent,
|
||||||
|
TimelineDot,
|
||||||
|
TimelineItem,
|
||||||
|
timelineItemClasses,
|
||||||
|
TimelineSeparator
|
||||||
|
} from "@mui/lab";
|
||||||
|
|
||||||
|
const CreateTimeLine = ({tabState}) => {
|
||||||
|
return (
|
||||||
|
<Box sx={{display: "flex", alignItems: "center"}}>
|
||||||
|
<Timeline position="right" sx={{
|
||||||
|
[`& .${timelineItemClasses.root}:before`]: {flex: 0, padding: 0}
|
||||||
|
}}>
|
||||||
|
<TimelineItem>
|
||||||
|
<TimelineSeparator>
|
||||||
|
<TimelineConnector/>
|
||||||
|
<TimelineDot sx={{backgroundColor: "#fff"}}>
|
||||||
|
<TravelExploreIcon color={tabState === 0 ? "primary" : "error"}
|
||||||
|
sx={{width: "1.5rem", height: "1.5rem"}}/>
|
||||||
|
</TimelineDot>
|
||||||
|
<TimelineConnector/>
|
||||||
|
</TimelineSeparator>
|
||||||
|
<TimelineContent sx={{py: '12px', px: 2}}>
|
||||||
|
<Typography variant="h6">
|
||||||
|
نقشه
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption" sx={{color: "#606060"}}>ثبت مختصات محل
|
||||||
|
آزمایش</Typography>
|
||||||
|
</TimelineContent>
|
||||||
|
</TimelineItem>
|
||||||
|
<TimelineItem>
|
||||||
|
<TimelineSeparator>
|
||||||
|
<TimelineConnector/>
|
||||||
|
<TimelineDot sx={{backgroundColor: "#fff"}}>
|
||||||
|
<TextSnippetIcon color={tabState === 1 ? "primary" : "error"}
|
||||||
|
sx={{width: "1.5rem", height: "1.5rem"}}/>
|
||||||
|
</TimelineDot>
|
||||||
|
<TimelineConnector/>
|
||||||
|
</TimelineSeparator>
|
||||||
|
<TimelineContent sx={{py: '12px', px: 2}}>
|
||||||
|
<Typography variant="h6">
|
||||||
|
مشخصات آزمایش
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption" sx={{color: "#606060"}}>ثبت مشخصات اولیه</Typography>
|
||||||
|
</TimelineContent>
|
||||||
|
</TimelineItem>
|
||||||
|
</Timeline>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CreateTimeLine;
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {Box, Stack} from "@mui/material";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import MapLoading from "@/core/components/MapLayer/Loading";
|
||||||
|
import ChooseLocation from "./ChooseLocation";
|
||||||
|
|
||||||
|
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
|
||||||
|
loading: () => <MapLoading/>,
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const MapBox = ({mapBoxData, setMapBoxData}) => {
|
||||||
|
return (
|
||||||
|
<Stack spacing={1} sx={{height: "500px"}}>
|
||||||
|
<Box sx={{
|
||||||
|
p: 1,
|
||||||
|
border: "1px dashed",
|
||||||
|
borderColor: "divider",
|
||||||
|
borderRadius: 1,
|
||||||
|
height: "100%"
|
||||||
|
}}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
height: "100%",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MapLayer>
|
||||||
|
<ChooseLocation mapBoxData={mapBoxData} setMapBoxData={setMapBoxData}/>
|
||||||
|
</MapLayer>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default MapBox;
|
||||||
@@ -0,0 +1,387 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {Controller} from "react-hook-form";
|
||||||
|
import {
|
||||||
|
Autocomplete,
|
||||||
|
CircularProgress,
|
||||||
|
FormControl,
|
||||||
|
FormHelperText,
|
||||||
|
Grid,
|
||||||
|
IconButton,
|
||||||
|
InputAdornment,
|
||||||
|
InputLabel,
|
||||||
|
OutlinedInput,
|
||||||
|
TextField,
|
||||||
|
Typography
|
||||||
|
} from "@mui/material";
|
||||||
|
import useTest from "@/lib/hooks/useTest";
|
||||||
|
import useProvinces from "@/lib/hooks/useProvince";
|
||||||
|
import {LocalizationProvider, MobileDatePicker} from "@mui/x-date-pickers";
|
||||||
|
import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali";
|
||||||
|
import {faIR} from "@mui/x-date-pickers/locales";
|
||||||
|
import ClearIcon from "@mui/icons-material/Clear";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const TestGeneralInfo = ({control, register, setValue, errors}) => {
|
||||||
|
const {tests, errorTests, loadingTests} = useTest();
|
||||||
|
const {provinces, errorProvinces, loadingProvinces} = useProvinces();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12} md={6}
|
||||||
|
sx={{display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||||
|
<Controller
|
||||||
|
name="azmayesh_type_id"
|
||||||
|
control={control}
|
||||||
|
render={({field: {onChange, value}, fieldState: {error}}) => (
|
||||||
|
<FormControl error={!!errors.azmayesh_type_id} size="small" fullWidth
|
||||||
|
variant="outlined">
|
||||||
|
<InputLabel htmlFor="azmayesh_type_id"/>
|
||||||
|
{errorTests ? (
|
||||||
|
<Typography color={"red"}
|
||||||
|
sx={{display: "flex", alignItems: "center", gap: 2}}>
|
||||||
|
خطایی در دریافت لیست آزمایش ها رخ داده است!
|
||||||
|
</Typography>
|
||||||
|
) : loadingTests ? (
|
||||||
|
<Typography sx={{display: "flex", alignItems: "center", gap: 2}}>
|
||||||
|
<CircularProgress size={20}/>
|
||||||
|
درحال دریافت لیست آزمایش ها
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
|
<Autocomplete
|
||||||
|
id="azmayesh_type_id"
|
||||||
|
size="small"
|
||||||
|
value={tests.find((test) => test.id === value) || null}
|
||||||
|
disablePortal
|
||||||
|
options={tests}
|
||||||
|
getOptionLabel={(test) => test.name}
|
||||||
|
isOptionEqualToValue={(option, value) => option.id === value?.id}
|
||||||
|
onChange={(event, newValue) => {
|
||||||
|
onChange(newValue ? newValue.id : "");
|
||||||
|
setValue("azmayesh_type_name", newValue ? newValue.name : "");
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
autoComplete="off"
|
||||||
|
error={!!errors.azmayesh_type_id}
|
||||||
|
fullWidth
|
||||||
|
label="نوع آزمایش"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<FormHelperText id="azmayesh_type_id">
|
||||||
|
{errors.azmayesh_type_id ? errors.azmayesh_type_id.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}
|
||||||
|
sx={{display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||||
|
<Controller
|
||||||
|
name="province_id"
|
||||||
|
control={control}
|
||||||
|
render={({field: {onChange, value}, fieldState: {error}}) => (
|
||||||
|
<FormControl error={!!errors.province_id} size="small" fullWidth
|
||||||
|
variant="outlined">
|
||||||
|
<InputLabel htmlFor="province_id"/>
|
||||||
|
{errorProvinces ? (
|
||||||
|
<Typography color={"red"}
|
||||||
|
sx={{display: "flex", alignItems: "center", gap: 2}}>
|
||||||
|
خطایی در دریافت لیست استان ها رخ داده است!
|
||||||
|
</Typography>
|
||||||
|
) : loadingProvinces ? (
|
||||||
|
<Typography sx={{display: "flex", alignItems: "center", gap: 2}}>
|
||||||
|
<CircularProgress size={20}/>
|
||||||
|
درحال دریافت لیست استان ها
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
|
<Autocomplete
|
||||||
|
id="province_id"
|
||||||
|
size="small"
|
||||||
|
value={provinces.find((province) => province.id === value) || null}
|
||||||
|
disablePortal
|
||||||
|
options={provinces}
|
||||||
|
getOptionLabel={(province) => province.name}
|
||||||
|
isOptionEqualToValue={(option, value) => option.id === value?.id}
|
||||||
|
onChange={(event, newValue) => {
|
||||||
|
onChange(newValue ? newValue.id : "");
|
||||||
|
setValue("province_name", newValue ? newValue.name : "");
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
autoComplete="off"
|
||||||
|
error={!!errors.province_id}
|
||||||
|
fullWidth
|
||||||
|
label="استان"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<FormHelperText id="province_id">
|
||||||
|
{errors.province_id ? errors.province_id.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<FormControl error={!!errors.project_name} size="small" fullWidth
|
||||||
|
variant="outlined">
|
||||||
|
<InputLabel htmlFor="project_name">
|
||||||
|
پروژه
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="project_name"
|
||||||
|
label={"پروژه"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("project_name")}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="project_name">
|
||||||
|
{errors.project_name ? errors.project_name.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<FormControl error={!!errors.employer} size="small" fullWidth variant="outlined">
|
||||||
|
<InputLabel htmlFor="employer">
|
||||||
|
کارفرما
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="employer"
|
||||||
|
label={"کارفرما"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("employer")}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="employer">
|
||||||
|
{errors.employer ? errors.employer.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<FormControl error={!!errors.consultant} size="small" fullWidth variant="outlined">
|
||||||
|
<InputLabel htmlFor="consultant">
|
||||||
|
مشاور
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="consultant"
|
||||||
|
label={"مشاور"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("consultant")}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="consultant">
|
||||||
|
{errors.consultant ? errors.consultant.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<FormControl error={!!errors.contractor} size="small" fullWidth variant="outlined">
|
||||||
|
<InputLabel htmlFor="contractor">
|
||||||
|
پیمانکار
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="contractor"
|
||||||
|
label={"پیمانکار"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("contractor")}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="contractor">
|
||||||
|
{errors.contractor ? errors.contractor.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<FormControl error={!!errors.applicant} size="small" fullWidth variant="outlined">
|
||||||
|
<InputLabel htmlFor="applicant">
|
||||||
|
متقاضی
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="applicant"
|
||||||
|
label={"متقاضی"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("applicant")}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="applicant">
|
||||||
|
{errors.applicant ? errors.applicant.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<FormControl error={!!errors.work_number} size="small" fullWidth variant="outlined">
|
||||||
|
<InputLabel htmlFor="work_number">
|
||||||
|
شماره کار
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="work_number"
|
||||||
|
label={"شماره کار"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("work_number")}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="work_number">
|
||||||
|
{errors.work_number ? errors.work_number.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<FormControl error={!!errors.request_number} size="small" fullWidth
|
||||||
|
variant="outlined">
|
||||||
|
<InputLabel htmlFor="request_number">
|
||||||
|
شماره درخواست
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="request_number"
|
||||||
|
label={"شماره درخواست"}
|
||||||
|
autoComplete="off"
|
||||||
|
{...register("request_number")}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<FormHelperText id="request_number">
|
||||||
|
{errors.request_number ? errors.request_number.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Controller
|
||||||
|
name="request_date"
|
||||||
|
control={control}
|
||||||
|
defaultValue={new Date()}
|
||||||
|
render={({field: {onChange, value}, fieldState: {error}}) => (
|
||||||
|
<FormControl
|
||||||
|
error={!!errors.request_date}
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
>
|
||||||
|
<LocalizationProvider
|
||||||
|
dateAdapter={AdapterDateFnsJalali}
|
||||||
|
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
|
||||||
|
>
|
||||||
|
<MobileDatePicker
|
||||||
|
value={value || null}
|
||||||
|
onChange={(newValue) => {
|
||||||
|
onChange(newValue);
|
||||||
|
}}
|
||||||
|
slotProps={{
|
||||||
|
textField: {
|
||||||
|
size: "small",
|
||||||
|
error: !!errors.request_date,
|
||||||
|
placeholder: "تاریخ درخواست",
|
||||||
|
InputProps: {
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
setValue("request_date", "");
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
color: "#bfbfbf",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||||
|
color: "#363434",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ClearIcon/>
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
<FormHelperText id="request_date">
|
||||||
|
{errors.request_date ? errors.request_date.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Controller
|
||||||
|
name="report_date"
|
||||||
|
control={control}
|
||||||
|
defaultValue={new Date()}
|
||||||
|
render={({field: {onChange, value}, fieldState: {error}}) => (
|
||||||
|
<FormControl
|
||||||
|
error={!!errors.report_date}
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
>
|
||||||
|
<LocalizationProvider
|
||||||
|
dateAdapter={AdapterDateFnsJalali}
|
||||||
|
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
|
||||||
|
>
|
||||||
|
<MobileDatePicker
|
||||||
|
value={value || null}
|
||||||
|
onChange={(newValue) => {
|
||||||
|
onChange(newValue);
|
||||||
|
}}
|
||||||
|
slotProps={{
|
||||||
|
textField: {
|
||||||
|
size: "small",
|
||||||
|
error: !!errors.report_date,
|
||||||
|
placeholder: "تاریخ گزارش",
|
||||||
|
InputProps: {
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
setValue("report_date", "");
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
color: "#bfbfbf",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||||
|
color: "#363434",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ClearIcon/>
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
<FormHelperText id="report_date">
|
||||||
|
{errors.report_date ? errors.report_date.message : null}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default TestGeneralInfo;
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {Box, Button, Dialog, DialogActions, DialogContent, Tab, Tabs, useMediaQuery} from "@mui/material";
|
||||||
|
import {useTheme} from "@emotion/react";
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import MapBox from "./MapBox";
|
||||||
|
import TravelExploreIcon from '@mui/icons-material/TravelExplore';
|
||||||
|
import TextSnippetIcon from '@mui/icons-material/TextSnippet';
|
||||||
|
import KeyboardDoubleArrowRightIcon from '@mui/icons-material/KeyboardDoubleArrowRight';
|
||||||
|
import KeyboardDoubleArrowLeftIcon from '@mui/icons-material/KeyboardDoubleArrowLeft';
|
||||||
|
import ExitToAppIcon from '@mui/icons-material/ExitToApp';
|
||||||
|
import BeenhereIcon from '@mui/icons-material/Beenhere';
|
||||||
|
import CreateTimeLine from "./CreateTimeLine";
|
||||||
|
import {useForm} from "react-hook-form";
|
||||||
|
import StyledForm from "@/core/components/StyledForm";
|
||||||
|
import {object, string} from "yup";
|
||||||
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
|
import {yupResolver} from "@hookform/resolvers/yup";
|
||||||
|
import moment from "jalali-moment";
|
||||||
|
import {POST_TEST} from "@/core/utils/routes";
|
||||||
|
import TestGeneralInfo from "@/components/dashboard/test/Actions/create/CreateDialog/TestGeneralInfo";
|
||||||
|
|
||||||
|
function TabPanel(props) {
|
||||||
|
const {children, value, index} = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
hidden={value !== index}
|
||||||
|
>
|
||||||
|
{value === index && (
|
||||||
|
<Box>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateDialog = ({open, setOpen}) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
const [tabState, setTabState] = useState(0);
|
||||||
|
const [mapBoxData, setMapBoxData] = useState(null);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeTab = (event, newValue) => {
|
||||||
|
setTabState(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
if (tabState === 0) {
|
||||||
|
handleClose();
|
||||||
|
} else {
|
||||||
|
setTabState(tabState - 1)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const validationSchema = object({
|
||||||
|
azmayesh_type_id: string().required("نوع آزمایش را مشخص کنید!"),
|
||||||
|
province_id: string().required("استان را وارد کنید!"),
|
||||||
|
project_name: string().required("عنوان پروژه را وارد کنید!"),
|
||||||
|
employer: string().required("کارفرما را وارد کنید!"),
|
||||||
|
consultant: string().required("مشاور را وارد کنید!"),
|
||||||
|
contractor: string().required("پیمانکار را وارد کنید!"),
|
||||||
|
applicant: string().required("متقاضی را وارد کنید!"),
|
||||||
|
work_number: string().required("شماره کار را وارد کنید!"),
|
||||||
|
request_number: string().required("شماره درخواست را وارد کنید!"),
|
||||||
|
request_date: string().required("تاریخ درخواست را وارد کنید!"),
|
||||||
|
report_date: string().required("تاریخ گزارش را وارد کنید!"),
|
||||||
|
});
|
||||||
|
const requestServer = useRequest({auth: true});
|
||||||
|
|
||||||
|
const defaultValues = {
|
||||||
|
azmayesh_type_id: "",
|
||||||
|
azmayesh_type_name: "",
|
||||||
|
province_id: "",
|
||||||
|
province_name: "",
|
||||||
|
project_name: "",
|
||||||
|
employer: "",
|
||||||
|
consultant: "",
|
||||||
|
contractor: "",
|
||||||
|
applicant: "",
|
||||||
|
work_number: "",
|
||||||
|
request_number: "",
|
||||||
|
request_date: "",
|
||||||
|
report_date: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
setValue,
|
||||||
|
formState: {isSubmitting, errors, touchedFields},
|
||||||
|
} = useForm({defaultValues, resolver: yupResolver(validationSchema), mode: "onBlur"});
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
console.log("data", data);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("lat", mapBoxData.lat);
|
||||||
|
formData.append("lng", mapBoxData.lng);
|
||||||
|
formData.append("azmayesh_type_id", data.azmayesh_type_id);
|
||||||
|
formData.append("azmayesh_type_name", data.azmayesh_type_name);
|
||||||
|
formData.append("province_id", data.province_id);
|
||||||
|
formData.append("province_name", data.province_name);
|
||||||
|
formData.append("project_name", data.project_name);
|
||||||
|
formData.append("employer", data.employer);
|
||||||
|
formData.append("consultant", data.consultant);
|
||||||
|
formData.append("contractor", data.contractor);
|
||||||
|
formData.append("applicant", data.applicant);
|
||||||
|
formData.append("work_number", data.work_number);
|
||||||
|
formData.append("request_number", data.request_number);
|
||||||
|
formData.append("request_date", moment(data.request_date).format("YYYY-MM-DD"));
|
||||||
|
formData.append("report_date", moment(data.report_date).format("YYYY-MM-DD"));
|
||||||
|
|
||||||
|
for (var pair of formData.entries()) {
|
||||||
|
console.log(pair[0] + ', ' + pair[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestServer(POST_TEST, "post", {
|
||||||
|
data: formData,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} fullWidth={true} maxWidth={"lg"}>
|
||||||
|
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Tabs allowScrollButtonsMobile value={tabState} onChange={handleChangeTab}
|
||||||
|
variant={`${isMobile ? "scrollable" : "fullWidth"}`}
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "#efefef"
|
||||||
|
}}>
|
||||||
|
<Tab icon={<TravelExploreIcon/>} label="انتخاب محل آزمایش"></Tab>
|
||||||
|
<Tab disabled={!mapBoxData} icon={<TextSnippetIcon/>} label="مشخصات آزمایش"></Tab>
|
||||||
|
</Tabs>
|
||||||
|
<DialogContent dividers sx={{display: "flex"}}>
|
||||||
|
<Box sx={{flex: 1}}>
|
||||||
|
<TabPanel value={tabState} index={0}>
|
||||||
|
<MapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData}/>
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel value={tabState} index={1}>
|
||||||
|
<TestGeneralInfo control={control} register={register} setValue={setValue} errors={errors}/>
|
||||||
|
</TabPanel>
|
||||||
|
</Box>
|
||||||
|
{!isMobile && (
|
||||||
|
<Box sx={{display: "flex", alignItems: "center"}}>
|
||||||
|
<CreateTimeLine tabState={tabState}/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions sx={{alignItems: "center", justifyContent: "center"}}>
|
||||||
|
<Button onClick={handlePrev} variant="outlined" color="error" size="large"
|
||||||
|
startIcon={tabState === 0 ? <ExitToAppIcon/> : <KeyboardDoubleArrowRightIcon/>}>
|
||||||
|
{tabState === 0 ? "بستن" : "مرحله قبل"}
|
||||||
|
</Button>
|
||||||
|
{
|
||||||
|
tabState === 0 ? <Button onClick={() => setTabState(tabState + 1)} variant="contained"
|
||||||
|
size="large"
|
||||||
|
disabled={!mapBoxData}
|
||||||
|
endIcon={<KeyboardDoubleArrowLeftIcon/>}>
|
||||||
|
مرحله بعد
|
||||||
|
</Button> : <Button variant="contained"
|
||||||
|
size="large"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
type={"submit"}
|
||||||
|
endIcon={<BeenhereIcon/>}>
|
||||||
|
{isSubmitting ? "در حال ثبت آزمایش" : "ثبت آزمایش"}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
</DialogActions>
|
||||||
|
</StyledForm>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CreateDialog;
|
||||||
33
src/components/dashboard/test/Actions/create/index.jsx
Normal file
33
src/components/dashboard/test/Actions/create/index.jsx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
"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 CreateDialog from "./CreateDialog";
|
||||||
|
|
||||||
|
const TestCreate = () => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleOpen = () => {
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isMobile ? (
|
||||||
|
<IconButton aria-label="ایجاد آزمایش جدید" color="primary" onClick={handleOpen}>
|
||||||
|
<AddCircle sx={{fontSize: "25px"}}/>
|
||||||
|
</IconButton>
|
||||||
|
) : (
|
||||||
|
<Button variant="contained" color="primary" startIcon={<AddCircle/>} onClick={handleOpen}>
|
||||||
|
ثبت آزمایش
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{open && <CreateDialog open={open} setOpen={setOpen}/>}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default TestCreate;
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {Marker, useMap} from "react-leaflet";
|
||||||
|
import {useEffect, useRef} from "react";
|
||||||
|
import L from "leaflet";
|
||||||
|
import TestActiveIcon from "@/assets/images/examine_marker_active.png";
|
||||||
|
import {Box, FormControl, InputAdornment, InputLabel, OutlinedInput, Stack, useMediaQuery} from "@mui/material";
|
||||||
|
import VerifiedIcon from '@mui/icons-material/Verified';
|
||||||
|
import {useTheme} from "@emotion/react";
|
||||||
|
|
||||||
|
const ShowLocationMarker = ({lat, lng}) => {
|
||||||
|
const map = useMap();
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
|
||||||
|
const mapTestMarker = useRef();
|
||||||
|
const defaultIconSize = [35, 35];
|
||||||
|
const createCustomIcon = (size, iconUrl) => {
|
||||||
|
return L.icon({
|
||||||
|
iconUrl: iconUrl,
|
||||||
|
iconSize: size,
|
||||||
|
iconAnchor: [size[0] / 2, size[1]],
|
||||||
|
popupAnchor: [0, -size[1]]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
map.flyTo({lat: lat, lng: lng}, 14);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Marker
|
||||||
|
position={{lat: lat, lng: lng}}
|
||||||
|
ref={mapTestMarker}
|
||||||
|
icon={createCustomIcon(defaultIconSize, TestActiveIcon.src)}
|
||||||
|
/>
|
||||||
|
<Box sx={{
|
||||||
|
zIndex: "400",
|
||||||
|
position: "absolute",
|
||||||
|
background: "#ffffff94",
|
||||||
|
p: 2,
|
||||||
|
borderRadius: "10px",
|
||||||
|
boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px",
|
||||||
|
bottom: "5px",
|
||||||
|
left: "10px",
|
||||||
|
right: isMobile ? "10px" : "",
|
||||||
|
}}>
|
||||||
|
<Stack sx={{gap: 2}}>
|
||||||
|
<FormControl size="small" variant="outlined">
|
||||||
|
<InputLabel sx={{color: "success.main"}} htmlFor="lat">
|
||||||
|
طول جغرافیایی
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="lat"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
readOnly
|
||||||
|
sx={{
|
||||||
|
'& .MuiOutlinedInput-notchedOutline': {
|
||||||
|
borderColor: "success.main",
|
||||||
|
},
|
||||||
|
color: "success.main"
|
||||||
|
}}
|
||||||
|
value={lat}
|
||||||
|
endAdornment={
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<VerifiedIcon color="success"/>
|
||||||
|
</InputAdornment>
|
||||||
|
}
|
||||||
|
label="طول جغرافیایی"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl size="small" variant="outlined">
|
||||||
|
<InputLabel sx={{color: "success.main"}} htmlFor="lng">
|
||||||
|
عرض جغرافیایی
|
||||||
|
</InputLabel>
|
||||||
|
<OutlinedInput
|
||||||
|
id="lng"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
readOnly
|
||||||
|
sx={{
|
||||||
|
'& .MuiOutlinedInput-notchedOutline': {
|
||||||
|
borderColor: "success.main",
|
||||||
|
},
|
||||||
|
color: "success.main"
|
||||||
|
}}
|
||||||
|
value={lng}
|
||||||
|
endAdornment={
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<VerifiedIcon color="success"/>
|
||||||
|
</InputAdornment>
|
||||||
|
}
|
||||||
|
label="عرض جغرافیایی"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShowLocationMarker;
|
||||||
50
src/components/dashboard/test/ShowLocation/index.jsx
Normal file
50
src/components/dashboard/test/ShowLocation/index.jsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import ExploreIcon from "@mui/icons-material/Explore";
|
||||||
|
import {Box, Button, Dialog, DialogActions, DialogContent, IconButton} from "@mui/material";
|
||||||
|
import {useState} from "react";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import MapLoading from "@/core/components/MapLayer/Loading";
|
||||||
|
import ShowLocationMarker from "./ShowLocationMarker";
|
||||||
|
|
||||||
|
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
|
||||||
|
loading: () => <MapLoading/>,
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const ShowLocation = ({lat, lng}) => {
|
||||||
|
const [openShowLocationModal, setOpenShowLocationModal] = useState(false);
|
||||||
|
|
||||||
|
const handleOpenShowLocationModal = () => {
|
||||||
|
setOpenShowLocationModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseShowLocationModal = () => {
|
||||||
|
setOpenShowLocationModal(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<IconButton onClick={handleOpenShowLocationModal} size="small" color="primary"><ExploreIcon/></IconButton>
|
||||||
|
<Dialog
|
||||||
|
open={openShowLocationModal}
|
||||||
|
onClose={handleCloseShowLocationModal}
|
||||||
|
aria-labelledby="responsive-dialog-title"
|
||||||
|
>
|
||||||
|
<DialogContent>
|
||||||
|
<Box sx={{width: "400px", height: "400px"}}>
|
||||||
|
<MapLayer>
|
||||||
|
<ShowLocationMarker lat={lat} lng={lng}/>
|
||||||
|
</MapLayer>
|
||||||
|
</Box>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button color="error" variant="outlined" onClick={handleCloseShowLocationModal}>
|
||||||
|
بستن
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default ShowLocation;
|
||||||
135
src/components/dashboard/test/TestList.jsx
Normal file
135
src/components/dashboard/test/TestList.jsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {useMemo} from "react";
|
||||||
|
import {Box, Typography} from "@mui/material";
|
||||||
|
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
|
||||||
|
import Toolbar from "./Toolbar";
|
||||||
|
import {GET_AZMAYESH_LIST} from "@/core/utils/routes";
|
||||||
|
import moment from "jalali-moment";
|
||||||
|
import ShowLocation from "./ShowLocation";
|
||||||
|
|
||||||
|
const TestList = () => {
|
||||||
|
const columns = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
accessorKey: "id",
|
||||||
|
header: "کد یکتا",
|
||||||
|
id: "id",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "notEquals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "azmayesh_type_name",
|
||||||
|
header: "نوع آزمایش",
|
||||||
|
id: "azmayesh_type_name",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "notEquals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "project_name",
|
||||||
|
header: "پروژه",
|
||||||
|
id: "project_name",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "lat",
|
||||||
|
header: "نمایش مختصات",
|
||||||
|
id: "lat",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
Cell: ({row}) => (<ShowLocation lat={row.original.lat} lng={row.original.lng}/>),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "employer",
|
||||||
|
header: "کارفرما",
|
||||||
|
id: "employer",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "consultant",
|
||||||
|
header: "مشاور",
|
||||||
|
id: "consultant",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "contractor",
|
||||||
|
header: "پیمانکار",
|
||||||
|
id: "contractor",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "applicant",
|
||||||
|
header: "متقاضی",
|
||||||
|
id: "applicant",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "work_number",
|
||||||
|
header: "شماره کار",
|
||||||
|
id: "work_number",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "request_number",
|
||||||
|
header: "شماره درخواست",
|
||||||
|
id: "request_number",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "text",
|
||||||
|
filterFn: "equals",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "request_date",
|
||||||
|
header: "تاریخ درخواست",
|
||||||
|
id: "request_date",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "date",
|
||||||
|
filterFn: "equals",
|
||||||
|
Cell: ({renderedCellValue}) => (<Typography
|
||||||
|
variant="body2">{moment(renderedCellValue).locale("fa").format("YYYY/MM/DD")}</Typography>),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "report_date",
|
||||||
|
header: "تاریخ گزارش",
|
||||||
|
id: "report_date",
|
||||||
|
enableColumnFilter: false,
|
||||||
|
datatype: "date",
|
||||||
|
filterFn: "equals",
|
||||||
|
Cell: ({renderedCellValue}) => (<Typography
|
||||||
|
variant="body2">{moment(renderedCellValue).locale("fa").format("YYYY/MM/DD")}</Typography>),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box sx={{p: 1, border: 1, borderColor: "divider", borderRadius: 1}}>
|
||||||
|
<DataTableWithAuth
|
||||||
|
table_title={"لیست آزمایش ها"}
|
||||||
|
need_filter={false}
|
||||||
|
columns={columns}
|
||||||
|
table_url={GET_AZMAYESH_LIST}
|
||||||
|
page_name={"azmayesh"}
|
||||||
|
table_name={"azmayeshList"}
|
||||||
|
TableToolbar={Toolbar}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default TestList;
|
||||||
10
src/components/dashboard/test/Toolbar.jsx
Normal file
10
src/components/dashboard/test/Toolbar.jsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import TestCreate from "./Actions/Create";
|
||||||
|
|
||||||
|
const Toolbar = ({mutate}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TestCreate mutate={mutate}/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Toolbar;
|
||||||
15
src/components/dashboard/test/index.jsx
Normal file
15
src/components/dashboard/test/index.jsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import PageTitle from "@/core/components/PageTitle";
|
||||||
|
import {Stack} from "@mui/material";
|
||||||
|
import TestList from "./TestList";
|
||||||
|
|
||||||
|
const TestPage = () => {
|
||||||
|
return (
|
||||||
|
<Stack spacing={1}>
|
||||||
|
<PageTitle title={"آزمایشات"}/>
|
||||||
|
<TestList/>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default TestPage;
|
||||||
@@ -18,6 +18,7 @@ import EngineeringIcon from "@mui/icons-material/Engineering";
|
|||||||
import ReportIcon from "@mui/icons-material/Report";
|
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';
|
||||||
|
|
||||||
export const pageMenu = [
|
export const pageMenu = [
|
||||||
{
|
{
|
||||||
@@ -25,7 +26,7 @@ export const pageMenu = [
|
|||||||
label: "پیشخوان",
|
label: "پیشخوان",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: "/dashboard",
|
route: "/dashboard",
|
||||||
icon: <SpaceDashboardIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <SpaceDashboardIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
permissions: ["all"],
|
permissions: ["all"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -33,14 +34,14 @@ export const pageMenu = [
|
|||||||
label: "مدیریت کاربران",
|
label: "مدیریت کاربران",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management",
|
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"],
|
permissions: ["full-user-management", "limited-user-management"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "projectsManagment",
|
id: "projectsManagment",
|
||||||
label: "پروژه های راهداری",
|
label: "پروژه های راهداری",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <AccountTreeIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <AccountTreeIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
Subitems: [
|
Subitems: [
|
||||||
{
|
{
|
||||||
@@ -48,7 +49,7 @@ export const pageMenu = [
|
|||||||
label: "ثبت قرارداد و پروژه",
|
label: "ثبت قرارداد و پروژه",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance",
|
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"],
|
permissions: ["show-contract", "show-contract-province"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -56,7 +57,7 @@ export const pageMenu = [
|
|||||||
label: "لیست پروژه ها",
|
label: "لیست پروژه ها",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list",
|
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"],
|
permissions: ["all"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -64,7 +65,7 @@ export const pageMenu = [
|
|||||||
label: "پروژه های پیشنهادی",
|
label: "پروژه های پیشنهادی",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal",
|
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"],
|
permissions: ["show-proposal", "show-proposal-province"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -72,7 +73,7 @@ export const pageMenu = [
|
|||||||
label: "درخواست نمایندگان",
|
label: "درخواست نمایندگان",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers",
|
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"],
|
permissions: ["show-lawmaker", "show-lawmaker-province"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -80,7 +81,7 @@ export const pageMenu = [
|
|||||||
label: "پراکندگی بر روی نقشه",
|
label: "پراکندگی بر روی نقشه",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects",
|
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"],
|
permissions: ["all"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -89,7 +90,7 @@ export const pageMenu = [
|
|||||||
id: "roadItemManagment",
|
id: "roadItemManagment",
|
||||||
label: "فعالیت های روزانه",
|
label: "فعالیت های روزانه",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <FactCheckIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <FactCheckIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_items.total"],
|
badges: ["road_items.total"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -97,7 +98,7 @@ export const pageMenu = [
|
|||||||
id: "roadItemManagmentSupervisor",
|
id: "roadItemManagmentSupervisor",
|
||||||
label: "ارزیابی",
|
label: "ارزیابی",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <SpeedIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_items.supervise_cnt"],
|
badges: ["road_items.supervise_cnt"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -117,7 +118,7 @@ export const pageMenu = [
|
|||||||
id: "roadItemManagmentOparation",
|
id: "roadItemManagmentOparation",
|
||||||
label: "عملیات",
|
label: "عملیات",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_items.operation_cnt"],
|
badges: ["road_items.operation_cnt"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -142,7 +143,7 @@ export const pageMenu = [
|
|||||||
label: "پراکندگی بر روی نقشه",
|
label: "پراکندگی بر روی نقشه",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items",
|
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: [
|
permissions: [
|
||||||
"show-road-item-supervise-cartable",
|
"show-road-item-supervise-cartable",
|
||||||
"show-road-item-supervise-cartable-province",
|
"show-road-item-supervise-cartable-province",
|
||||||
@@ -154,7 +155,7 @@ export const pageMenu = [
|
|||||||
label: "گزارش ها",
|
label: "گزارش ها",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report",
|
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report",
|
||||||
icon: <ReportIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <ReportIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
permissions: [
|
permissions: [
|
||||||
"show-road-item-supervise-cartable",
|
"show-road-item-supervise-cartable",
|
||||||
"show-road-item-supervise-cartable-province",
|
"show-road-item-supervise-cartable-province",
|
||||||
@@ -167,7 +168,7 @@ export const pageMenu = [
|
|||||||
id: "roadPatrolManagment",
|
id: "roadPatrolManagment",
|
||||||
label: "گشت راهداری و ترابری",
|
label: "گشت راهداری و ترابری",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <FireTruckIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <FireTruckIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_patrols.total"],
|
badges: ["road_patrols.total"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -175,7 +176,7 @@ export const pageMenu = [
|
|||||||
id: "roadPatrolManagmentSupervisor",
|
id: "roadPatrolManagmentSupervisor",
|
||||||
label: "ارزیابی",
|
label: "ارزیابی",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <SpeedIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_patrols.supervise_cnt"],
|
badges: ["road_patrols.supervise_cnt"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -195,7 +196,7 @@ export const pageMenu = [
|
|||||||
id: "roadPatrolManagmentOparation",
|
id: "roadPatrolManagmentOparation",
|
||||||
label: "عملیات",
|
label: "عملیات",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_patrols.operation_cnt"],
|
badges: ["road_patrols.operation_cnt"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -220,7 +221,7 @@ export const pageMenu = [
|
|||||||
label: "پراکندگی بر روی نقشه",
|
label: "پراکندگی بر روی نقشه",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols",
|
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: [
|
permissions: [
|
||||||
"add-road-patrol",
|
"add-road-patrol",
|
||||||
"show-road-patrol-supervise-cartable",
|
"show-road-patrol-supervise-cartable",
|
||||||
@@ -232,7 +233,7 @@ export const pageMenu = [
|
|||||||
label: "گزارش ها",
|
label: "گزارش ها",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report",
|
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report",
|
||||||
icon: <ReportIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <ReportIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
permissions: [
|
permissions: [
|
||||||
"add-road-patrol",
|
"add-road-patrol",
|
||||||
"show-road-patrol-supervise-cartable",
|
"show-road-patrol-supervise-cartable",
|
||||||
@@ -245,7 +246,7 @@ export const pageMenu = [
|
|||||||
id: "inquiryPrivacyManagment",
|
id: "inquiryPrivacyManagment",
|
||||||
label: "استعلام حریم راه",
|
label: "استعلام حریم راه",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <DoorbellIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <DoorbellIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
Subitems: [
|
Subitems: [
|
||||||
{
|
{
|
||||||
@@ -282,7 +283,7 @@ export const pageMenu = [
|
|||||||
id: "safetyAndPrivacyManagment",
|
id: "safetyAndPrivacyManagment",
|
||||||
label: "نگهداری حریم راه",
|
label: "نگهداری حریم راه",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <RouteIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <RouteIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["safety_and_privacy.step_one", "safety_and_privacy.step_two"],
|
badges: ["safety_and_privacy.step_one", "safety_and_privacy.step_two"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -290,7 +291,7 @@ export const pageMenu = [
|
|||||||
id: "safetyAndPrivacyManagmentOparation",
|
id: "safetyAndPrivacyManagmentOparation",
|
||||||
label: "عملیات",
|
label: "عملیات",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
Subitems: [
|
Subitems: [
|
||||||
{
|
{
|
||||||
@@ -318,7 +319,7 @@ export const pageMenu = [
|
|||||||
label: "پراکندگی بر روی نقشه",
|
label: "پراکندگی بر روی نقشه",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy",
|
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: [
|
permissions: [
|
||||||
"show-safety-and-privacy-operator-cartable",
|
"show-safety-and-privacy-operator-cartable",
|
||||||
"show-safety-and-privacy-operator-cartable-province",
|
"show-safety-and-privacy-operator-cartable-province",
|
||||||
@@ -331,7 +332,7 @@ export const pageMenu = [
|
|||||||
label: "گزارش ها",
|
label: "گزارش ها",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report",
|
route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report",
|
||||||
icon: <ReportIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <ReportIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
permissions: [
|
permissions: [
|
||||||
"show-safety-and-privacy-operator-cartable",
|
"show-safety-and-privacy-operator-cartable",
|
||||||
"show-safety-and-privacy-operator-cartable-province",
|
"show-safety-and-privacy-operator-cartable-province",
|
||||||
@@ -345,7 +346,7 @@ export const pageMenu = [
|
|||||||
id: "roadObservationsManagment",
|
id: "roadObservationsManagment",
|
||||||
label: "واکنش سریع",
|
label: "واکنش سریع",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <ElectricBoltIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <ElectricBoltIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_observations.total"],
|
badges: ["road_observations.total"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -353,7 +354,7 @@ export const pageMenu = [
|
|||||||
id: "roadObservationsManagmentSupervisor",
|
id: "roadObservationsManagmentSupervisor",
|
||||||
label: "ارزیابی",
|
label: "ارزیابی",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <SpeedIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <SpeedIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_observations.supervise_cnt"],
|
badges: ["road_observations.supervise_cnt"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -371,14 +372,14 @@ export const pageMenu = [
|
|||||||
label: "رسیدگی به شکایات",
|
label: "رسیدگی به شکایات",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations",
|
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"],
|
permissions: ["show-fast-react", "show-fast-react-province", "show-fast-react-edarate-shahri"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "roadObservationsManagmentOparation",
|
id: "roadObservationsManagmentOparation",
|
||||||
label: "عملیات",
|
label: "عملیات",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
badges: ["road_observations.operation_cnt"],
|
badges: ["road_observations.operation_cnt"],
|
||||||
Subitems: [
|
Subitems: [
|
||||||
@@ -396,7 +397,7 @@ export const pageMenu = [
|
|||||||
label: "پراکندگی بر روی نقشه",
|
label: "پراکندگی بر روی نقشه",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations",
|
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"],
|
permissions: ["all"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -404,7 +405,7 @@ export const pageMenu = [
|
|||||||
label: "گزارش ها",
|
label: "گزارش ها",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index",
|
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index",
|
||||||
icon: <ReportIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <ReportIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
permissions: ["all"],
|
permissions: ["all"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -413,7 +414,7 @@ export const pageMenu = [
|
|||||||
id: "winterCampManagment",
|
id: "winterCampManagment",
|
||||||
label: "قرارگاه زمستانی",
|
label: "قرارگاه زمستانی",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <CottageIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <CottageIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
Subitems: [
|
Subitems: [
|
||||||
{
|
{
|
||||||
@@ -421,7 +422,7 @@ export const pageMenu = [
|
|||||||
label: "محور های انسدادی",
|
label: "محور های انسدادی",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp",
|
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"],
|
permissions: ["show-camp", "show-camp-province"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -429,7 +430,7 @@ export const pageMenu = [
|
|||||||
label: "محور های حلقه اول",
|
label: "محور های حلقه اول",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp",
|
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"],
|
permissions: ["show-camp", "show-camp-province"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -437,7 +438,7 @@ export const pageMenu = [
|
|||||||
label: "گزارش ها",
|
label: "گزارش ها",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew",
|
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew",
|
||||||
icon: <ReportIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <ReportIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
permissions: ["show-camp", "show-camp-province"],
|
permissions: ["show-camp", "show-camp-province"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -446,14 +447,14 @@ export const pageMenu = [
|
|||||||
id: "receiptManagment",
|
id: "receiptManagment",
|
||||||
label: "خسارات وارده بر ابنیه فنی و تاسیسات راه",
|
label: "خسارات وارده بر ابنیه فنی و تاسیسات راه",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <GppMaybeIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <GppMaybeIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
Subitems: [
|
Subitems: [
|
||||||
{
|
{
|
||||||
id: "receiptManagmentOparation",
|
id: "receiptManagmentOparation",
|
||||||
label: "عملیات",
|
label: "عملیات",
|
||||||
type: "menu",
|
type: "menu",
|
||||||
icon: <EngineeringIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <EngineeringIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
hasSubitems: true,
|
hasSubitems: true,
|
||||||
Subitems: [
|
Subitems: [
|
||||||
{
|
{
|
||||||
@@ -470,9 +471,17 @@ export const pageMenu = [
|
|||||||
label: "گزارش ها",
|
label: "گزارش ها",
|
||||||
type: "page",
|
type: "page",
|
||||||
route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report",
|
route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report",
|
||||||
icon: <ReportIcon sx={{ width: "inherit", height: "inherit" }} />,
|
icon: <ReportIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
permissions: ["all"],
|
permissions: ["all"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "test",
|
||||||
|
label: "آزمایشات",
|
||||||
|
type: "page",
|
||||||
|
route: "/dashboard/test",
|
||||||
|
icon: <ScienceIcon sx={{width: "inherit", height: "inherit"}}/>,
|
||||||
|
permissions: ["all"],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -12,3 +12,6 @@ export const GET_CITY_LISTS = "/v3/api/fake-cities";
|
|||||||
export const GET_PROVINCE_LISTS = "/v3/api/fake-provinces";
|
export const GET_PROVINCE_LISTS = "/v3/api/fake-provinces";
|
||||||
export const GET_PREV_STATE_OPINION = "/v3/api/fake-prev-state-opinion";
|
export const GET_PREV_STATE_OPINION = "/v3/api/fake-prev-state-opinion";
|
||||||
export const SUBMIT_ROAD_SAFETY_FORM = "/v3/api/fake-submit";
|
export const SUBMIT_ROAD_SAFETY_FORM = "/v3/api/fake-submit";
|
||||||
|
export const POST_TEST = api + "/api/v3/azmayeshes/store";
|
||||||
|
export const GET_TESTS_LIST = api + "/api/v3/azmayesh_types";
|
||||||
|
export const GET_AZMAYESH_LIST = api + "/api/v3/azmayeshes";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useState, useEffect } from "react";
|
import {useEffect, useState} from "react";
|
||||||
import axios from "axios";
|
import {GET_PROVINCE_LISTS} from "@/core/utils/routes";
|
||||||
import { GET_PROVINCE_LISTS } from "@/core/utils/routes";
|
|
||||||
import useRequest from "@/lib/hooks/useRequest";
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
|
|
||||||
const useProvinces = () => {
|
const useProvinces = () => {
|
||||||
@@ -25,7 +24,7 @@ const useProvinces = () => {
|
|||||||
fetchCities(); // Call the fetch function
|
fetchCities(); // Call the fetch function
|
||||||
}, []); // Empty dependency array to ensure it only runs once
|
}, []); // Empty dependency array to ensure it only runs once
|
||||||
|
|
||||||
return { provinces, loadingProvinces, errorProvinces };
|
return {provinces, loadingProvinces, errorProvinces};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useProvinces;
|
export default useProvinces;
|
||||||
|
|||||||
30
src/lib/hooks/useTest.js
Normal file
30
src/lib/hooks/useTest.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {GET_TESTS_LIST} from "@/core/utils/routes";
|
||||||
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
|
|
||||||
|
const useTest = () => {
|
||||||
|
const requestServer = useRequest();
|
||||||
|
const [tests, setTests] = useState([]);
|
||||||
|
const [loadingTests, setLoadingTests] = useState(true);
|
||||||
|
const [errorTests, setErrorTests] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchTests = async () => {
|
||||||
|
try {
|
||||||
|
const response = await requestServer(`${GET_TESTS_LIST}`);
|
||||||
|
setTests(response.data.data);
|
||||||
|
setLoadingTests(false);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error fetching tests types:", e);
|
||||||
|
setErrorTests(e);
|
||||||
|
setLoadingTests(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchTests();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {tests, loadingTests, errorTests};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useTest;
|
||||||
Reference in New Issue
Block a user