Merge branch 'feature/update_azmayesh_page' into 'develop'
rename folder structure See merge request witel-front-end/rms!29
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import TestPage from "@/components/dashboard/test";
|
import TestPage from "@/components/dashboard/azmayesh";
|
||||||
|
|
||||||
const Page = () => {
|
const Page = () => {
|
||||||
return <TestPage/>;
|
return <TestPage/>;
|
||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
Typography
|
Typography
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import useTest from "@/lib/hooks/useTest";
|
import useAzmayesh from "@/lib/hooks/useAzmayesh";
|
||||||
import useProvinces from "@/lib/hooks/useProvince";
|
import useProvinces from "@/lib/hooks/useProvince";
|
||||||
import {LocalizationProvider, MobileDatePicker} from "@mui/x-date-pickers";
|
import {LocalizationProvider, MobileDatePicker} from "@mui/x-date-pickers";
|
||||||
import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali";
|
import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali";
|
||||||
@@ -22,8 +22,8 @@ import {faIR} from "@mui/x-date-pickers/locales";
|
|||||||
import ClearIcon from "@mui/icons-material/Clear";
|
import ClearIcon from "@mui/icons-material/Clear";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const TestGeneralInfo = ({control, register, setValue, errors}) => {
|
const AzmayeshGeneralInfo = ({control, register, setValue, errors}) => {
|
||||||
const {tests, errorTests, loadingTests} = useTest();
|
const {azmayeshes, errorAzmayeshes, loadingAzmayeshes} = useAzmayesh();
|
||||||
const {provinces, errorProvinces, loadingProvinces} = useProvinces();
|
const {provinces, errorProvinces, loadingProvinces} = useProvinces();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -37,12 +37,12 @@ const TestGeneralInfo = ({control, register, setValue, errors}) => {
|
|||||||
<FormControl error={!!errors.azmayesh_type_id} size="small" fullWidth
|
<FormControl error={!!errors.azmayesh_type_id} size="small" fullWidth
|
||||||
variant="outlined">
|
variant="outlined">
|
||||||
<InputLabel htmlFor="azmayesh_type_id"/>
|
<InputLabel htmlFor="azmayesh_type_id"/>
|
||||||
{errorTests ? (
|
{errorAzmayeshes ? (
|
||||||
<Typography color={"red"}
|
<Typography color={"red"}
|
||||||
sx={{display: "flex", alignItems: "center", gap: 2}}>
|
sx={{display: "flex", alignItems: "center", gap: 2}}>
|
||||||
خطایی در دریافت لیست آزمایش ها رخ داده است!
|
خطایی در دریافت لیست آزمایش ها رخ داده است!
|
||||||
</Typography>
|
</Typography>
|
||||||
) : loadingTests ? (
|
) : loadingAzmayeshes ? (
|
||||||
<Typography sx={{display: "flex", alignItems: "center", gap: 2}}>
|
<Typography sx={{display: "flex", alignItems: "center", gap: 2}}>
|
||||||
<CircularProgress size={20}/>
|
<CircularProgress size={20}/>
|
||||||
درحال دریافت لیست آزمایش ها
|
درحال دریافت لیست آزمایش ها
|
||||||
@@ -51,10 +51,10 @@ const TestGeneralInfo = ({control, register, setValue, errors}) => {
|
|||||||
<Autocomplete
|
<Autocomplete
|
||||||
id="azmayesh_type_id"
|
id="azmayesh_type_id"
|
||||||
size="small"
|
size="small"
|
||||||
value={tests.find((test) => test.id === value) || null}
|
value={azmayeshes.find((azmayesh) => azmayesh.id === value) || null}
|
||||||
disablePortal
|
disablePortal
|
||||||
options={tests}
|
options={azmayeshes}
|
||||||
getOptionLabel={(test) => test.name}
|
getOptionLabel={(azmayesh) => azmayesh.name}
|
||||||
isOptionEqualToValue={(option, value) => option.id === value?.id}
|
isOptionEqualToValue={(option, value) => option.id === value?.id}
|
||||||
onChange={(event, newValue) => {
|
onChange={(event, newValue) => {
|
||||||
onChange(newValue ? newValue.id : "");
|
onChange(newValue ? newValue.id : "");
|
||||||
@@ -384,4 +384,4 @@ const TestGeneralInfo = ({control, register, setValue, errors}) => {
|
|||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default TestGeneralInfo;
|
export default AzmayeshGeneralInfo;
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
import {Marker, useMapEvents} from "react-leaflet";
|
import {Marker, useMapEvents} from "react-leaflet";
|
||||||
import {useEffect, useRef} from "react";
|
import {useEffect, useRef} from "react";
|
||||||
import L from "leaflet";
|
import L from "leaflet";
|
||||||
import TestIcon from "@/assets/images/examine_marker.png";
|
import AzmayeshIcon from "@/assets/images/examine_marker.png";
|
||||||
import TestActiveIcon from "@/assets/images/examine_marker_active.png";
|
import AzmayeshActiveIcon from "@/assets/images/examine_marker_active.png";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@@ -25,7 +25,7 @@ const ChooseLocation = ({mapBoxData, setMapBoxData}) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
|
||||||
const mapTestMarker = useRef();
|
const mapAzmayeshMarker = useRef();
|
||||||
const defaultIconSize = [35, 35];
|
const defaultIconSize = [35, 35];
|
||||||
const createCustomIcon = (size, iconUrl) => {
|
const createCustomIcon = (size, iconUrl) => {
|
||||||
return L.icon({
|
return L.icon({
|
||||||
@@ -39,37 +39,40 @@ const ChooseLocation = ({mapBoxData, setMapBoxData}) => {
|
|||||||
const map = useMapEvents({
|
const map = useMapEvents({
|
||||||
move(e) {
|
move(e) {
|
||||||
if (!mapBoxData) {
|
if (!mapBoxData) {
|
||||||
mapTestMarker.current.setLatLng(e.target.getCenter());
|
mapAzmayeshMarker.current.setLatLng(e.target.getCenter());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
movestart() {
|
movestart() {
|
||||||
if (!mapBoxData) {
|
if (!mapBoxData) {
|
||||||
mapTestMarker.current.setIcon(createCustomIcon([45, 45], TestIcon.src));
|
mapAzmayeshMarker.current.setIcon(createCustomIcon([45, 45], AzmayeshIcon.src));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
moveend() {
|
moveend() {
|
||||||
if (!mapBoxData) {
|
if (!mapBoxData) {
|
||||||
mapTestMarker.current.setIcon(createCustomIcon(defaultIconSize, TestIcon.src));
|
mapAzmayeshMarker.current.setIcon(createCustomIcon(defaultIconSize, AzmayeshIcon.src));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mapTestMarker.current) {
|
if (mapAzmayeshMarker.current) {
|
||||||
const newIcon = mapBoxData
|
const newIcon = mapBoxData
|
||||||
? createCustomIcon([45, 45], TestActiveIcon.src)
|
? createCustomIcon([45, 45], AzmayeshActiveIcon.src)
|
||||||
: createCustomIcon(defaultIconSize, TestIcon.src);
|
: createCustomIcon(defaultIconSize, AzmayeshIcon.src);
|
||||||
mapTestMarker.current.setIcon(newIcon);
|
mapAzmayeshMarker.current.setIcon(newIcon);
|
||||||
}
|
}
|
||||||
if (mapBoxData) {
|
if (mapBoxData) {
|
||||||
mapTestMarker.current.setLatLng(mapBoxData);
|
mapAzmayeshMarker.current.setLatLng(mapBoxData);
|
||||||
map.flyTo(mapBoxData, 14);
|
map.flyTo(mapBoxData, 14);
|
||||||
}
|
}
|
||||||
}, [mapBoxData]);
|
}, [mapBoxData]);
|
||||||
|
|
||||||
const handleMarkerClick = () => {
|
const handleMarkerClick = () => {
|
||||||
if (!mapBoxData) {
|
if (!mapBoxData) {
|
||||||
setMapBoxData({lat: mapTestMarker.current.getLatLng().lat, lng: mapTestMarker.current.getLatLng().lng});
|
setMapBoxData({
|
||||||
|
lat: mapAzmayeshMarker.current.getLatLng().lat,
|
||||||
|
lng: mapAzmayeshMarker.current.getLatLng().lng
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,9 +84,9 @@ const ChooseLocation = ({mapBoxData, setMapBoxData}) => {
|
|||||||
<>
|
<>
|
||||||
<Marker
|
<Marker
|
||||||
position={map.getCenter()}
|
position={map.getCenter()}
|
||||||
ref={mapTestMarker}
|
ref={mapAzmayeshMarker}
|
||||||
eventHandlers={{click: handleMarkerClick}}
|
eventHandlers={{click: handleMarkerClick}}
|
||||||
icon={createCustomIcon(defaultIconSize, TestIcon.src)}
|
icon={createCustomIcon(defaultIconSize, AzmayeshIcon.src)}
|
||||||
/>
|
/>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
zIndex: "400",
|
zIndex: "400",
|
||||||
@@ -17,8 +17,8 @@ import {object, string} from "yup";
|
|||||||
import useRequest from "@/lib/hooks/useRequest";
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
import {yupResolver} from "@hookform/resolvers/yup";
|
import {yupResolver} from "@hookform/resolvers/yup";
|
||||||
import moment from "jalali-moment";
|
import moment from "jalali-moment";
|
||||||
import {POST_TEST} from "@/core/utils/routes";
|
import {POST_AZMAYESH} from "@/core/utils/routes";
|
||||||
import TestGeneralInfo from "@/components/dashboard/test/Actions/create/CreateDialog/TestGeneralInfo";
|
import AzmayeshGeneralInfo from "./AzmayeshGeneralInfo";
|
||||||
|
|
||||||
function TabPanel(props) {
|
function TabPanel(props) {
|
||||||
const {children, value, index} = props;
|
const {children, value, index} = props;
|
||||||
@@ -37,7 +37,7 @@ function TabPanel(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateDialog = ({open, setOpen}) => {
|
const CreateDialog = ({open, setOpen, mutate}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
const [tabState, setTabState] = useState(0);
|
const [tabState, setTabState] = useState(0);
|
||||||
@@ -99,7 +99,6 @@ const CreateDialog = ({open, setOpen}) => {
|
|||||||
} = useForm({defaultValues, resolver: yupResolver(validationSchema), mode: "onBlur"});
|
} = useForm({defaultValues, resolver: yupResolver(validationSchema), mode: "onBlur"});
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
const onSubmit = async (data) => {
|
||||||
console.log("data", data);
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("lat", mapBoxData.lat);
|
formData.append("lat", mapBoxData.lat);
|
||||||
formData.append("lng", mapBoxData.lng);
|
formData.append("lng", mapBoxData.lng);
|
||||||
@@ -117,14 +116,11 @@ const CreateDialog = ({open, setOpen}) => {
|
|||||||
formData.append("request_date", moment(data.request_date).format("YYYY-MM-DD"));
|
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("report_date", moment(data.report_date).format("YYYY-MM-DD"));
|
||||||
|
|
||||||
for (var pair of formData.entries()) {
|
requestServer(POST_AZMAYESH, "post", {
|
||||||
console.log(pair[0] + ', ' + pair[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
requestServer(POST_TEST, "post", {
|
|
||||||
data: formData,
|
data: formData,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
mutate();
|
||||||
handleClose();
|
handleClose();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@@ -151,7 +147,8 @@ const CreateDialog = ({open, setOpen}) => {
|
|||||||
<MapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData}/>
|
<MapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData}/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value={tabState} index={1}>
|
<TabPanel value={tabState} index={1}>
|
||||||
<TestGeneralInfo control={control} register={register} setValue={setValue} errors={errors}/>
|
<AzmayeshGeneralInfo control={control} register={register} setValue={setValue}
|
||||||
|
errors={errors}/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</Box>
|
</Box>
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
@@ -6,7 +6,7 @@ import {useState} from "react";
|
|||||||
import {AddCircle} from "@mui/icons-material";
|
import {AddCircle} from "@mui/icons-material";
|
||||||
import CreateDialog from "./CreateDialog";
|
import CreateDialog from "./CreateDialog";
|
||||||
|
|
||||||
const TestCreate = () => {
|
const AzmayeshCreate = ({mutate}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
@@ -26,8 +26,8 @@ const TestCreate = () => {
|
|||||||
ثبت آزمایش
|
ثبت آزمایش
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{open && <CreateDialog open={open} setOpen={setOpen}/>}
|
{open && <CreateDialog open={open} setOpen={setOpen} mutate={mutate}/>}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default TestCreate;
|
export default AzmayeshCreate;
|
||||||
@@ -8,7 +8,7 @@ import {GET_AZMAYESH_LIST} from "@/core/utils/routes";
|
|||||||
import moment from "jalali-moment";
|
import moment from "jalali-moment";
|
||||||
import ShowLocation from "./ShowLocation";
|
import ShowLocation from "./ShowLocation";
|
||||||
|
|
||||||
const TestList = () => {
|
const AzmayeshList = () => {
|
||||||
const columns = useMemo(
|
const columns = useMemo(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
@@ -132,4 +132,4 @@ const TestList = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default TestList;
|
export default AzmayeshList;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import {Marker, useMap} from "react-leaflet";
|
import {Marker, useMap} from "react-leaflet";
|
||||||
import {useEffect, useRef} from "react";
|
import {useEffect} from "react";
|
||||||
import L from "leaflet";
|
import L from "leaflet";
|
||||||
import TestActiveIcon from "@/assets/images/examine_marker_active.png";
|
import AzmayeshActiveIcon from "@/assets/images/examine_marker_active.png";
|
||||||
import {Box, FormControl, InputAdornment, InputLabel, OutlinedInput, Stack, useMediaQuery} from "@mui/material";
|
import {Box, FormControl, InputAdornment, InputLabel, OutlinedInput, Stack, useMediaQuery} from "@mui/material";
|
||||||
import VerifiedIcon from '@mui/icons-material/Verified';
|
import VerifiedIcon from '@mui/icons-material/Verified';
|
||||||
import {useTheme} from "@emotion/react";
|
import {useTheme} from "@emotion/react";
|
||||||
@@ -13,7 +13,6 @@ const ShowLocationMarker = ({lat, lng}) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
|
||||||
const mapTestMarker = useRef();
|
|
||||||
const defaultIconSize = [35, 35];
|
const defaultIconSize = [35, 35];
|
||||||
const createCustomIcon = (size, iconUrl) => {
|
const createCustomIcon = (size, iconUrl) => {
|
||||||
return L.icon({
|
return L.icon({
|
||||||
@@ -33,8 +32,7 @@ const ShowLocationMarker = ({lat, lng}) => {
|
|||||||
<>
|
<>
|
||||||
<Marker
|
<Marker
|
||||||
position={{lat: lat, lng: lng}}
|
position={{lat: lat, lng: lng}}
|
||||||
ref={mapTestMarker}
|
icon={createCustomIcon(defaultIconSize, AzmayeshActiveIcon.src)}
|
||||||
icon={createCustomIcon(defaultIconSize, TestActiveIcon.src)}
|
|
||||||
/>
|
/>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
zIndex: "400",
|
zIndex: "400",
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import TestCreate from "./Actions/Create";
|
import AzmayeshCreate from "./Actions/Create";
|
||||||
|
|
||||||
const Toolbar = ({mutate}) => {
|
const Toolbar = ({mutate}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TestCreate mutate={mutate}/>
|
<AzmayeshCreate mutate={mutate}/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
import PageTitle from "@/core/components/PageTitle";
|
import PageTitle from "@/core/components/PageTitle";
|
||||||
import {Stack} from "@mui/material";
|
import {Stack} from "@mui/material";
|
||||||
import TestList from "./TestList";
|
import AzmayeshList from "./AzmayeshList";
|
||||||
|
|
||||||
const TestPage = () => {
|
const TestPage = () => {
|
||||||
return (
|
return (
|
||||||
<Stack spacing={1}>
|
<Stack spacing={1}>
|
||||||
<PageTitle title={"آزمایشات"}/>
|
<PageTitle title={"آزمایشات"}/>
|
||||||
<TestList/>
|
<AzmayeshList/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -12,6 +12,6 @@ export const GET_CITY_LISTS = "/v3/api/fake-cities";
|
|||||||
export const GET_PROVINCE_LISTS = "/v3/api/fake-provinces";
|
export const GET_PROVINCE_LISTS = "/v3/api/fake-provinces";
|
||||||
export const GET_PREV_STATE_OPINION = "/v3/api/fake-prev-state-opinion";
|
export const GET_PREV_STATE_OPINION = "/v3/api/fake-prev-state-opinion";
|
||||||
export const SUBMIT_ROAD_SAFETY_FORM = "/v3/api/fake-submit";
|
export const SUBMIT_ROAD_SAFETY_FORM = "/v3/api/fake-submit";
|
||||||
export const POST_TEST = api + "/api/v3/azmayeshes/store";
|
export const POST_AZMAYESH = api + "/api/v3/azmayeshes/store";
|
||||||
export const GET_TESTS_LIST = api + "/api/v3/azmayesh_types";
|
export const GET_AZMAYESH_TYPE_LIST = api + "/api/v3/azmayesh_types";
|
||||||
export const GET_AZMAYESH_LIST = api + "/api/v3/azmayeshes";
|
export const GET_AZMAYESH_LIST = api + "/api/v3/azmayeshes";
|
||||||
|
|||||||
30
src/lib/hooks/useAzmayesh.js
Normal file
30
src/lib/hooks/useAzmayesh.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {GET_AZMAYESH_TYPE_LIST} from "@/core/utils/routes";
|
||||||
|
import useRequest from "@/lib/hooks/useRequest";
|
||||||
|
|
||||||
|
const useAzmayesh = () => {
|
||||||
|
const requestServer = useRequest();
|
||||||
|
const [azmayeshes, setAzmayeshes] = useState([]);
|
||||||
|
const [loadingAzmayeshes, setLoadingAzmayeshes] = useState(true);
|
||||||
|
const [errorAzmayeshes, setErrorAzmayeshes] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchTests = async () => {
|
||||||
|
try {
|
||||||
|
const response = await requestServer(`${GET_AZMAYESH_TYPE_LIST}`);
|
||||||
|
setAzmayeshes(response.data.data);
|
||||||
|
setLoadingAzmayeshes(false);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error fetching tests types:", e);
|
||||||
|
setErrorAzmayeshes(e);
|
||||||
|
setLoadingAzmayeshes(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchTests();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {azmayeshes, loadingAzmayeshes, errorAzmayeshes};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useAzmayesh;
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import {GET_TESTS_LIST} from "@/core/utils/routes";
|
|
||||||
import useRequest from "@/lib/hooks/useRequest";
|
|
||||||
|
|
||||||
const useTest = () => {
|
|
||||||
const requestServer = useRequest();
|
|
||||||
const [tests, setTests] = useState([]);
|
|
||||||
const [loadingTests, setLoadingTests] = useState(true);
|
|
||||||
const [errorTests, setErrorTests] = useState(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchTests = async () => {
|
|
||||||
try {
|
|
||||||
const response = await requestServer(`${GET_TESTS_LIST}`);
|
|
||||||
setTests(response.data.data);
|
|
||||||
setLoadingTests(false);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error fetching tests types:", e);
|
|
||||||
setErrorTests(e);
|
|
||||||
setLoadingTests(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchTests();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return {tests, loadingTests, errorTests};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useTest;
|
|
||||||
Reference in New Issue
Block a user