Skip to content
Permalink
Browse files

Preferences: polish notifications (#976)

  • Loading branch information...
sohkai committed Sep 9, 2019
1 parent b4d3a31 commit 3ee7e1b30b998cdbcc4e8347d85fbdd36f9f4481
@@ -29,6 +29,8 @@ export default function ManageNotifications({
token,
onServiceUnavailable,
}) {
const toast = useToast()

const [apiError, setApiError] = useState(null)
const [isFetching, setIsFetching] = useState(true)
const [subscriptions, setSubscriptions] = useState([])
@@ -67,8 +69,6 @@ export default function ManageNotifications({
}
}, [apiError, onServiceUnavailable])

const toast = useToast()

const handleLogout = useCallback(() => {
onLogout()
toast('Signed out from email notifications')
@@ -99,7 +99,7 @@ export default function ManageNotifications({
wide
onClick={handleLogout}
>
Sign Out
Sign out
</Button>
</Box>
<DeleteAccount
@@ -137,9 +137,13 @@ ManageNotifications.propTypes = {
}

function DeleteAccount({ token, onLogout, onApiError, toast }) {
const theme = useTheme()

const [isFetching, setIsFetching] = useState(false)
const [isAccountDeleted, setIsAccountDeleted] = useState(false)
const theme = useTheme()
const [deleteAccountModalOpened, setDeleteAccountModalOpened] = useState(
false
)

const handleDeleteAccount = useCallback(async () => {
try {
@@ -156,28 +160,21 @@ function DeleteAccount({ token, onLogout, onApiError, toast }) {
setIsFetching(false)
}, [token, onLogout, toast, onApiError])

const [isModalOpen, setIsModalOpen] = useState(false)

const onClick = useCallback(() => {
setIsModalOpen(true)
setDeleteAccountModalOpened(true)
}, [])

const onCloseModal = useCallback(() => {
setIsModalOpen(false)
setDeleteAccountModalOpened(false)
}, [])

const onModalConfirm = useCallback(() => {
setIsModalOpen(false)
setDeleteAccountModalOpened(false)
handleDeleteAccount()
}, [handleDeleteAccount])

return (
<React.Fragment>
<DeleteAccountConfirmationModal
visible={isModalOpen}
onConfirm={onModalConfirm}
onClose={onCloseModal}
/>
<Box heading="Email Notification Data">
<Button wide onClick={onClick}>
{isFetching ? (
@@ -195,6 +192,11 @@ function DeleteAccount({ token, onLogout, onApiError, toast }) {
Delete your email
</Button>
</Box>
<DeleteAccountConfirmationModal
visible={deleteAccountModalOpened}
onConfirm={onModalConfirm}
onClose={onCloseModal}
/>
</React.Fragment>
)
}
@@ -71,7 +71,7 @@ DeleteSubscriptionConfirmationModal.propTypes = {
visible: PropTypes.bool,
}

export function ConfirmationModal({
function ConfirmationModal({
children,
onConfirm,
onClose,
@@ -110,7 +110,7 @@ ConfirmationModal.propTypes = {
visible: PropTypes.bool,
}

export const ModalControls = styled.div`
const ModalControls = styled.div`
margin-top: ${3 * GU}px;
display: grid;
grid-gap: ${1.5 * GU}px;
@@ -124,7 +124,7 @@ export const ModalControls = styled.div`
)}
`

export const RemoveButton = styled(Button)`
const RemoveButton = styled(Button)`
${breakpoint(
'medium',
`
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react'
import PropTypes from 'prop-types'
import { AppType } from '../../../prop-types'
import { ButtonText, GU, LoadingRing, textStyle } from '@aragon/ui'
import { Link, GU, LoadingRing, textStyle } from '@aragon/ui'
import ManageNotifications from './ManageNotifications'
import NotificationsLogin from './NotificationsLogin'
import {
@@ -73,8 +73,7 @@ function useAuthState() {
if (email && token) {
handleAuthenticate()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [email, token])
}, [email, token, handleAuthenticate])

useEffect(() => {
token
@@ -187,10 +186,10 @@ export default function Notifications({
<p
css={`
margin-left: ${GU}px;
${textStyle('body1')};z
${textStyle('body1')};
`}
>
Authenticating...
Authenticating
</p>
</div>
</NotificationsInfoBox>
@@ -204,44 +203,46 @@ export default function Notifications({
>
<div>
Authentication was unsuccessful.{' '}
<ButtonText
<Link
css={`
font-weight: bold;
`}
onClick={handleLogout}
>
Try logging in again.
</ButtonText>
Try logging in again
</Link>
.
</div>
</NotificationsInfoBox>
)
case AUTH_SERVICE_UNAVAILABLE:
return (
<NotificationsInfoBox
header="Error connecting to the Notifications server"
header="Error connecting to the notifications server"
icon={ICON_ERROR}
image={IMAGE_NETWORK_ERROR}
>
<div>
There was an error when trying to connect to the Notifications
There was an error when trying to connect to the notifications
server. Please
<ButtonText
<Link
css={`
font-weight: bold;
`}
onClick={handleLogout}
>
sign out
</ButtonText>
</Link>
or
<ButtonText
<Link
css={`
font-weight: bold;
`}
onClick={handleAuthenticate}
>
try again.
</ButtonText>
try again
</Link>
.
</div>
</NotificationsInfoBox>
)
@@ -1,18 +1,10 @@
import React from 'react'
import PropTypes from 'prop-types'
import {
Box,
IconCheck,
IconCross,
GU,
RADIUS,
useTheme,
textStyle,
useViewport,
} from '@aragon/ui'
import { Box, GU, RADIUS, useTheme, textStyle, useViewport } from '@aragon/ui'
import notification from './notification.png'
import notificationError from './notification-error.png'
import notificationNetworkError from './notification-network-error.png'
import FeedbackIndicator from '../../FeedbackIndicator/FeedbackIndicator'

export const ICON_SUCCESS = 'success'
export const ICON_NEUTRAL = 'neutral'
@@ -36,13 +28,13 @@ export default function NotificationsInfoBox({
let IconComponent = null
switch (icon) {
case ICON_SUCCESS:
IconComponent = <Checkmark color={theme.accent} />
IconComponent = <FeedbackIndicator status="success" />
break
case ICON_NEUTRAL:
IconComponent = <Checkmark color={theme.disabled} />
IconComponent = <FeedbackIndicator status="pending" />
break
case ICON_ERROR:
IconComponent = <Cross color={theme.negative} />
IconComponent = <FeedbackIndicator status="error" />
break
}
let ImageComponent = null
@@ -60,7 +52,16 @@ export default function NotificationsInfoBox({

return (
<Box heading="Email notifications">
{ImageComponent}
<div
css={`
margin: ${3 * GU}px auto;
display: flex;
align-items: center;
justify-content: center;
`}
>
{ImageComponent}
</div>
<div
css={`
min-height: ${GU * 24}px;
@@ -112,79 +113,18 @@ NotificationsInfoBox.propTypes = {
image: PropTypes.oneOf(ALLOWED_IMAGES),
}

export const NotificationImage = () => (
<img
src={notification}
alt="Notifications"
css={`
display: block;
margin: ${3 * GU}px auto;
height: 193px;
`}
/>
const NotificationImage = () => (
<img src={notification} alt="Notifications" height="193" />
)

export const NotificationErrorImage = () => (
<img
src={notificationError}
alt="Notifications"
css={`
display: block;
margin: ${3 * GU}px auto;
height: 193px;
`}
/>
const NotificationErrorImage = () => (
<img src={notificationError} alt="Notifications error" height="193" />
)

export const NotificationNetworkErrorImage = () => (
const NotificationNetworkErrorImage = () => (
<img
src={notificationNetworkError}
alt="Notifications"
css={`
display: block;
margin: ${3 * GU}px auto;
height: 270px;
`}
alt="Notifications network error"
height="270"
/>
)

export const Checkmark = ({ color }) => (
<div
css={`
border: 2px solid ${color};
border-radius: 50%;
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
color: ${color};
`}
>
<IconCheck />
</div>
)
Checkmark.propTypes = {
color: PropTypes.object,
}

export const Cross = ({ color }) => (
<div
css={`
border: 2px solid ${color};
border-radius: 50%;
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
color: ${color};
`}
>
<IconCross />
</div>
)

Cross.propTypes = {
color: PropTypes.object,
}
@@ -160,10 +160,10 @@ export default function NotificationsLogin({
different browser session or device to access your subsciptions. This
process doens’t require a password, just for you to confirm your email
address.`
: `Receive email notifications for the new app events. For
example, whenever a new vote is created or when tokens added, you’ll get
an email informing you of the latest activity in your organization. You
will be asked to enter with your email address whenever using a
: `Receive email notifications for new events in this organization. For
example, whenever a new vote is created or when funds are transferred,
you’ll get an email informing you of the latest activity in your organization.
You will be asked to enter with your email address whenever using a
different browser session or device to access your subsciptions. This
process doens’t require a password, just for you to confirm your email
address whenever you want to sing in.`}

0 comments on commit 3ee7e1b

Please sign in to comment.
You can’t perform that action at this time.