fix bundle size by route
This commit is contained in:
parent
1726dcaaef
commit
435c8ddad1
File diff suppressed because one or more lines are too long
70
src/App.tsx
70
src/App.tsx
|
|
@ -1,71 +1,23 @@
|
|||
import React, { Suspense, lazy, useEffect } from "react";
|
||||
import { Route, Routes, useNavigate } from "react-router-dom";
|
||||
import Layout from "./Layout/Ui/Layout";
|
||||
import { Suspense, lazy } from "react";
|
||||
import { Route, Routes } from "react-router-dom";
|
||||
import { CrudRoute, menuItems } from "./Routes";
|
||||
import { Spin } from "antd";
|
||||
import { hasAbility } from "./utils/hasAbility";
|
||||
import useAuthState from "./zustand/AuthState";
|
||||
import { TMenuItem } from "./types/App";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import SpinContainer from "./Components/Layout/SpinContainer";
|
||||
import { renderRoutesRecursively } from "./Components/Routes/RenderRoutesRecursively";
|
||||
import { RenderRouteElement } from "./Components/Routes/RenderRouteElement";
|
||||
|
||||
const Page404 = lazy(() => import("./Layout/Ui/NotFoundPage"));
|
||||
const Auth = lazy(() => import("./Pages/Auth/Page"));
|
||||
|
||||
const App = () => {
|
||||
const navigate = useNavigate();
|
||||
const { isAuthenticated } = useAuthState();
|
||||
const [t] = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthenticated) {
|
||||
navigate("/auth");
|
||||
}
|
||||
}, [isAuthenticated, navigate]);
|
||||
|
||||
const renderRouteElement = (route: any) => (
|
||||
<Suspense
|
||||
fallback={
|
||||
<Layout>
|
||||
{" "}
|
||||
<SpinContainer />{" "}
|
||||
</Layout>
|
||||
}
|
||||
>
|
||||
{route.header ? (
|
||||
<Layout>{route.element}</Layout>
|
||||
) : (
|
||||
route.element || <h1>please Create the Page</h1>
|
||||
)}
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
const renderRoutesRecursively = (routes: TMenuItem[]) =>
|
||||
routes.map((route: TMenuItem) => {
|
||||
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
||||
const tableHeader = t(`${route?.header}`);
|
||||
// useSetPageTitle(tableHeader,route?.path);
|
||||
|
||||
if (useAbility) {
|
||||
return (
|
||||
<React.Fragment key={route.path}>
|
||||
<Route path={route.path} element={renderRouteElement(route)} />
|
||||
{route.children && renderRoutesRecursively(route.children)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
key={"auth"}
|
||||
path={"/auth"}
|
||||
element={
|
||||
<Suspense fallback={<Spin />}>
|
||||
{" "}
|
||||
<Auth />{" "}
|
||||
<Suspense fallback={<Spin />}>
|
||||
<Auth />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
|
|
@ -73,9 +25,8 @@ const App = () => {
|
|||
key={"Page404"}
|
||||
path={"/*"}
|
||||
element={
|
||||
<Suspense fallback={<Spin />}>
|
||||
{" "}
|
||||
<Page404 />{" "}
|
||||
<Suspense fallback={<Spin />}>
|
||||
<Page404 />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
|
|
@ -84,9 +35,6 @@ const App = () => {
|
|||
|
||||
{CrudRoute.map((route) => {
|
||||
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
||||
const tableHeader = t(`${route?.header}`);
|
||||
// useSetPageTitle(tableHeader,route?.path);
|
||||
|
||||
if (!useAbility) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -94,7 +42,7 @@ const App = () => {
|
|||
<Route
|
||||
key={route.path ?? ""}
|
||||
path={route.path ?? ""}
|
||||
element={renderRouteElement(route)}
|
||||
element={RenderRouteElement(route)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
19
src/Components/Routes/RenderRouteElement.tsx
Normal file
19
src/Components/Routes/RenderRouteElement.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { Layout } from "antd";
|
||||
import { Suspense } from "react";
|
||||
import SpinContainer from "../Layout/SpinContainer";
|
||||
|
||||
export const RenderRouteElement = (route: any) => (
|
||||
<Suspense
|
||||
fallback={
|
||||
<Layout>
|
||||
<SpinContainer />
|
||||
</Layout>
|
||||
}
|
||||
>
|
||||
{route.header ? (
|
||||
<Layout>{route.element}</Layout>
|
||||
) : (
|
||||
route.element || <></>
|
||||
)}
|
||||
</Suspense>
|
||||
);
|
||||
20
src/Components/Routes/RenderRoutesRecursively.tsx
Normal file
20
src/Components/Routes/RenderRoutesRecursively.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React from "react";
|
||||
import { TMenuItem } from "../../types/App";
|
||||
import { hasAbility } from "../../utils/hasAbility";
|
||||
import { Route } from "react-router-dom";
|
||||
import { RenderRouteElement } from "./RenderRouteElement";
|
||||
|
||||
export const renderRoutesRecursively = (routes: TMenuItem[]) =>
|
||||
routes.map((route: TMenuItem) => {
|
||||
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
||||
if (!useAbility) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
<React.Fragment key={route.path}>
|
||||
<Route path={route.path} element={RenderRouteElement(route)} />
|
||||
{route.children && renderRoutesRecursively(route.children)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
import React, { memo } from "react";
|
||||
import type { MenuProps } from "antd";
|
||||
import { Button, Dropdown, Space } from "antd";
|
||||
import { useChangeLanguage } from "../../Hooks/useChangeLanguage";
|
||||
import { useTranslation } from "react-i18next";
|
||||
const Translate: React.FC = () => {
|
||||
const { currentLanguage, changeLanguage } = useChangeLanguage();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const EnLanguage = memo(() => (
|
||||
<div className="MenuChange" onClick={EnLanguageClickHandler}>
|
||||
<img alt="" src="../Layout/En.svg" width={20} height={20} />
|
||||
{t("En")}
|
||||
</div>
|
||||
));
|
||||
|
||||
const ArLanguage = memo(() => (
|
||||
<div className="MenuChange" onClick={ArLanguageClickHandler}>
|
||||
<img alt="" src="../Layout/Ar.svg" width={20} height={20} />
|
||||
{t("Ar")}
|
||||
</div>
|
||||
));
|
||||
|
||||
const EnLanguageClickHandler = React.useCallback(() => {
|
||||
changeLanguage("en");
|
||||
}, [changeLanguage]);
|
||||
|
||||
const ArLanguageClickHandler = React.useCallback(() => {
|
||||
changeLanguage("ar");
|
||||
}, [changeLanguage]);
|
||||
|
||||
const items: MenuProps["items"] = [
|
||||
{
|
||||
key: "1",
|
||||
label: <EnLanguage />,
|
||||
},
|
||||
{
|
||||
key: "2",
|
||||
label: <ArLanguage />,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Space direction="vertical">
|
||||
<Dropdown menu={{ items }} placement="top">
|
||||
<Button disabled>
|
||||
{currentLanguage === "en" ? <EnLanguage /> : <ArLanguage />}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
export default Translate;
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import { useCallback, useLayoutEffect, useState } from "react";
|
||||
import translationEN from "../translate/en.json";
|
||||
import translationAR from "../translate/ar.json";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import i18n from "i18next"; // Make sure this import is correct
|
||||
import { LANGUAGE_KEY } from "../config/AppKey";
|
||||
|
||||
i18n.use(initReactI18next).init({
|
||||
resources: {
|
||||
en: {
|
||||
translation: translationEN,
|
||||
},
|
||||
ar: {
|
||||
translation: translationAR,
|
||||
},
|
||||
},
|
||||
lng: localStorage.getItem(LANGUAGE_KEY) || "ar",
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
});
|
||||
|
||||
export const useChangeLanguage = () => {
|
||||
const [currentLanguage, setCurrentLanguage] = useState(
|
||||
localStorage.getItem(LANGUAGE_KEY) || "ar",
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (currentLanguage === "ar") {
|
||||
i18n.changeLanguage("ar");
|
||||
document.body.setAttribute("dir", "rtl");
|
||||
document.body.classList.remove("en");
|
||||
} else if (currentLanguage === "en") {
|
||||
i18n.changeLanguage("en");
|
||||
document.body.setAttribute("dir", "ltr");
|
||||
document.body.classList.add("en");
|
||||
}
|
||||
|
||||
localStorage.setItem(LANGUAGE_KEY, currentLanguage);
|
||||
}, [currentLanguage]);
|
||||
|
||||
const changeLanguage = useCallback((newLanguage: any) => {
|
||||
setCurrentLanguage(newLanguage);
|
||||
}, []);
|
||||
|
||||
return { currentLanguage, changeLanguage };
|
||||
};
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { useGetTitleFromRoute } from "../../Hooks/useGetTitleFromRoute ";
|
||||
import { Helmet } from "react-helmet";
|
||||
import React from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import NavBar from "./NavBar";
|
||||
import SideBar from "./SideBar";
|
||||
import { USER_KEY } from "../../config/AppKey";
|
||||
import ProtectedRouteProvider from "../../lib/ProtectedRouteProvider";
|
||||
|
||||
const Layout = ({
|
||||
children,
|
||||
|
|
@ -13,20 +11,16 @@ const Layout = ({
|
|||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) => {
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{useGetTitleFromRoute(location.pathname)}</title>
|
||||
</Helmet>
|
||||
<div className="Layout">
|
||||
<ProtectedRouteProvider className="Layout">
|
||||
<main className={`${className} Layout_Body`}>
|
||||
<NavBar />
|
||||
<div className="Layout_Children">{children}</div>
|
||||
</main>
|
||||
<SideBar />
|
||||
</div>
|
||||
</ProtectedRouteProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useNavigate } from "react-router-dom";
|
|||
function NotFoundPage() {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div className="not_foound_page">
|
||||
<div className="not_found_page">
|
||||
<div className="container-not-found">
|
||||
<p>
|
||||
404 <h6>|</h6>This page could not be found
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ function ProviderContainer({ children }: ChildrenType) {
|
|||
return (
|
||||
<BrowserRouter basename="/">
|
||||
<I18nProvider>
|
||||
<QueryProvider>
|
||||
<QueryProvider>
|
||||
<ToastProvider>
|
||||
<AntdProvider>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { TCrudRoute, TMenuItem } from "./types/App";
|
||||
import { FaHome, FaMoneyBill, FaUser } from "react-icons/fa";
|
||||
import { ImBooks } from "react-icons/im";
|
||||
import React, { lazy } from "react";
|
||||
import { FaHome, FaMoneyBill } from "react-icons/fa";
|
||||
import React from "react";
|
||||
const Dummy = React.lazy(() => import("./Pages/Home/Dummy"));
|
||||
|
||||
const Subject = React.lazy(() => import("./Pages/subject/Table/Page"));
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ svg {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.not_foound_page {
|
||||
.not_found_page {
|
||||
background: black;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ function useAddMutation(
|
|||
toast: boolean = true,
|
||||
): UseMutationResult<AxiosResponse, unknown, any, unknown> {
|
||||
const axios = useAxios();
|
||||
console.log(toast, key);
|
||||
|
||||
return useMutation<AxiosResponse, unknown, any, unknown>(
|
||||
async (dataToSend) => {
|
||||
const filterDataToSend = filterData(dataToSend);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
import {
|
||||
BRANCH_OBJECT_KEY,
|
||||
CYCLE_OBJECT_KEY,
|
||||
TERM_OBJECT_KEY,
|
||||
} from "../../config/AppKey";
|
||||
|
||||
import useAuthState from "../../zustand/AuthState";
|
||||
import { BaseURL, HEADER_KEY } from "../config";
|
||||
import AxiosBuilder from "./AxiosBuilder";
|
||||
|
|
@ -12,7 +8,6 @@ import { useQueryClient } from "react-query";
|
|||
import { useValidationState } from "../../Components/ValidationField/utils/ValidationState";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { AxiosQueryEnum, AxiosStatusEnum } from "../../enums/Axios";
|
||||
import { getLocalStorage } from "../../utils/LocalStorage";
|
||||
|
||||
function useAxios() {
|
||||
const { isAuthenticated, token } = useAuthState();
|
||||
|
|
@ -43,7 +38,6 @@ function useAxios() {
|
|||
|
||||
const key = response.config.headers[HEADER_KEY];
|
||||
const isToasted = response.config.headers["X-Custom-Message"];
|
||||
console.log(isToasted);
|
||||
|
||||
const ResponseMessage =
|
||||
responseMsg || t("validation.the_possess_done_successful");
|
||||
|
|
|
|||
26
src/lib/ProtectedRouteProvider.tsx
Normal file
26
src/lib/ProtectedRouteProvider.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { useNavigate } from "react-router-dom";
|
||||
import useAuthState from "../zustand/AuthState";
|
||||
import { useEffect } from "react";
|
||||
|
||||
interface ProtectedRouteProviderProps extends React.HTMLProps<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function ProtectedRouteProvider({ children, ...props }: ProtectedRouteProviderProps) {
|
||||
const navigate = useNavigate();
|
||||
const { isAuthenticated } = useAuthState();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthenticated) {
|
||||
navigate("/auth");
|
||||
}
|
||||
}, [isAuthenticated, navigate]);
|
||||
|
||||
return (
|
||||
<div {...props}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProtectedRouteProvider;
|
||||
Loading…
Reference in New Issue
Block a user