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 0000000..ac2446d Binary files /dev/null and b/src/assets/images/examine_marker.png differ diff --git a/src/assets/images/examine_marker_active.png b/src/assets/images/examine_marker_active.png new file mode 100644 index 0000000..07cbca5 Binary files /dev/null and b/src/assets/images/examine_marker_active.png differ diff --git a/src/assets/scss/global.scss b/src/assets/scss/global.scss index 7b73e7e..5db6087 100644 --- a/src/assets/scss/global.scss +++ b/src/assets/scss/global.scss @@ -3,8 +3,7 @@ @import "react-toastify/dist/ReactToastify.css"; .filter-toast { - box-shadow: - rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, - rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - background-color: #d0dfe8; -} + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, + rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + background-color: #d0dfe8; +} \ No newline at end of file diff --git a/src/assets/scss/map-styles.scss b/src/assets/scss/map-styles.scss index 851873f..2dd81bb 100644 --- a/src/assets/scss/map-styles.scss +++ b/src/assets/scss/map-styles.scss @@ -25,4 +25,3 @@ font-size: 12px; color: #ffeb3b; } - diff --git a/src/components/dashboard/test/Actions/create/CreateDialog/ChooseLocation.jsx b/src/components/dashboard/test/Actions/create/CreateDialog/ChooseLocation.jsx new file mode 100644 index 0000000..433543e --- /dev/null +++ b/src/components/dashboard/test/Actions/create/CreateDialog/ChooseLocation.jsx @@ -0,0 +1,162 @@ +"use client"; + +import {Marker, useMapEvents} from "react-leaflet"; +import {useEffect, useRef} from "react"; +import L from "leaflet"; +import TestIcon from "@/assets/images/examine_marker.png"; +import TestActiveIcon from "@/assets/images/examine_marker_active.png"; +import { + Box, + Button, + FormControl, + InputAdornment, + InputLabel, + OutlinedInput, + Stack, + Tooltip, + useMediaQuery +} from "@mui/material"; +import NewReleasesIcon from '@mui/icons-material/NewReleases'; +import VerifiedIcon from '@mui/icons-material/Verified'; +import EditIcon from '@mui/icons-material/Edit'; +import {useTheme} from "@emotion/react"; + +const ChooseLocation = ({mapBoxData, setMapBoxData}) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + + const mapTestMarker = useRef(); + const defaultIconSize = [35, 35]; + const createCustomIcon = (size, iconUrl) => { + return L.icon({ + iconUrl: iconUrl, + iconSize: size, + iconAnchor: [size[0] / 2, size[1]], + popupAnchor: [0, -size[1]] + }); + }; + + const map = useMapEvents({ + move(e) { + if (!mapBoxData) { + mapTestMarker.current.setLatLng(e.target.getCenter()); + } + }, + movestart() { + if (!mapBoxData) { + mapTestMarker.current.setIcon(createCustomIcon([45, 45], TestIcon.src)); + } + }, + moveend() { + if (!mapBoxData) { + mapTestMarker.current.setIcon(createCustomIcon(defaultIconSize, TestIcon.src)); + } + } + }); + + useEffect(() => { + if (mapTestMarker.current) { + const newIcon = mapBoxData + ? createCustomIcon([45, 45], TestActiveIcon.src) + : createCustomIcon(defaultIconSize, TestIcon.src); + mapTestMarker.current.setIcon(newIcon); + } + if (mapBoxData) { + mapTestMarker.current.setLatLng(mapBoxData); + map.flyTo(mapBoxData, 14); + } + }, [mapBoxData]); + + const handleMarkerClick = () => { + if (!mapBoxData) { + setMapBoxData({lat: mapTestMarker.current.getLatLng().lat, lng: mapTestMarker.current.getLatLng().lng}); + } + }; + + const handleEditLocation = () => { + setMapBoxData(null); + } + + return ( + <> + + + + + + + طول جغرافیایی + + + {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;