mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-19 19:07:47 -05:00
Split sign up email messaging based on if user is under 13
This commit is contained in:
parent
14132591e8
commit
0fb18c4650
4 changed files with 56 additions and 10 deletions
|
@ -39,7 +39,7 @@ class EmailStep extends React.Component {
|
||||||
if (this.props.sendAnalytics) {
|
if (this.props.sendAnalytics) {
|
||||||
this.props.sendAnalytics('join-email');
|
this.props.sendAnalytics('join-email');
|
||||||
}
|
}
|
||||||
// automatically start with focus on username field
|
// automatically start with focus on email field
|
||||||
if (this.emailInput) this.emailInput.focus();
|
if (this.emailInput) this.emailInput.focus();
|
||||||
}
|
}
|
||||||
handleSetEmailRef (emailInputRef) {
|
handleSetEmailRef (emailInputRef) {
|
||||||
|
@ -48,7 +48,7 @@ class EmailStep extends React.Component {
|
||||||
handleCaptchaLoad () {
|
handleCaptchaLoad () {
|
||||||
this.setState({captchaIsLoading: false});
|
this.setState({captchaIsLoading: false});
|
||||||
}
|
}
|
||||||
// simple function to memoize remote requests for usernames
|
// simple function to memoize remote requests for emails
|
||||||
validateEmailRemotelyWithCache (email) {
|
validateEmailRemotelyWithCache (email) {
|
||||||
if (Object.prototype.hasOwnProperty.call(this.emailRemoteCache, email)) {
|
if (Object.prototype.hasOwnProperty.call(this.emailRemoteCache, email)) {
|
||||||
return Promise.resolve(this.emailRemoteCache[email]);
|
return Promise.resolve(this.emailRemoteCache[email]);
|
||||||
|
@ -89,7 +89,7 @@ class EmailStep extends React.Component {
|
||||||
this.captchaRef.executeCaptcha();
|
this.captchaRef.executeCaptcha();
|
||||||
}
|
}
|
||||||
handleCaptchaSolved (token) {
|
handleCaptchaSolved (token) {
|
||||||
// Now thatcaptcha is done, we can tell Formik we're submitting.
|
// Now that captcha is done, we can tell Formik we're submitting.
|
||||||
this.formikBag.setSubmitting(true);
|
this.formikBag.setSubmitting(true);
|
||||||
this.formData['g-recaptcha-response'] = token;
|
this.formData['g-recaptcha-response'] = token;
|
||||||
this.props.onNextStep(this.formData);
|
this.props.onNextStep(this.formData);
|
||||||
|
@ -98,6 +98,14 @@ class EmailStep extends React.Component {
|
||||||
this.captchaRef = ref;
|
this.captchaRef = ref;
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
const title = this.props.under13 ?
|
||||||
|
this.props.intl.formatMessage({id: 'registration.under13.emailStepTitle'}) :
|
||||||
|
this.props.intl.formatMessage({id: 'registration.emailStepTitle'});
|
||||||
|
|
||||||
|
const description = this.props.under13 ?
|
||||||
|
this.props.intl.formatMessage({id: 'registration.under13.emailStepDescription'}) :
|
||||||
|
undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
|
@ -149,8 +157,9 @@ class EmailStep extends React.Component {
|
||||||
headerImgSrc="/images/join-flow/email-header.png"
|
headerImgSrc="/images/join-flow/email-header.png"
|
||||||
innerClassName="join-flow-inner-email-step"
|
innerClassName="join-flow-inner-email-step"
|
||||||
nextButton={this.props.intl.formatMessage({id: 'registration.createAccount'})}
|
nextButton={this.props.intl.formatMessage({id: 'registration.createAccount'})}
|
||||||
title={this.props.intl.formatMessage({id: 'registration.emailStepTitle'})}
|
title={title}
|
||||||
titleClassName="join-flow-email-title"
|
titleClassName="join-flow-email-title"
|
||||||
|
description={description}
|
||||||
waiting={this.props.waiting || isSubmitting || this.state.captchaIsLoading}
|
waiting={this.props.waiting || isSubmitting || this.state.captchaIsLoading}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
|
@ -205,7 +214,8 @@ EmailStep.propTypes = {
|
||||||
onCaptchaError: PropTypes.func,
|
onCaptchaError: PropTypes.func,
|
||||||
onNextStep: PropTypes.func,
|
onNextStep: PropTypes.func,
|
||||||
sendAnalytics: PropTypes.func.isRequired,
|
sendAnalytics: PropTypes.func.isRequired,
|
||||||
waiting: PropTypes.bool
|
waiting: PropTypes.bool,
|
||||||
|
under13: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ class JoinFlow extends React.Component {
|
||||||
formData: defaults({}, newFormData, this.state.formData)
|
formData: defaults({}, newFormData, this.state.formData)
|
||||||
};
|
};
|
||||||
this.setState(newState, () => {
|
this.setState(newState, () => {
|
||||||
this.handleSubmitRegistration(this.state.formData);
|
this.handleSubmitRegistration(this.state.formData, this.isUnder13());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getErrorsFromResponse (err, body, res) {
|
getErrorsFromResponse (err, body, res) {
|
||||||
|
@ -175,7 +175,7 @@ class JoinFlow extends React.Component {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleSubmitRegistration (formData) {
|
handleSubmitRegistration (formData, isUnder13) {
|
||||||
this.setState({
|
this.setState({
|
||||||
registrationError: null, // clear any existing error
|
registrationError: null, // clear any existing error
|
||||||
waiting: true
|
waiting: true
|
||||||
|
@ -191,6 +191,7 @@ class JoinFlow extends React.Component {
|
||||||
'password': formData.password,
|
'password': formData.password,
|
||||||
'birth_month': formData.birth_month,
|
'birth_month': formData.birth_month,
|
||||||
'birth_year': formData.birth_year,
|
'birth_year': formData.birth_year,
|
||||||
|
'under_13': isUnder13,
|
||||||
'g-recaptcha-response': formData['g-recaptcha-response'],
|
'g-recaptcha-response': formData['g-recaptcha-response'],
|
||||||
'gender': formData.gender,
|
'gender': formData.gender,
|
||||||
'country': formData.country,
|
'country': formData.country,
|
||||||
|
@ -213,7 +214,7 @@ class JoinFlow extends React.Component {
|
||||||
}
|
}
|
||||||
handleErrorNext () {
|
handleErrorNext () {
|
||||||
if (this.canTryAgain()) {
|
if (this.canTryAgain()) {
|
||||||
this.handleSubmitRegistration(this.state.formData);
|
this.handleSubmitRegistration(this.state.formData, this.isUnder13());
|
||||||
} else {
|
} else {
|
||||||
this.resetState();
|
this.resetState();
|
||||||
}
|
}
|
||||||
|
@ -229,6 +230,39 @@ class JoinFlow extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseDateComponent (fieldValue) {
|
||||||
|
// The dates are set to either `'null'` (before the BirthDateStep) or a string representation of a number.
|
||||||
|
if (fieldValue && fieldValue !== 'null') {
|
||||||
|
return Number(fieldValue);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isUnder13 () {
|
||||||
|
const birthYear = this.parseDateComponent(this.state.formData.birth_year);
|
||||||
|
const birthMonth = this.parseDateComponent(this.state.formData.birth_month);
|
||||||
|
|
||||||
|
if (!birthYear || !birthMonth) {
|
||||||
|
// We're not yet at the point where the user has specified their birth date
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const yearDiff = now.getFullYear() - birthYear;
|
||||||
|
|
||||||
|
if (yearDiff > 13) {
|
||||||
|
return false;
|
||||||
|
} else if (yearDiff < 13) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
const currentMonth1Based = now.getMonth() + 1;
|
||||||
|
const monthsLeftToBirthday = birthMonth - currentMonth1Based;
|
||||||
|
|
||||||
|
return monthsLeftToBirthday >= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
|
@ -264,6 +298,7 @@ class JoinFlow extends React.Component {
|
||||||
<EmailStep
|
<EmailStep
|
||||||
sendAnalytics={this.sendAnalytics}
|
sendAnalytics={this.sendAnalytics}
|
||||||
waiting={this.state.waiting}
|
waiting={this.state.waiting}
|
||||||
|
under13={this.isUnder13()}
|
||||||
onCaptchaError={this.handleCaptchaError}
|
onCaptchaError={this.handleCaptchaError}
|
||||||
onNextStep={this.handlePrepareToRegister}
|
onNextStep={this.handlePrepareToRegister}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -208,6 +208,8 @@
|
||||||
"registration.genderOptionAnother": "Another gender:",
|
"registration.genderOptionAnother": "Another gender:",
|
||||||
"registration.genderOptionPreferNotToSay": "Prefer not to say",
|
"registration.genderOptionPreferNotToSay": "Prefer not to say",
|
||||||
"registration.emailStepTitle": "What's your email?",
|
"registration.emailStepTitle": "What's your email?",
|
||||||
|
"registration.under13.emailStepTitle": "What's your parent/adult email address?",
|
||||||
|
"registration.under13.emailStepDescription": "They will need to verify your account through an email link.",
|
||||||
"registration.emailStepInfo": "This will help if you forget your password. This information will not be made public on your account.",
|
"registration.emailStepInfo": "This will help if you forget your password. This information will not be made public on your account.",
|
||||||
"registration.goToClass": "Go to Class",
|
"registration.goToClass": "Go to Class",
|
||||||
"registration.invitedBy": "invited by",
|
"registration.invitedBy": "invited by",
|
||||||
|
|
|
@ -16,7 +16,6 @@ const Register = () => (
|
||||||
src="/images/logo_sm.png"
|
src="/images/logo_sm.png"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
<Scratch3Registration
|
<Scratch3Registration
|
||||||
createProjectOnComplete
|
createProjectOnComplete
|
||||||
|
|
Loading…
Reference in a new issue