Merge pull request #777 from rschamp/bugfix/class-invite

Resurrect old invite step design for new users
This commit is contained in:
Ray Schamp 2016-07-27 19:34:34 -04:00 committed by GitHub
commit ade303bd80
5 changed files with 65 additions and 28 deletions

View file

@ -6,6 +6,7 @@ var intl = require('../../lib/intl.jsx');
var log = require('../../lib/log');
var smartyStreets = require('../../lib/smarty-streets');
var Avatar = require('../../components/avatar/avatar.jsx');
var Button = require('../../components/forms/button.jsx');
var Card = require('../../components/card/card.jsx');
var CharCount = require('../../components/forms/charcount.jsx');
@ -805,7 +806,44 @@ module.exports = {
);
}
})),
ClassInviteStep: intl.injectIntl(React.createClass({
ClassInviteNewStudentStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {
waiting: false
};
},
onNextStep: function () {
this.props.onNextStep();
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
return (
<Slide className="registration-step class-invite-step">
{this.props.waiting ? [
<Spinner />
] : [
<Avatar className="invite-avatar"
src={this.props.classroom.educator.profile.images['50x50']} />,
<h2>{this.props.classroom.educator.username}</h2>,
<p className="description">
{formatMessage({id: 'registration.classroomInviteNewStudentStepDescription'})}
</p>,
<Card>
<div className="contents">
<h3>{this.props.classroom.title}</h3>
<img className="class-image" src={this.props.classroom.images['250x150']} />
</div>
<NextStepButton onClick={this.onNextStep}
waiting={this.props.waiting}
text={formatMessage({id: 'general.getStarted'})} />
</Card>,
<StepNavigation steps={this.props.totalSteps - 1} active={this.props.activeStep} />
]}
</Slide>
);
}
})),
ClassInviteExistingStudentStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {
classroom: null,
@ -826,7 +864,7 @@ module.exports = {
] : [
<h2>{this.props.studentUsername}</h2>,
<p className="description">
{formatMessage({id: 'registration.classroomInviteStepDescription'})}
{formatMessage({id: 'registration.classroomInviteExistingStudentStepDescription'})}
</p>,
<Card>
<div className="contents">

View file

@ -111,7 +111,9 @@
"registration.choosePasswordStepDescription": "Type in a new password for your account. You will use this password the next time you log into Scratch.",
"registration.choosePasswordStepTitle": "Create a password",
"registration.choosePasswordStepTooltip": "Don't use your name or anything that's easy for someone else to guess.",
"registration.classroomInviteStepDescription": "you have been invited to join the class:",
"registration.classroomApiGeneralError": "Sorry, we could not find the registration information for this class",
"registration.classroomInviteExistingStudentStepDescription": "you have been invited to join the class:",
"registration.classroomInviteNewStudentStepDescription": "has invited you to join the class:",
"registration.confirmYourEmail": "Confirm Your Email",
"registration.confirmYourEmailDescription": "If you haven't already, please click the link in the confirmation email sent to:",
"registration.createUsername": "Create a Username",

View file

@ -34,19 +34,16 @@ var StudentCompleteRegistration = intl.injectIntl(React.createClass({
});
},
componentDidUpdate: function (prevProps) {
if (prevProps.session.session !== this.props.session.session &&
this.props.session.session.permissions &&
this.props.session.session.permissions.student) {
var classroomId = this.props.session.session.user.classroomId;
if (prevProps.studentUsername !== this.props.studentUsername && this.props.newStudent) {
this.setState({waiting: true});
api({
uri: '/classrooms/' + classroomId
uri: '/classrooms/' + this.props.classroomId
}, function (err, body, res) {
this.setState({waiting: false});
if (err || res.statusCode !== 200) {
return this.setState({
registrationErrors: {
__all__: this.props.intl.formatMessage({id: 'studentRegistration.classroomApiGeneralError'})
__all__: this.props.intl.formatMessage({id: 'registration.classroomApiGeneralError'})
}
});
}
@ -80,7 +77,7 @@ var StudentCompleteRegistration = intl.injectIntl(React.createClass({
country: formData.user.country,
is_robot: formData.user.isRobot
};
if (this.props.session.session.flags.must_reset_password) {
if (this.props.must_reset_password) {
submittedData.password = formData.user.password;
}
api({
@ -103,11 +100,7 @@ var StudentCompleteRegistration = intl.injectIntl(React.createClass({
var demographicsDescription = this.props.intl.formatMessage({
id: 'registration.studentPersonalStepDescription'});
var registrationErrors = this.state.registrationErrors;
if (this.props.session.status === sessionStatus.FETCHED && !(
this.props.session.session.permissions &&
this.props.session.session.permissions.student &&
this.props.session.session.flags.must_complete_registration)
) {
if (!this.props.newStudent) {
registrationErrors = {
__all__: this.props.intl.formatMessage({id: 'registration.mustBeNewStudent'})
};
@ -131,12 +124,12 @@ var StudentCompleteRegistration = intl.injectIntl(React.createClass({
<Spinner />
) : (
<Progression {... this.state}>
<Steps.ClassInviteStep classroom={this.state.classroom}
<Steps.ClassInviteExistingStudentStep classroom={this.state.classroom}
onHandleLogOut={this.handleLogOut}
onNextStep={this.advanceStep}
studentUsername={this.props.session.session.user.username}
studentUsername={this.props.studentUsername}
waiting={this.state.waiting} />
{this.props.session.session.flags.must_reset_password ?
{this.props.must_reset_password ?
<Steps.ChoosePasswordStep onNextStep={this.advanceStep}
showPassword={true}
waiting={this.state.waiting} />
@ -159,7 +152,14 @@ var StudentCompleteRegistration = intl.injectIntl(React.createClass({
var mapStateToProps = function (state) {
return {
session: state.session
classroomId: state.session.session.user && state.session.session.user.classroomId,
must_reset_password: state.session.session.flags && state.session.session.flags.must_reset_password,
newStudent: (
state.session.session.permissions &&
state.session.session.permissions.student &&
state.session.session.flags.must_complete_registration),
sessionFetched: state.session.status === sessionStatus.FETCHED,
studentUsername: state.session.session.user && state.session.session.user.username
};
};

View file

@ -1,3 +0,0 @@
{
"studentRegistration.classroomApiGeneralError": "Sorry, we could not find the registration information for this class"
}

View file

@ -44,7 +44,7 @@ var StudentRegistration = intl.injectIntl(React.createClass({
if (err) {
return this.setState({
registrationError: this.props.intl.formatMessage({
id: 'studentRegistration.classroomApiGeneralError'
id: 'registration.classroomApiGeneralError'
})
});
}
@ -106,7 +106,7 @@ var StudentRegistration = intl.injectIntl(React.createClass({
</Steps.RegistrationError>
:
<Progression {... this.state}>
<Steps.ClassInviteStep classroom={this.state.classroom}
<Steps.ClassInviteNewStudentStep classroom={this.state.classroom}
onNextStep={this.advanceStep}
waiting={this.state.waiting || !this.state.classroom} />
<Steps.UsernameStep onNextStep={this.advanceStep}