LFFE-12 add toast and correct the user and language bsaed on it

This commit is contained in:
2023-11-05 14:37:22 +03:30
parent c12154368a
commit 8833120e31
7 changed files with 68 additions and 65 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) =>

View File

@@ -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]);
})
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}, []);

View File

@@ -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]

View File

@@ -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)
})

View File

@@ -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}) => {
<MuiLayout isBot={pageProps.isBot}>
{pageProps.messages ? <TitlePage text={pageProps.title}/> : ''}
<LoadingProvider>
<AppLayout isBot={pageProps.isBot}>
<Layout layout={pageProps.layout}>
<Component {...pageProps} />
</Layout>
</AppLayout>
<ToastProvider>
<AppLayout isBot={pageProps.isBot}>
<Layout layout={pageProps.layout}>
<Component {...pageProps} />
</Layout>
</AppLayout>
</ToastProvider>
</LoadingProvider>
</MuiLayout>
</NextIntlProvider>