diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json
index 435a0c7..c91dc84 100644
--- a/public/locales/fa/app.json
+++ b/public/locales/fa/app.json
@@ -15,6 +15,8 @@
"Resend_code_in": "ارسال مجدد کد در",
"seconds_later": "ثانیه دیگر",
"upload_file_text": "بارگذاری فایل",
+ "online_message": "شما به اینترنت وصل هستید",
+ "offline_message": "اتصال شما به اینترنت قطع شده است",
"header": {
"open_profile": "پروفایل",
"edit_profile": "ویرایش پروفایل",
diff --git a/src/core/components/GlobalHead.jsx b/src/core/components/GlobalHead.jsx
new file mode 100644
index 0000000..5d6186d
--- /dev/null
+++ b/src/core/components/GlobalHead.jsx
@@ -0,0 +1,58 @@
+import Head from "next/head";
+
+const GlobalHead = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default GlobalHead
\ No newline at end of file
diff --git a/src/core/components/NetworkComponent.jsx b/src/core/components/NetworkComponent.jsx
new file mode 100644
index 0000000..8ebbb68
--- /dev/null
+++ b/src/core/components/NetworkComponent.jsx
@@ -0,0 +1,34 @@
+import useNetwork from "@/lib/app/hooks/useNetwork";
+import {useEffect, useRef} from "react";
+import {toast} from "react-toastify";
+import WifiIcon from '@mui/icons-material/Wifi';
+import WifiOffIcon from '@mui/icons-material/WifiOff';
+import {useTranslations} from "next-intl";
+
+const NetworkComponent = () => {
+ const toastId = useRef(null);
+ const network = useNetwork()
+ const t = useTranslations()
+
+ useEffect(() => {
+ if (network.online) {
+ toast.update(toastId.current, {
+ type: toast.TYPE.SUCCESS,
+ render: t('online_message'),
+ autoClose: 2000,
+ closeButton: true,
+ closeOnClick: true,
+ icon:
+ });
+ return
+ }
+ toast.dismiss()
+ toastId.current = toast.warn(t('offline_message'), {
+ autoClose: false, closeButton: false, closeOnClick: false, icon:
+ })
+ }, [network.online]);
+
+ return ''
+}
+
+export default NetworkComponent
\ No newline at end of file
diff --git a/src/layouts/AppLayout.jsx b/src/layouts/AppLayout.jsx
index 611e707..2b4593b 100644
--- a/src/layouts/AppLayout.jsx
+++ b/src/layouts/AppLayout.jsx
@@ -2,12 +2,13 @@ import theme from "@/core/utils/theme";
import useLanguage from "@/lib/app/hooks/useLanguage";
import useLoading from "@/lib/app/hooks/useLoading";
import useUser from "@/lib/app/hooks/useUser";
-import Head from "next/head";
import NextNProgress from "nextjs-progressbar";
import {useEffect} from "react";
import {ToastContainer} from "react-toastify";
import useDirection from "@/lib/app/hooks/useDirection";
import "react-toastify/dist/ReactToastify.css";
+import NetworkComponent from "@/core/components/NetworkComponent";
+import GlobalHead from "@/core/components/GlobalHead";
function AppLayout({children, isBot}) {
const {languageIsReady} = useLanguage();
@@ -40,66 +41,16 @@ function AppLayout({children, isBot}) {
if (!languageIsReady) return;
}
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {children}
- >
- );
+ return (<>
+
+
+
+
+ {children}
+ >);
}
-export default AppLayout;
+export default AppLayout;
\ No newline at end of file
diff --git a/src/lib/app/hooks/useNetwork.jsx b/src/lib/app/hooks/useNetwork.jsx
new file mode 100644
index 0000000..4fff7fe
--- /dev/null
+++ b/src/lib/app/hooks/useNetwork.jsx
@@ -0,0 +1,58 @@
+import {useEffect, useState} from "react";
+
+function getNetworkConnection() {
+ return (
+ navigator.connection ||
+ navigator.mozConnection ||
+ navigator.webkitConnection ||
+ null
+ );
+}
+
+function getNetworkConnectionInfo() {
+ const connection = getNetworkConnection();
+ if (!connection) {
+ return {};
+ }
+ return {
+ rtt: connection.rtt,
+ type: connection.type,
+ saveData: connection.saveData,
+ downLink: connection.downLink,
+ downLinkMax: connection.downLinkMax,
+ effectiveType: connection.effectiveType,
+ };
+}
+
+function useNetwork() {
+ const [state, setState] = useState(() => {
+ return {
+ online: navigator.onLine,
+ };
+ });
+ useEffect(() => {
+ const handleOnline = () => {
+ setState((prevState) => ({
+ ...prevState,
+ online: true,
+ }));
+ };
+ const handleOffline = () => {
+ setState((prevState) => ({
+ ...prevState,
+ online: false,
+ }));
+ };
+
+ window.addEventListener("online", handleOnline);
+ window.addEventListener("offline", handleOffline);
+ return () => {
+ window.removeEventListener("online", handleOnline);
+ window.removeEventListener("offline", handleOffline);
+ };
+ }, []);
+
+ return state;
+}
+
+export default useNetwork;
\ No newline at end of file
diff --git a/src/lib/app/hooks/useRequest.js b/src/lib/app/hooks/useRequest.js
index 5c567ca..d361e08 100644
--- a/src/lib/app/hooks/useRequest.js
+++ b/src/lib/app/hooks/useRequest.js
@@ -4,27 +4,23 @@ import PendingNotification from "@/core/components/notifications/PendingNotifica
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";
const defaultOptions = {
- auth: false,
- data: {},
- requestOptions: {
+ auth: false, data: {}, requestOptions: {
headers: {}
- },
- notification: true,
- pending: true,
- success: {
+ }, notification: true, pending: true, success: {
notification: {
show: true,
},
- },
- failed: {
+ }, failed: {
notification: {
show: true,
},
},
}
const useRequest = (initOptions) => {
+ const network = useNetwork()
const t = useTranslations()
const {token, clearToken} = useUser()
let _options = {...defaultOptions, ...initOptions}
@@ -32,20 +28,20 @@ const useRequest = (initOptions) => {
function requestServer(url = '', method = 'get', options) {
_options = {..._options, ...options}
if (_options.auth) _options = {
- ..._options,
- requestOptions: {
+ ..._options, requestOptions: {
..._options.requestOptions,
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)
axios({
- url: url,
- method: method,
- data: _options.data,
- ..._options.requestOptions
+ url: url, method: method, data: _options.data, ..._options.requestOptions
})
.then(response => {
successRequest(response, t, _options)