Feature/amiriis azmayesh

This commit is contained in:
AmirHossein Mahmoodi
2024-12-25 11:37:01 +00:00
parent fe7e504917
commit 6c5e9506bf
9 changed files with 234 additions and 114 deletions

View File

@@ -8,6 +8,7 @@ import { GET_AZMAYESH_LIST } from "@/core/utils/routes";
import ShowLocation from "./ShowLocation";
import moment from "jalali-moment";
import RowActions from "./RowActions";
import ShowSampleOfAzmayesh from "./RowActions/ShowSampleOfAzmayesh";
const AzmayeshList = () => {
const columns = useMemo(
@@ -19,6 +20,16 @@ const AzmayeshList = () => {
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
grow: false,
size: 100
},
{
accessorKey: "province_name",
header: "استان",
id: "province_name",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "azmayesh_type_name",
@@ -28,6 +39,14 @@ const AzmayeshList = () => {
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "contract_subitem_id",
header: "کد یکتا پروژه",
id: "contract_subitem_id",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "project_name",
header: "پروژه",
@@ -37,13 +56,24 @@ const AzmayeshList = () => {
filterMode: "equals",
},
{
accessorKey: "lat",
accessorKey: "location",
header: "نمایش مختصات",
id: "lat",
id: "location",
enableColumnFilter: false,
datatype: "text",
enableSorting: false,
filterMode: "equals",
grow: false,
size: 100,
muiTableBodyCellProps: {
sx: {
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ row }) => <ShowLocation lat={row.original.lat} lng={row.original.lng} />,
},
{
@@ -101,6 +131,8 @@ const AzmayeshList = () => {
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
@@ -114,6 +146,8 @@ const AzmayeshList = () => {
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
@@ -127,12 +161,35 @@ const AzmayeshList = () => {
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "samples",
header: "نمونه ها",
id: "samples",
enableColumnFilter: false,
datatype: "text",
enableSorting: false,
filterMode: "equals",
grow: false,
size: 100,
muiTableBodyCellProps: {
sx: {
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ row }) => <ShowSampleOfAzmayesh rowData={row.original} />,
},
],
[]
);

View File

@@ -1,11 +1,12 @@
"use client";
import { Marker, useMapEvents } from "react-leaflet";
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import L from "leaflet";
import AzmayeshIcon from "@/assets/images/examine_marker.png";
import AzmayeshActiveIcon from "@/assets/images/examine_marker_active.png";
import {
Alert,
Box,
Button,
FormControl,
@@ -14,6 +15,7 @@ import {
OutlinedInput,
Stack,
Tooltip,
Zoom,
useMediaQuery,
} from "@mui/material";
import NewReleasesIcon from "@mui/icons-material/NewReleases";
@@ -21,9 +23,12 @@ import VerifiedIcon from "@mui/icons-material/Verified";
import EditIcon from "@mui/icons-material/Edit";
import { useTheme } from "@emotion/react";
const MAX_ZOOM_FOR_MARKER = 13
const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [enableSend, setEnableSend] = useState(false);
const mapAzmayeshMarker = useRef();
const defaultIconSize = [35, 35];
@@ -38,6 +43,7 @@ const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
const map = useMapEvents({
move(e) {
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER)
if (!mapBoxData) {
mapAzmayeshMarker.current.setLatLng(e.target.getCenter());
}
@@ -52,22 +58,25 @@ const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
mapAzmayeshMarker.current.setIcon(createCustomIcon(defaultIconSize, AzmayeshIcon.src));
}
},
zoom(e) {
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER)
}
});
useEffect(() => {
if (mapAzmayeshMarker.current) {
const newIcon = mapBoxData
? createCustomIcon([45, 45], AzmayeshActiveIcon.src)
: createCustomIcon(defaultIconSize, AzmayeshIcon.src);
mapAzmayeshMarker.current.setIcon(newIcon);
}
if (!mapAzmayeshMarker.current) return;
if (mapBoxData) {
mapAzmayeshMarker.current.setIcon(createCustomIcon([45, 45], AzmayeshActiveIcon.src));
mapAzmayeshMarker.current.setLatLng(mapBoxData);
map.flyTo(mapBoxData, 14);
map.setView(mapBoxData, 14);
} else {
mapAzmayeshMarker.current.setIcon(createCustomIcon(defaultIconSize, AzmayeshIcon.src));
}
}, [mapBoxData]);
}, [mapBoxData, mapAzmayeshMarker.current]);
const handleMarkerClick = () => {
if (!enableSend) return
if (!mapBoxData) {
setMapBoxData({
lat: mapAzmayeshMarker.current.getLatLng().lat,
@@ -86,93 +95,113 @@ const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
position={map.getCenter()}
ref={mapAzmayeshMarker}
eventHandlers={{ click: handleMarkerClick }}
icon={createCustomIcon(defaultIconSize, AzmayeshIcon.src)}
/>
<Box
<Stack
direction={'row'}
justifyContent={'center'}
sx={{
zIndex: "400",
width: '100%',
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" : "",
top: 0,
left: 0,
}}
>
<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>
<Zoom in={!enableSend}>
<Alert sx={{ mt: 1, py: .5, px: 2, borderRadius: 2, border: 1 }} icon={false} color={'warning'}>برای ثبت محل آزمایش، لطفاً نقشه را بیشتر زوم کنید.</Alert>
</Zoom>
</Stack>
<Stack
direction={'row'}
sx={{
zIndex: "400",
width: '100%',
position: "absolute",
bottom: 0,
left: 0,
}}
>
<Box sx={{
background: "#ffffff94",
flex: isMobile ? 1 : "",
m: 1,
p: 2,
borderRadius: 2,
boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px",
}}>
<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>
</Stack>
</>
);
};

View File

@@ -66,6 +66,11 @@ const CandUGeneralInfo = ({ control, register, setValue, errors }) => {
label="نوع آزمایش"
/>
)}
renderOption={(props, option) => (
<li {...props} key={option.id}>
{option.name}
</li>
)}
/>
)}
<FormHelperText id="azmayesh_type_id">
@@ -122,6 +127,23 @@ const CandUGeneralInfo = ({ control, register, setValue, errors }) => {
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.contract_subitem_id} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="contract_subitem_id">کد یکتا پروژه</InputLabel>
<OutlinedInput
id="contract_subitem_id"
label={"کد یکتا پروژه"}
autoComplete="off"
{...register("contract_subitem_id")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="contract_subitem_id">
{errors.contract_subitem_id ? errors.contract_subitem_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>
@@ -252,6 +274,7 @@ const CandUGeneralInfo = ({ control, register, setValue, errors }) => {
onChange={(newValue) => {
onChange(newValue);
}}
closeOnSelect
slotProps={{
textField: {
size: "small",
@@ -305,6 +328,7 @@ const CandUGeneralInfo = ({ control, register, setValue, errors }) => {
onChange={(newValue) => {
onChange(newValue);
}}
closeOnSelect
slotProps={{
textField: {
size: "small",

View File

@@ -33,6 +33,7 @@ function TabPanel(props) {
const validationSchema = object({
azmayesh_type_id: string().required("نوع آزمایش را مشخص کنید!"),
province_id: string().required("استان را وارد کنید!"),
contract_subitem_id: string().required("کد یکتا پروژه را وارد کنید!"),
project_name: string().required("عنوان پروژه را وارد کنید!"),
employer: string().required("کارفرما را وارد کنید!"),
consultant: string().required("مشاور را وارد کنید!"),
@@ -72,6 +73,7 @@ const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
azmayesh_type_name: updateInfo ? updateInfo.azmayesh_type_name : "",
province_id: updateInfo ? updateInfo.province_id : "",
province_name: updateInfo ? updateInfo.province_name : "",
contract_subitem_id: updateInfo ? updateInfo.contract_subitem_id : "",
project_name: updateInfo ? updateInfo.project_name : "",
employer: updateInfo ? updateInfo.employer : "",
consultant: updateInfo ? updateInfo.consultant : "",
@@ -99,6 +101,7 @@ const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
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("contract_subitem_id", data.contract_subitem_id);
formData.append("project_name", data.project_name);
formData.append("employer", data.employer);
formData.append("consultant", data.consultant);
@@ -109,14 +112,15 @@ const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
formData.append("request_date", moment(new Date(data.request_date)).format("YYYY-MM-DD"));
formData.append("report_date", moment(new Date(data.report_date)).format("YYYY-MM-DD"));
requestServer(updateInfo ? `${UPDATE_AZMAYESH}/${rowId}` : CREATE_AZMAYESH, "post", {
data: formData,
})
.then(() => {
mutate();
handleClose();
})
.catch(() => {});
try {
const url = updateInfo ? `${UPDATE_AZMAYESH}/${rowId}` : CREATE_AZMAYESH;
await requestServer(url, "post", {
data: formData,
});
mutate();
handleClose();
} catch (error) {
}
};
return (
@@ -187,8 +191,8 @@ const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
? "در حال ویرایش آزمایش"
: "ویرایش آزمایش"
: isSubmitting
? "در حال ثبت آزمایش"
: "ثبت آزمایش"}
? "در حال ثبت آزمایش"
: "ثبت آزمایش"}
</Button>
)}
</DialogActions>

View File

@@ -24,10 +24,12 @@ const ShowSampleList = ({ sampleInfo, rowData }) => {
id: "id",
enableColumnFilter: false,
datatype: "text",
grow: false,
size: 100,
},
...sampleInfo.map((item) => ({
accessorKey: item.id.toString(),
header: item.name,
header: item.unit ? `${item.name} (${item.unit})` : item.name,
id: item.id.toString(),
enableColumnFilter: false,
datatype: "text",
@@ -38,6 +40,8 @@ const ShowSampleList = ({ sampleInfo, rowData }) => {
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}

View File

@@ -1,4 +1,4 @@
import { Button, Dialog, DialogActions, DialogContent, IconButton, Tooltip } from "@mui/material";
import { Box, Button, Dialog, DialogActions, DialogContent, IconButton, Tooltip } from "@mui/material";
import AssignmentIcon from "@mui/icons-material/Assignment";
import { useState } from "react";
import ShowSampleList from "./ShowSampleList";
@@ -14,13 +14,13 @@ const ShowSampleOfAzmayesh = ({ rowData }) => {
.then((response) => {
setSampleInfo(response.data.data);
})
.catch(() => {})
.catch(() => { })
.finally(() => {
setOpenShowSampleDialog(true);
});
};
return (
<>
<Box sx={{ display: "flex", justifyContent: "center" }}>
<Tooltip title="نمایش نمونه های آزمایش" arrow placement="right">
<IconButton
color="primary"
@@ -30,7 +30,7 @@ const ShowSampleOfAzmayesh = ({ rowData }) => {
<AssignmentIcon />
</IconButton>
</Tooltip>
<Dialog maxWidth="md" fullWidth open={openShowSampleDialog}>
<Dialog maxWidth="lg" fullWidth open={openShowSampleDialog}>
<DialogContent>
<ShowSampleList rowData={rowData} sampleInfo={sampleInfo} />
</DialogContent>
@@ -40,7 +40,7 @@ const ShowSampleOfAzmayesh = ({ rowData }) => {
</Button>
</DialogActions>
</Dialog>
</>
</Box>
);
};
export default ShowSampleOfAzmayesh;

View File

@@ -7,7 +7,6 @@ const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1 }}>
<AzmayeshUpdate mutate={mutate} rowId={row.getValue("id")} />
<ShowSampleOfAzmayesh rowData={row.original} />
<DeleteAzmayesh mutate={mutate} rowId={row.getValue("id")} />
</Box>
);

View File

@@ -9,13 +9,16 @@ const InputType = ({ itemInfo, defaultValues, setDefaultValues }) => {
[itemInfo.id]: value,
}));
};
console.log(itemInfo);
const label = itemInfo.unit ? `${itemInfo.name} (${itemInfo.unit})` : itemInfo.name
return (
<FormControl size="small" fullWidth variant="outlined">
<InputLabel htmlFor={itemInfo.id}>{itemInfo.name}</InputLabel>
<InputLabel htmlFor={itemInfo.id}>{label}</InputLabel>
<OutlinedInput
id={itemInfo.id}
label={itemInfo.name}
label={label}
autoComplete="off"
size="small"
fullWidth

View File

@@ -9,15 +9,15 @@ const SelectType = ({ itemInfo, defaultValues, setDefaultValues }) => {
[itemInfo.id]: newValue,
}));
};
const label = itemInfo.unit ? `${itemInfo.name} (${itemInfo.unit})` : itemInfo.name
return (
<FormControl size="small" fullWidth variant="outlined">
<InputLabel id={itemInfo.id}>{itemInfo.name}</InputLabel>
<InputLabel id={itemInfo.id}>{label}</InputLabel>
<Select
labelId={itemInfo.id}
id={itemInfo.id}
value={defaultValues[itemInfo.id] || ""}
label={itemInfo.name}
label={label}
onChange={handleChange}
>
<MenuItem value="">{itemInfo.name}</MenuItem>