From f4fc8915e3261c64114ee321de2bf6af96935269 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Fri, 9 Feb 2018 20:12:02 +0100
Subject: [PATCH] Refactor talk-plugin-auth part 1
---
client/coral-admin/src/components/SignIn.css | 9 +
client/coral-admin/src/components/SignIn.js | 21 +-
.../src/containers/LoginContainer.js | 4 -
.../coral-framework/components/Recaptcha.js | 8 +-
client/coral-framework/hocs/withSignIn.js | 8 +-
client/coral-login/src/containers/Main.js | 3 +-
plugins/talk-plugin-auth/client/actions.js | 0
.../client/components/FakeComment.css | 38 ----
.../client/components/FakeComment.js | 37 ----
.../client/components/ForgotContent.js | 81 -------
.../client/components/ResendVerification.css | 15 --
.../client/components/ResendVerification.js | 54 -----
.../client/components/SignDialog.js | 32 ---
.../client/components/SignInContainer.js | 202 ------------------
.../client/components/SignInContent.js | 108 ----------
.../client/components/SignUpContent.js | 143 -------------
.../client/components/UserBox.js | 33 ---
.../client/components/styles.css | 167 ---------------
plugins/talk-plugin-auth/client/index.js | 11 +-
.../client/login/components/Main.css | 8 +
.../client/login/components/Main.js | 13 ++
.../client/login/components/SignIn.css | 47 ++++
.../client/login/components/SignIn.js | 140 ++++++++++++
.../client/login/containers/Main.js | 10 +
.../client/login/containers/SignIn.js | 65 ++++++
.../stream/components/SetUsernameDialog.css | 0
.../components/SetUsernameDialog.js} | 6 +-
.../client/stream/components/SignInButton.css | 0
.../{ => stream}/components/SignInButton.js | 16 +-
.../client/stream/components/UserBox.css | 21 ++
.../client/stream/components/UserBox.js | 32 +++
.../containers/SetUsernameDialog.js} | 6 +-
.../client/stream/containers/SignInButton.js | 13 ++
.../client/stream/containers/UserBox.js | 12 ++
views/login.ejs | 1 +
yarn.lock | 4 +-
36 files changed, 413 insertions(+), 955 deletions(-)
delete mode 100644 client/coral-embed-stream/src/containers/LoginContainer.js
create mode 100644 plugins/talk-plugin-auth/client/actions.js
delete mode 100644 plugins/talk-plugin-auth/client/components/FakeComment.css
delete mode 100644 plugins/talk-plugin-auth/client/components/FakeComment.js
delete mode 100644 plugins/talk-plugin-auth/client/components/ForgotContent.js
delete mode 100644 plugins/talk-plugin-auth/client/components/ResendVerification.css
delete mode 100644 plugins/talk-plugin-auth/client/components/ResendVerification.js
delete mode 100644 plugins/talk-plugin-auth/client/components/SignDialog.js
delete mode 100644 plugins/talk-plugin-auth/client/components/SignInContainer.js
delete mode 100644 plugins/talk-plugin-auth/client/components/SignInContent.js
delete mode 100644 plugins/talk-plugin-auth/client/components/SignUpContent.js
delete mode 100644 plugins/talk-plugin-auth/client/components/UserBox.js
delete mode 100644 plugins/talk-plugin-auth/client/components/styles.css
create mode 100644 plugins/talk-plugin-auth/client/login/components/Main.css
create mode 100644 plugins/talk-plugin-auth/client/login/components/Main.js
create mode 100644 plugins/talk-plugin-auth/client/login/components/SignIn.css
create mode 100644 plugins/talk-plugin-auth/client/login/components/SignIn.js
create mode 100644 plugins/talk-plugin-auth/client/login/containers/Main.js
create mode 100644 plugins/talk-plugin-auth/client/login/containers/SignIn.js
create mode 100644 plugins/talk-plugin-auth/client/stream/components/SetUsernameDialog.css
rename plugins/talk-plugin-auth/client/{components/CreateUsernameDialog.js => stream/components/SetUsernameDialog.js} (95%)
create mode 100644 plugins/talk-plugin-auth/client/stream/components/SignInButton.css
rename plugins/talk-plugin-auth/client/{ => stream}/components/SignInButton.js (52%)
create mode 100644 plugins/talk-plugin-auth/client/stream/components/UserBox.css
create mode 100644 plugins/talk-plugin-auth/client/stream/components/UserBox.js
rename plugins/talk-plugin-auth/client/{components/ChangeUsername.js => stream/containers/SetUsernameDialog.js} (97%)
create mode 100644 plugins/talk-plugin-auth/client/stream/containers/SignInButton.js
create mode 100644 plugins/talk-plugin-auth/client/stream/containers/UserBox.js
diff --git a/client/coral-admin/src/components/SignIn.css b/client/coral-admin/src/components/SignIn.css
index 88d8a452c..10ab54c09 100644
--- a/client/coral-admin/src/components/SignIn.css
+++ b/client/coral-admin/src/components/SignIn.css
@@ -12,3 +12,12 @@
font-weight: normal;
text-decoration: none;
}
+
+.recaptcha {
+ margin-top: 16px;
+ margin-bottom: 6px;
+}
+
+.signInButton {
+ margin-top: 10px;
+}
diff --git a/client/coral-admin/src/components/SignIn.js b/client/coral-admin/src/components/SignIn.js
index 85bfb9810..1525145a7 100644
--- a/client/coral-admin/src/components/SignIn.js
+++ b/client/coral-admin/src/components/SignIn.js
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import styles from './SignIn.css';
import { Button, TextField, Alert } from 'coral-ui';
+import cn from 'classnames';
import Recaptcha from 'coral-framework/components/Recaptcha';
class SignIn extends React.Component {
@@ -27,9 +28,6 @@ class SignIn extends React.Component {
handleRecaptchaRef = ref => {
this.recaptcha = ref;
- setTimeout(() => {
- console.log(ref);
- }, 1000)
};
render() {
@@ -50,9 +48,16 @@ class SignIn extends React.Component {
onChange={this.handlePasswordChange}
type="password"
/>
-
+ {requireRecaptcha && (
+
+
+
+ )}
- {requireRecaptcha && (
-
- )}
);
}
diff --git a/client/coral-embed-stream/src/containers/LoginContainer.js b/client/coral-embed-stream/src/containers/LoginContainer.js
deleted file mode 100644
index 5ee0c54a1..000000000
--- a/client/coral-embed-stream/src/containers/LoginContainer.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import React from 'react';
-import Slot from 'coral-framework/components/Slot';
-
-export const LoginContainer = () => ;
diff --git a/client/coral-framework/components/Recaptcha.js b/client/coral-framework/components/Recaptcha.js
index e2e461382..f632514ba 100644
--- a/client/coral-framework/components/Recaptcha.js
+++ b/client/coral-framework/components/Recaptcha.js
@@ -31,6 +31,8 @@ class Recaptcha extends React.Component {
theme={this.props.theme}
onloadCallback={this.props.onLoad}
verifyCallback={this.props.onVerify}
+ size={this.props.size}
+ className={this.props.className}
/>
);
}
@@ -38,7 +40,8 @@ class Recaptcha extends React.Component {
Recaptcha.defaultProps = {
render: 'explicit',
- theme: 'dark',
+ theme: 'light',
+ size: 'normal',
};
Recaptcha.propTypes = {
@@ -46,7 +49,8 @@ Recaptcha.propTypes = {
onVerify: PropTypes.func.isRequired,
theme: PropTypes.string,
render: PropTypes.string,
- sitekey: PropTypes.string.isRequired,
+ size: PropTypes.string,
+ className: PropTypes.string,
};
export default Recaptcha;
diff --git a/client/coral-framework/hocs/withSignIn.js b/client/coral-framework/hocs/withSignIn.js
index e842c4263..fa70138f9 100644
--- a/client/coral-framework/hocs/withSignIn.js
+++ b/client/coral-framework/hocs/withSignIn.js
@@ -6,7 +6,7 @@ import { translateError } from '../utils';
import { t } from '../services/i18n';
/**
- * WithSignIn provides properties `signIn`, `loading` and `errorMessage`, `requireRecaptcha`.
+ * WithSignIn provides properties `signIn`, `loading`, `errorMessage`, `requireRecaptcha`, 'success'.
*/
export default hoistStatics(WrappedComponent => {
class WithSignIn extends React.Component {
@@ -18,6 +18,7 @@ export default hoistStatics(WrappedComponent => {
state = {
error: null,
loading: false,
+ success: false,
requireRecaptcha: false,
};
@@ -39,14 +40,14 @@ export default hoistStatics(WrappedComponent => {
rest('/auth/local', params)
.then(({ user, token }) => {
- this.setState({ loading: false, error: null });
+ this.setState({ success: true, loading: false, error: null });
store.dispatch(handleSuccessfulLogin(user, token));
})
.catch(error => {
if (!error.status || error.status !== 401) {
console.error(error);
}
- const changeSet = { loading: false, error };
+ const changeSet = { success: false, loading: false, error };
if (error.translation_key === 'LOGIN_MAXIMUM_EXCEEDED') {
changeSet.requireRecaptcha = !!this.context.store.getState().config
.static.TALK_RECAPTCHA_PUBLIC;
@@ -72,6 +73,7 @@ export default hoistStatics(WrappedComponent => {
loading={this.state.loading}
errorMessage={this.getErrorMessage()}
requireRecaptcha={this.state.requireRecaptcha}
+ success={this.state.success}
/>
);
}
diff --git a/client/coral-login/src/containers/Main.js b/client/coral-login/src/containers/Main.js
index 23193bbb6..1d38b9b8e 100644
--- a/client/coral-login/src/containers/Main.js
+++ b/client/coral-login/src/containers/Main.js
@@ -1,8 +1,9 @@
import React from 'react';
+import Slot from 'coral-framework/components/Slot';
class Main extends React.Component {
render() {
- return Hello World
;
+ return ;
}
}
diff --git a/plugins/talk-plugin-auth/client/actions.js b/plugins/talk-plugin-auth/client/actions.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/talk-plugin-auth/client/components/FakeComment.css b/plugins/talk-plugin-auth/client/components/FakeComment.css
deleted file mode 100644
index bc751b115..000000000
--- a/plugins/talk-plugin-auth/client/components/FakeComment.css
+++ /dev/null
@@ -1,38 +0,0 @@
-.root {
- border-top: 1px solid rgba(0, 0, 0, 0.1);
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
- margin-bottom: 10px;
- padding: 8px 0px 10px 0px;
- position: relative;
-}
-
-.footer {
- display: flex;
- justify-content: space-between;
-}
-
-.button {
- color: #2a2a2a;
- margin: 5px 10px 5px 0px;
- background: none;
- padding: 0px;
- border: none;
- font-size: inherit;
- vertical-align: middle;
-
- &:hover {
- color: #767676;
- cursor: pointer;
- }
-}
-
-.icon {
- font-size: 12px;
- padding: 0 2px 0 5px;
- vertical-align: middle;
-}
-
-.authorName {
- margin-right: 5px;
- font-weight: bold;
-}
\ No newline at end of file
diff --git a/plugins/talk-plugin-auth/client/components/FakeComment.js b/plugins/talk-plugin-auth/client/components/FakeComment.js
deleted file mode 100644
index 82c61182b..000000000
--- a/plugins/talk-plugin-auth/client/components/FakeComment.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import React from 'react';
-import t from 'coral-framework/services/i18n';
-import ReplyButton from 'coral-embed-stream/src/tabs/stream/components/ReplyButton';
-import styles from './FakeComment.css';
-import { Icon } from 'plugin-api/beta/client/components/ui';
-import { CommentTimestamp } from 'plugin-api/beta/client/components';
-
-export const FakeComment = ({ username, created_at, body }) => (
-
-
{username}
-
-
{body}
-
-
-
- {}}
- parentCommentId={'commentID'}
- currentUserId={{}}
- />
-
-
-
-
-
-
-
-);
diff --git a/plugins/talk-plugin-auth/client/components/ForgotContent.js b/plugins/talk-plugin-auth/client/components/ForgotContent.js
deleted file mode 100644
index bfadbb001..000000000
--- a/plugins/talk-plugin-auth/client/components/ForgotContent.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import styles from './styles.css';
-import { Button, TextField } from 'plugin-api/beta/client/components/ui';
-import t from 'coral-framework/services/i18n';
-
-class ForgotContent extends React.Component {
- state = { value: '' };
-
- handleSubmit = e => {
- e.preventDefault();
- this.props.fetchForgotPassword(this.state.value);
- };
-
- handleChangeEmail = e => {
- const { value } = e.target;
- this.setState({ value });
- };
-
- render() {
- const { changeView, auth } = this.props;
- const { passwordRequestSuccess, passwordRequestFailure } = auth;
-
- return (
-
-
-
{t('sign_in.recover_password')}
-
-
-
-
- );
- }
-}
-
-ForgotContent.propTypes = {
- auth: PropTypes.object,
- changeView: PropTypes.func,
- fetchForgotPassword: PropTypes.func,
-};
-
-export default ForgotContent;
diff --git a/plugins/talk-plugin-auth/client/components/ResendVerification.css b/plugins/talk-plugin-auth/client/components/ResendVerification.css
deleted file mode 100644
index dc59a9ff1..000000000
--- a/plugins/talk-plugin-auth/client/components/ResendVerification.css
+++ /dev/null
@@ -1,15 +0,0 @@
-.header {
- margin-bottom: 20px;
- text-align: center;
- font-size: 1.2em;
-}
-
-.notVerified {
- padding: 10px;
- margin-bottom: 20px;
- border-radius: 2px;
- border: solid 1px #dddd00;
- background: #FFFF9C;
- color: #777700;
-}
-
diff --git a/plugins/talk-plugin-auth/client/components/ResendVerification.js b/plugins/talk-plugin-auth/client/components/ResendVerification.js
deleted file mode 100644
index d2d71dd45..000000000
--- a/plugins/talk-plugin-auth/client/components/ResendVerification.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import React from 'react';
-import {
- Button,
- Spinner,
- Success,
- Alert,
-} from 'plugin-api/beta/client/components/ui';
-import PropTypes from 'prop-types';
-import styles from './ResendVerification.css';
-import t from 'coral-framework/services/i18n';
-
-class ResendVerification extends React.Component {
- render() {
- const { resendVerification, error, loading, success, email } = this.props;
- return (
-
-
{t('sign_in.email_verify_cta')}
-
- {error && (
-
- {error.translation_key
- ? t(`error.${error.translation_key}`)
- : error.toString()}
-
- )}
-
- {t('error.email_not_verified', email)}
-
-
-
- {loading && }
- {success && }
-
-
- );
- }
-}
-
-ResendVerification.propTypes = {
- resendVerification: PropTypes.bool.isRequired,
- error: PropTypes.object,
- loading: PropTypes.bool,
- success: PropTypes.bool,
- email: PropTypes.string.isRequired,
-};
-
-export default ResendVerification;
diff --git a/plugins/talk-plugin-auth/client/components/SignDialog.js b/plugins/talk-plugin-auth/client/components/SignDialog.js
deleted file mode 100644
index a33baeb99..000000000
--- a/plugins/talk-plugin-auth/client/components/SignDialog.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from 'react';
-import { Dialog } from 'plugin-api/beta/client/components/ui';
-import styles from './styles.css';
-
-import SignInContent from './SignInContent';
-import SignUpContent from './SignUpContent';
-import ForgotContent from './ForgotContent';
-import ResendVerification from './ResendVerification';
-
-const SignDialog = ({ open, view, resetSignInDialog, ...props }) => (
-
-);
-
-export default SignDialog;
diff --git a/plugins/talk-plugin-auth/client/components/SignInContainer.js b/plugins/talk-plugin-auth/client/components/SignInContainer.js
deleted file mode 100644
index a184f3256..000000000
--- a/plugins/talk-plugin-auth/client/components/SignInContainer.js
+++ /dev/null
@@ -1,202 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import SignDialog from './SignDialog';
-import { bindActionCreators } from 'redux';
-import t from 'coral-framework/services/i18n';
-import errorMsj from 'coral-framework/helpers/error';
-import validate from 'coral-framework/helpers/validate';
-
-import {
- changeView,
- fetchSignUp,
- fetchSignIn,
- hideSignInDialog,
- fetchSignInFacebook,
- fetchSignUpFacebook,
- fetchForgotPassword,
- requestConfirmEmail,
- resetSignInDialog,
- facebookCallback,
- invalidForm,
- validForm,
-} from 'coral-embed-stream/src/actions/login';
-
-class SignInContainer extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {
- formData: {
- email: '',
- username: '',
- password: '',
- confirmPassword: '',
- },
- errors: {},
- showErrors: false,
- };
- }
-
- componentDidMount() {
- this.listenToStorageChanges();
- const { formData } = this.state;
- const errors = Object.keys(formData).reduce((map, prop) => {
- map[prop] = t('sign_in.required_field');
- return map;
- }, {});
- this.setState({ errors });
- }
-
- componentWillUnmount() {
- this.unlisten();
- }
-
- listenToStorageChanges() {
- window.addEventListener('storage', this.handleAuth);
- }
-
- unlisten() {
- window.removeEventListener('storage', this.handleAuth);
- }
-
- handleAuth = e => {
- // Listening to FB changes
- // FB localStorage key is 'auth'
- const authCallback = this.props.facebookCallback;
-
- if (e.key === 'auth') {
- const { err, data } = JSON.parse(e.newValue);
- authCallback(err, data);
- this.unlisten();
- localStorage.removeItem('auth');
- }
- };
-
- handleChange = e => {
- const { name, value } = e.target;
- this.setState(
- state => ({
- ...state,
- formData: {
- ...state.formData,
- [name]: value,
- },
- }),
- () => {
- this.validation(name, value);
- }
- );
- };
-
- resendVerification = () => {
- this.props.requestConfirmEmail(this.props.auth.email).then(() => {
- setTimeout(() => {
- // allow success UI to be shown for a second, and then close the modal
- this.props.resetSignInDialog();
- }, 2500);
- });
- };
-
- addError = (name, error) => {
- return this.setState(state => ({
- errors: {
- ...state.errors,
- [name]: error,
- },
- }));
- };
-
- validation = (name, value) => {
- const { addError } = this;
- const { formData } = this.state;
-
- if (!value.length) {
- addError(name, t('sign_in.required_field'));
- } else if (
- name === 'confirmPassword' &&
- formData.confirmPassword !== formData.password
- ) {
- addError('confirmPassword', t('sign_in.passwords_dont_match'));
- } else if (!validate[name](value)) {
- addError(name, errorMsj[name]);
- } else {
- const {[name]: prop, ...errors} = this.state.errors; // eslint-disable-line
- // Removes Error
- this.setState(state => ({ ...state, errors }));
- }
- };
-
- isCompleted = () => {
- const { formData } = this.state;
- return !Object.keys(formData).filter(prop => !formData[prop].length).length;
- };
-
- displayErrors = (show = true) => {
- this.setState({ showErrors: show });
- };
-
- handleSignUp = e => {
- e.preventDefault();
- const { errors } = this.state;
- const { fetchSignUp, validForm, invalidForm } = this.props;
- this.displayErrors();
- if (this.isCompleted() && !Object.keys(errors).length) {
- fetchSignUp(this.state.formData);
- validForm();
- } else {
- invalidForm(t('sign_in.check_the_form'));
- }
- };
-
- handleSignIn = e => {
- e.preventDefault();
- this.props.fetchSignIn(this.state.formData);
- };
-
- render() {
- const { auth } = this.props;
- const {
- requireEmailConfirmation,
- emailVerificationLoading,
- emailVerificationSuccess,
- } = auth;
-
- return (
-
- );
- }
-}
-
-const mapStateToProps = state => ({
- auth: state.auth,
-});
-
-const mapDispatchToProps = dispatch =>
- bindActionCreators(
- {
- facebookCallback,
- fetchSignUp,
- fetchSignIn,
- fetchSignInFacebook,
- fetchSignUpFacebook,
- fetchForgotPassword,
- requestConfirmEmail,
- changeView,
- hideSignInDialog,
- resetSignInDialog,
- invalidForm,
- validForm,
- },
- dispatch
- );
-
-export default connect(mapStateToProps, mapDispatchToProps)(SignInContainer);
diff --git a/plugins/talk-plugin-auth/client/components/SignInContent.js b/plugins/talk-plugin-auth/client/components/SignInContent.js
deleted file mode 100644
index e74de4ff2..000000000
--- a/plugins/talk-plugin-auth/client/components/SignInContent.js
+++ /dev/null
@@ -1,108 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import {
- Button,
- TextField,
- Spinner,
- Alert,
-} from 'plugin-api/beta/client/components/ui';
-import styles from './styles.css';
-import t from 'coral-framework/services/i18n';
-
-const SignInContent = ({
- handleChange,
- formData,
- changeView,
- handleSignIn,
- auth,
- fetchSignInFacebook,
-}) => {
- return (
-
-
-
{t('sign_in.sign_in_to_join')}
-
- {auth.error && (
-
- {auth.error.translation_key
- ? t(`error.${auth.error.translation_key}`)
- : auth.error.toString()}
-
- )}
-
-
-
-
-
-
{t('sign_in.or')}
-
-
-
-
-
- );
-};
-
-SignInContent.propTypes = {
- auth: PropTypes.shape({
- isLoading: PropTypes.bool.isRequired,
- error: PropTypes.string,
- emailVerificationFailure: PropTypes.bool,
- }).isRequired,
- fetchSignInFacebook: PropTypes.func.isRequired,
- handleSignIn: PropTypes.func.isRequired,
- handleChange: PropTypes.func.isRequired,
- changeView: PropTypes.func.isRequired,
- emailVerificationLoading: PropTypes.bool.isRequired,
- emailVerificationSuccess: PropTypes.bool.isRequired,
- resendVerification: PropTypes.func.isRequired,
- formData: PropTypes.object,
-};
-
-export default SignInContent;
diff --git a/plugins/talk-plugin-auth/client/components/SignUpContent.js b/plugins/talk-plugin-auth/client/components/SignUpContent.js
deleted file mode 100644
index 845fe502c..000000000
--- a/plugins/talk-plugin-auth/client/components/SignUpContent.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import styles from './styles.css';
-import React from 'react';
-import {
- Button,
- TextField,
- Spinner,
- Success,
- Alert,
-} from 'plugin-api/beta/client/components/ui';
-import t from 'coral-framework/services/i18n';
-
-class SignUpContent extends React.Component {
- componentWillReceiveProps(next) {
- if (
- !this.props.emailVerificationEnabled &&
- !this.props.auth.successSignUp &&
- next.auth.successSignUp
- ) {
- setTimeout(() => {
- this.props.changeView('SIGNIN');
- }, 2000);
- }
- }
-
- render() {
- const {
- handleChange,
- formData,
- emailVerificationEnabled,
- auth,
- errors,
- showErrors,
- changeView,
- handleSignUp,
- fetchSignUpFacebook,
- } = this.props;
-
- return (
-
-
-
{t('sign_in.sign_up')}
-
-
- {auth.error &&
{auth.error}}
- {!auth.successSignUp && (
-
-
-
-
-
-
{t('sign_in.or')}
-
-
-
- )}
- {auth.successSignUp && (
-
-
- {emailVerificationEnabled && (
-
- {t('sign_in.verify_email')}
-
-
- {t('sign_in.verify_email2')}
-
- )}
-
- )}
-
-
- );
- }
-}
-
-export default SignUpContent;
diff --git a/plugins/talk-plugin-auth/client/components/UserBox.js b/plugins/talk-plugin-auth/client/components/UserBox.js
deleted file mode 100644
index 09e4302b6..000000000
--- a/plugins/talk-plugin-auth/client/components/UserBox.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react';
-import styles from './styles.css';
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
-import t from 'coral-framework/services/i18n';
-import { logout } from 'coral-framework/actions/auth';
-
-const UserBox = ({ user, logout, onShowProfile }) => (
-
- {user ? (
-
- ) : null}
-
-);
-
-const mapStateToProps = ({ auth }) => ({
- user: auth.user,
-});
-
-const mapDispatchToProps = dispatch => bindActionCreators({ logout }, dispatch);
-
-export default connect(mapStateToProps, mapDispatchToProps)(UserBox);
diff --git a/plugins/talk-plugin-auth/client/components/styles.css b/plugins/talk-plugin-auth/client/components/styles.css
deleted file mode 100644
index 735f34d31..000000000
--- a/plugins/talk-plugin-auth/client/components/styles.css
+++ /dev/null
@@ -1,167 +0,0 @@
-.dialog {
- border: none;
- box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
- width: 280px;
- top: 10px;
-}
-
-.header {
- margin-bottom: 20px;
-}
-
-.header h1, .separator h1{
- text-align: center;
- font-size: 1.2em;
-}
-
-.footer {
- margin: 20px auto 10px;
- text-align: center;
-}
-
-.footer span {
- display: block;
- margin-bottom: 5px;
-}
-
-.footer a {
- color: #2c69b6;
- cursor: pointer;
- margin: 0 5px;
-}
-
-.socialConnections {
- margin-bottom: 20px;
-}
-
-.signInButton {
- margin-top: 10px;
- background-color: #2a2a2a;
-}
-
-.close {
- font-size: 20px;
- line-height: 14px;
- top: 10px;
- right: 10px;
- position: absolute;
- display: block;
- font-weight: bold;
- color: #363636;
- cursor: pointer;
-}
-
-.close:hover {
- color: #6b6b6b;
-}
-
-input.error{
- border: solid 2px #f44336;
-}
-
-.errorMsg, .hint {
- color: grey;
- font-weight: 600;
- padding: 3px 0 16px;
-}
-
-.userBox {
- margin: 10px 0 20px;
- letter-spacing: 0.1px;
-}
-
-.userBoxLoggedIn {
- font-weight: bold;
-}
-
-.userBox a {
- color: black;
- font-weight: bold;
- cursor: pointer;
- margin: 0px;
- margin-left: 4px;
- padding-bottom: 2px;
-}
-
-.userBox .logout {
- border-bottom: solid 1px black;
-}
-
-.attention {
- display: inline-block;
- width: 15px;
- height: 15px;
- background: #B71C1C;
- color: #FFEBEE;
- font-weight: bolder;
- padding: 4px;
- vertical-align: middle;
- border-radius: 20px;
- box-sizing: border-box;
- font-size: 9px;
- line-height: 7px;
- text-align: center;
- margin-right: 5px;
-}
-
-.action {
- margin-top: 0px;
-}
-
-.passwordRequestSuccess {
- border: 1px solid green;
- background-color: lightgreen;
- padding: 10px;
-}
-
-.passwordRequestFailure {
- border: 1px solid orange;
- background-color: 1px solid coral;
- padding: 10px;
-}
-
-.emailConfirmDialog {
- margin-top: 15px;
-}
-
-.confirmLabel {
- display: block;
-}
-
-/* Change username Dialog*/
-
-.dialogusername {
- border: none;
- box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
- width: 400px;
- top: 10px;
-}
-
-.yourusername {
- display: block;
-}
-
-.example {
- display: block;
-}
-
-.ifyoudont {
- display: block;
- margin-top: 15px;
-}
-
-.saveusername {
- display: block;
- width: 100%;
-}
-
-.savebutton {
- display: inline;
- background-color: rgb(105,105,105);
- color: white;
-}
-
-.fakeComment {
- display: block;
- margin-bottom: 5px;
-}
diff --git a/plugins/talk-plugin-auth/client/index.js b/plugins/talk-plugin-auth/client/index.js
index 12aa8ccd5..0c70cb112 100644
--- a/plugins/talk-plugin-auth/client/index.js
+++ b/plugins/talk-plugin-auth/client/index.js
@@ -1,13 +1,12 @@
-import UserBox from './components/UserBox';
-import SignInButton from './components/SignInButton';
-import SignInContainer from './components/SignInContainer';
-import ChangeUserNameContainer from './components/ChangeUsername';
+import UserBox from './stream/containers/UserBox';
+import SignInButton from './stream/containers/SignInButton';
import translations from './translations.yml';
+import Login from './login/containers/Main';
export default {
translations,
slots: {
- stream: [UserBox, SignInButton, ChangeUserNameContainer],
- login: [SignInContainer],
+ stream: [UserBox, SignInButton],
+ login: [Login],
},
};
diff --git a/plugins/talk-plugin-auth/client/login/components/Main.css b/plugins/talk-plugin-auth/client/login/components/Main.css
new file mode 100644
index 000000000..9d73e7403
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/login/components/Main.css
@@ -0,0 +1,8 @@
+.dialog {
+ border: none;
+ box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
+ width: 280px;
+ top: 10px;
+ font-family: Helvetica, 'Helvetica Neue', Verdana, sans-serif;
+ font-size: 14px;
+}
diff --git a/plugins/talk-plugin-auth/client/login/components/Main.js b/plugins/talk-plugin-auth/client/login/components/Main.js
new file mode 100644
index 000000000..e74a38b66
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/login/components/Main.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import { Dialog } from 'plugin-api/beta/client/components/ui';
+import styles from './Main.css';
+
+import SignIn from '../containers/SignIn';
+
+const SignDialog = () => (
+
+);
+
+export default SignDialog;
diff --git a/plugins/talk-plugin-auth/client/login/components/SignIn.css b/plugins/talk-plugin-auth/client/login/components/SignIn.css
new file mode 100644
index 000000000..e6442d6f3
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/login/components/SignIn.css
@@ -0,0 +1,47 @@
+.header {
+ margin-bottom: 20px;
+}
+
+.header h1, .separator h1{
+ text-align: center;
+ font-size: 1.2em;
+}
+
+.socialConnections {
+ margin-bottom: 20px;
+}
+
+.separator h1{
+ text-align: center;
+ font-size: 1.2em;
+}
+
+.action {
+ margin-top: 0px;
+}
+
+.signInButton {
+ margin-top: 10px;
+ background-color: #2a2a2a;
+}
+
+.footer {
+ margin: 20px auto 10px;
+ text-align: center;
+}
+
+.footer span {
+ display: block;
+ margin-bottom: 5px;
+}
+
+.footer a {
+ color: #2c69b6;
+ cursor: pointer;
+ margin: 0 5px;
+}
+
+.recaptcha {
+ margin-top: 16px;
+ margin-bottom: 16px;
+}
diff --git a/plugins/talk-plugin-auth/client/login/components/SignIn.js b/plugins/talk-plugin-auth/client/login/components/SignIn.js
new file mode 100644
index 000000000..720a5aaf0
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/login/components/SignIn.js
@@ -0,0 +1,140 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {
+ Button,
+ TextField,
+ Spinner,
+ Alert,
+} from 'plugin-api/beta/client/components/ui';
+import styles from './SignIn.css';
+import t from 'coral-framework/services/i18n';
+import cn from 'classnames';
+import Recaptcha from 'coral-framework/components/Recaptcha';
+
+class SignIn extends React.Component {
+ recaptcha = null;
+
+ handleForgotPasswordLink = e => {
+ e.preventDefault();
+ this.props.onForgotPasswordLink();
+ };
+ handleRegisterLink = e => {
+ e.preventDefault();
+ this.props.onRegisterLink();
+ };
+ handleEmailChange = e => this.props.onEmailChange(e.target.value);
+ handlePasswordChange = e => this.props.onPasswordChange(e.target.value);
+
+ handleSubmit = e => {
+ e.preventDefault();
+ this.props.onSubmit();
+
+ // Reset recaptcha because each response can only
+ // be used once.
+ if (this.recaptcha) {
+ this.recaptcha.reset();
+ }
+ };
+
+ handleRecaptchaRef = ref => {
+ this.recaptcha = ref;
+ };
+
+ render() {
+ const {
+ email,
+ password,
+ errorMessage,
+ requireRecaptcha,
+ loading,
+ } = this.props;
+ return (
+
+
+
{t('sign_in.sign_in_to_join')}
+
+ {errorMessage &&
{errorMessage}}
+
+
+ Social
+
+
+
{t('sign_in.or')}
+
+
+
+
+
+ );
+ }
+}
+
+SignIn.propTypes = {
+ loading: PropTypes.bool.isRequired,
+ email: PropTypes.string.isRequired,
+ password: PropTypes.string.isRequired,
+ onEmailChange: PropTypes.func.isRequired,
+ onPasswordChange: PropTypes.func.isRequired,
+ onForgotPasswordLink: PropTypes.func.isRequired,
+ onRegisterLink: PropTypes.func.isRequired,
+ onRecaptchaVerify: PropTypes.func.isRequired,
+ onSubmit: PropTypes.func.isRequired,
+ errorMessage: PropTypes.string.isRequired,
+ requireRecaptcha: PropTypes.bool.isRequired,
+};
+
+export default SignIn;
diff --git a/plugins/talk-plugin-auth/client/login/containers/Main.js b/plugins/talk-plugin-auth/client/login/containers/Main.js
new file mode 100644
index 000000000..5baedcf08
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/login/containers/Main.js
@@ -0,0 +1,10 @@
+import React from 'react';
+import Main from '../components/Main';
+
+class MainContainer extends React.Component {
+ render() {
+ return ;
+ }
+}
+
+export default MainContainer;
diff --git a/plugins/talk-plugin-auth/client/login/containers/SignIn.js b/plugins/talk-plugin-auth/client/login/containers/SignIn.js
new file mode 100644
index 000000000..14d87bf0f
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/login/containers/SignIn.js
@@ -0,0 +1,65 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { withSignIn } from 'coral-framework/hocs';
+import { compose } from 'recompose';
+import SignIn from '../components/SignIn';
+
+class SignInContainer extends Component {
+ state = {
+ email: '',
+ password: '',
+ recaptchaResponse: '',
+ };
+
+ handleSubmit = () => {
+ this.props.signIn(
+ this.state.email,
+ this.state.password,
+ this.state.recaptchaResponse
+ );
+ };
+
+ handleEmailChange = email => {
+ this.setState({ email });
+ };
+
+ handlePasswordChange = password => {
+ this.setState({ password });
+ };
+
+ handleRecaptchaVerify = recaptchaResponse => {
+ this.setState({ recaptchaResponse });
+ };
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.success) {
+ window.close();
+ }
+ }
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+SignInContainer.propTypes = {
+ signIn: PropTypes.func.isRequired,
+ errorMessage: PropTypes.string.isRequired,
+ requireRecaptcha: PropTypes.bool.isRequired,
+ loading: PropTypes.bool.isRequired,
+ success: PropTypes.bool.isRequired,
+};
+
+export default compose(withSignIn)(SignInContainer);
diff --git a/plugins/talk-plugin-auth/client/stream/components/SetUsernameDialog.css b/plugins/talk-plugin-auth/client/stream/components/SetUsernameDialog.css
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/talk-plugin-auth/client/components/CreateUsernameDialog.js b/plugins/talk-plugin-auth/client/stream/components/SetUsernameDialog.js
similarity index 95%
rename from plugins/talk-plugin-auth/client/components/CreateUsernameDialog.js
rename to plugins/talk-plugin-auth/client/stream/components/SetUsernameDialog.js
index 08ddc171e..681f444ee 100644
--- a/plugins/talk-plugin-auth/client/components/CreateUsernameDialog.js
+++ b/plugins/talk-plugin-auth/client/stream/components/SetUsernameDialog.js
@@ -10,7 +10,7 @@ import {
import { FakeComment } from './FakeComment';
import t from 'coral-framework/services/i18n';
-const CreateUsernameDialog = ({
+const SetUsernameDialog = ({
open,
handleClose,
formData,
@@ -70,7 +70,7 @@ const CreateUsernameDialog = ({
);
-CreateUsernameDialog.propTypes = {
+SetUsernameDialog.propTypes = {
open: PropTypes.bool,
handleClose: PropTypes.func,
formData: PropTypes.object,
@@ -80,4 +80,4 @@ CreateUsernameDialog.propTypes = {
errors: PropTypes.object,
};
-export default CreateUsernameDialog;
+export default SetUsernameDialog;
diff --git a/plugins/talk-plugin-auth/client/stream/components/SignInButton.css b/plugins/talk-plugin-auth/client/stream/components/SignInButton.css
new file mode 100644
index 000000000..e69de29bb
diff --git a/plugins/talk-plugin-auth/client/components/SignInButton.js b/plugins/talk-plugin-auth/client/stream/components/SignInButton.js
similarity index 52%
rename from plugins/talk-plugin-auth/client/components/SignInButton.js
rename to plugins/talk-plugin-auth/client/stream/components/SignInButton.js
index 9ad19599e..dcc6e5c4a 100644
--- a/plugins/talk-plugin-auth/client/components/SignInButton.js
+++ b/plugins/talk-plugin-auth/client/stream/components/SignInButton.js
@@ -1,8 +1,6 @@
import React from 'react';
+import PropTypes from 'prop-types';
import { Button } from 'plugin-api/beta/client/components/ui';
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
-import { showSignInDialog } from 'coral-embed-stream/src/actions/login';
import t from 'coral-framework/services/i18n';
const SignInButton = ({ currentUser, showSignInDialog }) => (
@@ -15,11 +13,9 @@ const SignInButton = ({ currentUser, showSignInDialog }) => (
);
-const mapStateToProps = ({ auth }) => ({
- currentUser: auth.user,
-});
+SignInButton.propTypes = {
+ currentUser: PropTypes.object,
+ showSignInDialog: PropTypes.func,
+};
-const mapDispatchToProps = dispatch =>
- bindActionCreators({ showSignInDialog }, dispatch);
-
-export default connect(mapStateToProps, mapDispatchToProps)(SignInButton);
+export default SignInButton;
diff --git a/plugins/talk-plugin-auth/client/stream/components/UserBox.css b/plugins/talk-plugin-auth/client/stream/components/UserBox.css
new file mode 100644
index 000000000..799468177
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/stream/components/UserBox.css
@@ -0,0 +1,21 @@
+.userBox {
+ margin: 10px 0 20px;
+ letter-spacing: 0.1px;
+}
+
+.userBoxLoggedIn {
+ font-weight: bold;
+}
+
+.userBox a {
+ color: black;
+ font-weight: bold;
+ cursor: pointer;
+ margin: 0px;
+ margin-left: 4px;
+ padding-bottom: 2px;
+}
+
+.userBox .logout {
+ border-bottom: solid 1px black;
+}
diff --git a/plugins/talk-plugin-auth/client/stream/components/UserBox.js b/plugins/talk-plugin-auth/client/stream/components/UserBox.js
new file mode 100644
index 000000000..7f48513b8
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/stream/components/UserBox.js
@@ -0,0 +1,32 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import styles from './UserBox.css';
+import t from 'coral-framework/services/i18n';
+import cn from 'classnames';
+
+const UserBox = ({ user, logout, onShowProfile }) => (
+
+ {user ? (
+
+ ) : null}
+
+);
+
+UserBox.propTypes = {
+ user: PropTypes.object,
+ logout: PropTypes.func,
+ onShowProfile: PropTypes.func,
+};
+
+export default UserBox;
diff --git a/plugins/talk-plugin-auth/client/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/stream/containers/SetUsernameDialog.js
similarity index 97%
rename from plugins/talk-plugin-auth/client/components/ChangeUsername.js
rename to plugins/talk-plugin-auth/client/stream/containers/SetUsernameDialog.js
index 2eab273cc..cba032cd6 100644
--- a/plugins/talk-plugin-auth/client/components/ChangeUsername.js
+++ b/plugins/talk-plugin-auth/client/stream/containers/SetUsernameDialog.js
@@ -19,7 +19,7 @@ import {
updateUsername,
} from 'coral-embed-stream/src/actions/login';
-class ChangeUsernameContainer extends React.Component {
+class SetUsernameDialog extends React.Component {
constructor(props) {
super(props);
@@ -152,7 +152,7 @@ class ChangeUsernameContainer extends React.Component {
}
}
-ChangeUsernameContainer.propTypes = {
+SetUsernameDialog.propTypes = {
auth: PropTypes.object,
hideCreateUsernameDialog: PropTypes.func,
validForm: PropTypes.func,
@@ -180,4 +180,4 @@ const mapDispatchToProps = dispatch =>
export default compose(
withSetUsername,
connect(mapStateToProps, mapDispatchToProps)
-)(ChangeUsernameContainer);
+)(SetUsernameDialog);
diff --git a/plugins/talk-plugin-auth/client/stream/containers/SignInButton.js b/plugins/talk-plugin-auth/client/stream/containers/SignInButton.js
new file mode 100644
index 000000000..4fcd98ae3
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/stream/containers/SignInButton.js
@@ -0,0 +1,13 @@
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import { showSignInDialog } from 'coral-embed-stream/src/actions/login';
+import SignInButton from '../components//SignInButton';
+
+const mapStateToProps = ({ auth }) => ({
+ currentUser: auth.user,
+});
+
+const mapDispatchToProps = dispatch =>
+ bindActionCreators({ showSignInDialog }, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(SignInButton);
diff --git a/plugins/talk-plugin-auth/client/stream/containers/UserBox.js b/plugins/talk-plugin-auth/client/stream/containers/UserBox.js
new file mode 100644
index 000000000..ca50c7b6e
--- /dev/null
+++ b/plugins/talk-plugin-auth/client/stream/containers/UserBox.js
@@ -0,0 +1,12 @@
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import { logout } from 'coral-framework/actions/auth';
+import UserBox from '../components/UserBox';
+
+const mapStateToProps = ({ auth }) => ({
+ user: auth.user,
+});
+
+const mapDispatchToProps = dispatch => bindActionCreators({ logout }, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(UserBox);
diff --git a/views/login.ejs b/views/login.ejs
index 634054074..04e64d93c 100644
--- a/views/login.ejs
+++ b/views/login.ejs
@@ -15,6 +15,7 @@
+