Merge branch 'release/v0.3.8'

This commit is contained in:
Amirhossein Mahmoodi
2024-07-14 15:41:00 +03:30
26 changed files with 758 additions and 762 deletions

View File

@@ -1,3 +1,3 @@
NEXT_PUBLIC_VERSION="0.3.3" NEXT_PUBLIC_VERSION="0.3.8"
NEXT_PUBLIC_API_URL="https://rms.witel.ir" NEXT_PUBLIC_API_URL="https://rms.witel.ir"
NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map" NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map"

View File

@@ -1,11 +1,8 @@
import WithAuthMiddleware from "@/core/middlewares/withAuth"; import WithAuthMiddleware from "@/core/middlewares/withAuth";
import { AuthProvider } from "@/lib/contexts/auth";
const Layout = ({ children }) => { const Layout = ({ children }) => {
return ( return (
<AuthProvider> <WithAuthMiddleware>{children}</WithAuthMiddleware>
<WithAuthMiddleware>{children}</WithAuthMiddleware>
</AuthProvider>
); );
}; };

View File

@@ -1,3 +1,4 @@
import { AuthProvider } from "@/lib/contexts/auth";
import { TableSettingProvider } from "@/lib/contexts/tableSetting"; import { TableSettingProvider } from "@/lib/contexts/tableSetting";
export const metadata = { export const metadata = {
@@ -8,7 +9,9 @@ export default function RootLayout({ children }) {
return ( return (
<html lang="fa" dir={"rtl"}> <html lang="fa" dir={"rtl"}>
<body style={{ height: "100vh", width: '100vw' }}> <body style={{ height: "100vh", width: '100vw' }}>
<TableSettingProvider>{children}</TableSettingProvider> <AuthProvider>
<TableSettingProvider>{children}</TableSettingProvider>
</AuthProvider>
</body> </body>
</html> </html>
); );

View File

@@ -1,12 +1,14 @@
"use client"; "use client";
import { GET_LOGIN_ROUTE } from "@/core/utils/routes"; import { GET_LOGIN_ROUTE } from "@/core/utils/routes";
import { useAuth } from "@/lib/contexts/auth";
import useRequest from "@/lib/hooks/useRequest"; import useRequest from "@/lib/hooks/useRequest";
import { Button, Stack, Typography, Zoom } from "@mui/material"; import { Button, Stack, Typography, Zoom } from "@mui/material";
import Link from "next/link"; import Link from "next/link";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
const Page = ({ searchParams }) => { const Page = ({ searchParams }) => {
const { getUser } = useAuth()
const { username } = searchParams; const { username } = searchParams;
const [login, setLogin] = useState(0); const [login, setLogin] = useState(0);
const request = useRequest(); const request = useRequest();
@@ -15,6 +17,7 @@ const Page = ({ searchParams }) => {
const login = async () => { const login = async () => {
try { try {
await request(`${GET_LOGIN_ROUTE}?username=${username}`); await request(`${GET_LOGIN_ROUTE}?username=${username}`);
await getUser()
setLogin(1); setLogin(1);
} catch (error) { } catch (error) {
setLogin(2); setLogin(2);
@@ -28,6 +31,7 @@ const Page = ({ searchParams }) => {
setLogin(0); setLogin(0);
try { try {
await request(`${GET_LOGIN_ROUTE}?username=${username}`); await request(`${GET_LOGIN_ROUTE}?username=${username}`);
await getUser()
setLogin(1); setLogin(1);
} catch (error) { } catch (error) {
setLogin(2); setLogin(2);
@@ -40,8 +44,8 @@ const Page = ({ searchParams }) => {
{login === 0 {login === 0
? "درحال دریافت مجوز برای ارتباط با سرور..." ? "درحال دریافت مجوز برای ارتباط با سرور..."
: login === 1 : login === 1
? "ارتباط با سرور برقرار شد." ? "ارتباط با سرور برقرار شد."
: "ارتباط با سرور برقرار نشد. مشکلی وجود دارد."} : "ارتباط با سرور برقرار نشد. مشکلی وجود دارد."}
</Typography> </Typography>
<Zoom in={login === 1}> <Zoom in={login === 1}>
<Button component={Link} href="/"> <Button component={Link} href="/">

View File

@@ -16,15 +16,15 @@ const Template = ({ children }) => {
scrollbarColor: `#155175 transparent`, scrollbarColor: `#155175 transparent`,
}, },
"*&::-webkit-scrollbar": { "*&::-webkit-scrollbar": {
width: "5px", width: "4px",
}, },
"*&::-webkit-scrollbar-track": { "*&::-webkit-scrollbar-track": {
boxShadow: "inset 0 0 5px #fff", boxShadow: "inset 0 0 5px #fff",
borderRadius: "5px", borderRadius: "4px",
}, },
"*&::-webkit-scrollbar-thumb": { "*&::-webkit-scrollbar-thumb": {
background: "#155175", background: "#155175",
borderRadius: "5px", borderRadius: "4px",
}, },
}} }}
/> />

View File

@@ -0,0 +1,46 @@
"use client";
import DialogTransition from "@/core/components/DialogTransition";
import { AddCircle, Close } from "@mui/icons-material";
import { Button, Dialog, DialogTitle, IconButton } from "@mui/material";
import CreateOrUpdateForm from "../../Forms/CreateOrUpdate";
import { SET_INQUIRE_PRIVACY_FENCING } from "@/core/utils/routes";
import { useState } from "react";
const InquiryPrivacyFencingCreate = ({ mutate }) => {
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<>
<Button variant="contained" color="primary2" startIcon={<AddCircle />} onClick={handleOpen}>
ایجاد پاسخ به استعلام
</Button>
<Dialog open={open} fullScreen TransitionComponent={DialogTransition}>
<DialogTitle sx={{ m: 0, p: 2, borderBottom: 1, borderColor: 'divider' }} id="create-dialog">
ایجاد پاسخ به استعلام
</DialogTitle>
<IconButton
aria-label="close"
onClick={handleClose}
sx={{
position: "absolute",
right: 8,
top: 8,
color: (theme) => theme.palette.grey[500],
}}
>
<Close />
</IconButton>
<CreateOrUpdateForm handleClose={handleClose} mutate={mutate} url={SET_INQUIRE_PRIVACY_FENCING} />
</Dialog>
</>
);
};
export default InquiryPrivacyFencingCreate;

View File

@@ -1,570 +0,0 @@
import LtrTextField from "@/core/components/LtrTextField";
import StyledForm from "@/core/components/StyledForm";
import { SET_INQUIRE_PRIVACY_FENCING } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
import { Autocomplete, Box, Button, Chip, DialogActions, DialogContent, Fade, Grid, InputAdornment, Stack, TextField, Typography } from "@mui/material";
import { DatePicker, LocalizationProvider, faIR } from "@mui/x-date-pickers";
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
import moment from "jalali-moment";
import { Controller, useForm } from "react-hook-form";
import LocationOnMap from "./LocationOnMap";
const CreateForm = ({ handleClose, mutate }) => {
const { control, watch, register, handleSubmit, setValue } = useForm({
defaultValues: {
dabirkhaneh_number: '',
nameh_date: moment(),
nameh_date_fa: '',
marjae_pasokh: '',
motaghazi_is_legal_id: null,
motaghazi_is_legal: '',
motaghazi_type_id: '',
motaghazi_type: null,
motaghazi_firstname: '',
motaghazi_lastname: '',
national_id: '',
shenase_melli: '',
tel_number: '',
mobile_number: '',
address: '',
edare_kol_id: null,
edare_kol: '',
edare_shahri_id: null,
edare_shahri: '',
rah_type_id: null,
rah_type: '',
name_mehvar_id: '',
name_mehvar_fa: null,
mizan_harim: null,
arze_navar: null,
samt_id: null,
samt: '',
kilometr: '',
lat: '',
lon: '',
zone: null,
karbari_type_id: null,
karbari_type: '',
tarh_title: '',
masahat_zirbana: '',
ehdasat_type_id: [],
ehdasat_type: '',
divarkeshi_distance: '',
mostahadesat_distance: '',
mahale_ejra_id: null,
mahale_ejra: '',
traffic_id: null,
traffic: '',
vaziat_eghtesadi_id: null,
vaziat_eghtesadi: '',
has_access_id: null,
has_access: '',
shomare_estelam_harim: '',
max_month: '',
max_day: '',
shomare_tahaodname: '',
shomare_daftarkhaneh: '',
description: '',
ronevesht: '',
}
});
const request = useRequest()
const onSubmit = async (data) => {
const formData = new FormData()
formData.append('dabirkhaneh_number', data.dabirkhaneh_number)
formData.append('nameh_date', data.nameh_date.format('YYYY-MM-DD'))
formData.append('nameh_date_fa', data.nameh_date)
formData.append('marjae_pasokh', data.marjae_pasokh)
formData.append('motaghazi_is_legal_id', data.motaghazi_is_legal_id)
formData.append('motaghazi_is_legal', data.motaghazi_is_legal_id)
formData.append('motaghazi_type_id', 1)
formData.append('motaghazi_type', data.motaghazi_type)
formData.append('motaghazi_firstname', data.motaghazi_firstname)
formData.append('motaghazi_lastname', data.motaghazi_lastname)
formData.append('national_id', data.national_id)
formData.append('shenase_melli', data.national_id)
formData.append('tel_number', data.tel_number)
formData.append('mobile_number', data.mobile_number)
formData.append('address', data.address)
formData.append('edare_kol_id', data.edare_kol_id)
formData.append('edare_kol', data.edare_kol_id)
formData.append('edare_shahri_id', data.edare_shahri_id)
formData.append('edare_shahri', data.edare_shahri_id)
formData.append('rah_type_id', data.rah_type_id)
formData.append('rah_type', data.rah_type_id)
formData.append('name_mehvar_id', 1)
formData.append('name_mehvar_fa', data.name_mehvar_id)
formData.append('mizan_harim', data.mizan_harim)
formData.append('arze_navar', data.arze_navar)
formData.append('samt_id', data.samt_id)
formData.append('samt', data.samt_id)
formData.append('kilometr', data.kilometr)
formData.append('lat', data.lat)
formData.append('lon', data.lon)
formData.append('zone', data.zone)
formData.append('karbari_type_id', data.karbari_type_id)
formData.append('karbari_type', data.karbari_type_id)
formData.append('tarh_title', data.tarh_title)
formData.append('masahat_zirbana', data.masahat_zirbana)
formData.append('ehdasat_type_id', data.ehdasat_type_id.join("|"))
formData.append('ehdasat_type', data.ehdasat_type_id.join("|"))
formData.append('divarkeshi_distance', data.divarkeshi_distance)
formData.append('mostahadesat_distance', data.mostahadesat_distance)
formData.append('mahale_ejra_id', data.mahale_ejra_id)
formData.append('mahale_ejra', data.mahale_ejra)
formData.append('traffic_id', data.traffic_id)
formData.append('traffic', data.traffic_id)
formData.append('vaziat_eghtesadi_id', data.vaziat_eghtesadi_id)
formData.append('vaziat_eghtesadi', data.vaziat_eghtesadi)
formData.append('has_access_id', data.has_access_id)
formData.append('has_access', data.has_access_id)
formData.append('shomare_estelam_harim', data.shomare_estelam_harim)
formData.append('max_month', data.max_month)
formData.append('max_day', data.max_day)
formData.append('shomare_tahaodname', data.shomare_tahaodname)
formData.append('shomare_daftarkhaneh', data.shomare_daftarkhaneh)
formData.append('description', data.description)
formData.append('ronevesht', data.ronevesht)
try {
await request(SET_INQUIRE_PRIVACY_FENCING, 'post', { data: formData })
handleClose()
mutate()
} catch (error) {
}
};
return (
<LocalizationProvider
dateAdapter={AdapterDateFnsJalali}
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
>
<DialogContent>
<StyledForm onSubmit={handleSubmit(onSubmit)} id={'InquiryPrivacyFencingCreateForm'}>
<Grid container columns={{ xs: 1, sm: 2, md: 3 }} spacing={4}>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('dabirkhaneh_number')} label="شماره دبیرخانه درخواست *" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<Controller
name="nameh_date"
control={control}
render={({ field: { onChange, value } }) => (
<DatePicker
value={value.toDate()}
onChange={(newValue) => onChange(moment(newValue))}
label="تاریخ نامه درخواست *"
slotProps={{
textField: { fullWidth: true, size: "small", autoComplete: 'off' },
}}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('marjae_pasokh')} label="مرجع درخواست کننده پاسخ به استعلام" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<Controller
name="motaghazi_is_legal_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["حقوقی", "حقیقی"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="متقاضی *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Fade in={watch('motaghazi_is_legal_id') === 'حقوقی'} mountOnEnter={true} unmountOnExit={true}>
<Box>
<Controller
name="motaghazi_type"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["دولتی", "خصوصی"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع متقاضی *" />}
/>
)}
/>
</Box>
</Fade>
</Grid>
<Grid item xs={1}></Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('motaghazi_firstname')} label="نام متقاضی *" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<Fade in={watch('motaghazi_is_legal_id') === 'حقیقی'} mountOnEnter={true} unmountOnExit={true}>
<TextField autoComplete="off" {...register('motaghazi_lastname')} label="نام خانوادگی متقاضی *" size="small" fullWidth />
</Fade>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('national_id')} label="کد ملی/شناسه ملی *" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('tel_number')} label="تلفن" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<Fade in={watch('motaghazi_type') !== 'دولتی' || watch('formik.values.motaghazi_is_legal_id') === 'حقیقی'} mountOnEnter={true} unmountOnExit={true}>
<LtrTextField autoComplete="off" {...register('mobile_number')} label="تلفن همراه *" size="small" fullWidth type="tel" />
</Fade>
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('address')} label="آدرس *" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<Controller
name="edare_kol_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["تهران"]}
renderInput={(params) => (
<TextField autoComplete="off"
fullWidth
{...params}
label="اداره كل راهداری و حمل و نقل جاده ای *"
/>
)}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="edare_shahri_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["تهران"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="اداره شهرستان *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="rah_type_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["آزاد راه", "بزرگراه", 'راه فرعی درجه 3']}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع راه *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="name_mehvar_fa"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["سایر"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نام محور *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Fade in={watch('name_mehvar_fa') === "سایر"} mountOnEnter={true} unmountOnExit={true}>
<TextField autoComplete="off" label="سایر محورها" size="small" fullWidth />
</Fade>
</Grid>
<Grid item xs={1}>
<Controller
name="samt_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["چپ", "راست"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="سمت *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="mizan_harim"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["12.5", "17.5"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="میزان حریم *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Fade in={watch('rah_type_id') !== 'راه فرعی درجه 3'} mountOnEnter={true} unmountOnExit={true}>
<Box>
<Controller
name="arze_navar"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["15", "30"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="عرض نوار تاسیساتی زیربنایی *" />}
/>
)}
/>
</Box>
</Fade>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('kilometr')} label="كيلومتر *" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1} sm={2} sx={{ height: 300 }}>
<LocationOnMap setValue={setValue} />
</Grid>
<Grid item xs={1}>
<Stack spacing={3}>
<LtrTextField autoComplete="off" {...register('lat')} label="عرض جغرافیایی" size="small" fullWidth disabled={true} />
<LtrTextField autoComplete="off" {...register('lon')} label="طول جغرافیایی" size="small" fullWidth disabled={true} />
<Controller
name="zone"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["38", "39"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="Zone *" />}
/>
)}
/>
</Stack>
</Grid>
<Grid item xs={1}>
<Controller
name="karbari_type_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["اتاقک نگهبانی", "دولتی"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع کاربری *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('tarh_title')} label="عنوان طرح *" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('masahat_zirbana')} label="مساحت زیربنا" size="small" fullWidth type="tel" InputProps={{
endAdornment: <InputAdornment position="end">
مترمربع</InputAdornment>,
}} />
</Grid>
<Grid item xs={1}>
<Controller
name="ehdasat_type_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
multiple
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
renderTags={(value, getTagProps) =>
value.map((option, index) => {
const { key, ...tagProps } = getTagProps({ index });
return (
<Chip label={option} key={key} size="small" {...tagProps} />
);
})
}
options={["تعمیرات", "احداث بنا"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع احداثات *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('divarkeshi_distance')} label="فاصله دیوارکشی از آکس محور" size="small" fullWidth type="tel" InputProps={{
endAdornment: <InputAdornment position="end">متر</InputAdornment>,
}} />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('mostahadesat_distance')} label="فاصله مستحدثات از آکس محور" size="small" fullWidth type="tel" InputProps={{
endAdornment: <InputAdornment position="end">متر</InputAdornment>,
}} />
</Grid>
<Grid item xs={1}>
<Controller
name="mahale_ejra_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["داخل حریم"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="محل اجرا" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="traffic_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["سبک (ضریب ۱)"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="میزان ترافیک *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="vaziat_eghtesadi_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["تست"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="وضعیت اقتصادی" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="has_access_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["بله", "خیر"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="آیا راه دسترسی از قبل وجود دارد؟ *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('shomare_estelam_harim')} label="شماره استعلام دفتر ایمنی و حریم" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<Stack direction={'row'} spacing={1} alignItems={'center'}>
<Typography sx={{ flex: 2 }} variant="body2">حداکثر مدت زمان شروع عملیات: *</Typography>
<LtrTextField autoComplete="off" {...register('max_month')} sx={{ width: 60 }} label="ماه" size="small" type="tel" />
<LtrTextField autoComplete="off" {...register('max_day')} sx={{ width: 60 }} label="روز" size="small" type="tel" />
</Stack>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('shomare_tahaodname')} label="شماره تعهدنامه" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('shomare_daftarkhaneh')} label="شماره دفترخانه" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}></Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('description')} multiline rows={2} label="توضیحات" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('ronevesht')} multiline rows={2} label="رونوشت" size="small" fullWidth />
</Grid>
<Grid item xs={1}></Grid>
</Grid>
</StyledForm>
</DialogContent>
<DialogActions sx={{ p: 2 }}>
<Button variant="contained" size="large" type="submit" form={'InquiryPrivacyFencingCreateForm'}>ثبت</Button>
</DialogActions>
</LocalizationProvider >
);
};
export default CreateForm;

