add GlobalHead.jsx and NetworkComponent.jsx

and useNetwork.jsx and fixed bugs
This commit is contained in:
Amirhossein Mahmoodi
2023-08-23 11:12:18 +03:30
parent 4fae2f4da3
commit 0a7165c646
14 changed files with 186 additions and 158 deletions

View File

@@ -12,6 +12,8 @@
"lessThan": "کوچکتر از",
"greaterThan": "بزرگتر از",
"between": "میان",
"online_message": "شما به اینترنت وصل هستید",
"offline_message": "اتصال شما به اینترنت قطع شده است",
"header": {
"open_profile": "پروفایل",
"edit_profile": " پروفایل",

View File

@@ -16,7 +16,6 @@ import ImageResizer from "@/core/components/ImageConvertor";
const DashboardEditProfile = () => {
const t = useTranslations();
const {user, token, getUser, changeUser} = useUser();
console.log(user);
const {directionApp} = useDirection();
const editAvatar = async (avatar) => {
@@ -42,51 +41,7 @@ const DashboardEditProfile = () => {
}
};
const handleSubmit = (values, {setSubmitting}) => {
// const formData = new FormData();
// formData.append("email", values.expert_email);
// if (values.change_avatar !== false) {
// editAvatar(values.expert_avatar)
// .then(() => {
// return axios.post(UPDATE_PROFILE, formData, {
// headers: {
// authorization: `Bearer ${token}`,
// "Content-Type": "multipart/form-data",
// },
// });
// })
// .then((response) => {
// Notifications( t, response);
// getUser((data) => {
// changeUser(data);
// });
// })
// .catch((error) => {
// Notifications( t, error.response);
// })
// .finally(() => {
// setSubmitting(false);
// });
// } else {
// axios
// .post(UPDATE_PROFILE, formData, {
// headers: {
// authorization: `Bearer ${token}`,
// "Content-Type": "multipart/form-data",
// },
// })
// .then((response) => {
// Notifications( t, response);
// getUser((data) => {
// changeUser(data);
// });
// })
// .catch((error) => {
// Notifications( t, error.response);
// })
// .finally(() => {
// setSubmitting(false);
// });
// }
};
const initialValues = {
expert_avatar: null,
@@ -96,17 +51,7 @@ const DashboardEditProfile = () => {
province_name: user.province_name,
position: user.position,
};
const validationSchema = Yup.object().shape({
// username: Yup.string().required(t("UpdateProfile.error_message_required")),
// name: Yup.string().required(t("UpdateProfile.error_message_required")),
// email: Yup.string()
// .email(t("UpdateProfile.error_invalid_email"))
// .required(t("UpdateProfile.error_message_required")),
// province_name: Yup.string().required(
// t("UpdateProfile.error_message_required")
// ),
// position: Yup.string().required(t("UpdateProfile.error_message_required")),
});
const validationSchema = Yup.object().shape({});
return (
<DashboardLayouts>
@@ -264,19 +209,6 @@ const DashboardEditProfile = () => {
/>
</Grid>
</Grid>
{/* <Button
type="submit"
fullWidth
variant="contained"
color="primary"
size="large"
disabled={props.isSubmitting}
display="none"
>
{props.isSubmitting
? t("SubmitButton.button_while_submit")
: t("SubmitButton.button_submit")}
</Button> */}
</Stack>
</Paper>
</StyledForm>

View File

@@ -0,0 +1,58 @@
import Head from "next/head";
const GlobalHead = () => {
return (
<Head>
<meta
name="application-name"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<meta
name="apple-mobile-web-app-title"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="description" content="Marhaba does it for you"/>
<meta name="format-detection" content="telephone=no"/>
<meta name="format-detection" content="date=no"/>
<meta name="format-detection" content="address=no"/>
<meta name="format-detection" content="email=no"/>
<meta name="mobile-web-app-capable" content="yes"/>
<link rel="apple-touch-icon" href="/icons/maskable_icon_x512.png"/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="/icons/maskable_icon_x128.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/maskable_icon_x192.png"
/>
<meta name="google" content="notranslate"/>
<meta name="robots" content="noindex"/>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
/>
<link
rel="icon"
type="image/svg"
sizes="32x32"
href="/icons/favicon.png"
/>
<link
rel="icon"
type="image/svg"
sizes="16x16"
href="/icons/favicon.png"
/>
</Head>
)
}
export default GlobalHead

View File

@@ -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: <WifiIcon/>
});
return
}
toast.dismiss()
toastId.current = toast.warn(t('offline_message'), {
autoClose: false, closeButton: false, closeOnClick: false, icon: <WifiOffIcon/>
})
}, [network.online]);
return ''
}
export default NetworkComponent

