feat: loading and error pages
This commit is contained in:
@ -3,19 +3,28 @@ import {
|
||||
HydrationBoundary,
|
||||
QueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
import PageBody from "@/app/deals/components/shared/PageBody/PageBody";
|
||||
import { BoardsContextProvider } from "@/app/deals/contexts/BoardsContext";
|
||||
import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext";
|
||||
import { StatusesContextProvider } from "@/app/deals/contexts/StatusesContext";
|
||||
import { ViewContextProvider } from "@/app/deals/contexts/ViewContext";
|
||||
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||
import PageContainer from "@/components/layout/PageContainer/PageContainer";
|
||||
import { Suspense } from "react";
|
||||
import { Loader, Center } from "@mantine/core";
|
||||
import dynamic from "next/dynamic";
|
||||
import {
|
||||
getBoardsOptions,
|
||||
getProjectsOptions,
|
||||
} from "@/lib/client/@tanstack/react-query.gen";
|
||||
import { combineProviders } from "@/utils/combineProviders";
|
||||
import TopToolPanel from "./components/desktop/TopToolPanel/TopToolPanel";
|
||||
|
||||
// Dynamic imports for better code splitting
|
||||
const PageBody = dynamic(() => import("@/app/deals/components/shared/PageBody/PageBody"), {
|
||||
loading: () => <Center h={400}><Loader /></Center>
|
||||
});
|
||||
const BoardsContextProvider = dynamic(() => import("@/app/deals/contexts/BoardsContext").then(mod => ({ default: mod.BoardsContextProvider })));
|
||||
const ProjectsContextProvider = dynamic(() => import("@/app/deals/contexts/ProjectsContext").then(mod => ({ default: mod.ProjectsContextProvider })));
|
||||
const StatusesContextProvider = dynamic(() => import("@/app/deals/contexts/StatusesContext").then(mod => ({ default: mod.StatusesContextProvider })));
|
||||
const ViewContextProvider = dynamic(() => import("@/app/deals/contexts/ViewContext").then(mod => ({ default: mod.ViewContextProvider })));
|
||||
const PageBlock = dynamic(() => import("@/components/layout/PageBlock/PageBlock"));
|
||||
const PageContainer = dynamic(() => import("@/components/layout/PageContainer/PageContainer"));
|
||||
const TopToolPanel = dynamic(() => import("./components/desktop/TopToolPanel/TopToolPanel"), {
|
||||
loading: () => <div style={{ height: 60 }} />
|
||||
});
|
||||
|
||||
async function prefetchData() {
|
||||
const queryClient = new QueryClient();
|
||||
@ -44,12 +53,18 @@ export default async function DealsPage() {
|
||||
|
||||
return (
|
||||
<Providers>
|
||||
<PageContainer>
|
||||
<TopToolPanel />
|
||||
<PageBlock>
|
||||
<PageBody />
|
||||
</PageBlock>
|
||||
</PageContainer>
|
||||
<Suspense fallback={
|
||||
<Center h="50vh">
|
||||
<Loader size="lg" />
|
||||
</Center>
|
||||
}>
|
||||
<PageContainer>
|
||||
<TopToolPanel />
|
||||
<PageBlock>
|
||||
<PageBody />
|
||||
</PageBlock>
|
||||
</PageContainer>
|
||||
</Suspense>
|
||||
</Providers>
|
||||
);
|
||||
}
|
||||
|
||||
23
src/app/error.tsx
Normal file
23
src/app/error.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import { Button, Center, Stack, Text } from "@mantine/core";
|
||||
|
||||
export default function Error({
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}) {
|
||||
return (
|
||||
<Center h="100vh">
|
||||
<Stack align="center">
|
||||
<Text
|
||||
size="lg"
|
||||
fw={500}>
|
||||
Что-то пошло не так
|
||||
</Text>
|
||||
<Button onClick={reset}>Попробовать снова</Button>
|
||||
</Stack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
9
src/app/loading.tsx
Normal file
9
src/app/loading.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { Center, Loader } from "@mantine/core";
|
||||
|
||||
export default function Loading() {
|
||||
return (
|
||||
<Center h="100vh">
|
||||
<Loader size="lg" />
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
@ -13,7 +13,14 @@ export function ReactQueryProvider({ children }: Props) {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
staleTime: 3 * 60 * 1000,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
gcTime: 10 * 60 * 1000, // 10 minutes
|
||||
retry: 1,
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnMount: false,
|
||||
},
|
||||
mutations: {
|
||||
retry: 1,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
import { ReactNode } from "react";
|
||||
import { Provider } from "react-redux";
|
||||
import { PersistGate } from "redux-persist/integration/react";
|
||||
import { Center, Loader } from "@mantine/core";
|
||||
import { persistor, store } from "@/lib/store/store";
|
||||
|
||||
type Props = {
|
||||
@ -12,9 +13,12 @@ type Props = {
|
||||
export default function ReduxProvider({ children }: Props) {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
{" "}
|
||||
<PersistGate
|
||||
loading={null}
|
||||
loading={
|
||||
<Center h="100vh">
|
||||
<Loader size="sm" />
|
||||
</Center>
|
||||
}
|
||||
persistor={persistor}>
|
||||
{children}
|
||||
</PersistGate>
|
||||
|
||||
@ -19,6 +19,7 @@ const radius = "md";
|
||||
const font = Roboto({
|
||||
subsets: ["latin"],
|
||||
weight: ["400"],
|
||||
preload: true,
|
||||
});
|
||||
|
||||
export const theme = createTheme({
|
||||
|
||||
Reference in New Issue
Block a user