View File

@@ -1,32 +0,0 @@
"use client";
import DialogTransition from "@/core/components/DialogTransition";
import { Close } from "@mui/icons-material";
import { Dialog, DialogTitle, IconButton } from "@mui/material";
import CreateForm from "./Form";
const InquiryPrivacyFencingCreate = ({ open, handleClose, mutate }) => {
return (
<>
<Dialog open={open} fullScreen TransitionComponent={DialogTransition}>
<DialogTitle sx={{ m: 0, p: 2 }} id="create-dialog">
ایجاد پاسخ به استعلام
</DialogTitle>
<IconButton
aria-label="close"
onClick={handleClose}
sx={{
position: "absolute",
right: 8,
top: 8,
color: (theme) => theme.palette.grey[500],
}}
>
<Close />
</IconButton>
<CreateForm handleClose={handleClose} mutate={mutate} />
</Dialog>
</>
);
};
export default InquiryPrivacyFencingCreate;

View File

@@ -0,0 +1,571 @@
import LtrTextField from "@/core/components/LtrTextField";
import StyledForm from "@/core/components/StyledForm";
import useRequest from "@/lib/hooks/useRequest";
import { Autocomplete, Box, Button, Chip, Container, DialogActions, DialogContent, Fade, Grid, InputAdornment, Stack, TextField, Typography } from "@mui/material";
import { DatePicker, LocalizationProvider, faIR } from "@mui/x-date-pickers";
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
import moment from "jalali-moment";
import { Controller, useForm } from "react-hook-form";
import LocationOnMap from "./LocationOnMap";
const initValues = {
dabirkhaneh_number: '',
nameh_date: moment(),
nameh_date_fa: '',
marjae_pasokh: '',
motaghazi_is_legal_id: null,
motaghazi_is_legal: '',
motaghazi_type_id: '',
motaghazi_type: null,
motaghazi_firstname: '',
motaghazi_lastname: '',
national_id: '',
shenase_melli: '',
tel_number: '',
mobile_number: '',
address: '',
edare_kol_id: null,
edare_kol: '',
edare_shahri_id: null,
edare_shahri: '',
rah_type_id: null,
rah_type: '',
name_mehvar_id: '',
name_mehvar_fa: null,
mizan_harim: null,
arze_navar: null,
samt_id: null,
samt: '',
kilometr: '',
lat: '',
lon: '',
zone: null,
karbari_type_id: null,
karbari_type: '',
tarh_title: '',
masahat_zirbana: '',
ehdasat_type_id: [],
ehdasat_type: '',
divarkeshi_distance: '',
mostahadesat_distance: '',
mahale_ejra_id: null,
mahale_ejra: '',
traffic_id: null,
traffic: '',
vaziat_eghtesadi_id: null,
vaziat_eghtesadi: '',
has_access_id: null,
has_access: '',
shomare_estelam_harim: '',
max_month: '',
max_day: '',
shomare_tahaodname: '',
shomare_daftarkhaneh: '',
description: '',
ronevesht: '',
}
const CreateOrUpdateForm = ({ handleClose, mutate, defaultValues, url }) => {
const request = useRequest()
const { control, watch, register, handleSubmit, setValue, formState: { isSubmitting } } = useForm({ defaultValues: defaultValues || initValues });
const onSubmit = async (data) => {
const formData = new FormData()
formData.append('dabirkhaneh_number', data.dabirkhaneh_number)
formData.append('nameh_date', data.nameh_date.format('YYYY-MM-DD'))
formData.append('nameh_date_fa', data.nameh_date)
formData.append('marjae_pasokh', data.marjae_pasokh)
formData.append('motaghazi_is_legal_id', data.motaghazi_is_legal_id)
formData.append('motaghazi_is_legal', data.motaghazi_is_legal_id)
formData.append('motaghazi_type_id', 1)
formData.append('motaghazi_type', data.motaghazi_type)
formData.append('motaghazi_firstname', data.motaghazi_firstname)
formData.append('motaghazi_lastname', data.motaghazi_lastname)
formData.append('national_id', data.national_id)
formData.append('shenase_melli', data.national_id)
formData.append('tel_number', data.tel_number)
formData.append('mobile_number', data.mobile_number)
formData.append('address', data.address)
formData.append('edare_kol_id', data.edare_kol_id)
formData.append('edare_kol', data.edare_kol_id)
formData.append('edare_shahri_id', data.edare_shahri_id)
formData.append('edare_shahri', data.edare_shahri_id)
formData.append('rah_type_id', data.rah_type_id)
formData.append('rah_type', data.rah_type_id)
formData.append('name_mehvar_id', 1)
formData.append('name_mehvar_fa', data.name_mehvar_id)
formData.append('mizan_harim', data.mizan_harim)
formData.append('arze_navar', data.arze_navar)
formData.append('samt_id', data.samt_id)
formData.append('samt', data.samt_id)
formData.append('kilometr', data.kilometr)
formData.append('lat', data.lat)
formData.append('lon', data.lon)
formData.append('zone', data.zone)
formData.append('karbari_type_id', data.karbari_type_id)
formData.append('karbari_type', data.karbari_type_id)
formData.append('tarh_title', data.tarh_title)
formData.append('masahat_zirbana', data.masahat_zirbana)
formData.append('ehdasat_type_id', data.ehdasat_type_id.join("|"))
formData.append('ehdasat_type', data.ehdasat_type_id.join("|"))
formData.append('divarkeshi_distance', data.divarkeshi_distance)
formData.append('mostahadesat_distance', data.mostahadesat_distance)
formData.append('mahale_ejra_id', data.mahale_ejra_id)
formData.append('mahale_ejra', data.mahale_ejra)
formData.append('traffic_id', data.traffic_id)
formData.append('traffic', data.traffic_id)
formData.append('vaziat_eghtesadi_id', data.vaziat_eghtesadi_id)
formData.append('vaziat_eghtesadi', data.vaziat_eghtesadi)
formData.append('has_access_id', data.has_access_id)
formData.append('has_access', data.has_access_id)
formData.append('shomare_estelam_harim', data.shomare_estelam_harim)
formData.append('max_month', data.max_month)
formData.append('max_day', data.max_day)
formData.append('shomare_tahaodname', data.shomare_tahaodname)
formData.append('shomare_daftarkhaneh', data.shomare_daftarkhaneh)
formData.append('description', data.description)
formData.append('ronevesht', data.ronevesht)
try {
await request(url, 'post', { data: formData })
handleClose()
mutate()
} catch (error) {
}
};
return (
<LocalizationProvider
dateAdapter={AdapterDateFnsJalali}
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
>
<DialogContent>
<Container maxWidth='lg'>
<StyledForm onSubmit={handleSubmit(onSubmit)} id={'InquiryPrivacyFencingCreateForm'}>
<Grid container columns={{ xs: 1, sm: 2, md: 3 }} spacing={4}>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('dabirkhaneh_number')} label="شماره دبیرخانه درخواست *" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<Controller
name="nameh_date"
control={control}
render={({ field: { onChange, value } }) => (
<DatePicker
value={value.toDate()}
onChange={(newValue) => onChange(moment(newValue))}
label="تاریخ نامه درخواست *"
slotProps={{
textField: { fullWidth: true, size: "small", autoComplete: 'off' },
}}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('marjae_pasokh')} label="مرجع درخواست کننده پاسخ به استعلام" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<Controller
name="motaghazi_is_legal_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["حقوقی", "حقیقی"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="متقاضی *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Fade in={watch('motaghazi_is_legal_id') === 'حقوقی'} mountOnEnter={true} unmountOnExit={true}>
<Box>
<Controller
name="motaghazi_type"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["دولتی", "خصوصی"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع متقاضی *" />}
/>
)}
/>
</Box>
</Fade>
</Grid>
<Grid item xs={1}></Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('motaghazi_firstname')} label="نام متقاضی *" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<Fade in={watch('motaghazi_is_legal_id') === 'حقیقی'} mountOnEnter={true} unmountOnExit={true}>
<TextField autoComplete="off" {...register('motaghazi_lastname')} label="نام خانوادگی متقاضی *" size="small" fullWidth />
</Fade>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('national_id')} label="کد ملی/شناسه ملی *" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('tel_number')} label="تلفن" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<Fade in={watch('motaghazi_type') !== 'دولتی' || watch('formik.values.motaghazi_is_legal_id') === 'حقیقی'} mountOnEnter={true} unmountOnExit={true}>
<LtrTextField autoComplete="off" {...register('mobile_number')} label="تلفن همراه *" size="small" fullWidth type="tel" />
</Fade>
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('address')} label="آدرس *" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<Controller
name="edare_kol_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["تهران"]}
renderInput={(params) => (
<TextField autoComplete="off"
fullWidth
{...params}
label="اداره كل راهداری و حمل و نقل جاده ای *"
/>
)}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="edare_shahri_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["تهران"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="اداره شهرستان *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="rah_type_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["آزاد راه", "بزرگراه", 'راه فرعی درجه 3']}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع راه *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="name_mehvar_fa"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["سایر"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نام محور *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Fade in={watch('name_mehvar_fa') === "سایر"} mountOnEnter={true} unmountOnExit={true}>
<TextField autoComplete="off" label="سایر محورها" size="small" fullWidth />
</Fade>
</Grid>
<Grid item xs={1}>
<Controller
name="samt_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["چپ", "راست"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="سمت *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="mizan_harim"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["12.5", "17.5"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="میزان حریم *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Fade in={watch('rah_type_id') !== 'راه فرعی درجه 3'} mountOnEnter={true} unmountOnExit={true}>
<Box>
<Controller
name="arze_navar"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["15", "30"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="عرض نوار تاسیساتی زیربنایی *" />}
/>
)}
/>
</Box>
</Fade>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('kilometr')} label="كيلومتر *" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1} sm={2} sx={{ height: 300 }}>
<LocationOnMap setValue={setValue} defaultLatLon={defaultValues ? [defaultValues.lat, defaultValues.lon] : null} defaultValues />
</Grid>
<Grid item xs={1}>
<Stack spacing={3}>
<LtrTextField autoComplete="off" {...register('lat')} label="عرض جغرافیایی" size="small" fullWidth disabled={true} />
<LtrTextField autoComplete="off" {...register('lon')} label="طول جغرافیایی" size="small" fullWidth disabled={true} />
<Controller
name="zone"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["38", "39"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="Zone *" />}
/>
)}
/>
</Stack>
</Grid>
<Grid item xs={1}>
<Controller
name="karbari_type_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["اتاقک نگهبانی", "دولتی"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع کاربری *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('tarh_title')} label="عنوان طرح *" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('masahat_zirbana')} label="مساحت زیربنا" size="small" fullWidth type="tel" InputProps={{
endAdornment: <InputAdornment position="end">
مترمربع</InputAdornment>,
}} />
</Grid>
<Grid item xs={1}>
<Controller
name="ehdasat_type_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
multiple
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
renderTags={(value, getTagProps) =>
value.map((option, index) => {
const { key, ...tagProps } = getTagProps({ index });
return (
<Chip label={option} key={key} size="small" sx={{ '&.MuiAutocomplete-tag': { my: 0 } }} {...tagProps} />
);
})
}
options={["تعمیرات", "احداث بنا"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="نوع احداثات *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('divarkeshi_distance')} label="فاصله دیوارکشی از آکس محور" size="small" fullWidth type="tel" InputProps={{
endAdornment: <InputAdornment position="end">متر</InputAdornment>,
}} />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('mostahadesat_distance')} label="فاصله مستحدثات از آکس محور" size="small" fullWidth type="tel" InputProps={{
endAdornment: <InputAdornment position="end">متر</InputAdornment>,
}} />
</Grid>
<Grid item xs={1}>
<Controller
name="mahale_ejra_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["داخل حریم"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="محل اجرا" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="traffic_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["سبک (ضریب ۱)"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="میزان ترافیک *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="vaziat_eghtesadi_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["تست"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="وضعیت اقتصادی" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<Controller
name="has_access_id"
control={control}
render={({ field: { onChange, value } }) => (
<Autocomplete
size="small"
disablePortal
value={value}
onChange={(event, newValue) => {
onChange(newValue)
}}
options={["بله", "خیر"]}
renderInput={(params) => <TextField autoComplete="off" fullWidth {...params} label="آیا راه دسترسی از قبل وجود دارد؟ *" />}
/>
)}
/>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('shomare_estelam_harim')} label="شماره استعلام دفتر ایمنی و حریم" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<Stack direction={'row'} spacing={1} alignItems={'center'}>
<Typography sx={{ flex: 2 }} variant="body2">حداکثر مدت زمان شروع عملیات: *</Typography>
<LtrTextField autoComplete="off" {...register('max_month')} sx={{ width: 60 }} label="ماه" size="small" type="tel" />
<LtrTextField autoComplete="off" {...register('max_day')} sx={{ width: 60 }} label="روز" size="small" type="tel" />
</Stack>
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('shomare_tahaodname')} label="شماره تعهدنامه" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}>
<LtrTextField autoComplete="off" {...register('shomare_daftarkhaneh')} label="شماره دفترخانه" size="small" fullWidth type="tel" />
</Grid>
<Grid item xs={1}></Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('description')} multiline rows={2} label="توضیحات" size="small" fullWidth />
</Grid>
<Grid item xs={1}>
<TextField autoComplete="off" {...register('ronevesht')} multiline rows={2} label="رونوشت" size="small" fullWidth />
</Grid>
<Grid item xs={1}></Grid>
</Grid>
</StyledForm>
</Container>
</DialogContent>
<DialogActions sx={{ p: 2, borderTop: 1, borderColor: 'divider' }}>
<Button variant="contained" size="large" sx={{ width: 150 }} type="submit" form={'InquiryPrivacyFencingCreateForm'} disabled={isSubmitting}>ثبت</Button>
</DialogActions>
</LocalizationProvider >
);
};
export default CreateOrUpdateForm;

