Merge branch 'feature/azmayesh_sample' into 'develop'
complete up to request for storing azmayesh_sample and complete design of... See merge request witel-front-end/rms!30
This commit is contained in:
@@ -4,7 +4,7 @@ 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";
|
||||
import CandUAzmayesh from "@/components/dashboard/azmayesh/Forms/CandUAzmayesh";
|
||||
|
||||
const AzmayeshCreate = ({ mutate }) => {
|
||||
const theme = useTheme();
|
||||
@@ -26,7 +26,7 @@ const AzmayeshCreate = ({ mutate }) => {
|
||||
ثبت آزمایش
|
||||
</Button>
|
||||
)}
|
||||
{open && <CreateDialog open={open} setOpen={setOpen} mutate={mutate} />}
|
||||
{open && <CandUAzmayesh open={open} setOpen={setOpen} mutate={mutate} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,8 +5,9 @@ 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";
|
||||
import moment from "jalali-moment";
|
||||
import RowActions from "./RowActions";
|
||||
|
||||
const AzmayeshList = () => {
|
||||
const columns = useMemo(
|
||||
@@ -101,7 +102,7 @@ const AzmayeshList = () => {
|
||||
filterFn: "equals",
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{moment(renderedCellValue).locale("fa").format("YYYY/MM/DD")}
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
},
|
||||
@@ -114,7 +115,7 @@ const AzmayeshList = () => {
|
||||
filterFn: "equals",
|
||||
Cell: ({ renderedCellValue }) => (
|
||||
<Typography variant="body2">
|
||||
{moment(renderedCellValue).locale("fa").format("YYYY/MM/DD")}
|
||||
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
|
||||
</Typography>
|
||||
),
|
||||
},
|
||||
@@ -133,6 +134,9 @@ const AzmayeshList = () => {
|
||||
page_name={"azmayesh"}
|
||||
table_name={"azmayeshList"}
|
||||
TableToolbar={Toolbar}
|
||||
enableRowActions
|
||||
positionActionsColumn={"last"}
|
||||
RowActions={RowActions}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
|
||||
@@ -21,7 +21,7 @@ import VerifiedIcon from "@mui/icons-material/Verified";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
const ChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
|
||||
@@ -177,4 +177,4 @@ const ChooseLocation = ({ mapBoxData, setMapBoxData }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ChooseLocation;
|
||||
export default CandUChooseLocation;
|
||||
@@ -22,7 +22,7 @@ import { faIR } from "@mui/x-date-pickers/locales";
|
||||
import ClearIcon from "@mui/icons-material/Clear";
|
||||
import React from "react";
|
||||
|
||||
const AzmayeshGeneralInfo = ({ control, register, setValue, errors }) => {
|
||||
const CandUGeneralInfo = ({ control, register, setValue, errors }) => {
|
||||
const { azmayeshes, errorAzmayeshes, loadingAzmayeshes } = useAzmayesh();
|
||||
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
|
||||
|
||||
@@ -98,11 +98,11 @@ const AzmayeshGeneralInfo = ({ control, register, setValue, errors }) => {
|
||||
value={provinces.find((province) => province.id === value) || null}
|
||||
disablePortal
|
||||
options={provinces}
|
||||
getOptionLabel={(province) => province.name}
|
||||
getOptionLabel={(province) => province.name_fa}
|
||||
isOptionEqualToValue={(option, value) => option.id === value?.id}
|
||||
onChange={(event, newValue) => {
|
||||
onChange(newValue ? newValue.id : "");
|
||||
setValue("province_name", newValue ? newValue.name : "");
|
||||
setValue("province_name", newValue ? newValue.name_fa : "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
@@ -241,7 +241,6 @@ const AzmayeshGeneralInfo = ({ control, register, setValue, errors }) => {
|
||||
<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
|
||||
@@ -295,7 +294,6 @@ const AzmayeshGeneralInfo = ({ control, register, setValue, errors }) => {
|
||||
<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
|
||||
@@ -348,4 +346,4 @@ const AzmayeshGeneralInfo = ({ control, register, setValue, errors }) => {
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
export default AzmayeshGeneralInfo;
|
||||
export default CandUGeneralInfo;
|
||||
@@ -3,14 +3,14 @@
|
||||
import { Box, Stack } from "@mui/material";
|
||||
import dynamic from "next/dynamic";
|
||||
import MapLoading from "@/core/components/MapLayer/Loading";
|
||||
import ChooseLocation from "./ChooseLocation";
|
||||
import CandUChooseLocation from "./CandUChooseLocation";
|
||||
|
||||
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
|
||||
loading: () => <MapLoading />,
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const MapBox = ({ mapBoxData, setMapBoxData }) => {
|
||||
const CandUMapBox = ({ mapBoxData, setMapBoxData }) => {
|
||||
return (
|
||||
<Stack spacing={1} sx={{ height: "500px" }}>
|
||||
<Box
|
||||
@@ -31,11 +31,11 @@ const MapBox = ({ mapBoxData, setMapBoxData }) => {
|
||||
}}
|
||||
>
|
||||
<MapLayer>
|
||||
<ChooseLocation mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
|
||||
<CandUChooseLocation mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
|
||||
</MapLayer>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
export default MapBox;
|
||||
export default CandUMapBox;
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
TimelineSeparator,
|
||||
} from "@mui/lab";
|
||||
|
||||
const CreateTimeLine = ({ tabState }) => {
|
||||
const CandUCreateTimeLine = ({ tabState }) => {
|
||||
return (
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Timeline
|
||||
@@ -62,4 +62,4 @@ const CreateTimeLine = ({ tabState }) => {
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
export default CreateTimeLine;
|
||||
export default CandUCreateTimeLine;
|
||||
@@ -1,24 +1,24 @@
|
||||
"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 { useTheme } from "@emotion/react";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import { object, string } from "yup";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import moment from "jalali-moment";
|
||||
import { POST_AZMAYESH } from "@/core/utils/routes";
|
||||
import AzmayeshGeneralInfo from "./AzmayeshGeneralInfo";
|
||||
import { CREATE_AZMAYESH, UPDATE_AZMAYESH } from "@/core/utils/routes";
|
||||
import StyledForm from "@/core/components/StyledForm";
|
||||
import TravelExploreIcon from "@mui/icons-material/TravelExplore";
|
||||
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
|
||||
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
|
||||
import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
|
||||
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
|
||||
import BeenhereIcon from "@mui/icons-material/Beenhere";
|
||||
import CandUMapBox from "./CandUMapBox";
|
||||
import CandUCreateTimeLine from "./CandUTimeLine";
|
||||
import CandUGeneralInfo from "./CandUGeneralInfo";
|
||||
|
||||
function TabPanel(props) {
|
||||
const { children, value, index } = props;
|
||||
@@ -30,11 +30,26 @@ function TabPanel(props) {
|
||||
);
|
||||
}
|
||||
|
||||
const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
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 CandUAzmayesh = ({ open, setOpen, mutate, updateInfo, rowId }) => {
|
||||
const theme = useTheme();
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
const [tabState, setTabState] = useState(0);
|
||||
const [mapBoxData, setMapBoxData] = useState(null);
|
||||
const [mapBoxData, setMapBoxData] = useState(updateInfo ? { lat: updateInfo.lat, lng: updateInfo.lng } : null);
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
@@ -52,35 +67,20 @@ const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
}
|
||||
};
|
||||
|
||||
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: "",
|
||||
azmayesh_type_id: updateInfo ? updateInfo.azmayesh_type_id : "",
|
||||
azmayesh_type_name: updateInfo ? updateInfo.azmayesh_type_name : "",
|
||||
province_id: updateInfo ? updateInfo.province_id : "",
|
||||
province_name: updateInfo ? updateInfo.province_name : "",
|
||||
project_name: updateInfo ? updateInfo.project_name : "",
|
||||
employer: updateInfo ? updateInfo.employer : "",
|
||||
consultant: updateInfo ? updateInfo.consultant : "",
|
||||
contractor: updateInfo ? updateInfo.contractor : "",
|
||||
applicant: updateInfo ? updateInfo.applicant : "",
|
||||
work_number: updateInfo ? updateInfo.work_number : "",
|
||||
request_number: updateInfo ? updateInfo.request_number : "",
|
||||
request_date: updateInfo ? moment(updateInfo.request_date, "YYYY-MM-DD").toDate() : "",
|
||||
report_date: updateInfo ? moment(updateInfo.report_date, "YYYY-MM-DD").toDate() : "",
|
||||
};
|
||||
|
||||
const {
|
||||
@@ -106,10 +106,10 @@ const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
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"));
|
||||
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(POST_AZMAYESH, "post", {
|
||||
requestServer(updateInfo ? `${UPDATE_AZMAYESH}/${rowId}` : CREATE_AZMAYESH, "post", {
|
||||
data: formData,
|
||||
})
|
||||
.then(() => {
|
||||
@@ -140,10 +140,10 @@ const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
<DialogContent dividers sx={{ display: "flex" }}>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<TabPanel value={tabState} index={0}>
|
||||
<MapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
|
||||
<CandUMapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
|
||||
</TabPanel>
|
||||
<TabPanel value={tabState} index={1}>
|
||||
<AzmayeshGeneralInfo
|
||||
<CandUGeneralInfo
|
||||
control={control}
|
||||
register={register}
|
||||
setValue={setValue}
|
||||
@@ -153,7 +153,7 @@ const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
</Box>
|
||||
{!isMobile && (
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<CreateTimeLine tabState={tabState} />
|
||||
<CandUCreateTimeLine tabState={tabState} />
|
||||
</Box>
|
||||
)}
|
||||
</DialogContent>
|
||||
@@ -169,7 +169,10 @@ const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
</Button>
|
||||
{tabState === 0 ? (
|
||||
<Button
|
||||
onClick={() => setTabState(tabState + 1)}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
setTabState(tabState + 1);
|
||||
}}
|
||||
variant="contained"
|
||||
size="large"
|
||||
disabled={!mapBoxData}
|
||||
@@ -185,7 +188,13 @@ const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
type={"submit"}
|
||||
endIcon={<BeenhereIcon />}
|
||||
>
|
||||
{isSubmitting ? "در حال ثبت آزمایش" : "ثبت آزمایش"}
|
||||
{updateInfo
|
||||
? isSubmitting
|
||||
? "در حال ویرایش آزمایش"
|
||||
: "ویرایش آزمایش"
|
||||
: isSubmitting
|
||||
? "در حال ثبت آزمایش"
|
||||
: "ثبت آزمایش"}
|
||||
</Button>
|
||||
)}
|
||||
</DialogActions>
|
||||
@@ -193,4 +202,4 @@ const CreateDialog = ({ open, setOpen, mutate }) => {
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
export default CreateDialog;
|
||||
export default CandUAzmayesh;
|
||||
@@ -0,0 +1,47 @@
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import { GET_AZMAYESH_LIST } from "@/core/utils/routes";
|
||||
import CandUAzmayesh from "@/components/dashboard/azmayesh/Forms/CandUAzmayesh";
|
||||
|
||||
const AzmayeshUpdate = ({ rowId, mutate }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
|
||||
const [updateInfo, setUpdateInfo] = useState(null);
|
||||
|
||||
const handleGetInfo = () => {
|
||||
requestServer(`${GET_AZMAYESH_LIST}/${rowId}`, "get")
|
||||
.then((response) => {
|
||||
setUpdateInfo(response.data.data);
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setOpenUpdateDialog(true);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="ویرایش آزمایش" arrow placement="right">
|
||||
<IconButton
|
||||
color="success"
|
||||
sx={{ textTransform: "unset", alignSelf: "center" }}
|
||||
onClick={handleGetInfo}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
{openUpdateDialog && (
|
||||
<CandUAzmayesh
|
||||
open={openUpdateDialog}
|
||||
setOpen={setOpenUpdateDialog}
|
||||
mutate={mutate}
|
||||
updateInfo={updateInfo}
|
||||
rowId={rowId}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default AzmayeshUpdate;
|
||||
@@ -0,0 +1,78 @@
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
IconButton,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import { DELETE_AZMAYESH } from "@/core/utils/routes";
|
||||
|
||||
const DeleteAzmayesh = ({ rowId, mutate }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const handleSubmit = () => {
|
||||
setIsSubmitting(true);
|
||||
requestServer(`${DELETE_AZMAYESH}/${rowId}`, "post")
|
||||
.then(() => {
|
||||
setOpenDeleteDialog(false);
|
||||
mutate();
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setIsSubmitting(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="حذف آزمایش" arrow placement="right">
|
||||
<IconButton
|
||||
color="error"
|
||||
sx={{ textTransform: "unset", alignSelf: "center" }}
|
||||
onClick={() => {
|
||||
setOpenDeleteDialog(true);
|
||||
}}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Dialog
|
||||
maxWidth="sm"
|
||||
open={openDeleteDialog}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle>حذف آزمایش</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography>آیا از حذف این آزمایش مطمئن هستید؟</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => setOpenDeleteDialog(false)}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
disabled={isSubmitting}
|
||||
autoFocus
|
||||
>
|
||||
بستن
|
||||
</Button>
|
||||
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
|
||||
حذف
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default DeleteAzmayesh;
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Button, IconButton, useMediaQuery } from "@mui/material";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import { useEffect, useState } from "react";
|
||||
import { GET_AZMAYESH_SAMPLE_FIELDS } from "@/core/utils/routes";
|
||||
import { AddCircle } from "@mui/icons-material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import CandUSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/Forms/CandUSampleOfAzmayesh";
|
||||
|
||||
const AddSampleToAzmayesh = ({ azmayeshTypeId, mutate, rowId }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
const [sampleInfo, setSampleInfo] = useState(null);
|
||||
const [openAddSampleDialog, setOpenAddSampleDialog] = useState(false);
|
||||
const [defaultValues, setDefaultValues] = useState({});
|
||||
|
||||
const handleGetFields = () => {
|
||||
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${azmayeshTypeId}`, "get")
|
||||
.then((response) => {
|
||||
setSampleInfo(response.data.data);
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setOpenAddSampleDialog(true);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const initialValues = sampleInfo?.reduce((acc, item) => {
|
||||
acc[item.id] = "";
|
||||
return acc;
|
||||
}, {});
|
||||
setDefaultValues(initialValues);
|
||||
}, [sampleInfo]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isMobile ? (
|
||||
<IconButton aria-label="ایجاد نمونه جدید" color="primary" onClick={handleGetFields}>
|
||||
<AddCircle sx={{ fontSize: "25px" }} />
|
||||
</IconButton>
|
||||
) : (
|
||||
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleGetFields}>
|
||||
ثبت نمونه
|
||||
</Button>
|
||||
)}
|
||||
<CandUSampleOfAzmayesh
|
||||
openSampleDialog={openAddSampleDialog}
|
||||
setOpenSampleDialog={setOpenAddSampleDialog}
|
||||
sampleInfo={sampleInfo}
|
||||
mutate={mutate}
|
||||
rowId={rowId}
|
||||
defaultValues={defaultValues}
|
||||
setDefaultValues={setDefaultValues}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default AddSampleToAzmayesh;
|
||||
@@ -0,0 +1,82 @@
|
||||
"use client";
|
||||
|
||||
import { Box, Chip, Divider, Grid, Stack, Typography } from "@mui/material";
|
||||
import ScienceIcon from "@mui/icons-material/Science";
|
||||
import LocationCityIcon from "@mui/icons-material/LocationCity";
|
||||
|
||||
const AzmayeshInfo = ({ rowData }) => {
|
||||
return (
|
||||
<Stack sx={{ p: 2, alignItems: "center" }}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600, pb: 4 }}>
|
||||
{rowData.project_name}
|
||||
</Typography>
|
||||
<Grid container spacing={2} sx={{ alignItems: "center", justifyContent: "space-around" }}>
|
||||
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip
|
||||
icon={<ScienceIcon />}
|
||||
label={
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
|
||||
نوع آزمایش
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
|
||||
{rowData.azmayesh_type_name}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip
|
||||
icon={<LocationCityIcon />}
|
||||
label={
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
|
||||
نام استان
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
|
||||
{rowData.province_name}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip
|
||||
icon={<LocationCityIcon />}
|
||||
label={
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
|
||||
شماره کار
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
|
||||
{rowData.work_number}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Chip
|
||||
icon={<LocationCityIcon />}
|
||||
label={
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
|
||||
شماره درخواست
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Divider sx={{ flex: 1, mx: 2 }} />
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
|
||||
{rowData.request_number}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
export default AzmayeshInfo;
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from "@mui/material";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import React, { useState } from "react";
|
||||
import { ADD_SAMPLE_TO_AZMAYESH, UPDATE_SAMPLE_OF_AZMAYESH } from "@/core/utils/routes";
|
||||
import FormMaker from "@/core/components/FormMaker";
|
||||
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
|
||||
|
||||
const CandUSampleOfAzmayesh = ({
|
||||
sampleInfo,
|
||||
mutate,
|
||||
rowId,
|
||||
openSampleDialog,
|
||||
setOpenSampleDialog,
|
||||
defaultValues,
|
||||
setDefaultValues,
|
||||
isUpdate,
|
||||
azmayesh_id,
|
||||
}) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const handleSubmit = () => {
|
||||
const data = {};
|
||||
setIsSubmitting(true);
|
||||
const formData = new FormData();
|
||||
formData.append("azmayesh_id", isUpdate ? azmayesh_id : rowId);
|
||||
Object.entries(defaultValues).forEach(([key, value]) => {
|
||||
data[key] = value;
|
||||
});
|
||||
formData.append("data", JSON.stringify(data));
|
||||
requestServer(isUpdate ? `${UPDATE_SAMPLE_OF_AZMAYESH}/${rowId}` : `${ADD_SAMPLE_TO_AZMAYESH}`, "post", {
|
||||
data: formData,
|
||||
})
|
||||
.then(() => {
|
||||
mutate();
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setOpenSampleDialog(false);
|
||||
setIsSubmitting(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog maxWidth="md" fullWidth open={openSampleDialog}>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{isUpdate ? "ویرایش نمونه" : "افزودن نمونه"}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<DialogContent>
|
||||
<FormMaker formInfo={sampleInfo} defaultValues={defaultValues} setDefaultValues={setDefaultValues} />
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => setOpenSampleDialog(false)}
|
||||
variant="outlined"
|
||||
color="error"
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
بستن
|
||||
</Button>
|
||||
<Button onClick={handleSubmit} variant="contained" color="primary" disabled={isSubmitting}>
|
||||
{isUpdate
|
||||
? isSubmitting
|
||||
? "در حال ویرایش نمونه"
|
||||
: "ویرایش نمونه"
|
||||
: isSubmitting
|
||||
? "در حال ثبت نمونه"
|
||||
: "ثبت نمونه"}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
export default CandUSampleOfAzmayesh;
|
||||
@@ -0,0 +1,78 @@
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
IconButton,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import { DELETE_SAMPLE_LIST } from "@/core/utils/routes";
|
||||
|
||||
const DeleteSample = ({ rowId, mutate }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const handleSubmit = () => {
|
||||
setIsSubmitting(true);
|
||||
requestServer(`${DELETE_SAMPLE_LIST}/${rowId}`, "post")
|
||||
.then(() => {
|
||||
setOpenDeleteDialog(false);
|
||||
mutate();
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setIsSubmitting(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="حذف نمونه" arrow placement="right">
|
||||
<IconButton
|
||||
color="error"
|
||||
sx={{ textTransform: "unset", alignSelf: "center" }}
|
||||
onClick={() => {
|
||||
setOpenDeleteDialog(true);
|
||||
}}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Dialog
|
||||
maxWidth="sm"
|
||||
open={openDeleteDialog}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle>حذف نمونه</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography>آیا از حذف این نمونه مطمئن هستید؟</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => setOpenDeleteDialog(false)}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
disabled={isSubmitting}
|
||||
autoFocus
|
||||
>
|
||||
بستن
|
||||
</Button>
|
||||
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
|
||||
حذف
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default DeleteSample;
|
||||
@@ -0,0 +1,60 @@
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
import { useEffect, useState } from "react";
|
||||
import { GET_AZMAYESH_SAMPLE_FIELDS, GET_SAMPLE_LIST } from "@/core/utils/routes";
|
||||
import CandUSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/Forms/CandUSampleOfAzmayesh";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
|
||||
const UpdateSample = ({ azmayeshTypeId, mutate, rowId, azmayesh_id }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [sampleInfo, setSampleInfo] = useState(null);
|
||||
const [openUpdateSampleDialog, setOpenUpdateSampleDialog] = useState(false);
|
||||
const [defaultValues, setDefaultValues] = useState({});
|
||||
const [sampleDetail, setSampleDetail] = useState({});
|
||||
|
||||
const handleGetFields = () => {
|
||||
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${azmayeshTypeId}`, "get")
|
||||
.then((response) => {
|
||||
setSampleInfo(response.data.data);
|
||||
})
|
||||
.catch(() => {});
|
||||
requestServer(`${GET_SAMPLE_LIST}/${rowId}`, "get")
|
||||
.then((response) => {
|
||||
setSampleDetail(JSON.parse(response.data.data.data));
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setOpenUpdateSampleDialog(true);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setDefaultValues(sampleDetail);
|
||||
}, [sampleDetail]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="ویرایش نمونه" arrow placement="right">
|
||||
<IconButton
|
||||
color="success"
|
||||
sx={{ textTransform: "unset", alignSelf: "center" }}
|
||||
onClick={handleGetFields}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<CandUSampleOfAzmayesh
|
||||
openSampleDialog={openUpdateSampleDialog}
|
||||
setOpenSampleDialog={setOpenUpdateSampleDialog}
|
||||
sampleInfo={sampleInfo}
|
||||
mutate={mutate}
|
||||
rowId={rowId}
|
||||
defaultValues={defaultValues}
|
||||
setDefaultValues={setDefaultValues}
|
||||
isUpdate={true}
|
||||
azmayesh_id={azmayesh_id}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default UpdateSample;
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Box } from "@mui/material";
|
||||
import DeleteSample from "./DeleteSample";
|
||||
import UpdateSample from "./UpdateSample";
|
||||
|
||||
const RowActions = ({ rowData, row, mutate }) => {
|
||||
return (
|
||||
<Box sx={{ display: "flex", gap: 1 }}>
|
||||
<UpdateSample
|
||||
mutate={mutate}
|
||||
rowId={row.getValue("id")}
|
||||
azmayeshTypeId={rowData.azmayesh_type_id}
|
||||
azmayesh_id={rowData.id}
|
||||
/>
|
||||
<DeleteSample mutate={mutate} rowId={row.getValue("id")} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
export default RowActions;
|
||||
@@ -0,0 +1,64 @@
|
||||
import { useMemo } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
|
||||
import { GET_SAMPLE_LIST } from "@/core/utils/routes";
|
||||
import RowActions from "./RowActions";
|
||||
import AzmayeshInfo from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/AzmayeshInfo";
|
||||
import Toolbar from "./Toolbar";
|
||||
|
||||
const ShowSampleList = ({ sampleInfo, rowData }) => {
|
||||
const parsedData = (data) => {
|
||||
return data.data.map((item) => ({
|
||||
...JSON.parse(item.data),
|
||||
id: item.id,
|
||||
}));
|
||||
};
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
accessorKey: "id",
|
||||
header: "کد یکتا",
|
||||
id: "id",
|
||||
enableColumnFilter: false,
|
||||
datatype: "text",
|
||||
filterFn: "notEquals",
|
||||
},
|
||||
...sampleInfo.map((item) => ({
|
||||
accessorKey: item.id.toString(),
|
||||
header: item.name,
|
||||
id: item.id.toString(),
|
||||
enableColumnFilter: false,
|
||||
datatype: "text",
|
||||
filterFn: "notEquals",
|
||||
})),
|
||||
],
|
||||
[sampleInfo]
|
||||
);
|
||||
|
||||
const ToolbarWithRowData = (props) => <Toolbar rowData={rowData} {...props} />;
|
||||
const RowActionsWithRowData = (props) => <RowActions rowData={rowData} {...props} />;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<AzmayeshInfo rowData={rowData} />
|
||||
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
|
||||
<DataTableWithAuth
|
||||
table_title={"نمونه های ثبت شده"}
|
||||
need_filter={false}
|
||||
columns={columns}
|
||||
table_url={`${GET_SAMPLE_LIST}/index/${rowData.id}`}
|
||||
page_name={`azmayesh_${rowData.azmayesh_type_id}`}
|
||||
table_name={"sample_list"}
|
||||
TableToolbar={ToolbarWithRowData}
|
||||
specific_data={parsedData}
|
||||
enableRowActions
|
||||
positionActionsColumn={"last"}
|
||||
RowActions={RowActionsWithRowData}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShowSampleList;
|
||||
@@ -0,0 +1,10 @@
|
||||
import AddSampleToAzmayesh from "./Actions/Create";
|
||||
|
||||
const Toolbar = ({ mutate, rowData }) => {
|
||||
return (
|
||||
<>
|
||||
<AddSampleToAzmayesh mutate={mutate} azmayeshTypeId={rowData.azmayesh_type_id} rowId={rowData.id} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default Toolbar;
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Button, Dialog, DialogActions, DialogContent, IconButton, Tooltip } from "@mui/material";
|
||||
import AssignmentIcon from "@mui/icons-material/Assignment";
|
||||
import { useState } from "react";
|
||||
import ShowSampleList from "./ShowSampleList";
|
||||
import { GET_AZMAYESH_SAMPLE_FIELDS } from "@/core/utils/routes";
|
||||
import useRequest from "@/lib/hooks/useRequest";
|
||||
|
||||
const ShowSampleOfAzmayesh = ({ rowData }) => {
|
||||
const requestServer = useRequest({ auth: true });
|
||||
const [openShowSampleDialog, setOpenShowSampleDialog] = useState(false);
|
||||
const [sampleInfo, setSampleInfo] = useState(null);
|
||||
const handleGetSampleFields = () => {
|
||||
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${rowData.azmayesh_type_id}`, "get")
|
||||
.then((response) => {
|
||||
setSampleInfo(response.data.data);
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
setOpenShowSampleDialog(true);
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="نمایش نمونه های آزمایش" arrow placement="right">
|
||||
<IconButton
|
||||
color="primary"
|
||||
sx={{ textTransform: "unset", alignSelf: "center" }}
|
||||
onClick={handleGetSampleFields}
|
||||
>
|
||||
<AssignmentIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Dialog maxWidth="md" fullWidth open={openShowSampleDialog}>
|
||||
<DialogContent>
|
||||
<ShowSampleList rowData={rowData} sampleInfo={sampleInfo} />
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => setOpenShowSampleDialog(false)} variant="outlined" color="error">
|
||||
بستن
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default ShowSampleOfAzmayesh;
|
||||
15
src/components/dashboard/azmayesh/RowActions/index.jsx
Normal file
15
src/components/dashboard/azmayesh/RowActions/index.jsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Box } from "@mui/material";
|
||||
import DeleteAzmayesh from "./DeleteAzmayesh";
|
||||
import ShowSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh";
|
||||
import AzmayeshUpdate from "@/components/dashboard/azmayesh/RowActions/AzmayeshUpdate";
|
||||
|
||||
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>
|
||||
);
|
||||
};
|
||||
export default RowActions;
|
||||
@@ -100,7 +100,7 @@ const ReferFormContext = ({ setOpenReferDialog, rowId, mutate }) => {
|
||||
value={provinces.find((province) => province.id === value) || null}
|
||||
disablePortal
|
||||
options={provinces}
|
||||
getOptionLabel={(province) => province.name}
|
||||
getOptionLabel={(province) => province.name_fa}
|
||||
isOptionEqualToValue={(option, value) => option.id === value.id}
|
||||
onChange={(event, newValue) => {
|
||||
onChange(newValue ? newValue.id : "");
|
||||
|
||||
53
src/core/components/CustomDatePicker.jsx
Normal file
53
src/core/components/CustomDatePicker.jsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import React from "react";
|
||||
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
|
||||
import { faIR } from "@mui/x-date-pickers/locales";
|
||||
import { LocalizationProvider, MobileDatePicker } from "@mui/x-date-pickers";
|
||||
import { IconButton, InputAdornment } from "@mui/material";
|
||||
import ClearIcon from "@mui/icons-material/Clear";
|
||||
|
||||
const CustomDatePicker = ({ dateValue, setDateValue, placeholder = "انتخاب تاریخ", size = "small" }) => {
|
||||
const handleDateChange = (newValue) => {
|
||||
setDateValue(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<LocalizationProvider
|
||||
dateAdapter={AdapterDateFnsJalali}
|
||||
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
|
||||
>
|
||||
<MobileDatePicker
|
||||
value={dateValue || null}
|
||||
onChange={handleDateChange}
|
||||
slotProps={{
|
||||
textField: {
|
||||
size: size,
|
||||
placeholder: placeholder,
|
||||
InputProps: {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
size={size}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
setDateValue(null);
|
||||
}}
|
||||
sx={{
|
||||
color: "#bfbfbf",
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||
color: "#363434",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ClearIcon />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
},
|
||||
},
|
||||
}}
|
||||
></MobileDatePicker>
|
||||
</LocalizationProvider>
|
||||
);
|
||||
};
|
||||
export default CustomDatePicker;
|
||||
@@ -22,6 +22,7 @@ const DataTable_Main = (props) => {
|
||||
TableToolbar,
|
||||
table_title,
|
||||
RowActions,
|
||||
specific_data,
|
||||
} = props;
|
||||
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
||||
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
|
||||
@@ -50,7 +51,11 @@ const DataTable_Main = (props) => {
|
||||
const fetcher = async (url) => {
|
||||
try {
|
||||
const response = await request(url);
|
||||
return response.data;
|
||||
if (specific_data) {
|
||||
return specific_data(response.data);
|
||||
} else {
|
||||
return response.data?.data;
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
@@ -66,7 +71,7 @@ const DataTable_Main = (props) => {
|
||||
const table = useMaterialReactTable({
|
||||
localization: FA_DATATABLE_LOCALIZATION,
|
||||
columns,
|
||||
data: data?.data ?? [],
|
||||
data: data ?? [],
|
||||
initialState: {
|
||||
density: "compact",
|
||||
columnVisibility: flattenHideData,
|
||||
|
||||
@@ -81,7 +81,7 @@ function FilterBody({ columns, drawerState, setDrawerState, user_id, page_name,
|
||||
<Drawer
|
||||
open={drawerState}
|
||||
onClose={() => setDrawerState(false)}
|
||||
sx={{ overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%" }}
|
||||
sx={{ overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%", zIndex: "1300" }}
|
||||
>
|
||||
<FilterHeader setDrawerState={setDrawerState} />
|
||||
{Object.keys(initialValues).length > 0 && (
|
||||
|
||||
@@ -30,7 +30,7 @@ function HideBody({ columns, drawerState, setDrawerState }) {
|
||||
<Drawer
|
||||
open={drawerState}
|
||||
onClose={() => setDrawerState(false)}
|
||||
sx={{ overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%" }}
|
||||
sx={{ overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%", zIndex: "1300" }}
|
||||
>
|
||||
<HideHeader setDrawerState={setDrawerState} />
|
||||
<HideOrShowAll hideData={hideData} setHideData={setHideData} />
|
||||
|
||||
35
src/core/components/FormMaker/DateType.jsx
Normal file
35
src/core/components/FormMaker/DateType.jsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { FormControl } from "@mui/material";
|
||||
import CustomDatePicker from "@/core/components/CustomDatePicker";
|
||||
import moment from "jalali-moment";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const DateType = ({ itemInfo, defaultValues, setDefaultValues }) => {
|
||||
const [dateValue, setDateValue] = useState(null);
|
||||
const handleDateChange = (newValue) => {
|
||||
const date = new Date(newValue);
|
||||
const formattedDate = moment(date).locale("fa").format("YYYY/MM/DD");
|
||||
setDefaultValues((prev) => ({
|
||||
...prev,
|
||||
[itemInfo.id]: newValue ? formattedDate : "",
|
||||
}));
|
||||
setDateValue(moment(date).format("YYYY/MM/DD"));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultValues[itemInfo.id]) {
|
||||
setDateValue(moment.from(defaultValues[itemInfo.id], "fa", "YYYY/MM/DD"));
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<FormControl fullWidth size="small" variant="outlined">
|
||||
<CustomDatePicker
|
||||
dateValue={dateValue ? new Date(dateValue) : null}
|
||||
setDateValue={handleDateChange}
|
||||
placeholder={itemInfo.name}
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export default DateType;
|
||||
30
src/core/components/FormMaker/InputType.jsx
Normal file
30
src/core/components/FormMaker/InputType.jsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { FormControl, InputLabel, OutlinedInput } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
const InputType = ({ itemInfo, defaultValues, setDefaultValues }) => {
|
||||
const handleChange = (event) => {
|
||||
const { value } = event.target;
|
||||
setDefaultValues((prevValues) => ({
|
||||
...prevValues,
|
||||
[itemInfo.id]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl size="small" fullWidth variant="outlined">
|
||||
<InputLabel htmlFor={itemInfo.id}>{itemInfo.name}</InputLabel>
|
||||
<OutlinedInput
|
||||
id={itemInfo.id}
|
||||
label={itemInfo.name}
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
fullWidth
|
||||
type="text"
|
||||
onChange={handleChange}
|
||||
value={defaultValues[itemInfo.id] || ""}
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputType;
|
||||
34
src/core/components/FormMaker/SelectType.jsx
Normal file
34
src/core/components/FormMaker/SelectType.jsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { FormControl, InputLabel, MenuItem, Select } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
const SelectType = ({ itemInfo, defaultValues, setDefaultValues }) => {
|
||||
const handleChange = (event) => {
|
||||
const newValue = event.target.value;
|
||||
setDefaultValues((prev) => ({
|
||||
...prev,
|
||||
[itemInfo.id]: newValue,
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl size="small" fullWidth variant="outlined">
|
||||
<InputLabel id={itemInfo.id}>{itemInfo.name}</InputLabel>
|
||||
<Select
|
||||
labelId={itemInfo.id}
|
||||
id={itemInfo.id}
|
||||
value={defaultValues[itemInfo.id] || ""}
|
||||
label={itemInfo.name}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<MenuItem value="">{itemInfo.name}</MenuItem>
|
||||
{itemInfo.option?.map((item, index) => (
|
||||
<MenuItem key={index} value={item}>
|
||||
{item}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectType;
|
||||
33
src/core/components/FormMaker/index.jsx
Normal file
33
src/core/components/FormMaker/index.jsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import InputType from "./InputType";
|
||||
import SelectType from "./SelectType";
|
||||
import DateType from "./DateType";
|
||||
import { Grid } from "@mui/material";
|
||||
|
||||
const componentMap = {
|
||||
input: InputType,
|
||||
select: SelectType,
|
||||
date: DateType,
|
||||
};
|
||||
|
||||
const FormMaker = ({ formInfo, defaultValues, setDefaultValues }) => {
|
||||
return (
|
||||
<Grid container spacing={1}>
|
||||
{formInfo?.map((itemInfo) => {
|
||||
const Component = componentMap[itemInfo.type] || null;
|
||||
return (
|
||||
<Grid item xs={12} sm={6} md={4} key={itemInfo.id}>
|
||||
{Component ? (
|
||||
<Component
|
||||
itemInfo={itemInfo}
|
||||
defaultValues={defaultValues}
|
||||
setDefaultValues={setDefaultValues}
|
||||
/>
|
||||
) : null}
|
||||
</Grid>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormMaker;
|
||||
@@ -9,9 +9,16 @@ export const GET_SIDEBAR_BADGE_ROUTE = api + "/v2/activity_statistics";
|
||||
export const REFER_ADMIN_PROVINCE = "/v3/api/fake-submit";
|
||||
export const REFER_ADMIN_CITY = "/v3/api/fake-submit";
|
||||
export const GET_CITY_LISTS = "/v3/api/fake-cities";
|
||||
export const GET_PROVINCE_LISTS = "/v3/api/fake-provinces";
|
||||
export const GET_PROVINCE_LISTS = api + "/public/contents/provinces";
|
||||
export const GET_PREV_STATE_OPINION = "/v3/api/fake-prev-state-opinion";
|
||||
export const SUBMIT_ROAD_SAFETY_FORM = "/v3/api/fake-submit";
|
||||
export const POST_AZMAYESH = api + "/api/v3/azmayeshes/store";
|
||||
export const CREATE_AZMAYESH = api + "/api/v3/azmayeshes/store";
|
||||
export const UPDATE_AZMAYESH = api + "/api/v3/azmayeshes/update";
|
||||
export const GET_AZMAYESH_TYPE_LIST = api + "/api/v3/azmayesh_types";
|
||||
export const GET_AZMAYESH_LIST = api + "/api/v3/azmayeshes";
|
||||
export const DELETE_AZMAYESH = api + "/api/v3/azmayeshes/delete";
|
||||
export const GET_AZMAYESH_SAMPLE_FIELDS = api + "/api/v3/azmayesh_types/fields";
|
||||
export const ADD_SAMPLE_TO_AZMAYESH = api + "/api/v3/azmayesh_samples/store";
|
||||
export const UPDATE_SAMPLE_OF_AZMAYESH = api + "/api/v3/azmayesh_samples/update";
|
||||
export const GET_SAMPLE_LIST = api + "/api/v3/azmayesh_samples";
|
||||
export const DELETE_SAMPLE_LIST = api + "/api/v3/azmayesh_samples/delete";
|
||||
|
||||
@@ -11,18 +11,18 @@ const useProvinces = () => {
|
||||
useEffect(() => {
|
||||
const fetchCities = async () => {
|
||||
try {
|
||||
const response = await requestServer(`${GET_PROVINCE_LISTS}`); // Fetch the cities from the API
|
||||
setProvinces(response.data.data); // Set the cities data
|
||||
setLoadingProvinces(false); // Set loading to false after successful fetch
|
||||
const response = await requestServer(`${GET_PROVINCE_LISTS}`);
|
||||
setProvinces(response.data.data);
|
||||
setLoadingProvinces(false);
|
||||
} catch (e) {
|
||||
console.error("Error fetching cities:", e);
|
||||
console.error("Error fetching provinces:", e);
|
||||
setErrorProvinces(e);
|
||||
setLoadingProvinces(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchCities(); // Call the fetch function
|
||||
}, []); // Empty dependency array to ensure it only runs once
|
||||
fetchCities();
|
||||
}, []);
|
||||
|
||||
return { provinces, loadingProvinces, errorProvinces };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user