diff --git a/assets/css/src/components/_notice.scss b/assets/css/src/components/_notice.scss index 8d56c25d8a..abec02d4d0 100644 --- a/assets/css/src/components/_notice.scss +++ b/assets/css/src/components/_notice.scss @@ -19,3 +19,31 @@ margin: 0; } } + +.mailpoet_base_notice { + background: #fff; + border-left: 4px solid transparent; + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1); + margin: 5px 0 15px; + padding: 1px 12px; +} + +.mailpoet_success_notice { + @extend .mailpoet_base_notice; + border-left-color: #46b450; +} + +.mailpoet_error_notice { + @extend .mailpoet_base_notice; + border-left-color: #dc3232; +} + +.mailpoet_warning_notice { + @extend .mailpoet_base_notice; + border-left-color: #ffb900; +} + +.mailpoet_info_notice { + @extend .mailpoet_base_notice; + border-left-color: #00a0d2; +} diff --git a/assets/js/src/notices/notice.jsx b/assets/js/src/notices/notice.jsx new file mode 100644 index 0000000000..449b8da9db --- /dev/null +++ b/assets/js/src/notices/notice.jsx @@ -0,0 +1,44 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; + +const Notice = (props) => { + const [hidden, setHidden] = React.useState(false); + const elementRef = React.useRef(null); + const timeoutRef = React.useRef(null); + + React.useEffect(() => { + if (props.timeout) { + timeoutRef.current = setTimeout(() => setHidden(true), props.timeout); + } + return () => (timeoutRef.current ? clearTimeout(timeoutRef.current) : null); + }, [props.timeout]); + + React.useLayoutEffect(() => { + if (props.scroll && elementRef.current) { + elementRef.current.scrollIntoView(false); + } + }, [props.scroll]); + + if (hidden) return null; + return ReactDOM.createPortal( +
{props.children}
, + document.getElementById('mailpoet_notices') + ); +}; +Notice.propTypes = { + type: PropTypes.oneOf(['success', 'info', 'warning', 'error']).isRequired, + scroll: PropTypes.bool, + timeout: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf([false])]), + children: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.element, + PropTypes.arrayOf(PropTypes.element), + ]).isRequired, +}; +Notice.defaultProps = { + timeout: 10000, + scroll: false, +}; + +export default Notice; diff --git a/views/layout.html b/views/layout.html index 374bfec584..659fc08981 100644 --- a/views/layout.html +++ b/views/layout.html @@ -20,6 +20,8 @@ jQuery('.toplevel_page_mailpoet-newsletters.menu-top-last') + +
<% block title %><% endblock %>