mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-26 17:16:11 -05:00
Merge pull request #3265 from benjiwheeler/join-flow-email-improve
Join flow email improvements
This commit is contained in:
commit
4a01fabff8
7 changed files with 45 additions and 35 deletions
|
@ -8,19 +8,16 @@ require('./formik-forms.scss');
|
||||||
require('../forms/row.scss');
|
require('../forms/row.scss');
|
||||||
|
|
||||||
const FormikCheckboxSubComponent = ({
|
const FormikCheckboxSubComponent = ({
|
||||||
className,
|
|
||||||
field,
|
field,
|
||||||
id,
|
id,
|
||||||
label,
|
label,
|
||||||
|
labelClassName,
|
||||||
...props
|
...props
|
||||||
}) => (
|
}) => (
|
||||||
<div className="checkbox">
|
<div className="checkbox">
|
||||||
<input
|
<input
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
className={classNames(
|
className="formik-checkbox"
|
||||||
'formik-checkbox',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
id={id}
|
id={id}
|
||||||
name={field.name}
|
name={field.name}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -32,8 +29,9 @@ const FormikCheckboxSubComponent = ({
|
||||||
{label && (
|
{label && (
|
||||||
<label
|
<label
|
||||||
className={classNames(
|
className={classNames(
|
||||||
|
'formik-checkbox-label',
|
||||||
'formik-label',
|
'formik-label',
|
||||||
'formik-checkbox-label'
|
labelClassName
|
||||||
)}
|
)}
|
||||||
htmlFor={id}
|
htmlFor={id}
|
||||||
>
|
>
|
||||||
|
@ -44,7 +42,6 @@ const FormikCheckboxSubComponent = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
FormikCheckboxSubComponent.propTypes = {
|
FormikCheckboxSubComponent.propTypes = {
|
||||||
className: PropTypes.string,
|
|
||||||
field: PropTypes.shape({
|
field: PropTypes.shape({
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
onBlur: PropTypes.function,
|
onBlur: PropTypes.function,
|
||||||
|
@ -52,31 +49,32 @@ FormikCheckboxSubComponent.propTypes = {
|
||||||
value: PropTypes.bool
|
value: PropTypes.bool
|
||||||
}),
|
}),
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
label: PropTypes.string
|
label: PropTypes.string,
|
||||||
|
labelClassName: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const FormikCheckbox = ({
|
const FormikCheckbox = ({
|
||||||
className,
|
|
||||||
id,
|
id,
|
||||||
label,
|
label,
|
||||||
|
labelClassName,
|
||||||
name,
|
name,
|
||||||
...props
|
...props
|
||||||
}) => (
|
}) => (
|
||||||
<Field
|
<Field
|
||||||
className={className}
|
|
||||||
component={FormikCheckboxSubComponent}
|
component={FormikCheckboxSubComponent}
|
||||||
id={id}
|
id={id}
|
||||||
label={label}
|
label={label}
|
||||||
|
labelClassName={labelClassName}
|
||||||
name={name}
|
name={name}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
FormikCheckbox.propTypes = {
|
FormikCheckbox.propTypes = {
|
||||||
className: PropTypes.string,
|
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
|
labelClassName: PropTypes.string,
|
||||||
name: PropTypes.string
|
name: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
@import "../../colors";
|
@import "../../colors";
|
||||||
|
|
||||||
.formik-checkbox-label {
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"].formik-checkbox {
|
input[type="checkbox"].formik-checkbox {
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
|
@ -14,16 +10,12 @@ input[type="checkbox"].formik-checkbox {
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
|
|
||||||
&:focus:checked {
|
&:focus {
|
||||||
transition: all .5s ease;
|
transition: all .25s ease;
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: 0 0 0 .25rem $ui-blue-25percent;
|
box-shadow: 0 0 0 .25rem $ui-blue-25percent;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus:not(:checked) {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:checked {
|
&:checked {
|
||||||
background-color: $ui-blue;
|
background-color: $ui-blue;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -25,4 +25,9 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
font-style: italic;
|
||||||
|
color: $type-gray-75percent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
@import "../../colors";
|
|
||||||
@import "../../frameless";
|
|
||||||
|
|
||||||
.input::placeholder {
|
|
||||||
font-style: italic;
|
|
||||||
color: $type-gray-75percent;
|
|
||||||
}
|
|
|
@ -9,6 +9,7 @@ const FormattedMessage = require('react-intl').FormattedMessage;
|
||||||
|
|
||||||
const JoinFlowStep = require('./join-flow-step.jsx');
|
const JoinFlowStep = require('./join-flow-step.jsx');
|
||||||
const FormikInput = require('../../components/formik-forms/formik-input.jsx');
|
const FormikInput = require('../../components/formik-forms/formik-input.jsx');
|
||||||
|
const FormikCheckbox = require('../../components/formik-forms/formik-checkbox.jsx');
|
||||||
|
|
||||||
require('./join-flow-steps.scss');
|
require('./join-flow-steps.scss');
|
||||||
|
|
||||||
|
@ -17,12 +18,12 @@ class EmailStep extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
bindAll(this, [
|
bindAll(this, [
|
||||||
'handleValidSubmit',
|
'handleValidSubmit',
|
||||||
'validateEmailIfPresent',
|
'validateEmail',
|
||||||
'validateForm'
|
'validateForm'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
validateEmailIfPresent (email) {
|
validateEmail (email) {
|
||||||
if (!email) return null; // skip validation if email is blank; null indicates valid
|
if (!email) return this.props.intl.formatMessage({id: 'general.required'});
|
||||||
const isValidLocally = emailValidator.validate(email);
|
const isValidLocally = emailValidator.validate(email);
|
||||||
if (isValidLocally) {
|
if (isValidLocally) {
|
||||||
return null; // TODO: validate email address remotely
|
return null; // TODO: validate email address remotely
|
||||||
|
@ -51,6 +52,7 @@ class EmailStep extends React.Component {
|
||||||
errors,
|
errors,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
isSubmitting,
|
isSubmitting,
|
||||||
|
setFieldError,
|
||||||
validateField
|
validateField
|
||||||
} = props;
|
} = props;
|
||||||
return (
|
return (
|
||||||
|
@ -89,10 +91,20 @@ class EmailStep extends React.Component {
|
||||||
id="email"
|
id="email"
|
||||||
name="email"
|
name="email"
|
||||||
placeholder={this.props.intl.formatMessage({id: 'general.emailAddress'})}
|
placeholder={this.props.intl.formatMessage({id: 'general.emailAddress'})}
|
||||||
validate={this.validateEmailIfPresent}
|
validate={this.validateEmail}
|
||||||
validationClassName="validation-full-width-input"
|
validationClassName="validation-full-width-input"
|
||||||
onBlur={() => validateField('email')} // eslint-disable-line react/jsx-no-bind
|
/* eslint-disable react/jsx-no-bind */
|
||||||
|
onBlur={() => validateField('email')}
|
||||||
|
onFocus={() => setFieldError('email', null)}
|
||||||
|
/* eslint-enable react/jsx-no-bind */
|
||||||
/>
|
/>
|
||||||
|
<div className="join-flow-email-checkbox-row">
|
||||||
|
<FormikCheckbox
|
||||||
|
id="subscribeCheckbox"
|
||||||
|
label={this.props.intl.formatMessage({id: 'registration.receiveEmails'})}
|
||||||
|
name="subscribe"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</JoinFlowStep>
|
</JoinFlowStep>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -129,6 +129,15 @@
|
||||||
margin-left: .5rem;
|
margin-left: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-inner-content-email {
|
||||||
|
padding-top: 2.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-flow-email-checkbox-row {
|
||||||
|
font-size: .75rem;
|
||||||
|
margin: .25rem .125rem;
|
||||||
|
}
|
||||||
|
|
||||||
a.join-flow-link:link, a.join-flow-link:visited, a.join-flow-link:active {
|
a.join-flow-link:link, a.join-flow-link:visited, a.join-flow-link:active {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
"registration.classroomInviteNewStudentStepDescription": "Your teacher has invited you to join a class:",
|
"registration.classroomInviteNewStudentStepDescription": "Your teacher has invited you to join a class:",
|
||||||
"registration.confirmYourEmail": "Confirm Your Email",
|
"registration.confirmYourEmail": "Confirm Your Email",
|
||||||
"registration.confirmYourEmailDescription": "If you haven't already, please click the link in the confirmation email sent to:",
|
"registration.confirmYourEmailDescription": "If you haven't already, please click the link in the confirmation email sent to:",
|
||||||
"registration.createAccount": "Create Account",
|
"registration.createAccount": "Create Your Account",
|
||||||
"registration.createUsername": "Create a username",
|
"registration.createUsername": "Create a username",
|
||||||
"registration.genderStepTitle": "What's your gender?",
|
"registration.genderStepTitle": "What's your gender?",
|
||||||
"registration.genderStepDescription": "Scratch welcomes people of all genders. We will always keep this information private.",
|
"registration.genderStepDescription": "Scratch welcomes people of all genders. We will always keep this information private.",
|
||||||
|
@ -182,6 +182,7 @@
|
||||||
"registration.personalStepTitle": "Personal Information",
|
"registration.personalStepTitle": "Personal Information",
|
||||||
"registration.personalStepDescription": "Your individual responses will not be displayed publicly, and will be kept confidential and secure",
|
"registration.personalStepDescription": "Your individual responses will not be displayed publicly, and will be kept confidential and secure",
|
||||||
"registration.private": "Scratch will always keep this information private.",
|
"registration.private": "Scratch will always keep this information private.",
|
||||||
|
"registration.receiveEmails": "I'd like to receive emails from the Scratch Team about project ideas, events, and more.",
|
||||||
"registration.selectCountry": "select country",
|
"registration.selectCountry": "select country",
|
||||||
"registration.studentPersonalStepDescription": "This information will not appear on the Scratch website.",
|
"registration.studentPersonalStepDescription": "This information will not appear on the Scratch website.",
|
||||||
"registration.showPassword": "Show password",
|
"registration.showPassword": "Show password",
|
||||||
|
@ -192,7 +193,7 @@
|
||||||
"registration.studentUsernameStepHelpText": "Already have a Scratch account?",
|
"registration.studentUsernameStepHelpText": "Already have a Scratch account?",
|
||||||
"registration.studentUsernameStepTooltip": "You'll need to create a new Scratch account to join this class.",
|
"registration.studentUsernameStepTooltip": "You'll need to create a new Scratch account to join this class.",
|
||||||
"registration.studentUsernameFieldHelpText": "For safety, don't use your real name!",
|
"registration.studentUsernameFieldHelpText": "For safety, don't use your real name!",
|
||||||
"registration.acceptTermsOfUse": "By creating an account, I accept and agree to the {touLink}.",
|
"registration.acceptTermsOfUse": "By creating an account, you accept and agree to the {touLink}.",
|
||||||
"registration.usernameStepTitle": "Request a Teacher Account",
|
"registration.usernameStepTitle": "Request a Teacher Account",
|
||||||
"registration.usernameStepTitleScratcher": "Create a Scratch Account",
|
"registration.usernameStepTitleScratcher": "Create a Scratch Account",
|
||||||
"registration.validationMaxLength": "Sorry, you have exceeded the maximum character limit.",
|
"registration.validationMaxLength": "Sorry, you have exceeded the maximum character limit.",
|
||||||
|
|
Loading…
Reference in a new issue