react query: globally show error toast
This commit is contained in:
parent
284142eb4f
commit
bbf3a98bd5
@ -1,4 +1,5 @@
|
|||||||
import { AuthProvider } from '@/providers/auth';
|
import { AuthProvider } from '@/providers/auth';
|
||||||
|
import { ErrorProvider } from '@/providers/error';
|
||||||
import { QueryProvider } from '@/providers/query';
|
import { QueryProvider } from '@/providers/query';
|
||||||
import { ThemeProvider } from '@/providers/theme-provider';
|
import { ThemeProvider } from '@/providers/theme-provider';
|
||||||
import { I18nProvider } from '@/utils/i18n/provider';
|
import { I18nProvider } from '@/utils/i18n/provider';
|
||||||
@ -17,13 +18,15 @@ export default async function RootLayout({ children }: Readonly<PropsWithChildre
|
|||||||
return (
|
return (
|
||||||
<html lang={locale}>
|
<html lang={locale}>
|
||||||
<body className="flex min-h-screen flex-col bg-app-background">
|
<body className="flex min-h-screen flex-col bg-app-background">
|
||||||
<I18nProvider>
|
<ErrorProvider>
|
||||||
<ThemeProvider>
|
<I18nProvider>
|
||||||
<AuthProvider>
|
<ThemeProvider>
|
||||||
<QueryProvider>{children}</QueryProvider>
|
<AuthProvider>
|
||||||
</AuthProvider>
|
<QueryProvider>{children}</QueryProvider>
|
||||||
</ThemeProvider>
|
</AuthProvider>
|
||||||
</I18nProvider>
|
</ThemeProvider>
|
||||||
|
</I18nProvider>
|
||||||
|
</ErrorProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|||||||
11
apps/web/providers/error.tsx
Normal file
11
apps/web/providers/error.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Toaster } from '@repo/ui/components/ui/sonner';
|
||||||
|
import { type PropsWithChildren } from 'react';
|
||||||
|
|
||||||
|
export function ErrorProvider({ children }: Readonly<PropsWithChildren>) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Toaster position="top-center" richColors />
|
||||||
|
{children}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,7 +1,14 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { toast } from '@repo/ui/components/ui/sonner';
|
||||||
// Since QueryClientProvider relies on useContext under the hood, we have to put 'use client' on top
|
// Since QueryClientProvider relies on useContext under the hood, we have to put 'use client' on top
|
||||||
import { isServer, QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import {
|
||||||
|
isServer,
|
||||||
|
MutationCache,
|
||||||
|
QueryCache,
|
||||||
|
QueryClient,
|
||||||
|
QueryClientProvider,
|
||||||
|
} from '@tanstack/react-query';
|
||||||
|
|
||||||
function makeQueryClient() {
|
function makeQueryClient() {
|
||||||
return new QueryClient({
|
return new QueryClient({
|
||||||
@ -12,6 +19,12 @@ function makeQueryClient() {
|
|||||||
staleTime: 60 * 1_000,
|
staleTime: 60 * 1_000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mutationCache: new MutationCache({
|
||||||
|
onError: () => toast.error('Ошибка при отправке данных'),
|
||||||
|
}),
|
||||||
|
queryCache: new QueryCache({
|
||||||
|
onError: () => toast.error('Ошибка при загрузке данных'),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,8 +51,10 @@
|
|||||||
"@radix-ui/react-scroll-area": "^1.2.2",
|
"@radix-ui/react-scroll-area": "^1.2.2",
|
||||||
"@radix-ui/react-select": "^2.1.4",
|
"@radix-ui/react-select": "^2.1.4",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
|
"next-themes": "^0.4.4",
|
||||||
"react": "catalog:",
|
"react": "catalog:",
|
||||||
"react-day-picker": "8.10.1",
|
"react-day-picker": "8.10.1",
|
||||||
"react-dom": "catalog:"
|
"react-dom": "catalog:",
|
||||||
|
"sonner": "^1.7.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
packages/ui/src/components/ui/sonner.tsx
Normal file
31
packages/ui/src/components/ui/sonner.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useTheme } from 'next-themes';
|
||||||
|
import { Toaster as Sonner } from 'sonner';
|
||||||
|
|
||||||
|
type ToasterProps = React.ComponentProps<typeof Sonner>;
|
||||||
|
|
||||||
|
function Toaster({ ...props }: ToasterProps) {
|
||||||
|
const { theme = 'system' } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Sonner
|
||||||
|
className="toaster group"
|
||||||
|
theme={theme as ToasterProps['theme']}
|
||||||
|
toastOptions={{
|
||||||
|
classNames: {
|
||||||
|
actionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',
|
||||||
|
cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',
|
||||||
|
description: 'group-[.toast]:text-muted-foreground',
|
||||||
|
toast:
|
||||||
|
'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Toaster };
|
||||||
|
|
||||||
|
export { toast } from 'sonner';
|
||||||
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@ -330,6 +330,9 @@ importers:
|
|||||||
date-fns:
|
date-fns:
|
||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
|
next-themes:
|
||||||
|
specifier: ^0.4.4
|
||||||
|
version: 0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
react:
|
react:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 19.0.0
|
version: 19.0.0
|
||||||
@ -339,6 +342,9 @@ importers:
|
|||||||
react-dom:
|
react-dom:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 19.0.0(react@19.0.0)
|
version: 19.0.0(react@19.0.0)
|
||||||
|
sonner:
|
||||||
|
specifier: ^1.7.4
|
||||||
|
version: 1.7.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@radix-ui/react-slot':
|
'@radix-ui/react-slot':
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
@ -4615,6 +4621,7 @@ packages:
|
|||||||
|
|
||||||
lodash.get@4.4.2:
|
lodash.get@4.4.2:
|
||||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||||
|
deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
|
||||||
|
|
||||||
lodash.includes@4.3.0:
|
lodash.includes@4.3.0:
|
||||||
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
|
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
|
||||||
@ -5660,6 +5667,12 @@ packages:
|
|||||||
snake-case@3.0.4:
|
snake-case@3.0.4:
|
||||||
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
|
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
|
||||||
|
|
||||||
|
sonner@1.7.4:
|
||||||
|
resolution: {integrity: sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
|
||||||
|
|
||||||
source-map-js@1.2.1:
|
source-map-js@1.2.1:
|
||||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -11703,7 +11716,7 @@ snapshots:
|
|||||||
normalize-package-data@2.5.0:
|
normalize-package-data@2.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
hosted-git-info: 2.8.9
|
hosted-git-info: 2.8.9
|
||||||
resolve: 1.22.8
|
resolve: 1.22.10
|
||||||
semver: 5.7.2
|
semver: 5.7.2
|
||||||
validate-npm-package-license: 3.0.4
|
validate-npm-package-license: 3.0.4
|
||||||
|
|
||||||
@ -12482,6 +12495,11 @@ snapshots:
|
|||||||
dot-case: 3.0.4
|
dot-case: 3.0.4
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
sonner@1.7.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||||
|
dependencies:
|
||||||
|
react: 19.0.0
|
||||||
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
|
||||||
source-map-js@1.2.1: {}
|
source-map-js@1.2.1: {}
|
||||||
|
|
||||||
source-map@0.6.1: {}
|
source-map@0.6.1: {}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user