diff --git a/client/coral-ui/components/Checkbox.css b/client/coral-ui/components/Checkbox.css
index a25ea150f..36e6a73ba 100644
--- a/client/coral-ui/components/Checkbox.css
+++ b/client/coral-ui/components/Checkbox.css
@@ -50,6 +50,11 @@
color: #00a291;
}
+.input:disabled + .checkbox:before {
+ color: #e5e5e5;
+ cursor: default;
+}
+
.input:focus + .checkbox:before {
color: #00a291;
}
diff --git a/client/coral-ui/components/Spinner.js b/client/coral-ui/components/Spinner.js
index 69d805354..3a6e7d30b 100644
--- a/client/coral-ui/components/Spinner.js
+++ b/client/coral-ui/components/Spinner.js
@@ -1,8 +1,10 @@
import React from 'react';
+import PropTypes from 'prop-types';
import styles from './Spinner.css';
+import cn from 'classnames';
-const Spinner = () => (
-
+const Spinner = ({ className }) => (
+
);
+Spinner.propTypes = {
+ className: PropTypes.string,
+};
+
export default Spinner;
diff --git a/plugins/talk-plugin-auth/client/login/containers/ResendEmailConfirmation.js b/plugins/talk-plugin-auth/client/login/containers/ResendEmailConfirmation.js
index bd7c9ad8c..6edeb82f2 100644
--- a/plugins/talk-plugin-auth/client/login/containers/ResendEmailConfirmation.js
+++ b/plugins/talk-plugin-auth/client/login/containers/ResendEmailConfirmation.js
@@ -41,7 +41,7 @@ ResendEmailConfirmatonContainer.propTypes = {
success: PropTypes.bool.isRequired,
loading: PropTypes.bool.isRequired,
resendEmailConfirmation: PropTypes.func.isRequired,
- errorMessage: PropTypes.string.isRequired,
+ errorMessage: PropTypes.string,
setView: PropTypes.func.isRequired,
email: PropTypes.string.isRequired,
};
diff --git a/plugins/talk-plugin-notifications-category-featured/client/containers/Toggle.js b/plugins/talk-plugin-notifications-category-featured/client/containers/Toggle.js
index ec7586b16..f888789f3 100644
--- a/plugins/talk-plugin-notifications-category-featured/client/containers/Toggle.js
+++ b/plugins/talk-plugin-notifications-category-featured/client/containers/Toggle.js
@@ -36,7 +36,11 @@ class ToggleContainer extends React.Component {
render() {
return (
-
+
{t('talk-plugin-notifications-category-featured.toggle_description')}
);
@@ -50,6 +54,7 @@ ToggleContainer.propTypes = {
indicateOff: PropTypes.func.isRequired,
setTurnOffInputFragment: PropTypes.func.isRequired,
updateNotificationSettings: PropTypes.func.isRequired,
+ disabled: PropTypes.bool.isRequired,
};
const enhance = compose(
diff --git a/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js b/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js
index 61600a29f..d261946d0 100644
--- a/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js
+++ b/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js
@@ -36,7 +36,11 @@ class ToggleContainer extends React.Component {
render() {
return (
-
+
{t('talk-plugin-notifications-category-reply.toggle_description')}
);
@@ -50,6 +54,7 @@ ToggleContainer.propTypes = {
indicateOff: PropTypes.func.isRequired,
setTurnOffInputFragment: PropTypes.func.isRequired,
updateNotificationSettings: PropTypes.func.isRequired,
+ disabled: PropTypes.bool.isRequired,
};
const enhance = compose(
diff --git a/plugins/talk-plugin-notifications-category-staff/client/containers/Toggle.js b/plugins/talk-plugin-notifications-category-staff/client/containers/Toggle.js
index 44d6d5b3c..62a4cbbce 100644
--- a/plugins/talk-plugin-notifications-category-staff/client/containers/Toggle.js
+++ b/plugins/talk-plugin-notifications-category-staff/client/containers/Toggle.js
@@ -36,7 +36,11 @@ class ToggleContainer extends React.Component {
render() {
return (
-
+
{t('talk-plugin-notifications-category-staff.toggle_description')}
);
@@ -50,6 +54,7 @@ ToggleContainer.propTypes = {
indicateOff: PropTypes.func.isRequired,
setTurnOffInputFragment: PropTypes.func.isRequired,
updateNotificationSettings: PropTypes.func.isRequired,
+ disabled: PropTypes.bool.isRequired,
};
const enhance = compose(
diff --git a/plugins/talk-plugin-notifications/client/components/Banner.css b/plugins/talk-plugin-notifications/client/components/Banner.css
new file mode 100644
index 000000000..cfbff17cf
--- /dev/null
+++ b/plugins/talk-plugin-notifications/client/components/Banner.css
@@ -0,0 +1,42 @@
+.root {
+ display: flex;
+ border: 1px solid #a8afb3;
+ border-radius: 2px;
+ margin: 16px 0;
+
+ p:first-of-type {
+ margin-top: 0;
+ }
+ p:last-child {
+ margin-bottom: 0;
+ }
+}
+.leftColumn {
+ width: 32px;
+ background-color: #787d80;
+ text-align: center;
+ padding-top: 6px;
+ font-size: 18px;
+ flex-shrink: 0;
+
+ &.error {
+ background-color: #fa6265;
+ }
+ &.success {
+ background-color: #00cd7e;
+ }
+}
+.icon {
+ color: white;
+}
+.rightColumn {
+ padding: 8px 12px 10px 12px;
+ font-size: 14px;
+}
+.title {
+ font-size: 14px;
+ margin: 0;
+ margin-bottom: 4px;
+}
+
+
diff --git a/plugins/talk-plugin-notifications/client/components/Banner.js b/plugins/talk-plugin-notifications/client/components/Banner.js
new file mode 100644
index 000000000..401867afb
--- /dev/null
+++ b/plugins/talk-plugin-notifications/client/components/Banner.js
@@ -0,0 +1,50 @@
+import React from 'react';
+import styles from './Banner.css';
+import { Icon } from 'coral-ui';
+import PropTypes from 'prop-types';
+import cn from 'classnames';
+
+function getIcon(icon, error, success) {
+ if (icon) {
+ return icon;
+ }
+ if (error) {
+ return 'warning';
+ }
+ if (success) {
+ return 'done';
+ }
+ return 'info';
+}
+
+const Banner = ({ title, icon, error, success, children }) => (
+
+
+
+
+
+
{title}
+ {children}
+
+
+);
+
+Banner.propTypes = {
+ title: PropTypes.string,
+ icon: PropTypes.string,
+ children: PropTypes.node,
+ error: PropTypes.bool,
+ success: PropTypes.bool,
+};
+
+Banner.defaultProps = {
+ title: 'Title',
+ children: 'Lorem Ipsum Dolot Sit Ahmet',
+};
+
+export default Banner;
diff --git a/plugins/talk-plugin-notifications/client/components/EmailVerificationBanner.css b/plugins/talk-plugin-notifications/client/components/EmailVerificationBanner.css
new file mode 100644
index 000000000..388abe884
--- /dev/null
+++ b/plugins/talk-plugin-notifications/client/components/EmailVerificationBanner.css
@@ -0,0 +1,11 @@
+.spinner {
+ display: inline-block;
+}
+
+.link {
+ display: inline-block;
+ cursor: pointer;
+ margin: 2px;
+ color: #2099d6;
+ border-bottom: 1px solid #2099d6;
+}
diff --git a/plugins/talk-plugin-notifications/client/components/EmailVerificationBanner.js b/plugins/talk-plugin-notifications/client/components/EmailVerificationBanner.js
new file mode 100644
index 000000000..b2e344fc7
--- /dev/null
+++ b/plugins/talk-plugin-notifications/client/components/EmailVerificationBanner.js
@@ -0,0 +1,75 @@
+import React from 'react';
+import Banner from './Banner';
+import PropTypes from 'prop-types';
+import { Spinner } from 'plugin-api/beta/client/components/ui';
+import { t } from 'plugin-api/beta/client/services';
+import styles from './EmailVerificationBanner.css';
+
+const EmailVerificationBannerInfo = ({ onResendEmailVerification }) => (
+
+
+ {t('talk-plugin-notifications.banner_info.text')}
+ {
+ onResendEmailVerification();
+ return false;
+ }}
+ >
+ {t('talk-plugin-notifications.banner_info.verify_now')}
+
+
+
+);
+
+const EmailVerificationBannerLoading = () => (
+
+
+
+);
+
+const EmailVerificationBannerError = ({ errorMessage }) => (
+
+ {t('talk-plugin-notifications.banner_error.text')}
+ {errorMessage}
+
+);
+
+const EmailVerificationBannerSuccess = ({ email }) => (
+
+ {t('talk-plugin-notifications.banner_success.text', email)}
+
+);
+
+const EmailVerificationBanner = ({
+ onResendEmailVerification,
+ email,
+ success,
+ loading,
+ errorMessage,
+}) => (
+
+ {success && }
+ {errorMessage && (
+
+ )}
+ {loading && }
+ {!success &&
+ !errorMessage &&
+ !loading && (
+
+ )}
+
+);
+
+EmailVerificationBanner.propTypes = {
+ onResendEmailVerification: PropTypes.func.isRequired,
+ success: PropTypes.bool.isRequired,
+ errorMessage: PropTypes.string,
+ loading: PropTypes.bool.isRequired,
+ email: PropTypes.string.isRequired,
+};
+
+export default EmailVerificationBanner;
diff --git a/plugins/talk-plugin-notifications/client/components/Settings.css b/plugins/talk-plugin-notifications/client/components/Settings.css
index 12a7233e1..c4d43fd9a 100644
--- a/plugins/talk-plugin-notifications/client/components/Settings.css
+++ b/plugins/talk-plugin-notifications/client/components/Settings.css
@@ -1,5 +1,6 @@
.root {
margin-bottom: 20px;
+ width: 380px;
}
.innerSettings {
@@ -25,3 +26,7 @@
.notifcationSettingsSlot {
margin-bottom: 3px;
}
+
+.disabled {
+ color: #e5e5e5;
+}
diff --git a/plugins/talk-plugin-notifications/client/components/Settings.js b/plugins/talk-plugin-notifications/client/components/Settings.js
index dad6b2bed..010422491 100644
--- a/plugins/talk-plugin-notifications/client/components/Settings.js
+++ b/plugins/talk-plugin-notifications/client/components/Settings.js
@@ -5,6 +5,8 @@ import { Slot } from 'plugin-api/beta/client/components';
import { t } from 'plugin-api/beta/client/services';
import styles from './Settings.css';
import { BareButton } from 'plugin-api/beta/client/components/ui';
+import EmailVerificationBanner from '../containers/EmailVerificationBanner';
+import cn from 'classnames';
class Settings extends React.Component {
childFactory = el => {
@@ -23,13 +25,20 @@ class Settings extends React.Component {
updateNotificationSettings,
turnOffAll,
turnOffButtonDisabled,
+ needEmailVerification,
+ email,
} = this.props;
return (
{t('talk-plugin-notifications.settings_title')}
-
+ {needEmailVerification && }
+
{t('talk-plugin-notifications.settings_subtitle')}
@@ -40,6 +49,7 @@ class Settings extends React.Component {
childFactory={this.childFactory}
setTurnOffInputFragment={setTurnOffInputFragment}
updateNotificationSettings={updateNotificationSettings}
+ disabled={needEmailVerification}
/>
-
);
}
}
Toggle.propTypes = {
+ disabled: PropTypes.bool,
checked: PropTypes.bool,
onChange: PropTypes.func,
children: PropTypes.node,
diff --git a/plugins/talk-plugin-notifications/client/containers/EmailVerificationBanner.js b/plugins/talk-plugin-notifications/client/containers/EmailVerificationBanner.js
new file mode 100644
index 000000000..0d8a98214
--- /dev/null
+++ b/plugins/talk-plugin-notifications/client/containers/EmailVerificationBanner.js
@@ -0,0 +1,35 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { withResendEmailConfirmation } from 'plugin-api/beta/client/hocs';
+import { compose } from 'recompose';
+import EmailVerificationBanner from '../components/EmailVerificationBanner';
+
+class EmailVerificationBannerContainer extends Component {
+ handleResendEmailVerification = () => {
+ this.props.resendEmailConfirmation(this.props.email);
+ };
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+EmailVerificationBannerContainer.propTypes = {
+ success: PropTypes.bool.isRequired,
+ loading: PropTypes.bool.isRequired,
+ resendEmailConfirmation: PropTypes.func.isRequired,
+ errorMessage: PropTypes.string,
+ email: PropTypes.string.isRequired,
+};
+
+export default compose(withResendEmailConfirmation)(
+ EmailVerificationBannerContainer
+);
diff --git a/plugins/talk-plugin-notifications/client/containers/Settings.js b/plugins/talk-plugin-notifications/client/containers/Settings.js
index 9552ebe5f..61a21f440 100644
--- a/plugins/talk-plugin-notifications/client/containers/Settings.js
+++ b/plugins/talk-plugin-notifications/client/containers/Settings.js
@@ -31,6 +31,12 @@ class SettingsContainer extends React.Component {
this.props.updateNotificationSettings(this.state.turnOffInput);
};
+ getNeedEmailVerification() {
+ return !this.props.root.me.profiles.some(
+ profile => profile.provider === 'local' && profile.confirmedAt
+ );
+ }
+
render() {
return (
);
}
@@ -60,6 +68,7 @@ const enhance = compose(
__typename
${getSlotFragmentSpreads(slots, 'root')}
me {
+ email
profiles {
provider
... on LocalUserProfile {
diff --git a/plugins/talk-plugin-notifications/client/translations.yml b/plugins/talk-plugin-notifications/client/translations.yml
index 9088e6493..83a34526b 100644
--- a/plugins/talk-plugin-notifications/client/translations.yml
+++ b/plugins/talk-plugin-notifications/client/translations.yml
@@ -3,3 +3,13 @@ en:
settings_title: Notifications
settings_subtitle: Receive notifications when
turn_off_all: I do not want to receive notifications
+ banner_info:
+ title: Email Verification Required
+ text: To receive email notifications you must have a verified email address.
+ verify_now: Verify your email now
+ banner_success:
+ title: Email Verification Sent
+ text: An email has been sent to {0} containing a verification link.
+ banner_error:
+ title: Error
+ text: There have been an error sending your verification email. Please try again later.