From 45d1665155f0c3f2b846da1e1efa2b9b6ffb3edb Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 26 Oct 2024 05:31:11 +0000 Subject: [PATCH] complete design of adding new test and bundling and saving map data next step... --- src/app/(withAuth)/dashboard/test/page.js | 7 + src/app/api/fake-tests-type/route.js | 18 + src/app/api/fake-tests/route.js | 71 ++++ src/assets/images/examine_marker.png | Bin 0 -> 15040 bytes src/assets/images/examine_marker_active.png | Bin 0 -> 13021 bytes src/assets/scss/global.scss | 9 +- src/assets/scss/map-styles.scss | 1 - .../create/CreateDialog/ChooseLocation.jsx | 162 ++++++++ .../create/CreateDialog/CreateTimeLine.jsx | 59 +++ .../Actions/create/CreateDialog/MapBox.jsx | 39 ++ .../create/CreateDialog/TestGeneralInfo.jsx | 387 ++++++++++++++++++ .../Actions/create/CreateDialog/index.jsx | 187 +++++++++ .../dashboard/test/Actions/create/index.jsx | 33 ++ .../test/ShowLocation/ShowLocationMarker.jsx | 105 +++++ .../dashboard/test/ShowLocation/index.jsx | 50 +++ src/components/dashboard/test/TestList.jsx | 135 ++++++ src/components/dashboard/test/Toolbar.jsx | 10 + src/components/dashboard/test/index.jsx | 15 + src/core/utils/pageMenu.js | 81 ++-- src/core/utils/routes.js | 3 + src/lib/hooks/useProvince.js | 7 +- src/lib/hooks/useTest.js | 30 ++ 22 files changed, 1363 insertions(+), 46 deletions(-) create mode 100644 src/app/(withAuth)/dashboard/test/page.js create mode 100644 src/app/api/fake-tests-type/route.js create mode 100644 src/app/api/fake-tests/route.js create mode 100644 src/assets/images/examine_marker.png create mode 100644 src/assets/images/examine_marker_active.png create mode 100644 src/components/dashboard/test/Actions/create/CreateDialog/ChooseLocation.jsx create mode 100644 src/components/dashboard/test/Actions/create/CreateDialog/CreateTimeLine.jsx create mode 100644 src/components/dashboard/test/Actions/create/CreateDialog/MapBox.jsx create mode 100644 src/components/dashboard/test/Actions/create/CreateDialog/TestGeneralInfo.jsx create mode 100644 src/components/dashboard/test/Actions/create/CreateDialog/index.jsx create mode 100644 src/components/dashboard/test/Actions/create/index.jsx create mode 100644 src/components/dashboard/test/ShowLocation/ShowLocationMarker.jsx create mode 100644 src/components/dashboard/test/ShowLocation/index.jsx create mode 100644 src/components/dashboard/test/TestList.jsx create mode 100644 src/components/dashboard/test/Toolbar.jsx create mode 100644 src/components/dashboard/test/index.jsx create mode 100644 src/lib/hooks/useTest.js diff --git a/src/app/(withAuth)/dashboard/test/page.js b/src/app/(withAuth)/dashboard/test/page.js new file mode 100644 index 0000000..7baafa7 --- /dev/null +++ b/src/app/(withAuth)/dashboard/test/page.js @@ -0,0 +1,7 @@ +import TestPage from "@/components/dashboard/test"; + +const Page = () => { + return ; +}; + +export default Page; diff --git a/src/app/api/fake-tests-type/route.js b/src/app/api/fake-tests-type/route.js new file mode 100644 index 0000000..943b759 --- /dev/null +++ b/src/app/api/fake-tests-type/route.js @@ -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}); +} diff --git a/src/app/api/fake-tests/route.js b/src/app/api/fake-tests/route.js new file mode 100644 index 0000000..7d9c077 --- /dev/null +++ b/src/app/api/fake-tests/route.js @@ -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}); +} diff --git a/src/assets/images/examine_marker.png b/src/assets/images/examine_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2446dc43e7040cc612847335003cc7ecf6591c GIT binary patch literal 15040 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/examine_marker_active.png b/src/assets/images/examine_marker_active.png new file mode 100644 index 0000000000000000000000000000000000000000..07cbca51f4cff8ee207e6f3e7890b937fc73e6d8 GIT binary patch literal 13021 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 { + 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 ( + <> + + + + + + + طول جغرافیایی + + + {mapBoxData ? : + } + + } + label="طول جغرافیایی" + /> + + + + + + عرض جغرافیایی + + + {mapBoxData ? : + } + + } + label="عرض جغرافیایی" + /> + + + + + + + ); +}; + +export default ChooseLocation; \ No newline at end of file diff --git a/src/components/dashboard/test/Actions/create/CreateDialog/CreateTimeLine.jsx b/src/components/dashboard/test/Actions/create/CreateDialog/CreateTimeLine.jsx new file mode 100644 index 0000000..49a7d90 --- /dev/null +++ b/src/components/dashboard/test/Actions/create/CreateDialog/CreateTimeLine.jsx @@ -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 ( + + + + + + + + + + + + + نقشه + + ثبت مختصات محل + آزمایش + + + + + + + + + + + + + مشخصات آزمایش + + ثبت مشخصات اولیه + + + + + ); +}; +export default CreateTimeLine; diff --git a/src/components/dashboard/test/Actions/create/CreateDialog/MapBox.jsx b/src/components/dashboard/test/Actions/create/CreateDialog/MapBox.jsx new file mode 100644 index 0000000..8b1611c --- /dev/null +++ b/src/components/dashboard/test/Actions/create/CreateDialog/MapBox.jsx @@ -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: () => , + ssr: false, +}); + +const MapBox = ({mapBoxData, setMapBoxData}) => { + return ( + + + + + + + + + + ); +}; +export default MapBox; diff --git a/src/components/dashboard/test/Actions/create/CreateDialog/TestGeneralInfo.jsx b/src/components/dashboard/test/Actions/create/CreateDialog/TestGeneralInfo.jsx new file mode 100644 index 0000000..d424a1a --- /dev/null +++ b/src/components/dashboard/test/Actions/create/CreateDialog/TestGeneralInfo.jsx @@ -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 ( + + + ( + + + {errorTests ? ( + + خطایی در دریافت لیست آزمایش ها رخ داده است! + + ) : loadingTests ? ( + + + درحال دریافت لیست آزمایش ها + + ) : ( + 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) => ( + + )} + /> + )} + + {errors.azmayesh_type_id ? errors.azmayesh_type_id.message : null} + + + )} + /> + + + ( + + + {errorProvinces ? ( + + خطایی در دریافت لیست استان ها رخ داده است! + + ) : loadingProvinces ? ( + + + درحال دریافت لیست استان ها + + ) : ( + 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) => ( + + )} + /> + )} + + {errors.province_id ? errors.province_id.message : null} + + + )} + /> + + + + + پروژه + + + + {errors.project_name ? errors.project_name.message : null} + + + + + + + کارفرما + + + + {errors.employer ? errors.employer.message : null} + + + + + + + مشاور + + + + {errors.consultant ? errors.consultant.message : null} + + + + + + + پیمانکار + + + + {errors.contractor ? errors.contractor.message : null} + + + + + + + متقاضی + + + + {errors.applicant ? errors.applicant.message : null} + + + + + + + شماره کار + + + + {errors.work_number ? errors.work_number.message : null} + + + + + + + شماره درخواست + + + + {errors.request_number ? errors.request_number.message : null} + + + + + ( + + + { + onChange(newValue); + }} + slotProps={{ + textField: { + size: "small", + error: !!errors.request_date, + placeholder: "تاریخ درخواست", + InputProps: { + endAdornment: ( + + { + event.stopPropagation(); + setValue("request_date", ""); + }} + sx={{ + color: "#bfbfbf", + "&:hover": { + backgroundColor: "rgba(189, 189, 189, 0.1)", + color: "#363434", + }, + }} + > + + + + ), + }, + }, + }} + /> + + + {errors.request_date ? errors.request_date.message : null} + + + )} + /> + + + ( + + + { + onChange(newValue); + }} + slotProps={{ + textField: { + size: "small", + error: !!errors.report_date, + placeholder: "تاریخ گزارش", + InputProps: { + endAdornment: ( + + { + event.stopPropagation(); + setValue("report_date", ""); + }} + sx={{ + color: "#bfbfbf", + "&:hover": { + backgroundColor: "rgba(189, 189, 189, 0.1)", + color: "#363434", + }, + }} + > + + + + ), + }, + }, + }} + /> + + + {errors.report_date ? errors.report_date.message : null} + + + )} + /> + + + ); +}; +export default TestGeneralInfo; \ No newline at end of file diff --git a/src/components/dashboard/test/Actions/create/CreateDialog/index.jsx b/src/components/dashboard/test/Actions/create/CreateDialog/index.jsx new file mode 100644 index 0000000..f52c42a --- /dev/null +++ b/src/components/dashboard/test/Actions/create/CreateDialog/index.jsx @@ -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 ( + + ); +} + +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 ( + + + + } label="انتخاب محل آزمایش"> + } label="مشخصات آزمایش"> + + + + + + + + + + + {!isMobile && ( + + + + )} + + + + { + tabState === 0 ? : + } + + + + ); +}; +export default CreateDialog; diff --git a/src/components/dashboard/test/Actions/create/index.jsx b/src/components/dashboard/test/Actions/create/index.jsx new file mode 100644 index 0000000..9d59d00 --- /dev/null +++ b/src/components/dashboard/test/Actions/create/index.jsx @@ -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 ? ( + + + + ) : ( + + )} + {open && } + + ); +}; +export default TestCreate; diff --git a/src/components/dashboard/test/ShowLocation/ShowLocationMarker.jsx b/src/components/dashboard/test/ShowLocation/ShowLocationMarker.jsx new file mode 100644 index 0000000..6b65250 --- /dev/null +++ b/src/components/dashboard/test/ShowLocation/ShowLocationMarker.jsx @@ -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 ( + <> + + + + + + طول جغرافیایی + + + + + } + label="طول جغرافیایی" + /> + + + + عرض جغرافیایی + + + + + } + label="عرض جغرافیایی" + /> + + + + + ); +}; + +export default ShowLocationMarker; \ No newline at end of file diff --git a/src/components/dashboard/test/ShowLocation/index.jsx b/src/components/dashboard/test/ShowLocation/index.jsx new file mode 100644 index 0000000..557a780 --- /dev/null +++ b/src/components/dashboard/test/ShowLocation/index.jsx @@ -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: () => , + ssr: false, +}); + +const ShowLocation = ({lat, lng}) => { + const [openShowLocationModal, setOpenShowLocationModal] = useState(false); + + const handleOpenShowLocationModal = () => { + setOpenShowLocationModal(true); + }; + + const handleCloseShowLocationModal = () => { + setOpenShowLocationModal(false); + }; + + return ( + + + + + + + + + + + + + + + + ); +}; +export default ShowLocation; diff --git a/src/components/dashboard/test/TestList.jsx b/src/components/dashboard/test/TestList.jsx new file mode 100644 index 0000000..2c735f4 --- /dev/null +++ b/src/components/dashboard/test/TestList.jsx @@ -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}) => (), + }, + { + 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}) => ({moment(renderedCellValue).locale("fa").format("YYYY/MM/DD")}), + }, + { + accessorKey: "report_date", + header: "تاریخ گزارش", + id: "report_date", + enableColumnFilter: false, + datatype: "date", + filterFn: "equals", + Cell: ({renderedCellValue}) => ({moment(renderedCellValue).locale("fa").format("YYYY/MM/DD")}), + }, + ], + [] + ); + + return ( + <> + + + + + ); +}; +export default TestList; diff --git a/src/components/dashboard/test/Toolbar.jsx b/src/components/dashboard/test/Toolbar.jsx new file mode 100644 index 0000000..8aaa0a9 --- /dev/null +++ b/src/components/dashboard/test/Toolbar.jsx @@ -0,0 +1,10 @@ +import TestCreate from "./Actions/Create"; + +const Toolbar = ({mutate}) => { + return ( + <> + + + ); +}; +export default Toolbar; diff --git a/src/components/dashboard/test/index.jsx b/src/components/dashboard/test/index.jsx new file mode 100644 index 0000000..d2503a0 --- /dev/null +++ b/src/components/dashboard/test/index.jsx @@ -0,0 +1,15 @@ +"use client"; + +import PageTitle from "@/core/components/PageTitle"; +import {Stack} from "@mui/material"; +import TestList from "./TestList"; + +const TestPage = () => { + return ( + + + + + ); +}; +export default TestPage; diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index 7ab77de..1f9100c 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -18,6 +18,7 @@ import EngineeringIcon from "@mui/icons-material/Engineering"; import ReportIcon from "@mui/icons-material/Report"; import AssignmentLateIcon from "@mui/icons-material/AssignmentLate"; import LineAxisIcon from "@mui/icons-material/LineAxis"; +import ScienceIcon from '@mui/icons-material/Science'; export const pageMenu = [ { @@ -25,7 +26,7 @@ export const pageMenu = [ label: "پیشخوان", type: "page", route: "/dashboard", - icon: , + icon: , permissions: ["all"], }, { @@ -33,14 +34,14 @@ export const pageMenu = [ label: "مدیریت کاربران", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management", - icon: , + icon: , permissions: ["full-user-management", "limited-user-management"], }, { id: "projectsManagment", label: "پروژه های راهداری", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -48,7 +49,7 @@ export const pageMenu = [ label: "ثبت قرارداد و پروژه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance", - icon: , + icon: , permissions: ["show-contract", "show-contract-province"], }, { @@ -56,7 +57,7 @@ export const pageMenu = [ label: "لیست پروژه ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list", - icon: , + icon: , permissions: ["all"], }, { @@ -64,7 +65,7 @@ export const pageMenu = [ label: "پروژه های پیشنهادی", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal", - icon: , + icon: , permissions: ["show-proposal", "show-proposal-province"], }, { @@ -72,7 +73,7 @@ export const pageMenu = [ label: "درخواست نمایندگان", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers", - icon: , + icon: , permissions: ["show-lawmaker", "show-lawmaker-province"], }, { @@ -80,7 +81,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects", - icon: , + icon: , permissions: ["all"], }, ], @@ -89,7 +90,7 @@ export const pageMenu = [ id: "roadItemManagment", label: "فعالیت های روزانه", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_items.total"], Subitems: [ @@ -97,7 +98,7 @@ export const pageMenu = [ id: "roadItemManagmentSupervisor", label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_items.supervise_cnt"], Subitems: [ @@ -117,7 +118,7 @@ export const pageMenu = [ id: "roadItemManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_items.operation_cnt"], Subitems: [ @@ -142,7 +143,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items", - icon: , + icon: , permissions: [ "show-road-item-supervise-cartable", "show-road-item-supervise-cartable-province", @@ -154,7 +155,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report", - icon: , + icon: , permissions: [ "show-road-item-supervise-cartable", "show-road-item-supervise-cartable-province", @@ -167,7 +168,7 @@ export const pageMenu = [ id: "roadPatrolManagment", label: "گشت راهداری و ترابری", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_patrols.total"], Subitems: [ @@ -175,7 +176,7 @@ export const pageMenu = [ id: "roadPatrolManagmentSupervisor", label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_patrols.supervise_cnt"], Subitems: [ @@ -195,7 +196,7 @@ export const pageMenu = [ id: "roadPatrolManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_patrols.operation_cnt"], Subitems: [ @@ -220,7 +221,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols", - icon: , + icon: , permissions: [ "add-road-patrol", "show-road-patrol-supervise-cartable", @@ -232,7 +233,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report", - icon: , + icon: , permissions: [ "add-road-patrol", "show-road-patrol-supervise-cartable", @@ -245,7 +246,7 @@ export const pageMenu = [ id: "inquiryPrivacyManagment", label: "استعلام حریم راه", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -282,7 +283,7 @@ export const pageMenu = [ id: "safetyAndPrivacyManagment", label: "نگهداری حریم راه", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["safety_and_privacy.step_one", "safety_and_privacy.step_two"], Subitems: [ @@ -290,7 +291,7 @@ export const pageMenu = [ id: "safetyAndPrivacyManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -318,7 +319,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy", - icon: , + icon: , permissions: [ "show-safety-and-privacy-operator-cartable", "show-safety-and-privacy-operator-cartable-province", @@ -331,7 +332,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report", - icon: , + icon: , permissions: [ "show-safety-and-privacy-operator-cartable", "show-safety-and-privacy-operator-cartable-province", @@ -345,7 +346,7 @@ export const pageMenu = [ id: "roadObservationsManagment", label: "واکنش سریع", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_observations.total"], Subitems: [ @@ -353,7 +354,7 @@ export const pageMenu = [ id: "roadObservationsManagmentSupervisor", label: "ارزیابی", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_observations.supervise_cnt"], Subitems: [ @@ -371,14 +372,14 @@ export const pageMenu = [ label: "رسیدگی به شکایات", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations", - icon: , + icon: , permissions: ["show-fast-react", "show-fast-react-province", "show-fast-react-edarate-shahri"], }, { id: "roadObservationsManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, badges: ["road_observations.operation_cnt"], Subitems: [ @@ -396,7 +397,7 @@ export const pageMenu = [ label: "پراکندگی بر روی نقشه", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations", - icon: , + icon: , permissions: ["all"], }, { @@ -404,7 +405,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index", - icon: , + icon: , permissions: ["all"], }, ], @@ -413,7 +414,7 @@ export const pageMenu = [ id: "winterCampManagment", label: "قرارگاه زمستانی", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -421,7 +422,7 @@ export const pageMenu = [ label: "محور های انسدادی", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp", - icon: , + icon: , permissions: ["show-camp", "show-camp-province"], }, { @@ -429,7 +430,7 @@ export const pageMenu = [ label: "محور های حلقه اول", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp", - icon: , + icon: , permissions: ["show-camp", "show-camp-province"], }, { @@ -437,7 +438,7 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew", - icon: , + icon: , permissions: ["show-camp", "show-camp-province"], }, ], @@ -446,14 +447,14 @@ export const pageMenu = [ id: "receiptManagment", label: "خسارات وارده بر ابنیه فنی و تاسیسات راه", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { id: "receiptManagmentOparation", label: "عملیات", type: "menu", - icon: , + icon: , hasSubitems: true, Subitems: [ { @@ -470,9 +471,17 @@ export const pageMenu = [ label: "گزارش ها", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report", - icon: , + icon: , permissions: ["all"], }, ], }, + { + id: "test", + label: "آزمایشات", + type: "page", + route: "/dashboard/test", + icon: , + permissions: ["all"], + }, ]; diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 14bf801..0e60709 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -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_PREV_STATE_OPINION = "/v3/api/fake-prev-state-opinion"; 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"; diff --git a/src/lib/hooks/useProvince.js b/src/lib/hooks/useProvince.js index a21744b..7a058f6 100644 --- a/src/lib/hooks/useProvince.js +++ b/src/lib/hooks/useProvince.js @@ -1,6 +1,5 @@ -import { useState, useEffect } from "react"; -import axios from "axios"; -import { GET_PROVINCE_LISTS } from "@/core/utils/routes"; +import {useEffect, useState} from "react"; +import {GET_PROVINCE_LISTS} from "@/core/utils/routes"; import useRequest from "@/lib/hooks/useRequest"; const useProvinces = () => { @@ -25,7 +24,7 @@ const useProvinces = () => { fetchCities(); // Call the fetch function }, []); // Empty dependency array to ensure it only runs once - return { provinces, loadingProvinces, errorProvinces }; + return {provinces, loadingProvinces, errorProvinces}; }; export default useProvinces; diff --git a/src/lib/hooks/useTest.js b/src/lib/hooks/useTest.js new file mode 100644 index 0000000..ea1a386 --- /dev/null +++ b/src/lib/hooks/useTest.js @@ -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;