View File

@@ -3,6 +3,7 @@ import {toast} from "react-toastify";
const PendingNotification = (t) => {
toast(t("notifications.pending"), {
autoClose: false,
closeButton: false,
closeOnClick: false,
draggable: false,
});

View File

@@ -42,7 +42,7 @@ const sidebarMenu = [
{
key: "sidebar.passenger-boss",
secondary: "secondary.passenger-boss",
name: "province_manager_navgan",
name: "province_working_group",
type: "page",
route: "/dashboard/passenger-boss",
icon: <AssignmentIndIcon/>,

View File

@@ -3,15 +3,15 @@ import WarningNotification from "@/core/components/notifications/WarningNotifica
import {toast} from "react-toastify";
export const errorSetting = (t, notification) => {
//todo
if (notification) toast.dismiss();
}
export const errorRequest = (t, notification) => {
//todo
if (notification) toast.dismiss();
}
export const errorResponse = (response, clearToken, t, notification) => {
toast.dismiss();
if (notification) toast.dismiss();
if (isServerError(response.status)) {
errorServer(response, t, notification)
} else if (isClientError(response.status)) {

View File

@@ -2,8 +2,8 @@ import SuccessNotification from "@/core/components/notifications/SuccessNotifica
import {toast} from "react-toastify";
export const successRequest = (response, t, options) => {
toast.dismiss();
if (options.notification && options.success.notification.show) {
toast.dismiss();
SuccessNotification(t, response.status)
}
}

View File

@@ -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 (
<>
<Head>
<meta
name="application-name"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<meta
name="apple-mobile-web-app-title"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="description" content="Marhaba does it for you"/>
<meta name="format-detection" content="telephone=no"/>
<meta name="format-detection" content="date=no"/>
<meta name="format-detection" content="address=no"/>
<meta name="format-detection" content="email=no"/>
<meta name="mobile-web-app-capable" content="yes"/>
<link rel="apple-touch-icon" href="/icons/maskable_icon_x512.png"/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="/icons/maskable_icon_x128.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/maskable_icon_x192.png"
/>
<meta name="google" content="notranslate"/>
<meta name="robots" content="noindex"/>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
/>
<link
rel="icon"
type="image/svg"
sizes="32x32"
href="/icons/favicon.png"
/>
<link
rel="icon"
type="image/svg"
sizes="16x16"
href="/icons/favicon.png"
/>
</Head>
<NextNProgress
color={theme.palette.secondary.dark}
options={{showSpinner: false}}
/>
<ToastContainer position={directionApp === "ltr" ? "top-left" : "top-right"} rtl={directionApp === 'rtl'}/>
{children}
</>
);
return (<>
<GlobalHead/>
<NextNProgress
color={theme.palette.secondary.dark}
options={{showSpinner: false}}
/>
<ToastContainer position={directionApp === "ltr" ? "top-left" : "top-right"} rtl={directionApp === 'rtl'}/>
<NetworkComponent/>
{children}
</>);
}
export default AppLayout;

View File

@@ -10,7 +10,6 @@ import useNotification from "@/lib/app/hooks/useNotification";
const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
const t = useTranslations();
const {notification_count} = useNotification()
console.log(notification_count)
return (
<Fragment key={item.key}>

View File

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

View File

@@ -3,14 +3,11 @@ import {GET_SIDEBAR_NOTIFICATION} from "@/core/data/apiRoutes";
import useRequest from "@/lib/app/hooks/useRequest";
const useNotification = () => {
const requestServer = useRequest({auth: true})
const requestServer = useRequest({auth: true, notification: false})
//swr config
const fetcher = (...args) => {
return requestServer(args, 'get', {
pending: false,
success: {notification: {show: false}}
}).then((response) => {
return requestServer(args, 'get').then((response) => {
return response.data.data;
}).catch(() => {
})

View File

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

View File

@@ -3,7 +3,7 @@ import RolePermissionMiddleware from "@/middlewares/RolePermission";
import WithAuthMiddleware from "@/middlewares/WithAuth";
import {parse} from "next-useragent";
const requiredPermissions = ["manage_working_group_navgan"];
const requiredPermissions = ["manage_province_working_group_navgan"];
export default function PassengerBoss() {
return (
<WithAuthMiddleware>