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
66
src/App.tsx
66
src/App.tsx
|
|
@ -1,62 +1,15 @@
|
||||||
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
|
||||||
|
|
@ -64,8 +17,7 @@ const App = () => {
|
||||||
path={"/auth"}
|
path={"/auth"}
|
||||||
element={
|
element={
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
{" "}
|
<Auth />
|
||||||
<Auth />{" "}
|
|
||||||
</Suspense>
|
</Suspense>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -74,8 +26,7 @@ const App = () => {
|
||||||
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)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
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 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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ function ProviderContainer({ children }: ChildrenType) {
|
||||||
return (
|
return (
|
||||||
<BrowserRouter basename="/">
|
<BrowserRouter basename="/">
|
||||||
<I18nProvider>
|
<I18nProvider>
|
||||||
<QueryProvider>
|
<QueryProvider>
|
||||||
<ToastProvider>
|
<ToastProvider>
|
||||||
<AntdProvider>
|
<AntdProvider>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"));
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
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