LFFE-10 merging from develop on feature

This commit is contained in:
2023-11-15 10:01:57 +03:30
127 changed files with 2116 additions and 537 deletions

View File

@@ -14,7 +14,6 @@ function DataTable(props) {
const [columnFilters, setColumnFilters] = useState([]);
const [sorting, setSorting] = useState(props.sorting || []);
const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 10});
const [rowCount, setRowCount] = useState(0);
const [columnFilterFns, setColumnFilterFns] = useState(() => {
let output = {};
const list = props.columns.map((item) => item.enableColumnFilter ? {[item.id]: item.filterFn} : {[item.id]: ""});
@@ -34,8 +33,11 @@ function DataTable(props) {
const tableLocalization = useMemo(() => languageList.find((item) => item.key == languageApp).tableLocalization, [languageApp, languageList]);
const fetchUrl = useMemo(() => {
const url = new URL(props.tableUrl);
url.searchParams.set("start", `${pagination.pageIndex * pagination.pageSize}`);
const params = new URLSearchParams();
params.set(
"start",
`${pagination.pageIndex * pagination.pageSize}`
);
const filters = columnFilters.map((filter) => {
let datatype;
for (const i in props.columns) {
@@ -47,10 +49,10 @@ function DataTable(props) {
...filter, fn: columnFilterFns[filter.id], datatype: datatype,
};
});
url.searchParams.set("size", pagination.pageSize);
url.searchParams.set("filters", JSON.stringify(filters ?? []));
url.searchParams.set("sorting", JSON.stringify(sorting ?? []));
return url;
params.set("size", pagination.pageSize);
params.set("filters", JSON.stringify(filters ?? []));
params.set("sorting", JSON.stringify(sorting ?? []));
return `${props.tableUrl}?${params}`;
}, [props.tableUrl, columnFilters, columnFilterFns, pagination, sorting, props.columns,]);
const {data, isValidating, mutate} = useSWR(fetchUrl, (...args) =>
@@ -60,7 +62,7 @@ function DataTable(props) {
}).then((response) => response.data).catch(() => {
})
, {
revalidateIfStale: false,
revalidateIfStale: true,
revalidateOnFocus: false,
revalidateOnReconnect: true,
keepPreviousData: true

View File

@@ -1,4 +1,4 @@
import {Backdrop, Box, styled} from "@mui/material";
import {Backdrop, Box, Stack, styled, Typography} from "@mui/material";
import SvgLoading from "@/core/components/svgs/SvgLoading";
const LoadingImage = styled(Box)({
@@ -9,7 +9,7 @@ const LoadingImage = styled(Box)({
},
"50%": {
// opacity: 1,
transform: "scale(2)",
transform: "scale(.5)",
},
"100%": {
// opacity: 0,
@@ -19,20 +19,29 @@ const LoadingImage = styled(Box)({
animation: "load 2s infinite",
});
const LoadingHardPage = ({children, loading}) => {
const LoadingHardPage = ({children, loading, sx = {}, icon = null, width = 200, height = 200, label = ''}) => {
return (
<>
<Backdrop
sx={{bgcolor: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1}}
sx={{bgcolor: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1, ...sx}}
open={loading}
>
<LoadingImage
width={100}
height={100}
>
<SvgLoading width={100}
height={100}/>
</LoadingImage>
<Stack alignItems={'center'} spacing={2}>
<LoadingImage
width={width}
height={height}
>
{icon ? (
<Box sx={{color: "primary.main", width: width, height: height}}>
{icon}
</Box>
) : (
<SvgLoading width={width}
height={height}/>
)}
</LoadingImage>
<Typography variant={'body2'} sx={{color: "primary.main"}}>{label}</Typography>
</Stack>
</Backdrop>
{children}
</>

View File

@@ -0,0 +1,11 @@
import {styled, TextField} from "@mui/material";
const LtrTextField = styled(TextField)`
.MuiInputBase-input {
/* @noflip */
direction: ltr;
text-align: left;
}
`;
export default LtrTextField

View File

@@ -6,13 +6,13 @@ import WifiOffIcon from '@mui/icons-material/WifiOff';
import {useTranslations} from "next-intl";
const NetworkComponent = () => {
const toastId = useRef(null);
const networkToastId = useRef(null);
const network = useNetwork()
const t = useTranslations()
useEffect(() => {
if (network.online) {
toast.update(toastId.current, {
toast.update(networkToastId.current, {
type: toast.TYPE.SUCCESS,
render: t('online_message'),
autoClose: 2000,
@@ -22,8 +22,9 @@ const NetworkComponent = () => {
});
return
}
toast.dismiss()
toastId.current = toast.warn(t('offline_message'), {
networkToastId.current = toast.warn(t('offline_message'), {
containerId: 'connection',
draggable: false,
autoClose: false, closeButton: false, closeOnClick: false, icon: <WifiOffIcon/>
})
}, [network.online]);

View File

@@ -1,12 +1,13 @@
import {Stack, TextField, Typography} from "@mui/material";
import {Stack, Typography} from "@mui/material";
import {useTranslations} from "next-intl";
import LtrTextField from "@/core/components/LtrTextField";
const PriceField = (props) => {
const t = useTranslations();
return (
<Stack spacing={1}>
<Stack>
<TextField
<LtrTextField
{...props}
/>
</Stack>

View File

@@ -0,0 +1,82 @@
import {Box, Container, Divider, Grid, Paper, Stack, Typography} from '@mui/material';
const PrintablePage = ({children, header, footer}) => (
<>
<Box sx={{width: "100%", height: 8, displayPrint: 'none'}}/>
<Container
sx={{
width: '21cm',
minHeight: '29.7cm',
margin: '0 auto',
backgroundColor: 'white',
p: '16px !important',
pb: footer ? '84px!important' : '',
position: 'relative'
}}
component="article" maxWidth="false">
<Grid container columns={5} sx={{pt: 2, px: 4, display: header ? '' : 'none'}}>
<Grid item xs={1}>
<Box sx={{width: 70}}>
<Box component={'img'} sx={{width: '100%', height: '100%', objectFit: 'contain'}}
src={'/images/logo.png'}/>
</Box>
</Grid>
<Grid item xs={3} sx={{textAlign: 'center'}}>
<Typography sx={{fontFamily: 'Bnazanin'}}>باسمه تعالی</Typography>
<Typography sx={{fontFamily: 'Bnazanin'}}>جمهوری اسلامی ایران</Typography>
<Typography sx={{fontFamily: 'Bnazanin', fontWeight: 'bold'}}>وزارت راه و
شهرسازی</Typography>
<Typography sx={{fontFamily: 'Bnazanin', fontWeight: 'bold'}}>سازمان
راهداری و حمل و نقل جاده
ای</Typography>
</Grid>
<Grid item xs={1}>
<Stack>
<Typography sx={{fontFamily: 'Bnazanin'}}>شماره:</Typography>
<Typography sx={{fontFamily: 'Bnazanin'}}>تاریخ:</Typography>
<Typography sx={{fontFamily: 'Bnazanin'}}>پیوست:</Typography>
</Stack>
</Grid>
</Grid>
<Paper elevation={0} sx={{px: 8}}>
{children}
</Paper>
<Box sx={{
position: 'absolute',
bottom: 0,
left: 0,
width: '100%',
px: 4,
pb: 2,
display: footer ? '' : 'none'
}}>
<Divider sx={{borderStyle: 'double', borderBottomWidth: 3, borderColor: '#000'}}/>
<Stack sx={{my: .5}}>
<Box sx={{textAlign: 'center'}}>
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
sx={{fontFamily: 'Bnazanin', px: 1}}> آدرس: تهران-بلوار
کشاورز-خیابان فلسطین جنوبی-خیابان
دمشق-پلاک17 </Typography>
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
sx={{fontFamily: 'Bnazanin', px: 1}}> تلفن: 88-88804379 </Typography>
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
sx={{fontFamily: 'Bnazanin', px: 1}}> تلفن گویا: 88804400 </Typography>
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
sx={{fontFamily: 'Bnazanin', px: 1}}> کدپستی: 1416753941 </Typography>
</Box>
<Box sx={{textAlign: 'center'}}>
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
sx={{fontFamily: 'Bnazanin', px: 2}}>صندوق پستی: 3773-14155</Typography>
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
sx={{fontFamily: 'Bnazanin', px: 2}}>پست الکترونیک: info@rmto.ir</Typography>
<Typography variant={'caption'} fontWeight={'bold'} component={'span'}
sx={{fontFamily: 'Bnazanin', px: 2}}>سایت الکترونیک: www.rmto.ir</Typography>
</Box>
</Stack>
</Box>
</Container>
<Box sx={{width: "100%", height: 8, displayPrint: 'none'}}/>
</>
);
export default PrintablePage;

View File

@@ -10,7 +10,6 @@ const UploadSystem = ({
handleUploadChange,
fieldname,
setFieldValue,
imageAlt,
imageSize,
fileType,
fileName,
@@ -19,7 +18,6 @@ const UploadSystem = ({
}) => {
const t = useTranslations();
const fileInputRef = useRef(null);
const handleClick = () => {
fileInputRef.current.click();
};
@@ -69,13 +67,14 @@ const UploadSystem = ({
variant="subtitle2"
sx={{
fontWeight: 600,
fontSize: "1rem",
fontSize: "0.8rem",
color: "#a19d9d",
mt: 1,
}}
textAlign="center"
>
{t("UploadSystem.upload_file")}
{t("UploadSystem.upload_file_format")}<br/>
{t("UploadSystem.upload_file_unit")}
</Typography>
</Box>
</>

View File

@@ -2,8 +2,8 @@ import DangerousIcon from "@mui/icons-material/Dangerous";
import {Box, Typography} from "@mui/material";
import {toast} from "react-toastify";
const ErrorNotification = (t, status, message) => {
toast(
const ErrorNotification = (pushToastList, notificationType, t, status, message) => {
const toastId = toast(
() => (
<>
<Box
@@ -29,11 +29,13 @@ const ErrorNotification = (t, status, message) => {
</>
),
{
containerId: 'validation',
autoClose: false,
closeOnClick: false,
draggable: false,
}
);
pushToastList(notificationType, toastId);
};
export default ErrorNotification;
export default ErrorNotification;

View File

@@ -1,12 +1,14 @@
import {toast} from "react-toastify";
const PendingNotification = (t) => {
toast(t("notifications.pending"), {
const PendingNotification = (pushToastList, notificationType, t) => {
const toastId = toast(t("notifications.pending"), {
containerId: 'validation',
autoClose: false,
closeButton: false,
closeOnClick: false,
draggable: false,
});
pushToastList(notificationType, toastId);
};
export default PendingNotification;
export default PendingNotification;

View File

@@ -2,8 +2,8 @@ import BeenhereIcon from "@mui/icons-material/Beenhere";
import {Box, Typography} from "@mui/material";
import {toast} from "react-toastify";
const SuccessNotification = (t, status) => {
toast(
const SuccessNotification = (pushToastList, notificationType, t, status) => {
const toastId = toast(
() => (
<>
<Box
@@ -30,6 +30,7 @@ const SuccessNotification = (t, status) => {
</>
),
{
containerId: 'validation',
autoClose: 3000,
hideProgressBar: true,
pauseOnHover: true,
@@ -37,6 +38,7 @@ const SuccessNotification = (t, status) => {
draggable: true,
}
);
pushToastList(notificationType, toastId);
};
export default SuccessNotification;
export default SuccessNotification;

View File

@@ -26,6 +26,8 @@ const UploadFileNotification = (t) => {
</>
),
{
containerId: 'validation',
toastId: 'upload',
autoClose: 3000,
hideProgressBar: true,
pauseOnHover: true,
@@ -35,4 +37,4 @@ const UploadFileNotification = (t) => {
);
};
export default UploadFileNotification;
export default UploadFileNotification;

View File

@@ -2,8 +2,8 @@ import ReportIcon from "@mui/icons-material/Report";
import {Box, Typography} from "@mui/material";
import {toast} from "react-toastify";
const WarningNotification = (t, status) => {
toast(
const WarningNotification = (pushToastList, notificationType, t, status) => {
const toastId = toast(
() => (
<>
<Box
@@ -30,11 +30,13 @@ const WarningNotification = (t, status) => {
</>
),
{
containerId: 'validation',
autoClose: false,
closeOnClick: false,
draggable: false,
}
);
pushToastList(notificationType, toastId);
};
export default WarningNotification;
export default WarningNotification;

View File

@@ -1,54 +1,27 @@
import {toast} from "react-toastify";
import ErrorNotification from "./ErrorNotification";
import WarningNotification from "./WarningNotification";
import SuccessNotification from "./SuccessNotification";
import pendingNotification from "@/core/components/notifications/PendingNotification";
import WarningNotification from "@/core/components/notifications/WarningNotification";
import ErrorNotification from "@/core/components/notifications/ErrorNotification";
import SuccessNotification from "@/core/components/notifications/SuccessNotification";
const Notifications = async (t, response) => {
const {status, data} = response != undefined ? response : ""
toast.dismiss();
switch (status) {
case 200:
SuccessNotification(t, status);
const Notifications = (pushToastList, notificationType, t, status, message) => {
switch (notificationType) {
case "pending":
pendingNotification(pushToastList, notificationType, t);
break;
case 400:
ErrorNotification(t, status);
case "warning":
WarningNotification(pushToastList, notificationType, t, status);
break;
case 401:
ErrorNotification(t, status);
case "error":
if (message) {
ErrorNotification(pushToastList, notificationType, t, status, message)
} else {
ErrorNotification(pushToastList, notificationType, t, status)
}
break;
case 403:
ErrorNotification(t, status);
break;
case 422:
ErrorNotification(t, status, data.message);
break;
case 500:
WarningNotification(t, status);
break;
case 503:
WarningNotification(t, status);
break;
case 504:
WarningNotification(t, status);
break;
default:
toast(t("notifications.pending"), {
autoClose: false,
closeOnClick: false,
draggable: false,
});
case "success":
SuccessNotification(pushToastList, notificationType, t, status);
break;
}
};
export default Notifications;
/*
usage document
** for pending use ( Notifications( t, undefined) ) this before your request.
** for success use ( Notifications( t, response) ) this inside .then() of your request.
** for Error and Warning use ( Notifications( t, error.response) ) this inside .catche() of your request.
end usage document
*/