Chore: make notification center UI

Chore: fiatBalancesNotify refactor

Chore: removed now-unused code in some files

Feat: change column "detail" in database to use jsonb

Chore: add notification center background and button

Chore: notifications screen scaffolding

Fix: change position of notification UI

Feat: join backend and frontend

Feat: notification icons and machine names

Feat: add clear all button, stripe overlay on invalid notification

Fix: rework notification styles

Feat: use popper to render notifications

Feat: make notification center UI

Fix: fix css on notification center

Fix: fix invalidateNotification

Chore: apply PR requested changes

Fix: PR fixes

Fix: make toggleable body/root styles be handled by react

Chore: delete old notifier file

Fix: undo variable name changes for cryptobalance notifs
This commit is contained in:
Cesar 2020-12-17 22:18:35 +00:00 committed by Josh Harvey
parent 2a9e8dadba
commit c457faab40
37 changed files with 1337 additions and 1332 deletions

View file

@ -0,0 +1,144 @@
import { useQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core/styles'
import gql from 'graphql-tag'
import * as R from 'ramda'
import React, { useState } from 'react'
import ActionButton from 'src/components/buttons/ActionButton'
import { H5 } from 'src/components/typography'
import { ReactComponent as NotificationIconZodiac } from 'src/styling/icons/menu/notification-zodiac.svg'
import { ReactComponent as ClearAllIconInverse } from 'src/styling/icons/stage/spring/empty.svg'
import { ReactComponent as ClearAllIcon } from 'src/styling/icons/stage/zodiac/empty.svg'
import { ReactComponent as ShowUnreadIcon } from 'src/styling/icons/stage/zodiac/full.svg'
import styles from './NotificationCenter.styles'
import NotificationRow from './NotificationRow'
const useStyles = makeStyles(styles)
const GET_NOTIFICATIONS = gql`
query getNotifications {
notifications {
id
deviceName
type
detail
message
created
read
valid
}
hasUnreadNotifications
machines {
deviceId
name
}
}
`
const CLEAR_NOTIFICATION = gql`
mutation clearNotification($id: ID!) {
clearNotification(id: $id) {
id
}
}
`
const CLEAR_ALL_NOTIFICATIONS = gql`
mutation clearAllNotifications {
clearAllNotifications {
id
}
}
`
const NotificationCenter = ({ close, notifyUnread }) => {
const classes = useStyles()
const { data, loading } = useQuery(GET_NOTIFICATIONS)
const [showingUnread, setShowingUnread] = useState(false)
const machines = R.compose(
R.map(R.prop('name')),
R.indexBy(R.prop('deviceId'))
)(data?.machines ?? [])
const notifications = R.path(['notifications'])(data) ?? []
const hasUnread = data?.hasUnreadNotifications ?? false
if (!hasUnread) {
notifyUnread && notifyUnread()
}
const [clearNotification] = useMutation(CLEAR_NOTIFICATION, {
onError: () => console.error('Error while clearing notification'),
refetchQueries: () => ['getNotifications']
})
const [clearAllNotifications] = useMutation(CLEAR_ALL_NOTIFICATIONS, {
onError: () => console.error('Error while clearing all notifications'),
refetchQueries: () => ['getNotifications']
})
const handleClearNotification = id => {
clearNotification({ variables: { id } })
}
const buildNotifications = () => {
const notificationsToShow =
!showingUnread || !hasUnread
? notifications
: R.filter(R.propEq('read', false))(notifications)
return notificationsToShow.map(n => {
return (
<NotificationRow
key={n.id}
id={n.id}
type={n.type}
detail={n.detail}
message={n.message}
deviceName={machines[n.detail.deviceId]}
created={n.created}
read={n.read}
valid={n.valid}
onClear={handleClearNotification}
/>
)
})
}
return (
<>
<div className={classes.container}>
<div className={classes.header}>
<H5 className={classes.headerText}>Notifications</H5>
<button onClick={close} className={classes.notificationIcon}>
<NotificationIconZodiac />
{hasUnread && <div className={classes.hasUnread} />}
</button>
</div>
<div className={classes.actionButtons}>
{hasUnread && (
<ActionButton
color="primary"
Icon={ShowUnreadIcon}
InverseIcon={ClearAllIconInverse}
className={classes.clearAllButton}
onClick={() => setShowingUnread(!showingUnread)}>
{showingUnread ? 'Show all' : 'Show unread'}
</ActionButton>
)}
<ActionButton
color="primary"
Icon={ClearAllIcon}
InverseIcon={ClearAllIconInverse}
className={classes.clearAllButton}
onClick={clearAllNotifications}>
Mark all as read
</ActionButton>
</div>
<div className={classes.notificationsList}>
{!loading && buildNotifications()}
</div>
</div>
<div className={classes.background} />
</>
)
}
export default NotificationCenter