diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json
index 9d3297f..9fd2984 100644
--- a/public/locales/fa/app.json
+++ b/public/locales/fa/app.json
@@ -360,7 +360,8 @@
"permission_min_error": "حداقل باید یک دسترسی انتخاب شود",
"type_id": "نوع کاربر",
"navgan_id": "کد ناوگان",
- "button-update": "ویرایش"
+ "button-update": "ویرایش",
+ "loading_permissions_list": "درحال دریافت لیست دسترسی ها"
},
"UploadSystem": {
"upload_file": "فایل خود را بارگذاری کنید",
@@ -467,6 +468,7 @@
"type_id": "نوع کاربر",
"navgan_id": "کد ناوگان",
"button-cancel": "انصراف",
- "button-add": "ثبت"
+ "button-add": "ثبت",
+ "loading_permissions_list": "درحال دریافت لیست دسترسی ها"
}
}
diff --git a/src/components/dashboard/machinary-office/Form/ConfirmForm/ConfirmContent.jsx b/src/components/dashboard/machinary-office/Form/ConfirmForm/ConfirmContent.jsx
index 261c083..da0acda 100644
--- a/src/components/dashboard/machinary-office/Form/ConfirmForm/ConfirmContent.jsx
+++ b/src/components/dashboard/machinary-office/Form/ConfirmForm/ConfirmContent.jsx
@@ -37,7 +37,7 @@ const ConfirmContent = ({rowId, mutate, setOpenConfirmDialog}) => {
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
formData.append("proposed_amount", values.proposed_amount);
- if (values.description != "") formData.append("description", values.description);
+ if (values.description != "") formData.append("expert_description", values.description);
if (values.confirm_img != null) formData.append("attachment", values.confirm_img);
requestServer(`${CONFIRM_MACHINARY_OFFICE}/${rowId}`, 'post', {
diff --git a/src/components/dashboard/machinary-office/Form/RejectForm/RejectContent.jsx b/src/components/dashboard/machinary-office/Form/RejectForm/RejectContent.jsx
index 340a757..479b213 100644
--- a/src/components/dashboard/machinary-office/Form/RejectForm/RejectContent.jsx
+++ b/src/components/dashboard/machinary-office/Form/RejectForm/RejectContent.jsx
@@ -6,7 +6,7 @@ import {useFormik} from "formik";
import {useTranslations} from "next-intl";
import {useState} from "react";
import * as Yup from "yup";
-import {REJECT_INSPECTOR_EXPERT} from "@/core/data/apiRoutes";
+import {REJECT_MACHINARY_OFFICE} from "@/core/data/apiRoutes";
const RejectContent = ({rowId, mutate, setOpenRejectDialog}) => {
const [selectedImage, setSelectedImage] = useState("");
@@ -29,10 +29,10 @@ const RejectContent = ({rowId, mutate, setOpenRejectDialog}) => {
validationSchema,
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
- formData.append("description", values.description);
+ formData.append("expert_description", values.description);
if (values.reject_img != null) formData.append("attachment", values.reject_img);
- requestServer(`${REJECT_INSPECTOR_EXPERT}/${rowId}`, 'post', {
+ requestServer(`${REJECT_MACHINARY_OFFICE}/${rowId}`, 'post', {
data: formData,
}).then((response) => {
setOpenRejectDialog(false)
diff --git a/src/components/dashboard/navgan-province-manager/Form/ConfirmForm/ConfirmContent.jsx b/src/components/dashboard/navgan-province-manager/Form/ConfirmForm/ConfirmContent.jsx
index 5de9eb3..af9e93a 100644
--- a/src/components/dashboard/navgan-province-manager/Form/ConfirmForm/ConfirmContent.jsx
+++ b/src/components/dashboard/navgan-province-manager/Form/ConfirmForm/ConfirmContent.jsx
@@ -24,7 +24,7 @@ const ConfirmContent = ({rowId, mutate, setOpenConfirmDialog}) => {
},
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
- if (values.description != "") formData.append("description", values.description);
+ if (values.description != "") formData.append("expert_description", values.description);
if (values.confirm_img != null) formData.append("attachment", values.confirm_img);
requestServer(`${CONFIRM_NAVGAN_PROVINCE_MANAGER}/${rowId}`, 'post', {
diff --git a/src/components/dashboard/navgan-province-manager/Form/RejectForm/RejectContent.jsx b/src/components/dashboard/navgan-province-manager/Form/RejectForm/RejectContent.jsx
index 2502898..0b26c8b 100644
--- a/src/components/dashboard/navgan-province-manager/Form/RejectForm/RejectContent.jsx
+++ b/src/components/dashboard/navgan-province-manager/Form/RejectForm/RejectContent.jsx
@@ -29,7 +29,7 @@ const RejectContent = ({rowId, mutate, setOpenRejectDialog}) => {
validationSchema,
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
- formData.append("description", values.description);
+ formData.append("expert_description", values.description);
if (values.reject_img != null) formData.append("attachment", values.reject_img);
requestServer(`${REJECT_NAVGAN_PROVINCE_MANAGER}/${rowId}`, 'post', {
diff --git a/src/components/dashboard/passenger-boss/Form/ConfirmForm/ConfirmContent.jsx b/src/components/dashboard/passenger-boss/Form/ConfirmForm/ConfirmContent.jsx
index 66ccd27..d189a6b 100644
--- a/src/components/dashboard/passenger-boss/Form/ConfirmForm/ConfirmContent.jsx
+++ b/src/components/dashboard/passenger-boss/Form/ConfirmForm/ConfirmContent.jsx
@@ -37,7 +37,7 @@ const ConfirmContent = ({rowId, mutate, setOpenConfirmDialog}) => {
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
formData.append("approved_amount", values.approved_amount);
- if (values.description != "") formData.append("description", values.description);
+ if (values.description != "") formData.append("expert_description", values.description);
if (values.confirm_img != null) formData.append("attachment", values.confirm_img);
requestServer(`${CONFIRM_PASSENGER_BOSS}/${rowId}`, 'post', {
diff --git a/src/components/dashboard/passenger-boss/Form/RejectForm/RejectContent.jsx b/src/components/dashboard/passenger-boss/Form/RejectForm/RejectContent.jsx
index 6b6b385..93fe8c3 100644
--- a/src/components/dashboard/passenger-boss/Form/RejectForm/RejectContent.jsx
+++ b/src/components/dashboard/passenger-boss/Form/RejectForm/RejectContent.jsx
@@ -29,7 +29,7 @@ const RejectContent = ({rowId, mutate, setOpenRejectDialog}) => {
validationSchema,
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
- formData.append("description", values.description);
+ formData.append("expert_description", values.description);
if (values.reject_img != null) formData.append("attachment", values.reject_img);
requestServer(`${REJECT_PASSENGER_BOSS}/${rowId}`, 'post', {
diff --git a/src/components/dashboard/passenger-office/Form/RejectForm/RejectContent.jsx b/src/components/dashboard/passenger-office/Form/RejectForm/RejectContent.jsx
index fd7ea2c..2a8a82d 100644
--- a/src/components/dashboard/passenger-office/Form/RejectForm/RejectContent.jsx
+++ b/src/components/dashboard/passenger-office/Form/RejectForm/RejectContent.jsx
@@ -29,7 +29,7 @@ const RejectContent = ({rowId, mutate, setOpenRejectDialog}) => {
validationSchema,
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
- formData.append("description", values.description);
+ formData.append("expert_description", values.description);
if (values.reject_img != null) formData.append("attachment", values.reject_img);
requestServer(`${REJECT_PASSENGER_OFFICE}/${rowId}`, 'post', {
diff --git a/src/components/dashboard/role-management/Form/CreateForm/CreateContent.jsx b/src/components/dashboard/role-management/Form/CreateForm/CreateContent.jsx
index 45b14ba..e276e5d 100644
--- a/src/components/dashboard/role-management/Form/CreateForm/CreateContent.jsx
+++ b/src/components/dashboard/role-management/Form/CreateForm/CreateContent.jsx
@@ -1,6 +1,6 @@
import {
Button,
- Checkbox,
+ Checkbox, CircularProgress,
DialogActions,
DialogContent,
FormControl,
@@ -9,7 +9,7 @@ import {
FormLabel,
Grid,
Stack,
- TextField
+ TextField, Typography
} from "@mui/material";
import {useTranslations} from "next-intl";
import useRequest from "@/lib/app/hooks/useRequest";
@@ -21,7 +21,7 @@ import usePermissions from "@/lib/app/hooks/usePermissions";
const CreateContent = ({mutate, setOpenConfirmDialog}) => {
const t = useTranslations();
const requestServer = useRequest({auth: true})
- const {permissions_list} = usePermissions()
+ const {permissions_list, isLoading} = usePermissions()
const validationSchema = Yup.object().shape({
name: Yup.string().required(t("AddDialog.name_error")),
name_fa: Yup.string().required(t("AddDialog.name_fa_error")),
@@ -93,29 +93,40 @@ const CreateContent = ({mutate, setOpenConfirmDialog}) => {
sx={{mt: 2}}
>
{formik.touched.permissions && formik.errors.permissions}
-
- {permissions_list ? (
- permissions_list.map((permission) => (
-
- {
- if (e.target.checked) {
- formik.setFieldValue("permissions", [...formik.values.permissions, permission.id])
- } else {
- formik.setFieldValue("permissions", formik.values.permissions.filter((id) => id !== permission.id))
- }
- }}
+ {isLoading ?
+
+
+ {t("AddDialog.loading_permissions_list")}
+
+ : (
+
+ <>
+ {permissions_list.map((permission, index) => (
+
+ {
+ if (e.target.checked) {
+ formik.setFieldValue("permissions", [...formik.values.permissions, permission.id])
+ } else {
+ formik.setFieldValue("permissions", formik.values.permissions.filter((id) => id !== permission.id))
+ }
+ }}
+ />
+ }
+ label={permission.name_fa}
/>
- }
- label={permission.name_fa}
- />
-
- ))
- ) : null}
-
+
+ ))}
+ >
+
+ )
+ }
diff --git a/src/components/dashboard/role-management/Form/UpdateForm/UpdateContent.jsx b/src/components/dashboard/role-management/Form/UpdateForm/UpdateContent.jsx
index 8e13b12..037ed99 100644
--- a/src/components/dashboard/role-management/Form/UpdateForm/UpdateContent.jsx
+++ b/src/components/dashboard/role-management/Form/UpdateForm/UpdateContent.jsx
@@ -4,7 +4,7 @@ import usePermissions from "@/lib/app/hooks/usePermissions";
import useRequest from "@/lib/app/hooks/useRequest";
import {
Button,
- Checkbox,
+ Checkbox, CircularProgress,
DialogActions,
DialogContent,
FormControl,
@@ -13,7 +13,7 @@ import {
FormLabel,
Grid,
Stack,
- TextField
+ TextField, Typography
} from "@mui/material"
import {useFormik} from "formik";
import {useTranslations} from "next-intl";
@@ -23,7 +23,7 @@ const UpdateContent = ({row, mutate, setOpenConfirmDialog}) => {
const t = useTranslations();
const requestServer = useRequest({auth: true})
const {update_notification} = useNotification()
- const {permissions_list} = usePermissions()
+ const {permissions_list, isLoading} = usePermissions()
const validationSchema = Yup.object().shape({
name: Yup.string().required(t("UpdateDialog.name_error")),
@@ -93,29 +93,40 @@ const UpdateContent = ({row, mutate, setOpenConfirmDialog}) => {
sx={{mt: 2}}
>
{formik.touched.permissions && formik.errors.permissions}
-
- {permissions_list ? (
- permissions_list.map((permission) => (
-
- {
- if (e.target.checked) {
- formik.setFieldValue("permissions", [...formik.values.permissions, permission.id])
- } else {
- formik.setFieldValue("permissions", formik.values.permissions.filter((id) => id !== permission.id))
- }
- }}
+ {isLoading ?
+
+
+ {t("UpdateDialog.loading_permissions_list")}
+
+ : (
+
+ <>
+ {permissions_list.map((permission) => (
+
+ {
+ if (e.target.checked) {
+ formik.setFieldValue("permissions", [...formik.values.permissions, permission.id])
+ } else {
+ formik.setFieldValue("permissions", formik.values.permissions.filter((id) => id !== permission.id))
+ }
+ }}
+ />
+ }
+ label={permission.name_fa}
/>
- }
- label={permission.name_fa}
- />
-
- ))
- ) : null}
-
+
+ ))}
+ >
+
+ )
+ }
diff --git a/src/components/dashboard/transportation-assistance/Form/ConfirmForm/ConfirmContent.jsx b/src/components/dashboard/transportation-assistance/Form/ConfirmForm/ConfirmContent.jsx
index dc4d093..52137c2 100644
--- a/src/components/dashboard/transportation-assistance/Form/ConfirmForm/ConfirmContent.jsx
+++ b/src/components/dashboard/transportation-assistance/Form/ConfirmForm/ConfirmContent.jsx
@@ -24,7 +24,7 @@ const ConfirmContent = ({rowId, mutate, setOpenConfirmDialog}) => {
},
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
- if (values.description != "") formData.append("description", values.description);
+ if (values.description != "") formData.append("expert_description", values.description);
if (values.confirm_img != null) formData.append("attachment", values.confirm_img);
requestServer(`${CONFIRM_TRANSPORTATION_ASSISTANCE}/${rowId}`, 'post', {
@@ -106,7 +106,7 @@ const ConfirmContent = ({rowId, mutate, setOpenConfirmDialog}) => {
{t("ConfirmDialog.button-cancel")}
diff --git a/src/components/dashboard/transportation-assistance/Form/RejectForm/RejectContent.jsx b/src/components/dashboard/transportation-assistance/Form/RejectForm/RejectContent.jsx
index 3641f71..b692df4 100644
--- a/src/components/dashboard/transportation-assistance/Form/RejectForm/RejectContent.jsx
+++ b/src/components/dashboard/transportation-assistance/Form/RejectForm/RejectContent.jsx
@@ -29,7 +29,7 @@ const RejectContent = ({rowId, mutate, setOpenRejectDialog}) => {
validationSchema,
onSubmit: (values, {setSubmitting}) => {
const formData = new FormData();
- formData.append("description", values.description);
+ formData.append("expert_description", values.description);
if (values.reject_img != null) formData.append("attachment", values.reject_img);
requestServer(`${REJECT_TRANSPORTATION_ASSISTANCE}/${rowId}`, 'post', {
diff --git a/src/components/login-expert/index.jsx b/src/components/login-expert/index.jsx
index 221c530..23185df 100644
--- a/src/components/login-expert/index.jsx
+++ b/src/components/login-expert/index.jsx
@@ -1,5 +1,4 @@
import LinkRouting from "@/core/components/LinkRouting";
-import PasswordField from "@/core/components/PasswordField";
import StyledForm from "@/core/components/StyledForm";
import {GET_USER_TOKEN} from "@/core/data/apiRoutes";
import CenterLayout from "@/layouts/CenterLayout";
@@ -14,6 +13,7 @@ import * as Yup from "yup";
import useDirection from "@/lib/app/hooks/useDirection";
import SvgLogin from "@/core/components/svgs/SvgLogin";
import useRequest from "@/lib/app/hooks/useRequest";
+import PasswordField from "@/core/components/PasswordField";
const LoginComponent = () => {
const t = useTranslations();
diff --git a/src/core/components/DataTable.jsx b/src/core/components/DataTable.jsx
index d4b93e7..ea3a117 100644
--- a/src/core/components/DataTable.jsx
+++ b/src/core/components/DataTable.jsx
@@ -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) =>
diff --git a/src/core/components/PasswordField.jsx b/src/core/components/PasswordField/index.jsx
similarity index 100%
rename from src/core/components/PasswordField.jsx
rename to src/core/components/PasswordField/index.jsx
diff --git a/src/core/components/notifications/ErrorNotification.jsx b/src/core/components/notifications/ErrorNotification.jsx
index 4ff1ab0..776c904 100644
--- a/src/core/components/notifications/ErrorNotification.jsx
+++ b/src/core/components/notifications/ErrorNotification.jsx
@@ -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(
() => (
<>
{
>
),
{
+ containerId: 'validation',
autoClose: false,
closeOnClick: false,
draggable: false,
}
);
+ pushToastList(notificationType, toastId);
};
-export default ErrorNotification;
+export default ErrorNotification;
\ No newline at end of file
diff --git a/src/core/components/notifications/PendingNotification.jsx b/src/core/components/notifications/PendingNotification.jsx
index 846b847..cc28a58 100644
--- a/src/core/components/notifications/PendingNotification.jsx
+++ b/src/core/components/notifications/PendingNotification.jsx
@@ -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;
\ No newline at end of file
diff --git a/src/core/components/notifications/SuccessNotification.jsx b/src/core/components/notifications/SuccessNotification.jsx
index 998deaa..1207000 100644
--- a/src/core/components/notifications/SuccessNotification.jsx
+++ b/src/core/components/notifications/SuccessNotification.jsx
@@ -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(
() => (
<>
{
>
),
{
+ 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;
\ No newline at end of file
diff --git a/src/core/components/notifications/UploadFileNotification.jsx b/src/core/components/notifications/UploadFileNotification.jsx
index 6556944..1c20ba3 100644
--- a/src/core/components/notifications/UploadFileNotification.jsx
+++ b/src/core/components/notifications/UploadFileNotification.jsx
@@ -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;
\ No newline at end of file
diff --git a/src/core/components/notifications/WarningNotification.jsx b/src/core/components/notifications/WarningNotification.jsx
index 8493180..bc2a1fb 100644
--- a/src/core/components/notifications/WarningNotification.jsx
+++ b/src/core/components/notifications/WarningNotification.jsx
@@ -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(
() => (
<>
{
>
),
{
+ containerId: 'validation',
autoClose: false,
closeOnClick: false,
draggable: false,
}
);
+ pushToastList(notificationType, toastId);
};
-export default WarningNotification;
+export default WarningNotification;
\ No newline at end of file
diff --git a/src/core/components/notifications/index.jsx b/src/core/components/notifications/index.jsx
index bc8eb66..34e44f3 100644
--- a/src/core/components/notifications/index.jsx
+++ b/src/core/components/notifications/index.jsx
@@ -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
-*/
diff --git a/src/core/utils/errorHandler.js b/src/core/utils/errorHandler.js
index 8dbd364..e380e84 100644
--- a/src/core/utils/errorHandler.js
+++ b/src/core/utils/errorHandler.js
@@ -1,45 +1,48 @@
-import ErrorNotification from "@/core/components/notifications/ErrorNotification";
-import WarningNotification from "@/core/components/notifications/WarningNotification";
-import {toast} from "react-toastify";
+import Notifications from "@/core/components/notifications";
-export const errorSetting = (t, notification) => {
- if (notification) toast.dismiss();
+export const errorSetting = (dismissToastList, t, notification) => {
+ if (notification) {
+ dismissToastList(["pending", "warning", "error", "success"])
+ }
}
-
-export const errorRequest = (t, notification) => {
- if (notification) toast.dismiss();
-}
-
-export const errorResponse = (response, clearToken, t, notification) => {
- if (notification) toast.dismiss();
- if (isServerError(response.status)) {
- errorServer(response, t, notification)
- } else if (isClientError(response.status)) {
- errorClient(response, clearToken, t, notification)
+export const errorRequest = (dismissToastList, t, notification) => {
+ if (notification) {
+ dismissToastList(["pending", "warning", "error", "success"])
}
}
-const errorServer = (response, t, notification) => {
- if (notification) WarningNotification(t, response.status);
+export const errorResponse = (pushToastList, dismissToastList, response, clearToken, t, notification) => {
+ if (notification) {
+ dismissToastList(["pending", "warning", "error", "success"])
+ }
+ if (isServerError(response.status)) {
+ errorServer(pushToastList, response, t, notification)
+ } else if (isClientError(response.status)) {
+ errorClient(pushToastList, response, clearToken, t, notification)
+ }
}
-const errorClient = (response, clearToken, t, notification) => {
+
+const errorServer = (pushToastList, response, t, notification) => {
+ if (notification) Notifications(pushToastList, "warning", t, response.status);
+}
+const errorClient = (pushToastList, response, clearToken, t, notification) => {
switch (response.status) {
case 401:
clearToken()
- if (notification) ErrorNotification(t, response.status)
+ if (notification) Notifications(pushToastList, "error", t, response.status);
break;
case 422:
if ('type' in response.data) {
- errorLogic(response, t, notification)
+ errorLogic(pushToastList, response, t, notification)
break;
}
- errorValidation(response, t, notification)
+ errorValidation(pushToastList, response, t, notification)
break;
case 429:
- if (notification) ErrorNotification(t, response.status)
+ if (notification) Notifications(pushToastList, "error", t, response.status);
break
default:
- if (notification) ErrorNotification(t, response.status)
+ if (notification) Notifications(pushToastList, "error", t, response.status);
break
}
}
@@ -47,16 +50,16 @@ const errorClient = (response, clearToken, t, notification) => {
const isServerError = status => status >= 500 && status <= 599;
const isClientError = status => status >= 400 && status <= 499;
-const errorLogic = (response, t, notification) => {
- if (notification) ErrorNotification(t, response.status, response.data.message)
+const errorLogic = (pushToastList, response, t, notification) => {
+ if (notification) Notifications(pushToastList, "error", t, response.status, response.data.message);
}
-const errorValidation = (response, t, notification) => {
+const errorValidation = (pushToastList, response, t, notification) => {
if (notification) {
const errorsMap = Object.keys(response.data.errors)
const errorsArray = response.data.errors
errorsMap.map((item, index) => {
- ErrorNotification(t, response.status, errorsArray[item][0]);
+ Notifications(pushToastList, "error", t, response.status, errorsArray[item][0]);
})
}
}
\ No newline at end of file
diff --git a/src/core/utils/succesHandler.js b/src/core/utils/succesHandler.js
index a61ac85..c852f86 100644
--- a/src/core/utils/succesHandler.js
+++ b/src/core/utils/succesHandler.js
@@ -1,9 +1,8 @@
-import SuccessNotification from "@/core/components/notifications/SuccessNotification";
-import {toast} from "react-toastify";
+import Notifications from "@/core/components/notifications";
-export const successRequest = (response, t, options) => {
+export const successRequest = (pushToastList, dismissToastList, response, t, options) => {
if (options.notification && options.success.notification.show) {
- toast.dismiss();
- SuccessNotification(t, response.status)
+ dismissToastList(["pending", "warning", "error", "success"])
+ Notifications(pushToastList, "success", t, response.status);
}
}
\ No newline at end of file
diff --git a/src/lib/app/contexts/language.jsx b/src/lib/app/contexts/language.jsx
index a6df674..03e3bc3 100644
--- a/src/lib/app/contexts/language.jsx
+++ b/src/lib/app/contexts/language.jsx
@@ -1,8 +1,8 @@
import {FA_DATATABLE_LOCALIZATION} from "&/locales/fa/datatable";
-import {FA_CHART_LOCALIZATION} from "&/locales/fa/chart";
import {useRouter} from "next/router";
import {createContext, useEffect, useState} from "react";
import useUser from "../hooks/useUser";
+import {FA_CHART_LOCALIZATION} from "&/locales/fa/chart";
export const LanguageContext = createContext();
@@ -20,7 +20,7 @@ export const LanguageProvider = ({children}) => {
];
const {user, userChangedLanguage, changeLanguageState} = useUser();
const [languageIsReady, setLanguageIsReady] = useState(false);
- const [languageApp, setLanguageApp] = useState();
+ const [languageApp, setLanguageApp] = useState(process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE);
const [directionApp, setDirectionApp] = useState(
process.env.NEXT_PUBLIC_DEFAULT_DIRECTION
);
@@ -28,9 +28,7 @@ export const LanguageProvider = ({children}) => {
useEffect(() => {
const lang = localStorage.getItem("_language");
- if (!lang && !languageApp) {
- setLanguageApp(process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE);
- } else if (lang) {
+ if (lang) {
setLanguageApp(lang);
}
}, []);
diff --git a/src/lib/app/contexts/toast.jsx b/src/lib/app/contexts/toast.jsx
new file mode 100644
index 0000000..b9d4cbc
--- /dev/null
+++ b/src/lib/app/contexts/toast.jsx
@@ -0,0 +1,37 @@
+import {createContext, useReducer} from "react";
+import {toast} from "react-toastify";
+
+export const ToastContext = createContext()
+
+const reducer = (state, action) => {
+ switch (action.type) {
+ case "PUSH":
+ return {
+ ...state,
+ [action.toast_type]: [...state[action.toast_type], action.toast_id]
+ };
+ case "DISMISS":
+ action.toast_type.map((item) => {
+ state[item].map((id) => {
+ toast.dismiss(id);
+ })
+ state[item] = []
+ });
+ return state;
+ }
+};
+
+export const ToastProvider = ({children}) => {
+ const [state, dispatch] = useReducer(reducer, {
+ pending: [],
+ error: [],
+ warning: [],
+ success: []
+ });
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/lib/app/contexts/user.jsx b/src/lib/app/contexts/user.jsx
index 10611b8..7f5c97c 100644
--- a/src/lib/app/contexts/user.jsx
+++ b/src/lib/app/contexts/user.jsx
@@ -1,7 +1,6 @@
import {GET_USER_ROUTE} from "@/core/data/apiRoutes";
import axios from "axios";
import {createContext, useCallback, useEffect, useReducer} from "react";
-import {errorRequest, errorResponse, errorSetting} from "@/core/utils/errorHandler";
const initialUser = {
isAuth: false,
@@ -78,13 +77,7 @@ export const UserProvider = ({children}) => {
if (typeof callback === "function") callback(data);
})
.catch(error => {
- if (error.response) {
- errorResponse(error.response, clearToken, null, false)
- } else if (error.request) {
- errorRequest(null, false)
- } else {
- errorSetting(null, false)
- }
+ if (error.response.status === 401) clearToken()
})
},
[state.token]
diff --git a/src/lib/app/hooks/usePermissions.jsx b/src/lib/app/hooks/usePermissions.jsx
index 0e6aa07..2e6fff5 100644
--- a/src/lib/app/hooks/usePermissions.jsx
+++ b/src/lib/app/hooks/usePermissions.jsx
@@ -11,15 +11,16 @@ const usePermissions = () => {
})
};
- const {data} = useSWR(GET_PERMISSIONS_LIST, fetcher, {
+ const {data, isLoading} = useSWR(GET_PERMISSIONS_LIST, fetcher, {
revalidateIfStale: false,
revalidateOnFocus: false,
- revalidateOnReconnect: false
+ revalidateOnReconnect: false,
+ keepPreviousData : true
})
const permissions_list = data
//swr config
// render data
- return {permissions_list}
+ return {permissions_list, isLoading}
}
export default usePermissions;
\ No newline at end of file
diff --git a/src/lib/app/hooks/useRequest.jsx b/src/lib/app/hooks/useRequest.jsx
index d361e08..4c3be1d 100644
--- a/src/lib/app/hooks/useRequest.jsx
+++ b/src/lib/app/hooks/useRequest.jsx
@@ -1,10 +1,11 @@
import axios from "axios";
import {successRequest} from "@/core/utils/succesHandler";
-import PendingNotification from "@/core/components/notifications/PendingNotification";
import {useTranslations} from "next-intl";
import useUser from "@/lib/app/hooks/useUser";
import {errorRequest, errorResponse, errorSetting} from "@/core/utils/errorHandler";
import useNetwork from "@/lib/app/hooks/useNetwork";
+import Notifications from "@/core/components/notifications";
+import useToast from "@/lib/app/hooks/useToast";
const defaultOptions = {
auth: false, data: {}, requestOptions: {
@@ -23,6 +24,7 @@ const useRequest = (initOptions) => {
const network = useNetwork()
const t = useTranslations()
const {token, clearToken} = useUser()
+ const {pushToastList, dismissToastList} = useToast();
let _options = {...defaultOptions, ...initOptions}
function requestServer(url = '', method = 'get', options) {
@@ -33,27 +35,30 @@ const useRequest = (initOptions) => {
headers: {..._options.requestOptions.headers, authorization: `Bearer ${token}`}
}
}
-
return new Promise((resolve, reject) => {
if (!network.online) {
reject()
return
}
- if (_options.notification && _options.failed.notification.show && _options.pending) PendingNotification(t)
+ if (_options.notification && _options.failed.notification.show && _options.pending) {
+ dismissToastList(["pending", "warning", "error", "success"]);
+ Notifications(pushToastList, "pending", t);
+ }
+
axios({
url: url, method: method, data: _options.data, ..._options.requestOptions
})
.then(response => {
- successRequest(response, t, _options)
+ successRequest(pushToastList, dismissToastList, response, t, _options)
resolve(response)
})
.catch(error => {
if (error.response) {
- errorResponse(error.response, clearToken, t, _options.notification && _options.failed.notification.show)
+ errorResponse(pushToastList, dismissToastList, error.response, clearToken, t, _options.notification && _options.failed.notification.show)
} else if (error.request) {
- errorRequest(t, _options.notification && _options.failed.notification.show)
+ errorRequest(dismissToastList, t, _options.notification && _options.failed.notification.show)
} else {
- errorSetting(t, _options.notification && _options.failed.notification.show)
+ errorSetting(dismissToastList, t, _options.notification && _options.failed.notification.show)
}
reject(error)
})
diff --git a/src/lib/app/hooks/useToast.jsx b/src/lib/app/hooks/useToast.jsx
new file mode 100644
index 0000000..5e1d5b4
--- /dev/null
+++ b/src/lib/app/hooks/useToast.jsx
@@ -0,0 +1,21 @@
+import {useContext} from "react";
+import {ToastContext} from "@/lib/app/contexts/toast";
+
+const useToast = () => {
+ const {dispatch} = useContext(ToastContext);
+
+ const pushToastList = (toast_type, toast_id) => {
+ dispatch({type: "PUSH", toast_type, toast_id});
+ };
+
+ const dismissToastList = (toast_type) => {
+ dispatch({type: "DISMISS", toast_type});
+ };
+
+ return {
+ pushToastList,
+ dismissToastList
+ }
+};
+
+export default useToast;
\ No newline at end of file
diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx
index d7c2169..8d2f3b0 100644
--- a/src/pages/_app.jsx
+++ b/src/pages/_app.jsx
@@ -8,6 +8,7 @@ import "moment/locale/fa";
import {NextIntlProvider} from "next-intl";
import TitlePage from "@/core/components/TitlePage";
import Layout from "@/layouts";
+import {ToastProvider} from "@/lib/app/contexts/toast";
const App = ({Component, pageProps}) => {
@@ -19,11 +20,13 @@ const App = ({Component, pageProps}) => {
{pageProps.messages ? : ''}
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/pages/dashboard/change-password/index.jsx b/src/pages/dashboard/change-password/index.jsx
index d23721d..ef75fb7 100644
--- a/src/pages/dashboard/change-password/index.jsx
+++ b/src/pages/dashboard/change-password/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.change_password",
isBot,
+ locale,
layout: {name: 'DashboardLayout'}
},
};
diff --git a/src/pages/dashboard/commercial-chief/index.jsx b/src/pages/dashboard/commercial-chief/index.jsx
index e5dc96c..1ec5fbf 100644
--- a/src/pages/dashboard/commercial-chief/index.jsx
+++ b/src/pages/dashboard/commercial-chief/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.commercial_chief_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_commercial_refahi"]}}
},
};
diff --git a/src/pages/dashboard/development-assistant/index.jsx b/src/pages/dashboard/development-assistant/index.jsx
index 6f1a0ff..346a340 100644
--- a/src/pages/dashboard/development-assistant/index.jsx
+++ b/src/pages/dashboard/development-assistant/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.development_assistant_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_development_refahi"]}}
},
};
diff --git a/src/pages/dashboard/edit-profile/index.jsx b/src/pages/dashboard/edit-profile/index.jsx
index dede28e..032a607 100644
--- a/src/pages/dashboard/edit-profile/index.jsx
+++ b/src/pages/dashboard/edit-profile/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.edit_profile",
isBot,
+ locale,
layout: {name: 'DashboardLayout'}
},
};
diff --git a/src/pages/dashboard/expert-management/index.jsx b/src/pages/dashboard/expert-management/index.jsx
index eab73fc..5f1c29a 100644
--- a/src/pages/dashboard/expert-management/index.jsx
+++ b/src/pages/dashboard/expert-management/index.jsx
@@ -14,7 +14,8 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.expert_management",
isBot,
- layout: {name: 'DashboardLayout', props: {permissions: ["manage_transportation_navgan"]}}
+ locale,
+ layout: {name: 'DashboardLayout', props: {permissions: ["manage_experts"]}}
},
};
}
diff --git a/src/pages/dashboard/index.jsx b/src/pages/dashboard/index.jsx
index f3cf481..0e309c3 100644
--- a/src/pages/dashboard/index.jsx
+++ b/src/pages/dashboard/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.dashboard_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout'}
},
};
diff --git a/src/pages/dashboard/inspector-expert/index.jsx b/src/pages/dashboard/inspector-expert/index.jsx
index f953f30..c2d14f8 100644
--- a/src/pages/dashboard/inspector-expert/index.jsx
+++ b/src/pages/dashboard/inspector-expert/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.inspector_expert_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_inspector_refahi"]}}
},
};
diff --git a/src/pages/dashboard/machinery-expert/index.jsx b/src/pages/dashboard/machinery-expert/index.jsx
index 5b2f945..df23f2e 100644
--- a/src/pages/dashboard/machinery-expert/index.jsx
+++ b/src/pages/dashboard/machinery-expert/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.machinary_office_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_machinery_navgan"]}}
},
};
diff --git a/src/pages/dashboard/navgan-loan-management/index.jsx b/src/pages/dashboard/navgan-loan-management/index.jsx
index 61922ad..792ea3e 100644
--- a/src/pages/dashboard/navgan-loan-management/index.jsx
+++ b/src/pages/dashboard/navgan-loan-management/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.loan_management_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_navgan_loan"]}}
},
};
diff --git a/src/pages/dashboard/navgan-province-manager/index.jsx b/src/pages/dashboard/navgan-province-manager/index.jsx
index b0c0be6..39102cb 100644
--- a/src/pages/dashboard/navgan-province-manager/index.jsx
+++ b/src/pages/dashboard/navgan-province-manager/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.province_manager_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_province_affairs_navgan"]}}
},
};
diff --git a/src/pages/dashboard/passenger-boss/index.jsx b/src/pages/dashboard/passenger-boss/index.jsx
index a549f74..c38b95f 100644
--- a/src/pages/dashboard/passenger-boss/index.jsx
+++ b/src/pages/dashboard/passenger-boss/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.passenger_boss_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_province_working_group_navgan"]}}
},
};
diff --git a/src/pages/dashboard/passenger-office-chief/index.jsx b/src/pages/dashboard/passenger-office-chief/index.jsx
index 03aa612..5ca084e 100644
--- a/src/pages/dashboard/passenger-office-chief/index.jsx
+++ b/src/pages/dashboard/passenger-office-chief/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.passenger_office_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_passenger_office_navgan"]}}
},
};
diff --git a/src/pages/dashboard/province-head-expert/index.jsx b/src/pages/dashboard/province-head-expert/index.jsx
index 64bffb1..b556d20 100644
--- a/src/pages/dashboard/province-head-expert/index.jsx
+++ b/src/pages/dashboard/province-head-expert/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.province_head_expert",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_province_headquarter_refahi"]}}
},
};
diff --git a/src/pages/dashboard/refahi-loan-management/index.jsx b/src/pages/dashboard/refahi-loan-management/index.jsx
index 1ae6954..4aab9a0 100644
--- a/src/pages/dashboard/refahi-loan-management/index.jsx
+++ b/src/pages/dashboard/refahi-loan-management/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.loan_management_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_refahi_loan"]}}
},
};
diff --git a/src/pages/dashboard/refahi-province-manager/index.jsx b/src/pages/dashboard/refahi-province-manager/index.jsx
index 9922b50..cc5c1eb 100644
--- a/src/pages/dashboard/refahi-province-manager/index.jsx
+++ b/src/pages/dashboard/refahi-province-manager/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.province_manager_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_province_affairs_refahi"]}}
},
};
diff --git a/src/pages/dashboard/role-management/index.jsx b/src/pages/dashboard/role-management/index.jsx
index 97238db..7ae6d45 100644
--- a/src/pages/dashboard/role-management/index.jsx
+++ b/src/pages/dashboard/role-management/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.role_management_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_roles"]}}
},
};
diff --git a/src/pages/dashboard/transportation-assistant/index.jsx b/src/pages/dashboard/transportation-assistant/index.jsx
index eccb330..7c0b4b6 100644
--- a/src/pages/dashboard/transportation-assistant/index.jsx
+++ b/src/pages/dashboard/transportation-assistant/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.transportation_assistance",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_transportation_navgan"]}}
},
};
diff --git a/src/pages/dashboard/user-management/index.jsx b/src/pages/dashboard/user-management/index.jsx
index f0f9b24..e92c2b2 100644
--- a/src/pages/dashboard/user-management/index.jsx
+++ b/src/pages/dashboard/user-management/index.jsx
@@ -14,6 +14,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Dashboard.user_management_page",
isBot,
+ locale,
layout: {name: 'DashboardLayout', props: {permissions: ["manage_users"]}}
},
};
diff --git a/src/pages/login-expert.jsx b/src/pages/login-expert.jsx
index 1cc6abf..393f916 100644
--- a/src/pages/login-expert.jsx
+++ b/src/pages/login-expert.jsx
@@ -17,6 +17,7 @@ export async function getServerSideProps({req, locale}) {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Titles.title_login_expert_page",
isBot,
+ locale
},
};
}