View File

@@ -9,7 +9,7 @@ const locationMarker = L.icon({
iconAnchor: [25, 50], iconAnchor: [25, 50],
}); });
const MarkerLocation = ({ setValue }) => { const MarkerLocation = ({ setValue, defaultLatLon }) => {
const location = useRef(); const location = useRef();
const map = useMapEvents({ const map = useMapEvents({
move: (e) => { move: (e) => {
@@ -25,8 +25,9 @@ const MarkerLocation = ({ setValue }) => {
setValue('lon', latlon.lng) setValue('lon', latlon.lng)
}, },
}); });
return ( return (
<Marker ref={location} icon={locationMarker} position={map.getCenter()} key="location" /> <Marker ref={location} icon={locationMarker} position={defaultLatLon ? L.LatLng(defaultLatLon.lat, defaultLatLon.lon) : map.getCenter()} key="location" />
) )
} }
export default MarkerLocation export default MarkerLocation

View File

@@ -1,20 +1,19 @@
import MapLoading from "@/core/components/MapLayer/Loading"; import MapLoading from "@/core/components/MapLayer/Loading";
import MarkerLocation from "@/core/components/MapLayer/MarkerLocation";
import { Paper, Stack } from "@mui/material"; import { Paper, Stack } from "@mui/material";
import { useFormikContext } from "formik";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import MarkerLocation from "./MarkerLocation";
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), { const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
loading: () => <MapLoading />, loading: () => <MapLoading />,
ssr: false, ssr: false,
}); });
const LocationOnMap = ({ setValue }) => { const LocationOnMap = ({ setValue, defaultLatLon }) => {
return ( return (
<Stack sx={{ height: "100%", position: "relative" }}> <Stack sx={{ height: "100%", position: "relative" }}>
<Paper sx={{ flexGrow: 1, border: 1, borderRadius: 1, borderColor: 'divider' }} elevation={0}> <Paper sx={{ flexGrow: 1, border: 1, borderRadius: 1, borderColor: 'divider' }} elevation={0}>
<MapLayer style={{ borderRadius: '4px' }}> <MapLayer style={{ borderRadius: '4px' }}>
<MarkerLocation setValue={setValue} /> <MarkerLocation setValue={setValue} defaultLatLon={defaultLatLon} />
</MapLayer> </MapLayer>
</Paper> </Paper>
</Stack> </Stack>

View File

@@ -1,25 +1,10 @@
import { Button } from "@mui/material"; import InquiryPrivacyFencingCreate from "./Actions/Create";
import AddCircleIcon from "@mui/icons-material/AddCircle";
import { useState } from "react";
import InquiryPrivacyFencingCreate from "@/components/dashboard/inquiryPrivacyFencing/Create";
const Toolbar = ({ mutate }) => { const Toolbar = ({ mutate }) => {
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return ( return (
<> <>
<Button variant="contained" color="primary2" startIcon={<AddCircleIcon />} onClick={handleOpen}> <InquiryPrivacyFencingCreate mutate={mutate} />
ایجاد پاسخ به استعلام
</Button>
<InquiryPrivacyFencingCreate open={open} handleClose={handleClose} mutate={mutate} />
</> </>
); );
}; };

View File

@@ -85,13 +85,12 @@ const HeaderWithSidebar = ({ children }) => {
width: drawerWidth, width: drawerWidth,
flexShrink: 0, flexShrink: 0,
"& .MuiDrawer-paper": { "& .MuiDrawer-paper": {
height: "-webkit-fill-available",
overflow: "hidden", overflow: "hidden",
width: drawerWidth, width: drawerWidth,
boxSizing: "border-box", boxSizing: "border-box",
borderTop: 1, borderTop: 1,
borderTopColor: "divider", borderTopColor: "divider",
top: "unset", position: 'inherit'
}, },
}} }}
variant="persistent" variant="persistent"

View File

@@ -11,15 +11,14 @@ import useSWR from "swr";
const DataTable_Main = (props) => { const DataTable_Main = (props) => {
const request = useRequest(); const request = useRequest();
const isEmptyObject = (obj) => obj && Object.keys(obj).length === 0 && obj.constructor === Object; const isEmptyObject = (obj) => obj && Object.keys(obj).length === 0 && obj.constructor === Object;
const { filterData, sortData, setSortData } = useDataTable(); const { filterData, sortData, setSortData, hideData, setHideData } = useDataTable();
const { need_filter, table_url, user_id, page_name, table_name, columns, initialStateProps, TableToolbar } = props; const { need_filter, table_url, user_id, page_name, table_name, columns, initialStateProps, TableToolbar } = props;
const flatColumns = flattenArrayOfObjects(columns, "columns"); const flatColumns = flattenArrayOfObjects(columns, "columns");
const { settingStore, hideAction } = useTableSetting(); const { settingStore, hideAction } = useTableSetting();
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
const onColumnVisibilityChange = (event) => { const onColumnVisibilityChange = (event) => {
const settingValue = event(); setHideData(event);
hideAction(user_id, page_name, table_name, settingValue, flatColumns);
}; };
const onSortingChange = (event) => { const onSortingChange = (event) => {
@@ -57,13 +56,13 @@ const DataTable_Main = (props) => {
data: data?.data ?? [], data: data?.data ?? [],
initialState: { initialState: {
density: "compact", density: "compact",
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"], columnVisibility: hideData,
sorting: sortData, sorting: sortData,
...initialStateProps, ...initialStateProps,
}, },
state: { state: {
showProgressBars: isValidating, showProgressBars: isValidating,
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"], columnVisibility: hideData,
sorting: sortData, sorting: sortData,
pagination, pagination,
}, },

View File

@@ -22,7 +22,7 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
enableColumnPinning, enableColumnPinning,
enableGrouping, enableGrouping,
layoutMode, layoutMode,
mrtTheme: { draggingBorderColor }, mrtTheme: { draggingBorderColor, baseBackgroundColor },
muiSkeletonProps, muiSkeletonProps,
muiTableBodyCellProps, muiTableBodyCellProps,
}, },
@@ -83,10 +83,10 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
const borderStyle = showResizeBorder const borderStyle = showResizeBorder
? `2px solid ${draggingBorderColor} !important` ? `2px solid ${draggingBorderColor} !important`
: isDraggingColumn || isDraggingRow : isDraggingColumn || isDraggingRow
? `1px dashed ${theme.palette.grey[500]} !important` ? `1px dashed ${theme.palette.grey[500]} !important`
: isHoveredColumn || isHoveredRow || isResizingColumn : isHoveredColumn || isHoveredRow || isResizingColumn
? `2px dashed ${draggingBorderColor} !important` ? `2px dashed ${draggingBorderColor} !important`
: undefined; : undefined;
if (showResizeBorder) { if (showResizeBorder) {
return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle }; return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle };
@@ -94,18 +94,18 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
return borderStyle return borderStyle
? { ? {
borderBottom: borderBottom:
isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn) ? borderStyle : undefined, isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn) ? borderStyle : undefined,
borderLeft: borderLeft:
isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isFirstColumn) isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isFirstColumn)
? borderStyle ? borderStyle
: undefined, : undefined,
borderRight: borderRight:
isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isLastColumn) isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isLastColumn)
? borderStyle ? borderStyle
: undefined, : undefined,
borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined, borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined,
} }
: undefined; : undefined;
}, [columnSizingInfo.isResizingColumn, draggingColumn, draggingRow, hoveredColumn, hoveredRow, staticRowIndex]); }, [columnSizingInfo.isResizingColumn, draggingColumn, draggingRow, hoveredColumn, hoveredRow, staticRowIndex]);
@@ -179,8 +179,8 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
"&:hover": { "&:hover": {
outline: outline:
actionCell?.id === cell.id || actionCell?.id === cell.id ||
(editDisplayMode === "cell" && isEditable) || (editDisplayMode === "cell" && isEditable) ||
(editDisplayMode === "table" && (isCreating || isEditing)) (editDisplayMode === "table" && (isCreating || isEditing))
? `1px solid ${theme.palette.grey[500]}` ? `1px solid ${theme.palette.grey[500]}`
: undefined, : undefined,
textOverflow: "clip", textOverflow: "clip",
@@ -189,8 +189,8 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
cursor: isRightClickable cursor: isRightClickable
? "context-menu" ? "context-menu"
: isEditable && editDisplayMode === "cell" : isEditable && editDisplayMode === "cell"
? "pointer" ? "pointer"
: "inherit", : "inherit",
outline: actionCell?.id === cell.id ? `1px solid ${theme.palette.grey[500]}` : undefined, outline: actionCell?.id === cell.id ? `1px solid ${theme.palette.grey[500]}` : undefined,
outlineOffset: "-1px", outlineOffset: "-1px",
overflow: "hidden", overflow: "hidden",
@@ -200,12 +200,12 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
? "0 0.5rem" ? "0 0.5rem"
: "0.5rem" : "0.5rem"
: density === "comfortable" : density === "comfortable"
? columnDefType === "display" ? columnDefType === "display"
? "0.5rem 0.75rem" ? "0.5rem 0.75rem"
: "1rem" : "1rem"
: columnDefType === "display" : columnDefType === "display"
? "1rem 1.25rem" ? "1rem 1.25rem"
: "1.5rem", : "1.5rem",
textOverflow: columnDefType !== "display" ? "ellipsis" : undefined, textOverflow: columnDefType !== "display" ? "ellipsis" : undefined,
whiteSpace: row.getIsPinned() || density === "compact" ? "nowrap" : "normal", whiteSpace: row.getIsPinned() || density === "compact" ? "nowrap" : "normal",
@@ -216,6 +216,7 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
theme, theme,
}), }),
...draggingBorders, ...draggingBorders,
backgroundColor: baseBackgroundColor
})} })}
> >
{tableCellProps.children ?? ( {tableCellProps.children ?? (
@@ -225,8 +226,8 @@ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, sta
) : showSkeletons !== false && (isLoading || showSkeletons) ? ( ) : showSkeletons !== false && (isLoading || showSkeletons) ? (
<Skeleton animation="wave" height={20} width={skeletonWidth} {...skeletonProps} /> <Skeleton animation="wave" height={20} width={skeletonWidth} {...skeletonProps} />
) : columnDefType === "display" && ) : columnDefType === "display" &&
(["mrt-row-expand", "mrt-row-numbers", "mrt-row-select"].includes(column.id) || (["mrt-row-expand", "mrt-row-numbers", "mrt-row-select"].includes(column.id) ||
!row.getIsGrouped()) ? ( !row.getIsGrouped()) ? (
columnDef.Cell?.({ columnDef.Cell?.({
cell, cell,
column, column,

View File

@@ -91,16 +91,16 @@ const DataTable_TableBodyRow = ({
const cellHighlightColor = isRowSelected const cellHighlightColor = isRowSelected
? selectedRowBackgroundColor ? selectedRowBackgroundColor
: isRowPinned : isRowPinned
? pinnedRowBackgroundColor ? pinnedRowBackgroundColor
: undefined; : undefined;
const cellHighlightColorHover = const cellHighlightColorHover =
tableRowProps?.hover !== false tableRowProps?.hover !== false
? isRowSelected ? isRowSelected
? cellHighlightColor ? cellHighlightColor
: theme.palette.mode === "dark" : theme.palette.mode === "dark"
? `${lighten(baseBackgroundColor, 0.3)}` ? `${lighten(baseBackgroundColor, 0.2)}`
: `${darken(baseBackgroundColor, 0.3)}` : `${darken(baseBackgroundColor, 0.2)}`
: undefined; : undefined;
return ( return (
@@ -126,11 +126,10 @@ const DataTable_TableBodyRow = ({
sx={(theme) => ({ sx={(theme) => ({
"&:hover td:after": cellHighlightColorHover "&:hover td:after": cellHighlightColorHover
? { ? {
backgroundColor: alpha(cellHighlightColorHover, 0.3), backgroundColor: alpha(cellHighlightColorHover, 0.3),
...commonCellBeforeAfterStyles, ...commonCellBeforeAfterStyles,
} }
: undefined, : undefined,
backgroundColor: `${baseBackgroundColor} !important`,
bottom: bottom:
!virtualRow && bottomPinnedIndex !== undefined && isRowPinned !virtualRow && bottomPinnedIndex !== undefined && isRowPinned
? `${bottomPinnedIndex * rowHeight + (enableStickyFooter ? tableFooterHeight - 1 : 0)}px` ? `${bottomPinnedIndex * rowHeight + (enableStickyFooter ? tableFooterHeight - 1 : 0)}px`
@@ -141,25 +140,24 @@ const DataTable_TableBodyRow = ({
position: virtualRow position: virtualRow
? "absolute" ? "absolute"
: rowPinningDisplayMode?.includes("sticky") && isRowPinned : rowPinningDisplayMode?.includes("sticky") && isRowPinned
? "sticky" ? "sticky"
: "relative", : "relative",
td: { td: {
...getCommonPinnedCellStyles({ table, theme }), ...getCommonPinnedCellStyles({ table, theme }),
}, },
"td:after": cellHighlightColor "td:after": cellHighlightColor
? { ? {
backgroundColor: cellHighlightColor, backgroundColor: cellHighlightColor,
...commonCellBeforeAfterStyles, ...commonCellBeforeAfterStyles,
} }
: undefined, : undefined,
top: virtualRow top: virtualRow
? 0 ? 0
: topPinnedIndex !== undefined && isRowPinned : topPinnedIndex !== undefined && isRowPinned
? `${ ? `${topPinnedIndex * rowHeight +
topPinnedIndex * rowHeight + (enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0)
(enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0)
}px` }px`
: undefined, : undefined,
transition: virtualRow ? "none" : "all 150ms ease-in-out", transition: virtualRow ? "none" : "all 150ms ease-in-out",
width: "100%", width: "100%",
zIndex: rowPinningDisplayMode?.includes("sticky") && isRowPinned ? 2 : 0, zIndex: rowPinningDisplayMode?.includes("sticky") && isRowPinned ? 2 : 0,
@@ -183,11 +181,11 @@ const DataTable_TableBodyRow = ({
}; };
return cell ? ( return cell ? (
memoMode === "cells" && memoMode === "cells" &&
cell.column.columnDef.columnDefType === "data" && cell.column.columnDef.columnDefType === "data" &&
!draggingColumn && !draggingColumn &&
!draggingRow && !draggingRow &&
editingCell?.id !== cell.id && editingCell?.id !== cell.id &&
editingRow?.id !== row.id ? ( editingRow?.id !== row.id ? (
<Memo_DataTable_TableBodyCell key={cell.id} {...props} /> <Memo_DataTable_TableBodyCell key={cell.id} {...props} />
) : ( ) : (
<DataTable_TableBodyCell key={cell.id} {...props} /> <DataTable_TableBodyCell key={cell.id} {...props} />

View File

@@ -4,7 +4,7 @@ import { Box, TableCell } from "@mui/material";
import { MRT_TableHeadCellSortLabel } from "material-react-table"; import { MRT_TableHeadCellSortLabel } from "material-react-table";
import { useMemo } from "react"; import { useMemo } from "react";
const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex, table, ...rest }) => { const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex, backgroundColor, table, ...rest }) => {
const theme = useTheme(); const theme = useTheme();
const { const {
getState, getState,
@@ -67,20 +67,20 @@ const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex,
const borderStyle = showResizeBorder const borderStyle = showResizeBorder
? `2px solid ${draggingBorderColor} !important` ? `2px solid ${draggingBorderColor} !important`
: draggingColumn?.id === column.id : draggingColumn?.id === column.id
? `1px dashed ${theme.palette.grey[500]}` ? `1px dashed ${theme.palette.grey[500]}`
: hoveredColumn?.id === column.id : hoveredColumn?.id === column.id
? `2px dashed ${draggingBorderColor}` ? `2px dashed ${draggingBorderColor}`
: undefined; : undefined;
if (showResizeBorder) { if (showResizeBorder) {
return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle }; return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle };
} }
const draggingBorders = borderStyle const draggingBorders = borderStyle
? { ? {
borderLeft: borderStyle, borderLeft: borderStyle,
borderRight: borderStyle, borderRight: borderStyle,
borderTop: borderStyle, borderTop: borderStyle,
} }
: undefined; : undefined;
return draggingBorders; return draggingBorders;
@@ -151,19 +151,19 @@ const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex,
density === "compact" density === "compact"
? "0.5rem" ? "0.5rem"
: density === "comfortable" : density === "comfortable"
? columnDefType === "display" ? columnDefType === "display"
? "0.75rem" ? "0.75rem"
: "1rem" : "1rem"
: columnDefType === "display" : columnDefType === "display"
? "1rem 1.25rem" ? "1rem 1.25rem"
: "1.5rem", : "1.5rem",
pb: columnDefType === "display" ? 0 : showColumnFilters || density === "compact" ? "0.4rem" : "0.6rem", pb: columnDefType === "display" ? 0 : showColumnFilters || density === "compact" ? "0.4rem" : "0.6rem",
pt: pt:
columnDefType === "group" || density === "compact" columnDefType === "group" || density === "compact"
? "0.25rem" ? "0.25rem"
: density === "comfortable" : density === "comfortable"
? ".75rem" ? ".75rem"
: "1.25rem", : "1.25rem",
userSelect: enableMultiSort && column.getCanSort() ? "none" : undefined, userSelect: enableMultiSort && column.getCanSort() ? "none" : undefined,
verticalAlign: "middle", verticalAlign: "middle",
...getCommonMRTCellStyles({ ...getCommonMRTCellStyles({
@@ -174,6 +174,7 @@ const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex,
theme, theme,
}), }),
...draggingBorders, ...draggingBorders,
backgroundColor: backgroundColor,
})} })}
> >
{tableCellProps.children ?? ( {tableCellProps.children ?? (
@@ -187,8 +188,8 @@ const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex,
columnDefType === "group" || tableCellProps?.align === "center" columnDefType === "group" || tableCellProps?.align === "center"
? "center" ? "center"
: column.getCanResize() : column.getCanResize()
? "space-between" ? "space-between"
: "flex-start", : "flex-start",
position: "relative", position: "relative",
width: "100%", width: "100%",
}} }}
@@ -217,14 +218,18 @@ const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex,
textAlign: "start", textAlign: "start",
color: "#fff", color: "#fff",
fontWeight: "400", fontWeight: "400",
whiteSpace: (columnDef.header?.length ?? 0) < 20 ? "nowrap" : "normal", whiteSpace: "nowrap"
}} }}
> >
{HeaderElement} {HeaderElement}
</Box> </Box>
{column.getCanSort() && columnDefType !== "group" && ( {column.getCanSort() && columnDefType !== "group" && (
<MRT_TableHeadCellSortLabel <MRT_TableHeadCellSortLabel
sx={{ width: 20, color: "#fff" }} sx={{
width: 20, '& .MuiTableSortLabel-icon': {
color: `#fff !important`,
}
}}
header={header} header={header}
table={table} table={table}
/> />

View File

@@ -25,7 +25,6 @@ const DataTable_TableHeadRow = ({
sx: (theme) => ({ sx: (theme) => ({
// Access theme from the sx function // Access theme from the sx function
...(parseFromValuesOrFunc(muiTableHeadRowProps?.sx, theme) || {}), ...(parseFromValuesOrFunc(muiTableHeadRowProps?.sx, theme) || {}),
backgroundColor, // Apply background color
display: layoutMode?.startsWith("grid") ? "flex" : undefined, display: layoutMode?.startsWith("grid") ? "flex" : undefined,
position: enableStickyHeader && layoutMode === "semantic" ? "sticky" : "relative", position: enableStickyHeader && layoutMode === "semantic" ? "sticky" : "relative",
top: 0, top: 0,
@@ -44,6 +43,7 @@ const DataTable_TableHeadRow = ({
<DataTable_TableHeadCell <DataTable_TableHeadCell
columnVirtualizer={columnVirtualizer} columnVirtualizer={columnVirtualizer}
header={header} header={header}
backgroundColor={backgroundColor}
key={header.id} key={header.id}
staticColumnIndex={staticColumnIndex} staticColumnIndex={staticColumnIndex}
table={table} table={table}

View File

@@ -51,7 +51,7 @@ const DataTable_TopToolbar = ({ mutate, need_filter, table, columns, table_url,
display: "flex", display: "flex",
gap: "0.5rem", gap: "0.5rem",
justifyContent: "space-between", justifyContent: "space-between",
p: "0.5rem", py: "0.5rem",
position: stackAlertBanner ? "relative" : "absolute", position: stackAlertBanner ? "relative" : "absolute",
right: 0, right: 0,
top: 0, top: 0,

View File

@@ -6,8 +6,8 @@ import DownloadIcon from "@mui/icons-material/Download";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import useTableSetting from "@/lib/hooks/useTableSetting"; import useTableSetting from "@/lib/hooks/useTableSetting";
function AskForKeepData({ filterData, sortData, user_id, page_name, table_name, columns }) { function AskForKeepData({ filterData, sortData, hideData, user_id, page_name, table_name, columns }) {
const { filterAction, sortAction } = useTableSetting(); const { filterAction, sortAction, hideAction } = useTableSetting();
const onSaveFilter = () => { const onSaveFilter = () => {
const filteredItems = Object.keys(filterData) const filteredItems = Object.keys(filterData)
@@ -25,8 +25,8 @@ function AskForKeepData({ filterData, sortData, user_id, page_name, table_name,
}) })
.filter(Boolean); .filter(Boolean);
filterAction(user_id, page_name, table_name, filteredItems, columns); filterAction(user_id, page_name, table_name, filteredItems, columns);
sortAction(user_id, page_name, table_name, sortData, columns); sortAction(user_id, page_name, table_name, sortData, columns);
hideAction(user_id, page_name, table_name, hideData, columns);
toast.dismiss({ containerId: "datatable" }); toast.dismiss({ containerId: "datatable" });
}; };

View File

@@ -16,9 +16,10 @@ const errorServer = (response, notification, toastContainer) => {
if (notification) errorServerToast(toastContainer); if (notification) errorServerToast(toastContainer);
}; };
const errorClient = (response, notification, toastContainer) => { const errorClient = (response, notification, toastContainer, logout) => {
switch (response.status) { switch (response.status) {
case 401: case 401:
logout()
if (notification) errorUnauthorizedToast(toastContainer); if (notification) errorUnauthorizedToast(toastContainer);
break; break;
case 422: case 422:
@@ -50,11 +51,11 @@ const errorClient = (response, notification, toastContainer) => {
} }
}; };
export const errorResponse = (response, notification, toastContainer) => { export const errorResponse = (response, notification, toastContainer, logout) => {
if (notification) toast.dismiss({ container: toastContainer }); if (notification) toast.dismiss({ container: toastContainer });
if (isServerError(response.status)) { if (isServerError(response.status)) {
errorServer(response, notification, toastContainer); errorServer(response, notification, toastContainer);
} else if (isClientError(response.status)) { } else if (isClientError(response.status)) {
errorClient(response, notification, toastContainer); errorClient(response, notification, toastContainer, logout);
} }
}; };

View File

@@ -1,7 +1,5 @@
const api = process.env.NEXT_PUBLIC_API_URL; const api = process.env.NEXT_PUBLIC_API_URL;
export const GET_CSRF = api + "/csrf";
export const GET_USER_ROUTE = api + "/webapi/user/get-permission"; export const GET_USER_ROUTE = api + "/webapi/user/get-permission";
export const GET_LOGIN_ROUTE = api + "/login_dev"; export const GET_LOGIN_ROUTE = api + "/login_dev";
export const GET_INQUIRY_PRIVACY_FENCING_ROUTE = api + "/api/v3/harim/divarkeshi"; export const GET_INQUIRY_PRIVACY_FENCING_ROUTE = api + "/api/v3/harim/divarkeshi";

View File

@@ -11,9 +11,11 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns }
const [isInitStates, setInitStates] = useState(false); const [isInitStates, setInitStates] = useState(false);
const flatColumns = flattenArrayOfObjects(columns, "columns"); const flatColumns = flattenArrayOfObjects(columns, "columns");
const [initFilter, setInitFilter] = useState({}); const [initFilter, setInitFilter] = useState({});
const [initSort, setInitSort] = useState([]);
const [filterData, setFilterData] = useState({}); const [filterData, setFilterData] = useState({});
const [initSort, setInitSort] = useState([]);
const [sortData, setSortData] = useState([]); const [sortData, setSortData] = useState([]);
const [initHide, setInitHide] = useState({});
const [hideData, setHideData] = useState({});
useEffect(() => { useEffect(() => {
if (!settingStore) return; if (!settingStore) return;
@@ -47,22 +49,26 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns }
return acc; return acc;
}, {}); }, {});
setFilterData(values); setFilterData(values);
setSortData(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []);
setInitFilter(values); setInitFilter(values);
setSortData(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []);
setInitSort(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []); setInitSort(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []);
setHideData(settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"] || {});
setInitHide(settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"] || {});
setInitStates(true); setInitStates(true);
}, [settingStore, isInitStates]); }, [settingStore, isInitStates]);
useEffect(() => { useEffect(() => {
if ( if (
JSON.stringify(initFilter) !== JSON.stringify(filterData) || JSON.stringify(initFilter) !== JSON.stringify(filterData) ||
JSON.stringify(initSort) !== JSON.stringify(sortData) JSON.stringify(initSort) !== JSON.stringify(sortData) ||
JSON.stringify(initHide) !== JSON.stringify(hideData)
) { ) {
if (!toast.isActive("keep_data", "filtering")) { if (!toast.isActive("keep_data", "filtering")) {
toast( toast(
<AskForKeepData <AskForKeepData
filterData={filterData} filterData={filterData}
sortData={sortData} sortData={sortData}
hideData={hideData}
user_id={user_id} user_id={user_id}
page_name={page_name} page_name={page_name}
table_name={table_name} table_name={table_name}
@@ -85,6 +91,7 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns }
<AskForKeepData <AskForKeepData
filterData={filterData} filterData={filterData}
sortData={sortData} sortData={sortData}
hideData={hideData}
user_id={user_id} user_id={user_id}
page_name={page_name} page_name={page_name}
table_name={table_name} table_name={table_name}
@@ -96,12 +103,12 @@ const DataTableProvider = ({ children, user_id, page_name, table_name, columns }
} else { } else {
toast.dismiss({ containerId: "datatable" }); toast.dismiss({ containerId: "datatable" });
} }
}, [filterData, sortData]); }, [filterData, sortData, hideData]);
if (!isInitStates) return null; if (!isInitStates) return null;
return ( return (
<DataTableContext.Provider value={{ filterData, setFilterData, sortData, setSortData }}> <DataTableContext.Provider value={{ filterData, setFilterData, sortData, setSortData, hideData, setHideData }}>
{children} {children}
</DataTableContext.Provider> </DataTableContext.Provider>
); );

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import { createContext, useCallback, useContext, useEffect, useReducer } from "react";
import useRequest from "../hooks/useRequest";
import { GET_USER_ROUTE } from "@/core/utils/routes"; import { GET_USER_ROUTE } from "@/core/utils/routes";
import axios from "axios";
import { createContext, useCallback, useContext, useEffect, useReducer } from "react";
const initAuth = { const initAuth = {
initAuthState: false, initAuthState: false,
@@ -28,7 +28,6 @@ const AuthContext = createContext();
export const AuthProvider = ({ children }) => { export const AuthProvider = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, initAuth); const [state, dispatch] = useReducer(authReducer, initAuth);
const request = useRequest();
const clearUser = useCallback(() => { const clearUser = useCallback(() => {
dispatch({ type: "CLEAR_USER" }); dispatch({ type: "CLEAR_USER" });
@@ -46,9 +45,15 @@ export const AuthProvider = ({ children }) => {
dispatch({ type: "CHANGE_INIT_AUTH", initAuthState }); dispatch({ type: "CHANGE_INIT_AUTH", initAuthState });
}, []); }, []);
const logout = () => {
clearUser();
changeAuthState(false);
changeInitAuth(true);
}
const getUser = useCallback(async () => { const getUser = useCallback(async () => {
try { try {
const { data } = await request(GET_USER_ROUTE, "get"); const { data } = await axios.get(GET_USER_ROUTE, { withCredentials: true });
changeUser(data); changeUser(data);
changeAuthState(true); changeAuthState(true);
changeInitAuth(true); changeInitAuth(true);
@@ -72,6 +77,7 @@ export const AuthProvider = ({ children }) => {
isAuth: state.isAuth, isAuth: state.isAuth,
initAuthState: state.initAuthState, initAuthState: state.initAuthState,
getUser, getUser,
logout
}} }}
> >
{children} {children}

View File

@@ -2,8 +2,8 @@ import { useContext } from "react";
import { DataTableContext } from "@/lib/contexts/DataTable"; import { DataTableContext } from "@/lib/contexts/DataTable";
const useTableSetting = () => { const useTableSetting = () => {
const { filterData, setFilterData, sortData, setSortData } = useContext(DataTableContext); const { filterData, setFilterData, sortData, setSortData, hideData, setHideData } = useContext(DataTableContext);
return { filterData, setFilterData, sortData, setSortData }; return { filterData, setFilterData, sortData, setSortData, hideData, setHideData };
}; };
export default useTableSetting; export default useTableSetting;

View File

@@ -1,17 +1,7 @@
import { errorResponse } from "@/core/utils/errorResponse"; import { errorResponse } from "@/core/utils/errorResponse";
import { GET_CSRF } from "@/core/utils/routes";
import { successRequest } from "@/core/utils/successRequest"; import { successRequest } from "@/core/utils/successRequest";
import axios from "axios"; import axios from "axios";
import { useAuth } from "../contexts/auth";
const getCsrfToken = async () => {
try {
const response = await axios.get(GET_CSRF);
return response.data.data;
} catch (error) {
console.error("Error fetching CSRF token:", error);
throw error;
}
};
const defaultOptions = { const defaultOptions = {
data: {}, data: {},
@@ -26,19 +16,7 @@ const defaultOptions = {
}; };
const useRequest = (initOptions) => { const useRequest = (initOptions) => {
const instance = axios.create(); const { logout } = useAuth()
instance.interceptors.request.use(
async function (config) {
if (config.method !== 'get') {
const csrfToken = await getCsrfToken();
config.headers['X-CSRF-TOKEN'] = csrfToken;
}
return config;
},
function (error) {
return Promise.reject(error);
}
);
const _options = Object.assign({}, defaultOptions, initOptions); const _options = Object.assign({}, defaultOptions, initOptions);
@@ -46,7 +24,7 @@ const useRequest = (initOptions) => {
const mergedOptions = Object.assign({}, _options, options); const mergedOptions = Object.assign({}, _options, options);
try { try {
const response = await instance({ const response = await axios({
url, url,
method, method,
data: method === "get" ? null : mergedOptions.data, data: method === "get" ? null : mergedOptions.data,
@@ -60,7 +38,7 @@ const useRequest = (initOptions) => {
errorResponse( errorResponse(
error.response, error.response,
mergedOptions.notification.show && mergedOptions.notification.failed, mergedOptions.notification.show && mergedOptions.notification.failed,
"request_data" "request_data", logout
); );
} }
throw error; throw error;