Skip to content

Commit

Permalink
feat: unified notification with notistack (#127)
Browse files Browse the repository at this point in the history
* feat: unified existing notification with notistack

* chore: replaced with useSnackbar, added missing notifications

* chore: removed FIXME as per PR review
  • Loading branch information
vojtechsimetka committed Jun 2, 2021
1 parent 92c727e commit bec8405
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 51 deletions.
28 changes: 28 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"formik": "^2.2.8",
"formik-material-ui": "^3.0.1",
"material-ui-dropzone": "^3.5.0",
"notistack": "^1.0.9",
"opener": "^1.5.2",
"qrcode.react": "^1.0.1",
"react": "^17.0.2",
Expand Down
15 changes: 9 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import './App.css'

import { ThemeProvider } from '@material-ui/styles'
import CssBaseline from '@material-ui/core/CssBaseline'
import { SnackbarProvider } from 'notistack'

import BaseRouter from './routes/routes'
import { lightTheme, darkTheme } from './theme'
Expand Down Expand Up @@ -35,12 +36,14 @@ const App = (): ReactElement => {
<div className="App">
<ThemeProvider theme={themeMode === 'light' ? lightTheme : darkTheme}>
<StampsProvider>
<>
<CssBaseline />
<Router>
<BaseRouter />
</Router>
</>
<SnackbarProvider>
<>
<CssBaseline />
<Router>
<BaseRouter />
</Router>
</>
</SnackbarProvider>
</StampsProvider>
</ThemeProvider>
</div>
Expand Down
23 changes: 8 additions & 15 deletions src/components/CashoutModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import DialogActions from '@material-ui/core/DialogActions'
import DialogContent from '@material-ui/core/DialogContent'
import DialogContentText from '@material-ui/core/DialogContentText'
import DialogTitle from '@material-ui/core/DialogTitle'
import { Snackbar, Container, CircularProgress } from '@material-ui/core'
import { Container, CircularProgress } from '@material-ui/core'
import { useSnackbar } from 'notistack'

import { beeDebugApi } from '../services/bee'

Expand All @@ -19,8 +20,7 @@ interface Props {
export default function DepositModal({ peerId, uncashedAmount }: Props): ReactElement {
const [open, setOpen] = useState<boolean>(false)
const [loadingCashout, setLoadingCashout] = useState<boolean>(false)
const [showToast, setToastVisibility] = useState<boolean>(false)
const [toastContent, setToastContent] = useState<JSX.Element | null>(null)
const { enqueueSnackbar } = useSnackbar()

const handleClickOpen = () => {
setOpen(true)
Expand All @@ -37,37 +37,30 @@ export default function DepositModal({ peerId, uncashedAmount }: Props): ReactEl
.peerCashout(peerId)
.then(res => {
setOpen(false)
handleToast(
enqueueSnackbar(
<span>
Successfully cashed out cheque. Transaction
<EthereumAddress hideBlockie transaction address={res.transactionHash} network={'goerli'} />
</span>,
{ variant: 'success' },
)
})
.catch(() => {
// FIXME: handle errors more gracefully
handleToast(<span>Error with cashout</span>)
.catch((e: Error) => {
enqueueSnackbar(<span>Error: {e.message}</span>, { variant: 'error' })
})
.finally(() => {
setLoadingCashout(false)
})
} else {
handleToast(<span>Peer Id invalid</span>)
enqueueSnackbar(<span>Peer Id invalid</span>, { variant: 'error' })
}
}

const handleToast = (text: JSX.Element) => {
setToastContent(text)
setToastVisibility(true)
setTimeout(() => setToastVisibility(false), 7000)
}

return (
<div>
<Button variant="contained" color="primary" onClick={handleClickOpen} style={{ marginLeft: '7px' }}>
Cashout
</Button>
<Snackbar anchorOrigin={{ vertical: 'top', horizontal: 'center' }} open={showToast} message={toastContent} />
<Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Cashout Cheque</DialogTitle>
<DialogContent>
Expand Down
18 changes: 7 additions & 11 deletions src/components/ClipboardCopy.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { ReactElement, useState } from 'react'
import { IconButton, Snackbar } from '@material-ui/core'
import type { ReactElement } from 'react'
import IconButton from '@material-ui/core/IconButton'
import { CopyToClipboard } from 'react-copy-to-clipboard'
import { Clipboard } from 'react-feather'
import { useSnackbar } from 'notistack'

interface Props {
value: string
}

export default function ClipboardCopy(props: Props): ReactElement {
const [copied, setCopied] = useState(false)

const handleCopy = () => {
setCopied(true)
setTimeout(() => setCopied(false), 3000)
}
export default function ClipboardCopy({ value }: Props): ReactElement {
const { enqueueSnackbar } = useSnackbar()
const handleCopy = () => enqueueSnackbar(`Copied: ${value}`, { variant: 'success' })

return (
<div style={{ marginRight: '3px', marginLeft: '3px' }}>
<Snackbar anchorOrigin={{ vertical: 'top', horizontal: 'center' }} open={copied} message="Copied" />
<IconButton color="primary" size="small" onClick={handleCopy}>
<CopyToClipboard text={props.value}>
<CopyToClipboard text={value}>
<Clipboard style={{ height: '20px' }} />
</CopyToClipboard>
</IconButton>
Expand Down
17 changes: 5 additions & 12 deletions src/components/WDModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import DialogActions from '@material-ui/core/DialogActions'
import DialogContent from '@material-ui/core/DialogContent'
import DialogContentText from '@material-ui/core/DialogContentText'
import DialogTitle from '@material-ui/core/DialogTitle'
import { FormHelperText, Snackbar } from '@material-ui/core'
import FormHelperText from '@material-ui/core/FormHelperText'
import { Token } from '../models/Token'
import type { BigNumber } from 'bignumber.js'
import { useSnackbar } from 'notistack'

interface Props {
successMessage: string
Expand All @@ -33,8 +34,7 @@ export default function WithdrawModal({
const [amount, setAmount] = useState('')
const [amountToken, setAmountToken] = useState<Token | null>(null)
const [amountError, setAmountError] = useState<Error | null>(null)
const [showToast, setToastVisibility] = useState(false)
const [toastContent, setToastContent] = useState('')
const { enqueueSnackbar } = useSnackbar()

const handleClickOpen = () => {
setOpen(true)
Expand All @@ -50,18 +50,12 @@ export default function WithdrawModal({
try {
const { transactionHash } = await action(amountToken.toBigInt as bigint)
setOpen(false)
handleToast(`${successMessage} Transaction ${transactionHash}`)
enqueueSnackbar(`${successMessage} Transaction ${transactionHash}`, { variant: 'success' })
} catch (e) {
handleToast(`${errorMessage} Error: ${e.message}`)
enqueueSnackbar(`${errorMessage} Error: ${e.message}`, { variant: 'error' })
}
}

const handleToast = (text: string) => {
setToastContent(text)
setToastVisibility(true)
setTimeout(() => setToastVisibility(false), 7000)
}

const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
const value = e.target.value
setAmount(value)
Expand All @@ -83,7 +77,6 @@ export default function WithdrawModal({
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
{label}
</Button>
<Snackbar anchorOrigin={{ vertical: 'top', horizontal: 'center' }} open={showToast} message={toastContent} />
<Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">{label}</DialogTitle>
<DialogContent>
Expand Down
9 changes: 4 additions & 5 deletions src/pages/files/Upload.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ReactElement, useContext, useEffect, useState } from 'react'
import { beeApi } from '../../services/bee'

import { Button, Container, CircularProgress, FormHelperText } from '@material-ui/core'
import { Button, Container, CircularProgress } from '@material-ui/core'
import { DropzoneArea } from 'material-ui-dropzone'
import ClipboardCopy from '../../components/ClipboardCopy'
import { PostageBatch } from '@ethersphere/bee-js'
Expand All @@ -11,16 +11,17 @@ import Chip from '@material-ui/core/Chip'
import Avatar from '@material-ui/core/Avatar'
import SelectStamp from './SelectStamp'
import CreatePostageStamp from '../stamps/CreatePostageStampModal'
import { useSnackbar } from 'notistack'

export default function Files(): ReactElement {
const [file, setFile] = useState<File | null>(null)
const [uploadReference, setUploadReference] = useState('')
const [uploadError, setUploadError] = useState<Error | null>(null)
const [isUploadingFile, setIsUploadingFile] = useState(false)

const [selectedStamp, setSelectedStamp] = useState<PostageBatch | null>(null)

const { isLoading, error, stamps } = useContext(Context)
const { enqueueSnackbar } = useSnackbar()

// Choose a postage stamp that has the lowest utilization
useEffect(() => {
Expand All @@ -38,14 +39,13 @@ export default function Files(): ReactElement {
const uploadFile = () => {
if (file === null || selectedStamp === null) return
setIsUploadingFile(true)
setUploadError(null)
beeApi.files
.uploadFile(selectedStamp.batchID, file)
.then(hash => {
setUploadReference(hash)
setFile(null)
})
.catch(setUploadError) // FIXME: should instead trigger notification
.catch(e => enqueueSnackbar(`Error uploading: ${e.message}`, { variant: 'error' }))
.finally(() => {
setIsUploadingFile(false)
})
Expand Down Expand Up @@ -93,7 +93,6 @@ export default function Files(): ReactElement {
<ClipboardCopy value={uploadReference} />
</div>
)}
{uploadError && <FormHelperText error>{uploadError.message}</FormHelperText>}
</div>
</div>
</div>
Expand Down
5 changes: 3 additions & 2 deletions src/pages/stamps/CreatePostageStampModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { TextField } from 'formik-material-ui'
import { beeApi } from '../../services/bee'
import { Context } from '../../providers/Stamps'
import { makeStyles, Theme, createStyles } from '@material-ui/core/styles'
import { useSnackbar } from 'notistack'

interface FormValues {
depth?: string
Expand Down Expand Up @@ -55,6 +56,7 @@ export default function FormDialog({ label }: Props): ReactElement {
const { refresh } = useContext(Context)
const handleClickOpen = () => setOpen(true)
const handleClose = () => setOpen(false)
const { enqueueSnackbar } = useSnackbar()

return (
<Formik
Expand All @@ -71,8 +73,7 @@ export default function FormDialog({ label }: Props): ReactElement {
await refresh()
handleClose()
} catch (e) {
// TODO: trigger notification with notistack
console.error(`${e.message}`) // eslint-disable-line
enqueueSnackbar(`Error: ${e.message}`, { variant: 'error' })
actions.setSubmitting(false)
}
}}
Expand Down

0 comments on commit bec8405

Please sign in to comment.