diff --git a/apps/web/Components/Common/Loading.jsx b/apps/web/Components/Common/Loading.jsx
new file mode 100644
index 0000000..7edd339
--- /dev/null
+++ b/apps/web/Components/Common/Loading.jsx
@@ -0,0 +1,14 @@
+import getColors from '@/styles/colors';
+import { Result } from 'ui/elements';
+import { LoadingOutlined } from 'ui/elements/icons';
+
+const colors = getColors();
+
+export function Loading() {
+ return (
+ }
+ title="Загрузка..."
+ />
+ );
+}
diff --git a/apps/web/Components/Common/index.ts b/apps/web/Components/Common/index.ts
new file mode 100644
index 0000000..fc3571a
--- /dev/null
+++ b/apps/web/Components/Common/index.ts
@@ -0,0 +1,3 @@
+export * from './Error';
+export * from './Loading';
+export * from './Notification';
diff --git a/apps/web/hooks/index.ts b/apps/web/hooks/index.ts
new file mode 100644
index 0000000..22652cc
--- /dev/null
+++ b/apps/web/hooks/index.ts
@@ -0,0 +1 @@
+export * from './loading';
diff --git a/apps/web/hooks/loading.ts b/apps/web/hooks/loading.ts
new file mode 100644
index 0000000..5003ff5
--- /dev/null
+++ b/apps/web/hooks/loading.ts
@@ -0,0 +1,30 @@
+import { useRouter } from 'next/router';
+import { useEffect, useState } from 'react';
+
+export function usePageLoading() {
+ const [loading, setLoading] = useState(false);
+ const router = useRouter();
+
+ function handleStart() {
+ return setLoading(true);
+ }
+ function handleComplete() {
+ return setLoading(false);
+ }
+
+ useEffect(() => {
+ router.events.on('routeChangeStart', handleStart);
+ router.events.on('routeChangeComplete', handleComplete);
+ router.events.on('routeChangeError', handleComplete);
+
+ return () => {
+ router.events.off('routeChangeStart', handleStart);
+ router.events.off('routeChangeComplete', handleComplete);
+ router.events.off('routeChangeError', handleComplete);
+ };
+ }, []);
+
+ return {
+ loading,
+ };
+}
diff --git a/apps/web/pages/_app.jsx b/apps/web/pages/_app.jsx
index 2c4de9f..20c0bd4 100644
--- a/apps/web/pages/_app.jsx
+++ b/apps/web/pages/_app.jsx
@@ -4,9 +4,10 @@ import '../styles/globals.css';
import '../styles/antd-fix.css';
import initializeQueryClient from '@/api/client';
import initializeApollo from '@/apollo/client';
-import { Notification } from '@/Components/Common/Notification';
+import { Loading, Notification } from '@/Components/Common';
import Layout from '@/Components/Layout';
import { theme } from '@/config/ui';
+import { usePageLoading } from '@/hooks';
import StoreProvider from '@/stores/Provider';
import getColors from '@/styles/colors';
import { GlobalStyle } from '@/styles/global-style';
@@ -29,6 +30,8 @@ function App({ Component, pageProps }) {
const apolloClient = useMemo(() => initializeApollo(initialApolloState), [initialApolloState]);
const queryClient = useMemo(() => initializeQueryClient(initialQueryState), [initialQueryState]);
+ const { loading } = usePageLoading();
+
return (
@@ -53,7 +56,7 @@ function App({ Component, pageProps }) {
>
-
+ {loading ? : }