mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
added toasts
This commit is contained in:
parent
ef959af711
commit
39e801f6f3
10 changed files with 92 additions and 7 deletions
|
@ -29,6 +29,7 @@
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-dropzone": "^11.4.2",
|
"react-dropzone": "^11.4.2",
|
||||||
|
"react-hot-toast": "^2.1.1",
|
||||||
"react-lazyload": "^3.2.0",
|
"react-lazyload": "^3.2.0",
|
||||||
"react-masonry-css": "^1.0.16",
|
"react-masonry-css": "^1.0.16",
|
||||||
"react-popper": "^2.2.3",
|
"react-popper": "^2.2.3",
|
||||||
|
|
1
src/constants/dom/index.ts
Normal file
1
src/constants/dom/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const isTablet = () => window.innerWidth < 599;
|
|
@ -13,6 +13,8 @@ import { SWRConfigProvider } from '~/utils/providers/SWRConfigProvider';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { useGlobalLoader } from '~/hooks/dom/useGlobalLoader';
|
import { useGlobalLoader } from '~/hooks/dom/useGlobalLoader';
|
||||||
import { SearchProvider } from '~/utils/providers/SearchProvider';
|
import { SearchProvider } from '~/utils/providers/SearchProvider';
|
||||||
|
import { Toaster } from 'react-hot-toast';
|
||||||
|
import { ToastProvider } from '~/utils/providers/ToastProvider';
|
||||||
|
|
||||||
const App: VFC = observer(() => {
|
const App: VFC = observer(() => {
|
||||||
useGlobalLoader();
|
useGlobalLoader();
|
||||||
|
@ -25,6 +27,7 @@ const App: VFC = observer(() => {
|
||||||
<PageCoverProvider>
|
<PageCoverProvider>
|
||||||
<SearchProvider>
|
<SearchProvider>
|
||||||
<MainLayout>
|
<MainLayout>
|
||||||
|
<ToastProvider />
|
||||||
<Modal />
|
<Modal />
|
||||||
<Sprites />
|
<Sprites />
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ export const useCommentFormFormik = (
|
||||||
await sendData(values);
|
await sendData(values);
|
||||||
onSuccess(helpers)();
|
onSuccess(helpers)();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error', error);
|
|
||||||
onSuccess(helpers)(error);
|
onSuccess(helpers)(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,14 +8,13 @@ import { showErrorToast } from '~/utils/errors/showToast';
|
||||||
|
|
||||||
const validationSchema = object().shape({});
|
const validationSchema = object().shape({});
|
||||||
|
|
||||||
const afterSubmit = ({ resetForm, setStatus, setSubmitting, setErrors }: FormikHelpers<INode>) => (
|
const afterSubmit = ({ resetForm, setSubmitting, setErrors }: FormikHelpers<INode>) => (
|
||||||
e?: string,
|
e?: string,
|
||||||
errors?: Record<string, string>
|
errors?: Record<string, string>
|
||||||
) => {
|
) => {
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
setStatus(e);
|
|
||||||
showErrorToast(e);
|
showErrorToast(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,21 @@
|
||||||
const handle = (message: string) => console.warn(message);
|
import { hideToast, showToastError } from '~/utils/toast';
|
||||||
|
import { has, path } from 'ramda';
|
||||||
|
import { ERROR_LITERAL, ERRORS } from '~/constants/errors';
|
||||||
|
|
||||||
|
let toastId = '';
|
||||||
|
|
||||||
|
const handleUnknown = (message: string) => console.warn(message);
|
||||||
|
const handleTranslated = (message: string) => {
|
||||||
|
if (toastId) {
|
||||||
|
hideToast(toastId);
|
||||||
|
}
|
||||||
|
|
||||||
|
toastId = showToastError(ERROR_LITERAL[message]);
|
||||||
|
};
|
||||||
|
|
||||||
export const showErrorToast = (error: unknown) => {
|
export const showErrorToast = (error: unknown) => {
|
||||||
if (typeof error === 'string') {
|
if (typeof error === 'string' && has(error, ERROR_LITERAL)) {
|
||||||
handle(error);
|
handleTranslated(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,5 +24,17 @@ export const showErrorToast = (error: unknown) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle(error.message);
|
// TODO: Network error
|
||||||
|
if (error.message === 'Network Error') {
|
||||||
|
handleTranslated(ERRORS.NETWORK_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageFromBackend = String(path(['response', 'data', 'error'], error));
|
||||||
|
if (messageFromBackend && has(messageFromBackend, ERROR_LITERAL)) {
|
||||||
|
handleTranslated(messageFromBackend);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleUnknown(error.message);
|
||||||
};
|
};
|
||||||
|
|
11
src/utils/providers/ToastProvider.tsx
Normal file
11
src/utils/providers/ToastProvider.tsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { Toaster } from 'react-hot-toast';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const containerStyle = {
|
||||||
|
top: 10,
|
||||||
|
left: 10,
|
||||||
|
bottom: 10,
|
||||||
|
right: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ToastProvider = () => <Toaster containerStyle={containerStyle} />;
|
20
src/utils/toast/index.tsx
Normal file
20
src/utils/toast/index.tsx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react';
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
import { ToastOptions } from 'react-hot-toast/dist/core/types';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { isTablet } from '~/constants/dom';
|
||||||
|
|
||||||
|
const defaultOptions: ToastOptions = {
|
||||||
|
icon: null,
|
||||||
|
duration: 3000,
|
||||||
|
position: isTablet() ? 'top-center' : 'bottom-center',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const showToastError = (message: string) =>
|
||||||
|
toast.error(t => <span onClick={() => toast.dismiss(t.id)}>{message}</span>, {
|
||||||
|
...defaultOptions,
|
||||||
|
className: classNames(styles.toast, styles.error),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const hideToast = (id: string) => toast.dismiss(id);
|
14
src/utils/toast/styles.module.scss
Normal file
14
src/utils/toast/styles.module.scss
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
@import "src/styles/variables";
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
@include outer_shadow;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
font: $font_14_semibold;
|
||||||
|
background: $red_gradient_alt;
|
||||||
|
color: white;
|
||||||
|
user-select: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
12
yarn.lock
12
yarn.lock
|
@ -5390,6 +5390,11 @@ globule@^1.0.0:
|
||||||
lodash "~4.17.10"
|
lodash "~4.17.10"
|
||||||
minimatch "~3.0.2"
|
minimatch "~3.0.2"
|
||||||
|
|
||||||
|
goober@^2.0.35:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/goober/-/goober-2.1.1.tgz#2328a6dae015c3cd30fc55a70090037a244ad2f6"
|
||||||
|
integrity sha512-TkGCqHxE4g5DtdpwxFCi53bXRtvw0BoSgCihVSIOioe9kfkqin5wXG8BQKykN0tjzmxZJ81qU2KWinZf5qKVlw==
|
||||||
|
|
||||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2:
|
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2:
|
||||||
version "4.2.4"
|
version "4.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||||
|
@ -9429,6 +9434,13 @@ react-fast-compare@^3.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
||||||
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
||||||
|
|
||||||
|
react-hot-toast@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-hot-toast/-/react-hot-toast-2.1.1.tgz#56409ab406b534e9e58274cf98d80355ba0fdda0"
|
||||||
|
integrity sha512-Odrp4wue0fHh0pOfZt5H+9nWCMtqs3wdlFSzZPp7qsxfzmbE26QmGWIh6hG43CukiPeOjA8WQhBJU8JwtWvWbQ==
|
||||||
|
dependencies:
|
||||||
|
goober "^2.0.35"
|
||||||
|
|
||||||
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
|
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue