fix bundle size by route

This commit is contained in:
karimalden 2024-08-07 15:59:34 +03:00
parent 1726dcaaef
commit 435c8ddad1
14 changed files with 85 additions and 188 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,71 +1,23 @@
import React, { Suspense, lazy, useEffect } from "react"; import { Suspense, lazy } from "react";
import { Route, Routes, useNavigate } from "react-router-dom"; import { Route, Routes } from "react-router-dom";
import Layout from "./Layout/Ui/Layout";
import { CrudRoute, menuItems } from "./Routes"; import { CrudRoute, menuItems } from "./Routes";
import { Spin } from "antd"; import { Spin } from "antd";
import { hasAbility } from "./utils/hasAbility"; import { hasAbility } from "./utils/hasAbility";
import useAuthState from "./zustand/AuthState"; import { renderRoutesRecursively } from "./Components/Routes/RenderRoutesRecursively";
import { TMenuItem } from "./types/App"; import { RenderRouteElement } from "./Components/Routes/RenderRouteElement";
import { useTranslation } from "react-i18next";
import SpinContainer from "./Components/Layout/SpinContainer";
const Page404 = lazy(() => import("./Layout/Ui/NotFoundPage")); const Page404 = lazy(() => import("./Layout/Ui/NotFoundPage"));
const Auth = lazy(() => import("./Pages/Auth/Page")); const Auth = lazy(() => import("./Pages/Auth/Page"));
const App = () => { 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 ( return (
<Routes> <Routes>
<Route <Route
key={"auth"} key={"auth"}
path={"/auth"} path={"/auth"}
element={ element={
<Suspense fallback={<Spin />}> <Suspense fallback={<Spin />}>
{" "} <Auth />
<Auth />{" "}
</Suspense> </Suspense>
} }
/> />
@ -73,9 +25,8 @@ const App = () => {
key={"Page404"} key={"Page404"}
path={"/*"} path={"/*"}
element={ element={
<Suspense fallback={<Spin />}> <Suspense fallback={<Spin />}>
{" "} <Page404 />
<Page404 />{" "}
</Suspense> </Suspense>
} }
/> />
@ -84,9 +35,6 @@ const App = () => {
{CrudRoute.map((route) => { {CrudRoute.map((route) => {
const useAbility = hasAbility(route.abilities, route.abilities_value); const useAbility = hasAbility(route.abilities, route.abilities_value);
const tableHeader = t(`${route?.header}`);
// useSetPageTitle(tableHeader,route?.path);
if (!useAbility) { if (!useAbility) {
return false; return false;
} }
@ -94,7 +42,7 @@ const App = () => {
<Route <Route
key={route.path ?? ""} key={route.path ?? ""}
path={route.path ?? ""} path={route.path ?? ""}
element={renderRouteElement(route)} element={RenderRouteElement(route)}
/> />
); );
})} })}

View 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>
);

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

View File

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

View File

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

View File

@ -1,10 +1,8 @@
import React, { useEffect } from "react"; import React from "react";
import { useGetTitleFromRoute } from "../../Hooks/useGetTitleFromRoute ";
import { Helmet } from "react-helmet";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import NavBar from "./NavBar"; import NavBar from "./NavBar";
import SideBar from "./SideBar"; import SideBar from "./SideBar";
import { USER_KEY } from "../../config/AppKey"; import ProtectedRouteProvider from "../../lib/ProtectedRouteProvider";
const Layout = ({ const Layout = ({
children, children,
@ -13,20 +11,16 @@ const Layout = ({
children: React.ReactNode; children: React.ReactNode;
className?: string; className?: string;
}) => { }) => {
const location = useLocation();
return ( return (
<> <>
<Helmet> <ProtectedRouteProvider className="Layout">
<title>{useGetTitleFromRoute(location.pathname)}</title>
</Helmet>
<div className="Layout">
<main className={`${className} Layout_Body`}> <main className={`${className} Layout_Body`}>
<NavBar /> <NavBar />
<div className="Layout_Children">{children}</div> <div className="Layout_Children">{children}</div>
</main> </main>
<SideBar /> <SideBar />
</div> </ProtectedRouteProvider>
</> </>
); );
}; };

View File

@ -4,7 +4,7 @@ import { useNavigate } from "react-router-dom";
function NotFoundPage() { function NotFoundPage() {
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<div className="not_foound_page"> <div className="not_found_page">
<div className="container-not-found"> <div className="container-not-found">
<p> <p>
404 <h6>|</h6>This page could not be found 404 <h6>|</h6>This page could not be found

View File

@ -9,7 +9,7 @@ function ProviderContainer({ children }: ChildrenType) {
return ( return (
<BrowserRouter basename="/"> <BrowserRouter basename="/">
<I18nProvider> <I18nProvider>
<QueryProvider> <QueryProvider>
<ToastProvider> <ToastProvider>
<AntdProvider> <AntdProvider>

View File

@ -1,7 +1,6 @@
import { TCrudRoute, TMenuItem } from "./types/App"; import { TCrudRoute, TMenuItem } from "./types/App";
import { FaHome, FaMoneyBill, FaUser } from "react-icons/fa"; import { FaHome, FaMoneyBill } from "react-icons/fa";
import { ImBooks } from "react-icons/im"; import React from "react";
import React, { lazy } from "react";
const Dummy = React.lazy(() => import("./Pages/Home/Dummy")); const Dummy = React.lazy(() => import("./Pages/Home/Dummy"));
const Subject = React.lazy(() => import("./Pages/subject/Table/Page")); const Subject = React.lazy(() => import("./Pages/subject/Table/Page"));

View File

@ -36,7 +36,7 @@ svg {
cursor: pointer; cursor: pointer;
} }
.not_foound_page { .not_found_page {
background: black; background: black;
height: 100vh; height: 100vh;
display: flex; display: flex;

View File

@ -10,8 +10,6 @@ function useAddMutation(
toast: boolean = true, toast: boolean = true,
): UseMutationResult<AxiosResponse, unknown, any, unknown> { ): UseMutationResult<AxiosResponse, unknown, any, unknown> {
const axios = useAxios(); const axios = useAxios();
console.log(toast, key);
return useMutation<AxiosResponse, unknown, any, unknown>( return useMutation<AxiosResponse, unknown, any, unknown>(
async (dataToSend) => { async (dataToSend) => {
const filterDataToSend = filterData(dataToSend); const filterDataToSend = filterData(dataToSend);

View File

@ -1,8 +1,4 @@
import {
BRANCH_OBJECT_KEY,
CYCLE_OBJECT_KEY,
TERM_OBJECT_KEY,
} from "../../config/AppKey";
import useAuthState from "../../zustand/AuthState"; import useAuthState from "../../zustand/AuthState";
import { BaseURL, HEADER_KEY } from "../config"; import { BaseURL, HEADER_KEY } from "../config";
import AxiosBuilder from "./AxiosBuilder"; import AxiosBuilder from "./AxiosBuilder";
@ -12,7 +8,6 @@ import { useQueryClient } from "react-query";
import { useValidationState } from "../../Components/ValidationField/utils/ValidationState"; import { useValidationState } from "../../Components/ValidationField/utils/ValidationState";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { AxiosQueryEnum, AxiosStatusEnum } from "../../enums/Axios"; import { AxiosQueryEnum, AxiosStatusEnum } from "../../enums/Axios";
import { getLocalStorage } from "../../utils/LocalStorage";
function useAxios() { function useAxios() {
const { isAuthenticated, token } = useAuthState(); const { isAuthenticated, token } = useAuthState();
@ -43,7 +38,6 @@ function useAxios() {
const key = response.config.headers[HEADER_KEY]; const key = response.config.headers[HEADER_KEY];
const isToasted = response.config.headers["X-Custom-Message"]; const isToasted = response.config.headers["X-Custom-Message"];
console.log(isToasted);
const ResponseMessage = const ResponseMessage =
responseMsg || t("validation.the_possess_done_successful"); responseMsg || t("validation.the_possess_done_successful");

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