1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-15 12:59:09 +00:00
trezor-wallet/src/components/Notification/index.js

205 lines
5.3 KiB
JavaScript
Raw Normal View History

2018-09-27 07:13:29 +00:00
/* @flow */
2018-09-26 20:49:35 +00:00
import React from 'react';
2018-10-01 13:54:35 +00:00
import media from 'styled-media-query';
2018-02-20 09:30:36 +00:00
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
2018-08-28 14:27:59 +00:00
import styled, { css } from 'styled-components';
2018-08-28 12:33:42 +00:00
import colors from 'config/colors';
import { getColor, getIcon } from 'utils/notification';
2018-08-28 14:27:59 +00:00
import Icon from 'components/Icon';
import icons from 'config/icons';
2018-08-29 10:07:47 +00:00
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
2018-02-20 09:30:36 +00:00
2018-08-14 12:56:47 +00:00
import * as NotificationActions from 'actions/NotificationActions';
import Loader from 'components/Loader';
2018-09-27 07:13:29 +00:00
import type { Action, State } from 'flowtype';
import NotificationButton from './components/NotificationButton';
2018-02-20 09:30:36 +00:00
2018-09-27 07:13:29 +00:00
type Props = {
key?: number,
notifications: $ElementType<State, 'notifications'>,
close: (notif?: any) => Action,
};
type NProps = {
type: string,
cancelable?: boolean;
title: string;
message?: string;
actions?: Array<any>;
close?: typeof NotificationActions.close,
loading?: boolean
};
2018-08-28 12:33:42 +00:00
const Wrapper = styled.div`
2018-10-09 13:02:08 +00:00
width: 100%;
2018-08-28 12:33:42 +00:00
position: relative;
2018-08-28 14:27:59 +00:00
color: ${colors.TEXT_PRIMARY};
background: ${colors.TEXT_SECONDARY};
2018-08-29 10:07:47 +00:00
padding: 24px 48px 24px 24px;
2018-08-28 12:33:42 +00:00
display: flex;
min-height: 90px;
2018-08-28 12:33:42 +00:00
flex-direction: row;
text-align: left;
2018-08-28 14:27:59 +00:00
${props => props.type === 'info' && css`
color: ${colors.INFO_PRIMARY};
background: ${colors.INFO_SECONDARY};
`}
${props => props.type === 'success' && css`
color: ${colors.SUCCESS_PRIMARY};
background: ${colors.SUCCESS_SECONDARY};
`}
${props => props.type === 'warning' && css`
color: ${colors.WARNING_PRIMARY};
background: ${colors.WARNING_SECONDARY};
`}
${props => props.type === 'error' && css`
color: ${colors.ERROR_PRIMARY};
background: ${colors.ERROR_SECONDARY};
`}
2018-10-01 13:54:35 +00:00
${media.lessThan('610px')`
flex-direction: column;
`}
2018-08-28 14:27:59 +00:00
`;
const Body = styled.div`
2018-08-29 10:07:47 +00:00
display: flex;
2018-10-01 13:54:35 +00:00
width: 60%;
${media.lessThan('610px')`
width: 100%;
`}
2018-08-28 12:33:42 +00:00
`;
2018-08-29 10:07:47 +00:00
const Title = styled.div`
2018-08-29 13:48:05 +00:00
padding-bottom: 5px;
2018-08-29 10:07:47 +00:00
font-weight: ${FONT_WEIGHT.BIGGER};
2018-08-28 14:27:59 +00:00
`;
2018-08-29 11:54:41 +00:00
const CloseClick = styled.div`
position: absolute;
right: 0;
top: 0;
padding: 20px 10px 0 0;
`;
2018-08-28 14:27:59 +00:00
2018-08-29 10:07:47 +00:00
const Message = styled.div`
font-size: ${FONT_SIZE.SMALLER};
`;
const StyledIcon = styled(Icon)`
position: relative;
2018-08-29 11:54:41 +00:00
top: -7px;
2018-10-01 13:54:35 +00:00
min-width: 20px;
2018-08-29 10:07:47 +00:00
`;
2018-10-01 13:54:35 +00:00
const IconWrapper = styled.div`
min-width: 20px;
2018-08-29 13:48:05 +00:00
`;
const Texts = styled.div`
display: flex;
flex-direction: column;
2018-10-01 13:54:35 +00:00
flex: 1;
2018-08-29 13:48:05 +00:00
`;
2018-09-05 14:36:48 +00:00
const AdditionalContent = styled.div`
display: flex;
justify-content: flex-end;
align-items: flex-end;
2018-10-01 13:54:35 +00:00
flex: 1;
2018-09-05 14:36:48 +00:00
`;
const ActionContent = styled.div`
2018-10-01 13:54:35 +00:00
display: flex;
2018-09-05 14:36:48 +00:00
justify-content: right;
align-items: flex-end;
2018-10-01 13:54:35 +00:00
${media.lessThan('610px')`
width: 100%;
padding: 10px 0 0 30px;
align-items: flex-start;
`}
2018-09-05 14:36:48 +00:00
`;
2018-08-29 10:07:47 +00:00
2018-07-30 10:52:13 +00:00
export const Notification = (props: NProps): React$Element<string> => {
2018-04-16 21:19:50 +00:00
const close: Function = typeof props.close === 'function' ? props.close : () => {}; // TODO: add default close action
2018-08-29 09:33:17 +00:00
2018-08-29 11:07:37 +00:00
2018-02-20 09:30:36 +00:00
return (
<Wrapper type={props.type}>
2018-08-29 10:07:47 +00:00
{props.loading && <Loader size={50} /> }
{props.cancelable && (
2018-08-28 14:27:59 +00:00
<CloseClick onClick={() => close()}>
2018-08-29 11:54:41 +00:00
<Icon
color={getColor(props.type)}
2018-08-29 11:54:41 +00:00
icon={icons.CLOSE}
size={20}
/>
2018-08-28 14:27:59 +00:00
</CloseClick>
2018-08-29 10:07:47 +00:00
)}
2018-08-28 14:27:59 +00:00
<Body>
2018-10-01 13:54:35 +00:00
<IconWrapper>
2018-08-29 11:07:37 +00:00
<StyledIcon
color={getColor(props.type)}
icon={getIcon(props.type)}
2018-08-29 11:07:37 +00:00
/>
2018-10-01 13:54:35 +00:00
</IconWrapper>
<Texts>
<Title>{ props.title }</Title>
{ props.message && (
<Message>
<p dangerouslySetInnerHTML={{ __html: props.message }} />
</Message>
) }
</Texts>
2018-08-28 14:27:59 +00:00
</Body>
2018-08-29 13:48:05 +00:00
<AdditionalContent>
{props.actions && props.actions.length > 0 && (
<ActionContent>
{props.actions.map(action => (
2018-08-29 11:54:41 +00:00
<NotificationButton
2018-08-29 10:07:47 +00:00
key={action.label}
type={props.type}
2018-08-28 14:27:59 +00:00
text={action.label}
onClick={() => { close(); action.callback(); }}
>{action.label}
</NotificationButton>
2018-08-28 14:27:59 +00:00
))}
2018-08-29 13:48:05 +00:00
</ActionContent>
)}
</AdditionalContent>
2018-08-28 12:33:42 +00:00
</Wrapper>
2018-07-30 10:52:13 +00:00
);
};
2018-02-20 09:30:36 +00:00
2018-09-27 07:13:29 +00:00
export const NotificationGroup = (props: Props) => {
2018-02-20 09:30:36 +00:00
const { notifications, close } = props;
2018-09-06 15:04:28 +00:00
return notifications.map(n => (
2018-07-30 10:52:13 +00:00
<Notification
2018-09-06 15:04:28 +00:00
key={n.title}
type={n.type}
2018-07-30 10:52:13 +00:00
title={n.title}
message={n.message}
cancelable={n.cancelable}
actions={n.actions}
close={close}
/>
));
};
2018-02-20 09:30:36 +00:00
2018-07-30 10:52:13 +00:00
export default connect(
2018-08-29 11:07:37 +00:00
state => ({
2018-07-30 10:52:13 +00:00
notifications: state.notifications,
}),
2018-08-29 11:07:37 +00:00
dispatch => ({
2018-07-30 10:52:13 +00:00
close: bindActionCreators(NotificationActions.close, dispatch),
}),
2018-09-27 07:13:29 +00:00
)(NotificationGroup);