From 241b21c09f680fb6016d0494d168c6bb651a7c5c Mon Sep 17 00:00:00 2001 From: eddie <66155195+just-toby@users.noreply.github.com> Date: Thu, 2 Mar 2023 11:40:26 -0800 Subject: [PATCH] feat: new error dialog design (#511) * feat: new error view * fix: expandos for settings * fix: merge and delete file * fix: rename column * fix: use global x icon --- src/components/Error/ErrorBoundary.tsx | 40 ++++---- src/components/Error/ErrorDialog.tsx | 105 -------------------- src/components/Error/ErrorView.tsx | 86 ++++++++++++++++ src/components/Swap/Status/StatusDialog.tsx | 6 +- 4 files changed, 110 insertions(+), 127 deletions(-) delete mode 100644 src/components/Error/ErrorDialog.tsx create mode 100644 src/components/Error/ErrorView.tsx diff --git a/src/components/Error/ErrorBoundary.tsx b/src/components/Error/ErrorBoundary.tsx index 5fba5ff07..3d0272db1 100644 --- a/src/components/Error/ErrorBoundary.tsx +++ b/src/components/Error/ErrorBoundary.tsx @@ -1,8 +1,8 @@ -import { DEFAULT_ERROR_ACTION, DEFAULT_ERROR_HEADER, WidgetError } from 'errors' +import { t } from '@lingui/macro' +import { DEFAULT_ERROR_HEADER, WidgetError } from 'errors' import { Component, ErrorInfo, PropsWithChildren, useCallback, useState } from 'react' -import Dialog from '../Dialog' -import ErrorDialog from './ErrorDialog' +import ErrorView from './ErrorView' export type OnError = (error: Error, info?: ErrorInfo) => void @@ -53,30 +53,30 @@ export default class ErrorBoundary extends Component - { - this.setState({ error: undefined }) - } - : () => window.location.reload() - } - /> - + { + this.setState({ error: undefined }) + } + : () => window.location.reload() + } + onClick={() => { + window.open('https://support.uniswap.org/', '_blank', 'noopener,noreferrer') + }} + /> ) } render() { if (this.state.error) { - return this.renderErrorDialog(this.state.error) + return this.renderErrorView(this.state.error) } return this.props.children } diff --git a/src/components/Error/ErrorDialog.tsx b/src/components/Error/ErrorDialog.tsx deleted file mode 100644 index a31360003..000000000 --- a/src/components/Error/ErrorDialog.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { Trans } from '@lingui/macro' -import ActionButton from 'components/ActionButton' -import Column from 'components/Column' -import Expando from 'components/Expando' -import Row from 'components/Row' -import { AlertTriangle, Icon, LargeIcon, StyledXButton } from 'icons' -import { Info as InfoIcon } from 'icons' -import { ReactNode, useCallback, useState } from 'react' -import styled from 'styled-components/macro' -import { AnimationSpeed, Color, ThemedText } from 'theme' - -const HeaderIcon = styled(LargeIcon)` - flex-grow: 1; - transition: height ${AnimationSpeed.Medium}, width ${AnimationSpeed.Medium}; - - svg { - transition: height ${AnimationSpeed.Medium}, width ${AnimationSpeed.Medium}; - } -` - -interface StatusHeaderProps { - icon: Icon - iconColor?: Color - iconSize?: number - children: ReactNode -} - -export function StatusHeader({ icon: Icon, iconColor, iconSize = 2.5, children }: StatusHeaderProps) { - return ( - <> - - - - {children} - - - - ) -} - -const ErrorHeader = styled(Column)<{ open: boolean }>` - transition: gap ${AnimationSpeed.Medium}; - - div:last-child { - max-height: ${({ open }) => (open ? 0 : 60 / 14)}em; // 3 * line-height - overflow-y: hidden; - transition: max-height ${AnimationSpeed.Medium}; - } -` - -const ExpandoContent = styled(ThemedText.Code)` - margin: 0.5em 0; -` - -interface ErrorDialogProps { - header?: ReactNode - message: ReactNode - error?: Error - action: ReactNode - onClick: () => void -} - -export default function ErrorDialog({ header, message, error, action, onClick }: ErrorDialogProps) { - const [open, setOpen] = useState(false) - const onExpand = useCallback(() => setOpen((open) => !open), []) - - return ( - - - - - - - {header || Something went wrong.} - {!open && {message}} - - - - {error ? ( - - - Error details - - } - open={open} - onExpand={onExpand} - height={7.5} - > - - {error.name} - {error.message ? `: ${error.message}` : ''} - - - ) : ( - - )} - - {action} - - - - ) -} diff --git a/src/components/Error/ErrorView.tsx b/src/components/Error/ErrorView.tsx new file mode 100644 index 000000000..df152a48e --- /dev/null +++ b/src/components/Error/ErrorView.tsx @@ -0,0 +1,86 @@ +import { Trans } from '@lingui/macro' +import ActionButton from 'components/ActionButton' +import Column from 'components/Column' +import Expando from 'components/Expando' +import Row from 'components/Row' +import { AlertTriangle, Icon, LargeIcon, StyledXButton } from 'icons' +import { ReactNode, useState } from 'react' +import styled from 'styled-components/macro' +import { Color, ThemedText } from 'theme' + +const HeaderIcon = styled(LargeIcon)` + flex-grow: 1; + margin: 2em 0; +` + +interface StatusHeaderProps { + icon: Icon + iconColor?: Color + iconSize?: number + children: ReactNode +} + +export function StatusHeader({ icon: Icon, iconColor, iconSize = 2.5, children }: StatusHeaderProps) { + return ( + <> + + + + {children} + + + + ) +} + +const ExpandoContent = styled(ThemedText.Code)` + margin: 0.5em; +` + +const ErrorDialogWrapper = styled(Column)` + background-color: ${({ theme }) => theme.container}; +` + +interface ErrorDialogProps { + header?: ReactNode + message: ReactNode + error?: Error + action: ReactNode + onClick: () => void + onDismiss: () => void +} + +export default function ErrorDialog({ header, message, error, action, onClick, onDismiss }: ErrorDialogProps) { + const [open, setOpen] = useState(false) + + return ( + + + + + + + {header || Something went wrong} + {message} + + + {error ? ( + Show less : Show more} + open={open} + onExpand={() => setOpen((open) => !open)} + maxHeight={11.5 /* em */} + > + + {error.toString()} + + + ) : ( + + )} + + {action} + + + ) +} diff --git a/src/components/Swap/Status/StatusDialog.tsx b/src/components/Swap/Status/StatusDialog.tsx index b3b677843..7e276ce70 100644 --- a/src/components/Swap/Status/StatusDialog.tsx +++ b/src/components/Swap/Status/StatusDialog.tsx @@ -1,5 +1,6 @@ import { Trans } from '@lingui/macro' -import ErrorDialog, { StatusHeader } from 'components/Error/ErrorDialog' +import ErrorView from 'components/Error/ErrorView' +import { StatusHeader } from 'components/Error/ErrorView' import EtherscanLink from 'components/EtherscanLink' import Row from 'components/Row' import SwapSummary from 'components/Swap/Summary' @@ -56,7 +57,7 @@ function TransactionStatus({ tx, onClose }: TransactionStatusProps) { export default function TransactionStatusDialog({ tx, onClose }: TransactionStatusProps) { return tx.receipt?.status === 0 ? ( - Your swap failed.} message={ @@ -67,6 +68,7 @@ export default function TransactionStatusDialog({ tx, onClose }: TransactionStat } action={Dismiss} onClick={onClose} + onDismiss={onClose} /> ) : (