mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 10:42:12 +00:00
intro-screen refactored
This commit is contained in:
parent
17b0874f1a
commit
eec39c8582
3 changed files with 182 additions and 173 deletions
|
|
@ -26,6 +26,7 @@ class Checkbox extends Component {
|
|||
icon={this.props.checked ? 'ic_check' : 'ic_box_empty'}
|
||||
/>
|
||||
<input
|
||||
ref={this.props.forwardedRef}
|
||||
className={styles['native-checkbox']}
|
||||
type={'checkbox'}
|
||||
disabled={this.props.disabled}
|
||||
|
|
@ -49,4 +50,10 @@ Checkbox.defaultProps = {
|
|||
checked: false
|
||||
};
|
||||
|
||||
export default Checkbox;
|
||||
const CheckboxWithForwardedRef = React.forwardRef((props, ref) => (
|
||||
<Checkbox {...props} forwardedRef={ref} />
|
||||
));
|
||||
|
||||
CheckboxWithForwardedRef.displayName = 'CheckboxWithForwardedRef';
|
||||
|
||||
export default CheckboxWithForwardedRef;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
import React, { Component } from 'react';
|
||||
import Icon from 'stremio-icons/dom';
|
||||
import { Checkbox } from 'stremio-common';
|
||||
import CheckboxLabel from './CheckboxLabel';
|
||||
import styles from './styles';
|
||||
|
||||
const FORMS = {
|
||||
LOGIN: '1',
|
||||
SIGN_UP: '2'
|
||||
};
|
||||
|
||||
class Intro extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -10,26 +15,33 @@ class Intro extends Component {
|
|||
this.emailRef = React.createRef();
|
||||
this.passwordRef = React.createRef();
|
||||
this.confirmPasswordRef = React.createRef();
|
||||
this.termsRef = React.createRef();
|
||||
this.privacyPolicyRef = React.createRef();
|
||||
this.marketingRef = React.createRef();
|
||||
|
||||
this.state = {
|
||||
selectedOption: 'signUp',
|
||||
selectedForm: FORMS.SIGN_UP,
|
||||
termsAccepted: false,
|
||||
privacyPolicyAccepted: false,
|
||||
communicationsAccepted: false,
|
||||
marketingAccepted: false,
|
||||
email: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
error: ''
|
||||
};
|
||||
}
|
||||
|
||||
changeSelectedOption = (event) => {
|
||||
this.setState({ selectedOption: event.currentTarget.dataset.option,
|
||||
changeSelectedForm = (event) => {
|
||||
this.setState({
|
||||
selectedForm: event.currentTarget.dataset.option,
|
||||
termsAccepted: false,
|
||||
privacyPolicyAccepted: false,
|
||||
communicationsAccepted: false,
|
||||
marketingAccepted: false,
|
||||
email: '',
|
||||
password: '',
|
||||
error: '', });
|
||||
confirmPassword: '',
|
||||
error: '',
|
||||
});
|
||||
}
|
||||
|
||||
emailOnChange = (event) => {
|
||||
|
|
@ -40,6 +52,10 @@ class Intro extends Component {
|
|||
this.setState({ password: event.target.value });
|
||||
}
|
||||
|
||||
confirmPasswordOnChange = (event) => {
|
||||
this.setState({ confirmPassword: event.target.value });
|
||||
}
|
||||
|
||||
toggleTerms = () => {
|
||||
this.setState(({ termsAccepted }) => {
|
||||
return { termsAccepted: !termsAccepted }
|
||||
|
|
@ -47,106 +63,103 @@ class Intro extends Component {
|
|||
}
|
||||
|
||||
togglePrivacyPolicy = () => {
|
||||
this.setState(({ privacyPolicyAccepted }) => {
|
||||
return { privacyPolicyAccepted: !privacyPolicyAccepted }
|
||||
});
|
||||
this.setState(({ privacyPolicyAccepted }) => ({
|
||||
privacyPolicyAccepted: !privacyPolicyAccepted
|
||||
}));
|
||||
}
|
||||
|
||||
toggleCommunications = () => {
|
||||
this.setState(({ communicationsAccepted }) => {
|
||||
return { communicationsAccepted: !communicationsAccepted }
|
||||
toggleMarketing = () => {
|
||||
this.setState(({ marketingAccepted }) => {
|
||||
return { marketingAccepted: !marketingAccepted }
|
||||
});
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return nextState.selectedOption !== this.state.selectedOption ||
|
||||
return nextState.selectedForm !== this.state.selectedForm ||
|
||||
nextState.termsAccepted !== this.state.termsAccepted ||
|
||||
nextState.privacyPolicyAccepted !== this.state.privacyPolicyAccepted ||
|
||||
nextState.communicationsAccepted !== this.state.communicationsAccepted ||
|
||||
nextState.marketingAccepted !== this.state.marketingAccepted ||
|
||||
nextState.email !== this.state.email ||
|
||||
nextState.password !== this.state.password ||
|
||||
nextState.confirmPassword !== this.state.confirmPassword ||
|
||||
nextState.error !== this.state.error;
|
||||
}
|
||||
|
||||
renderAcceptanceOption({ accept, label, href, checked, onClick }) {
|
||||
return (
|
||||
<label className={styles['toggle-option']}>
|
||||
<div className={styles['checkbox-container']}>
|
||||
<Checkbox className={styles['checkbox']} checked={checked} disabled={false} onClick={onClick} />
|
||||
</div>
|
||||
<div className={styles['accept']}>{accept}
|
||||
<span> </span>
|
||||
<a href={href} target={'_blank'} tabIndex={'-1'} className={styles['acceptance-label']}>{label}</a>
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
loginErrorLabel = () => {
|
||||
loginErrorLabel = (event) => {
|
||||
event.preventDefault();
|
||||
if (this.state.email.length < 8) {
|
||||
event.preventDefault();
|
||||
this.setState({ error: 'Please enter a valid email' });
|
||||
} else {
|
||||
if (this.emailRef.current === document.activeElement) {
|
||||
this.passwordRef.current.focus();
|
||||
}
|
||||
|
||||
if (this.state.password.length < 1) {
|
||||
event.preventDefault();
|
||||
this.setState({ error: 'Wrong email or password. In case you have forgotten your password, click here.' });
|
||||
this.setState({ error: 'Wrong email or password.' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
singUpErrorLabel = () => {
|
||||
singUpErrorLabel = (event) => {
|
||||
event.preventDefault();
|
||||
if (this.state.email.length < 8) {
|
||||
event.preventDefault();
|
||||
this.setState({ error: 'Please enter a valid email' });
|
||||
} else {
|
||||
if (!this.state.termsAccepted) {
|
||||
event.preventDefault();
|
||||
this.setState({ error: 'You must accept the Terms of Service' });
|
||||
if (this.emailRef.current === document.activeElement) {
|
||||
this.passwordRef.current.focus();
|
||||
}
|
||||
|
||||
if (this.state.password.length < 1) {
|
||||
this.setState({ error: 'Invalid password' });
|
||||
} else {
|
||||
if (!this.state.privacyPolicyAccepted) {
|
||||
event.preventDefault();
|
||||
this.setState({ error: 'You must accept the Privacy Policy' });
|
||||
if (this.passwordRef.current === document.activeElement) {
|
||||
this.confirmPasswordRef.current.focus();
|
||||
}
|
||||
|
||||
if (this.state.password !== this.state.confirmPassword) {
|
||||
this.setState({ error: 'Passwords dont match' });
|
||||
} else {
|
||||
if (this.state.password.length < 1) {
|
||||
event.preventDefault();
|
||||
this.setState({ error: 'Invalid password' });
|
||||
if (this.confirmPasswordRef.current === document.activeElement) {
|
||||
this.termsRef.current.focus();
|
||||
}
|
||||
|
||||
if (!this.state.termsAccepted) {
|
||||
this.setState({ error: 'You must accept the Terms of Service' });
|
||||
} else {
|
||||
this.setState({ error: 'Passwords dont match' });
|
||||
if (this.termsRef.current === document.activeElement) {
|
||||
this.privacyPolicyRef.current.focus();
|
||||
}
|
||||
|
||||
if (!this.state.privacyPolicyAccepted) {
|
||||
this.setState({ error: 'You must accept the Privacy Policy' });
|
||||
} else {
|
||||
if (this.privacyPolicyRef.current === document.activeElement) {
|
||||
this.marketingRef.current.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guestLoginErrorLabel = () => {
|
||||
guestLoginErrorLabel = (event) => {
|
||||
if (!this.state.termsAccepted) {
|
||||
event.preventDefault();
|
||||
this.setState({ error: 'You must accept the Terms of Service' });
|
||||
}
|
||||
}
|
||||
|
||||
focusNextRef = (event) => {
|
||||
if(event.keyCode === 13 && this.state.email.length > 7) {
|
||||
this.passwordRef.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
renderSignUpForm = () => {
|
||||
return (
|
||||
<form className={styles['login-form']}>
|
||||
<div className={styles['fb-button']}>
|
||||
<Icon className={styles['icon']} icon={'ic_facebook'} />
|
||||
<div className={styles['label']}>Login with Facebook</div>
|
||||
</div>
|
||||
<div className={styles['text']}>We won't post anything on your behalf</div>
|
||||
<div className={styles['or']}>OR</div>
|
||||
<input ref={this.emailRef} onKeyDown={this.focusNextRef} className={styles['email']} type={'text'} placeholder={'Email'} value={this.state.email} onChange={this.emailOnChange} />
|
||||
<input ref={this.passwordRef} onKeyDown={this.focusNextRef} className={styles['password']} type={'password'} placeholder={'Password'} value={this.state.password} onChange={this.passwordOnChange} />
|
||||
<input ref={this.confirmPasswordRef} className={styles['password']} type={'password'} placeholder={'Confirm Password'} />
|
||||
<form className={styles['form-container']} onSubmit={this.singUpErrorLabel}>
|
||||
<input ref={this.emailRef} className={styles['email']} type={'text'} placeholder={'Email'} value={this.state.email} onChange={this.emailOnChange} />
|
||||
<input ref={this.passwordRef} className={styles['password']} type={'password'} placeholder={'Password'} value={this.state.password} onChange={this.passwordOnChange} />
|
||||
<input ref={this.confirmPasswordRef} className={styles['password']} type={'password'} placeholder={'Confirm Password'} value={this.state.confirmPassword} onChange={this.confirmPasswordOnChange} />
|
||||
<div className={styles['acceptance-section']}>
|
||||
{this.renderAcceptanceOption({ accept: 'I have read and agree with the Stremio', label: 'Terms and conditions', href: 'https://www.stremio.com/tos', checked: this.state.termsAccepted, onClick: this.toggleTerms })}
|
||||
{this.renderAcceptanceOption({ accept: 'I have read and agree with the Stremio', label: 'Privacy Policy', href: 'https://www.stremio.com/privacy', checked: this.state.privacyPolicyAccepted, onClick: this.togglePrivacyPolicy })}
|
||||
{this.renderAcceptanceOption({ accept: 'I agree to receive marketing communications from Stremio', checked: this.state.communicationsAccepted, onClick: this.toggleCommunications })}
|
||||
<CheckboxLabel ref={this.termsRef} className={styles['checkbox-label']} label='I have read and agree with the Stremio' link='Terms and conditions' href='https://www.stremio.com/tos' checked={this.state.termsAccepted} onClick={this.toggleTerms} />
|
||||
<CheckboxLabel ref={this.privacyPolicyRef} className={styles['checkbox-label']} label='I have read and agree with the Stremio' link='Privacy Policy' href='https://www.stremio.com/privacy' checked={this.state.privacyPolicyAccepted} onClick={this.togglePrivacyPolicy} />
|
||||
<CheckboxLabel ref={this.marketingRef} className={styles['checkbox-label']} label='I agree to receive marketing communications from Stremio' checked={this.state.marketingAccepted} onClick={this.toggleMarketing} />
|
||||
</div>
|
||||
{
|
||||
this.state.error ?
|
||||
|
|
@ -154,43 +167,33 @@ class Intro extends Component {
|
|||
:
|
||||
null
|
||||
}
|
||||
<input className={styles['submit-button']} type={'submit'} value={'SING UP'} onClick={this.singUpErrorLabel}>
|
||||
</input>
|
||||
<div className={styles['option']} data-option={'login'} onClick={this.changeSelectedOption}>LOG IN</div>
|
||||
<a href={'#/'} className={styles['option']} onClick={this.guestLoginErrorLabel}>GUEST LOGIN</a>
|
||||
<input className={styles['submit-button']} type={'submit'} value={'SING UP'} />
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
renderLoginForm = () => {
|
||||
return (
|
||||
<form className={styles['login-form']}>
|
||||
<div className={styles['fb-button']}>
|
||||
<Icon className={styles['icon']} icon={'ic_facebook'} />
|
||||
<div className={styles['label']}>Login with Facebook</div>
|
||||
</div>
|
||||
<div className={styles['text']}>We won't post anything on your behalf</div>
|
||||
<div className={styles['or']}>OR</div>
|
||||
<form className={styles['form-container']} onSubmit={this.loginErrorLabel}>
|
||||
<input ref={this.emailRef} className={styles['email']} type={'text'} placeholder={'Email'} value={this.state.email} onChange={this.emailOnChange} />
|
||||
<input ref={this.passwordRef} className={styles['password']} type={'password'} placeholder={'Password'} value={this.state.password} onChange={this.passwordOnChange} />
|
||||
<a className={styles['forgot-password']} href={'https://www.strem.io/reset-password/'} target={'_blank'}>Forgot password?</a>
|
||||
{
|
||||
this.state.error ?
|
||||
<div className={styles['error']}>{this.state.error}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
<input className={styles['submit-button']} type={'submit'} value={'LOG IN'} onClick={this.loginErrorLabel}>
|
||||
</input>
|
||||
<div className={styles['option']} data-option={'signUp'} onClick={this.changeSelectedOption}>SING UP WITH EMAIL</div>
|
||||
<input className={styles['submit-button']} type={'submit'} value={'LOG IN'} />
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
renderSelectedMenu = () => {
|
||||
switch (this.state.selectedOption) {
|
||||
case 'signUp':
|
||||
switch (this.state.selectedForm) {
|
||||
case FORMS.SIGN_UP:
|
||||
return this.renderSignUpForm();
|
||||
case 'login':
|
||||
case FORMS.LOGIN:
|
||||
return this.renderLoginForm();
|
||||
default:
|
||||
return null;
|
||||
|
|
@ -201,7 +204,22 @@ class Intro extends Component {
|
|||
return (
|
||||
<div className={styles['intro-container']}>
|
||||
<div className={styles['overlay']} />
|
||||
{this.renderSelectedMenu()}
|
||||
<div className={styles['intro']}>
|
||||
<div className={styles['facebook-button']}>
|
||||
<Icon className={styles['icon']} icon={'ic_facebook'} />
|
||||
<div className={styles['label']}>Login with Facebook</div>
|
||||
</div>
|
||||
<div className={styles['text']}>We won't post anything on your behalf</div>
|
||||
<div className={styles['or']}>OR</div>
|
||||
{this.renderSelectedMenu()}
|
||||
<div className={styles['option']} data-option={this.state.selectedForm === FORMS.SIGN_UP ? FORMS.LOGIN : FORMS.SIGN_UP} onClick={this.changeSelectedForm}>{this.state.selectedForm === FORMS.SIGN_UP ? 'LOG IN' : 'SING UP WITH EMAIL'}</div>
|
||||
{
|
||||
this.state.selectedForm === FORMS.SIGN_UP ?
|
||||
<a className={styles['option']} href={'#/'} onClick={this.guestLoginErrorLabel}>GUEST LOGIN</a>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
.intro-container {
|
||||
--login-form-width: 270px;
|
||||
--spacing: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.intro-container {
|
||||
|
|
@ -22,8 +23,7 @@
|
|||
background-color: var(--color-backgrounddark80);
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: var(--login-form-width);
|
||||
.intro {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
|
|
@ -31,140 +31,124 @@
|
|||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
margin: auto;
|
||||
|
||||
.fb-button {
|
||||
.facebook-button {
|
||||
width: var(--login-form-width);
|
||||
height: 68px;
|
||||
height: calc(var(--login-form-width) * 0.25);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
padding: 20px 0;
|
||||
padding: calc(var(--spacing) * 1.25) 0;
|
||||
background: var(--color-secondarydark);
|
||||
|
||||
.icon {
|
||||
height: 100%;
|
||||
margin-right: 16px;
|
||||
margin-right: var(--spacing);
|
||||
fill: var(--color-surfacelighter);
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 15px;
|
||||
font-size: 1.1em;
|
||||
color: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
margin: calc(var(--spacing) * 0.5) 0;
|
||||
font-size: 14px;
|
||||
color: var(--color-surface);
|
||||
}
|
||||
|
||||
.or {
|
||||
margin: calc(var(--spacing) * 3) 0 var(--spacing) 0;
|
||||
font-size: 18px;
|
||||
font-size: 1.3em;
|
||||
color: var(--color-surface);
|
||||
}
|
||||
|
||||
.email {
|
||||
.form-container {
|
||||
width: var(--login-form-width);
|
||||
margin-bottom: var(--spacing);
|
||||
padding: calc(var(--spacing) * 0.5) 0;
|
||||
border-bottom: 1px solid var(--color-surface);
|
||||
font-size: 15px;
|
||||
color: var(--color-surfacelighter);
|
||||
outline: none;
|
||||
background: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-surfacelight);
|
||||
}
|
||||
}
|
||||
|
||||
.password {
|
||||
width: var(--login-form-width);
|
||||
margin-bottom: var(--spacing);
|
||||
padding: calc(var(--spacing) * 0.5) 0;
|
||||
border-bottom: 1px solid var(--color-surface);
|
||||
font-size: 15px;
|
||||
color: var(--color-surfacelighter);
|
||||
outline: none;
|
||||
background: none;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-surfacelight);
|
||||
}
|
||||
}
|
||||
|
||||
.acceptance-section {
|
||||
width: var(--login-form-width);
|
||||
|
||||
.toggle-option {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.email {
|
||||
width: var(--login-form-width);
|
||||
margin-bottom: var(--spacing);
|
||||
padding: calc(var(--spacing) * 0.5) 0;
|
||||
border-bottom: 1px solid var(--color-surface);
|
||||
font-size: 1.1em;
|
||||
color: var(--color-surfacelighter);
|
||||
outline: none;
|
||||
background: none;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-surfacelight);
|
||||
}
|
||||
}
|
||||
|
||||
.password {
|
||||
width: var(--login-form-width);
|
||||
margin-bottom: var(--spacing);
|
||||
padding: calc(var(--spacing) * 0.5) 0;
|
||||
border-bottom: 1px solid var(--color-surface);
|
||||
font-size: 1.1em;
|
||||
color: var(--color-surfacelighter);
|
||||
outline: none;
|
||||
background: none;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-surfacelight);
|
||||
}
|
||||
}
|
||||
|
||||
.acceptance-section {
|
||||
width: var(--login-form-width);
|
||||
|
||||
.checkbox-label {
|
||||
margin-bottom: var(--spacing);
|
||||
}
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
cursor: pointer;
|
||||
margin-bottom: var(--spacing);
|
||||
color: var(--color-surfacelight);
|
||||
|
||||
.checkbox-container {
|
||||
margin-right: calc(var(--spacing) * 0.5);
|
||||
|
||||
.checkbox {
|
||||
width: var(--spacing);
|
||||
height: var(--spacing);
|
||||
fill: var(--color-surface);
|
||||
|
||||
&:global(.checked) {
|
||||
fill: var(--color-surfacelight);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
fill: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accept {
|
||||
font-size: 14px;
|
||||
color: var(--color-surface);
|
||||
}
|
||||
|
||||
.acceptance-label {
|
||||
font-size: 14px;
|
||||
&:hover {
|
||||
color: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
margin: 0 0 var(--spacing) 0;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: var(--color-signal1);
|
||||
}
|
||||
.error {
|
||||
margin: 0 0 var(--spacing) 0;
|
||||
text-align: center;
|
||||
color: var(--color-signal1);
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
width: var(--login-form-width);
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
padding: 17px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--color-surfacelighter);
|
||||
background-color: var(--color-primary);
|
||||
|
||||
&:hover, &:focus {
|
||||
.submit-button {
|
||||
width: var(--login-form-width);
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
padding: calc(var(--spacing) * 1.1);
|
||||
font-size: 1.1em;
|
||||
font-weight: 600;
|
||||
color: var(--color-surfacelighter);
|
||||
background-color: var(--color-primarydark);
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.option {
|
||||
margin-top: calc(var(--spacing) * 2);
|
||||
cursor: pointer;
|
||||
font-size: 1.1em;
|
||||
font-weight: 600;
|
||||
color: var(--color-surfacelighter);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue