hexabot/frontend/src/pages/_app.tsx
2024-09-30 15:44:20 +01:00

108 lines
3.9 KiB
TypeScript

/*
* Copyright © 2024 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import { CssBaseline } from "@mui/material";
import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
import type { NextPage } from "next";
import type { AppProps } from "next/app";
import { Roboto } from "next/font/google";
import Head from "next/head";
import { type ReactElement, type ReactNode } from "react";
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
import { SnackbarCloseButton } from "@/app-components/displays/Toast/CloseButton";
import { ApiClientProvider } from "@/contexts/apiClient.context";
import { AuthProvider } from "@/contexts/auth.context";
import { ConfigProvider } from "@/contexts/config.context";
import { PermissionProvider } from "@/contexts/permission.context";
import { SettingsProvider } from "@/contexts/setting.context";
import { ToastProvider } from "@/hooks/useToast";
import { theme } from "@/layout/themes/theme";
import { SocketProvider } from "@/websocket/socket-hooks";
import "../components/inbox/inbox.css";
import "../i18n/config";
import "../styles/globals.css";
import "../styles/visual-editor.css";
type TNextPageWithLayout = NextPage & {
// eslint-disable-next-line no-unused-vars
getLayout?: (page: ReactElement) => ReactNode;
};
type TAppPropsWithLayout = AppProps & {
Component: TNextPageWithLayout;
};
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
refetchOnWindowFocus: false,
staleTime: Infinity,
cacheTime: Infinity,
},
},
});
export const roboto = Roboto({
subsets: ["latin"],
weight: ["100", "300", "400", "700", "900", "500"],
});
const App = ({ Component, pageProps }: TAppPropsWithLayout) => {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
return (
<>
<Head>
<title>Hexabot</title>
<link rel="icon" href="/images/favicon.ico" />
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
/>
</Head>
<main className={roboto.className}>
<ConfigProvider>
<ThemeProvider theme={theme}>
<ToastProvider
maxSnack={3}
anchorOrigin={{ vertical: "top", horizontal: "center" }}
action={(snackbarKey) => (
<SnackbarCloseButton snackbarKey={snackbarKey} />
)}
>
<StyledEngineProvider injectFirst>
<QueryClientProvider client={queryClient}>
<CssBaseline />
<ApiClientProvider>
<AuthProvider>
<PermissionProvider>
<SettingsProvider>
<SocketProvider>
{getLayout(<Component {...pageProps} />)}
</SocketProvider>
</SettingsProvider>
</PermissionProvider>
</AuthProvider>
</ApiClientProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</StyledEngineProvider>
</ToastProvider>
</ThemeProvider>
</ConfigProvider>
</main>
</>
);
};
export default App;