Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teachercon 18-19 Teacher Registration #19874

Merged
merged 15 commits into from
Jan 11, 2018
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ describe('entry tests', () => {
'pd/application/facilitator_application/new': './src/sites/studio/pages/pd/application/facilitator_application/new.js',
'pd/application/teacher_application/new': './src/sites/studio/pages/pd/application/teacher_application/new.js',
'pd/application/principal_approval_application/new': './src/sites/studio/pages/pd/application/principal_approval_application/new.js',
'pd/teachercon1819_registration/new': './src/sites/studio/pages/pd/teachercon1819_registration/new.js',

'pd/professional_learning_landing/index': './src/sites/studio/pages/pd/professional_learning_landing/index.js',
'pd/regional_partner_contact/new': './src/sites/studio/pages/pd/regional_partner_contact/new.js',
Expand Down
9 changes: 9 additions & 0 deletions apps/script/generateSharedConstants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require_relative '../../lib/cdo/shared_constants/pd/facilitator1819_application_constants'
require_relative '../../lib/cdo/shared_constants/pd/teacher1819_application_constants'
require_relative '../../lib/cdo/shared_constants/pd/principal_approval1819_application_constants'
require_relative '../../lib/cdo/shared_constants/pd/teachercon1819_registration_constants'

REPO_DIR = File.expand_path('../../../', __FILE__)

Expand Down Expand Up @@ -105,6 +106,14 @@ def main
),
"#{REPO_DIR}/apps/src/generated/pd/principalApproval1819ApplicationConstants.js"
)
generate_shared_js_file(
generate_multiple_constants(
%w(TEACHER_SEAT_ACCEPTANCE_OPTIONS),
source_module: Teachercon1819RegistrationConstants,
transform_keys: true
),
"#{REPO_DIR}/apps/src/generated/pd/teachercon1819RegistrationConstants.js"
)
end

main
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';

import {
FormGroup,
} from 'react-bootstrap';

import Teachercon1819FormComponent from './Teachercon1819FormComponent';

export default class Confirmation extends Teachercon1819FormComponent {
static associatedFields = [];

render() {
return (
<FormGroup>
{this.isTeacherApplication() &&
<p>
We're excited you're planning to join the Professional Learning
Program! You will receive more information about travel approximately
six weeks before TeacherCon. In the meantime, please <strong>do not</strong> book your
flight, and make sure to contact <a href="mailto:teacher@code.org">teacher@code.org</a> with any questions.
We look forward to meeting you this summer!
</p>
}

{this.isFacilitatorApplication() &&
<p>
We're excited you're planning to join us this summer! You will
receive more information about travel approximately six weeks before
TeacherCon. In the meantime, please <strong>do not</strong> book your flight, and make
sure to contact <a href="mailto:facilitators@code.org">facilitators@code.org</a> with any questions. We look
forward to meeting you this summer!
</p>
}

{this.isPartnerApplication() &&
<p>
We're excited you're planning to join us this summer! You will
receive more information about travel approximately six weeks before
TeacherCon. In the meantime, please <strong>do not</strong> book your flight, and make
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first 2 sentences are the same in all cases. Might it make sense to split that out into its own paragraph, supplied once?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, one says "join the Professional Learning Program" and the other two say "join us this summer" :/

I'mma just leave it as is; if we get lots of changes coming in to the copy I'll probably try and dedup to make those easier.

sure to contact your Outreach Regional Manager with any questions. We
look forward to meeting you this summer!
</p>
}
</FormGroup>
);
}
}

111 changes: 111 additions & 0 deletions apps/src/code-studio/pd/teachercon1819_registration/Joining.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from 'react';
import {
FormGroup,
ControlLabel
} from 'react-bootstrap';
import Teachercon1819FormComponent from './Teachercon1819FormComponent';
import UsPhoneNumberInput from "../form_components/UsPhoneNumberInput";

import { TeacherSeatAcceptanceOptions } from '@cdo/apps/generated/pd/teachercon1819RegistrationConstants';

export default class Joining extends Teachercon1819FormComponent {
static associatedFields = [
'preferredFirstName',
'lastName',
'email',
'phone',
'teacherAcceptSeat',
'teacherWaitlistExplain',
'teacherDeclineExplain',
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be Object.keys(Joining.labels), if moved below the labels definition.


static labels = {
preferredFirstName: "Preferred first name",
lastName: "Last name",
email: "Email",
phone: "Phone number",
teacherAcceptSeat: "Do you want to accept your seat in the Professional Learning Program? (Select one)",
teacherWaitlistExplain: "Optional: Please explain more why you cannot accept your seat in the Professional Learning Program.",
teacherDeclineExplain: "Optional: Please explain more why you cannot accept your seat in the Professional Learning Program.",
}

/**
* @override
*/
static getErrorMessages(data) {
const formatErrors = {};

if (!UsPhoneNumberInput.isValid(data.phone)) {
formatErrors.phone = "Must be a valid phone number including area code";
}

return formatErrors;
}

render() {
return (
<FormGroup>
<h4>Section 1: Are you joining us?</h4>

<FormGroup>
{this.inputFor("preferredFirstName")}
{this.inputFor("lastName")}
{this.inputFor("email", { readOnly: true })}
{this.usPhoneNumberInputFor("phone")}
</FormGroup>
<FormGroup>
<ControlLabel>
Your assigned summer workshop is:
<br />
<strong>
TeacherCon {this.props.city}, {this.props.date}
</strong>
</ControlLabel>
</FormGroup>

{this.isTeacherApplication() &&
<FormGroup>
<p>
As a reminder, all participants in the Professional Learning Program
are expected to:
</p>
<ul>
<li>Attend their assigned summer workshop</li>
<li>Attend their assigned academic year workshops</li>
<li>Teach this curriculum in the 2018-19 school year</li>
</ul>
{this.radioButtonsFor("teacherAcceptSeat")}
{(
this.props.data.teacherAcceptSeat === TeacherSeatAcceptanceOptions.withdrawDate ||
this.props.data.teacherAcceptSeat === TeacherSeatAcceptanceOptions.withdrawOther
) &&
<FormGroup>
<p>
Thank you for letting us know. We will remove your seat in your
assigned summer workshop for now, and add you to our waitlist.
Please complete the rest of this form so we have your information
in our records, and we will contact you if a seat becomes
available for an alternate date.
</p>
{this.inputFor("teacherWaitlistExplain", { required: false })}
</FormGroup>
}

{this.props.data.teacherAcceptSeat === TeacherSeatAcceptanceOptions.decline &&
<FormGroup>
<p>
Thank you for letting us know. You do not need to complete the rest
of this form. We will close your application today, but please feel
free to use all of our free curricula and resources available at
code.org/educate. We hope you consider applying again in 2019!
</p>
{this.inputFor("teacherDeclineExplain", { required: false })}
</FormGroup>
}
</FormGroup>
}

</FormGroup>
);
}
}
67 changes: 67 additions & 0 deletions apps/src/code-studio/pd/teachercon1819_registration/Releases.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';

import {
FormGroup,
ControlLabel
} from 'react-bootstrap';

import Teachercon1819FormComponent from './Teachercon1819FormComponent';

export default class Releases extends Teachercon1819FormComponent {
static associatedFields = [
'photoRelease',
'liabilityWaiver',
'agreeShareContact',
];

static labels = {
photoRelease: "Do you agree to the conditions in the photo release?",
liabilityWaiver: "Do you agree to the conditions in the liability waiver?",
agreeShareContact: "By submitting this application, I agree to share my contact information and registration with Code.org's Regional Partners.",
};

render() {
return (
<FormGroup>
<h4>Section 3: Releases</h4>
<FormGroup>
<ControlLabel>
Please read this <a href="https://docs.google.com/document/d/12NVUcqccNRbVukoGMCserwSpg4vfG0vNlEqTxr6oit0/edit">photo release.</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add target="_blank" to open in a new window

</ControlLabel>
{this.selectFor("photoRelease", { placeholder: "--" })}
<ControlLabel>
Please read this <a href="https://docs.google.com/document/d/15N5N1m-BPCU7obQDf7FLLhEt3IComFGB1u3N6kEQR6k/edit">liability waiver.</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above - new window

</ControlLabel>
{this.selectFor("liabilityWaiver", { placeholder: "--" })}
</FormGroup>

{(
this.isTeacherApplication() || this.isFacilitatorApplication()
) &&
<FormGroup>
<ControlLabel>
<strong>
Code.org works closely with local Regional Partners to organize and
deliver the Professional Learning Program. By enrolling in this
program, you are agreeing to allow Code.org to share information on
how you use Code.org and the Professional Learning resources with your
Regional Partner and school district. In order to organize the
workshops and support you, our partners need to know who is attending
and what content is relevant for them. So, we will share your contact
information, which courses/units you are using in your classrooms and
aggregate data about your classes. This includes the number of
students in your classes, the demographic breakdown of your classroom,
and the name of your school and district. We will not share any
information about individual students with our Regional Partners - all
information will be de-identified and aggregated. Our Regional
Partners are contractually obliged to treat this information with the
same level of confidentiality as Code.org.
</strong>
</ControlLabel>
{this.singleCheckboxFor("agreeShareContact")}
</FormGroup>
}
</FormGroup>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import LabeledFormComponent from '../form_components/LabeledFormComponent';

const TEACHER = "Teacher";
const FACILITATOR = "Facilitator";
const PARTNER = "Partner";

export default class Teachercon1819FormComponent extends LabeledFormComponent {

isTeacherApplication() {
return this.props.applicationType === TEACHER;
}

isFacilitatorApplication() {
return this.props.applicationType === FACILITATOR;
}

isPartnerApplication() {
return this.props.applicationType === PARTNER;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {PropTypes} from 'react';
import FormController from '../form_components/FormController';

import Welcome from './Welcome';
import Joining from './Joining';
import TravelPlans from './TravelPlans';
import Releases from './Releases';
import Confirmation from './Confirmation';

import { TeacherSeatAcceptanceOptions } from '@cdo/apps/generated/pd/teachercon1819RegistrationConstants';

export default class Teachercon1819Registration extends FormController {
static propTypes = {
...FormController.propTypes,
applicationId: PropTypes.number.isRequired,
applicationType: PropTypes.string.isRequired,
course: PropTypes.string.isRequired,
city: PropTypes.string.isRequired,
date: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
firstName: PropTypes.string,
lastName: PropTypes.string,
phone: PropTypes.string,
};

constructor(props) {
super(props);

// initialize some fields with reasonable defaults
this.state.data = {
...this.state.data,
email: this.props.email,
preferredFirstName: this.props.firstName,
lastName: this.props.lastName,
phone: this.props.phone
};
}

//static sessionStorageKey = "Teachercon1819Registration";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, thanks! I disabled it for testing and forgot to mark with TODO


/**
* @override
*/
getPageComponents() {
const pageComponents = [
Welcome,
Joining,
TravelPlans,
Releases,
];

// We want to include the confirmation page by default, but remove it if the
// teacher has responded to the "accept seat" question with something other
// than yes. It would of course be easier to just add the confirmation page
// once they respond yes, but if we do that then the user-visible page count
// will _grow_ as they progress through the form, which is a much weirder
// user experience than it shrinking.
if (!(this.state.data.teacherAcceptSeat && this.state.data.teacherAcceptSeat !== TeacherSeatAcceptanceOptions.accept)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice explanation :)

pageComponents.push(Confirmation);
}

return pageComponents;
}

/**
* @override
*/
getPageProps() {
return {
...super.getPageProps(),
applicationType: this.props.applicationType,
course: this.props.course,
city: this.props.city,
date: this.props.date,
email: this.props.email,
firstName: this.props.firstName,
lastName: this.props.lastName,
phone: this.props.phone,
};
}

/**
* @override
*/
serializeFormData() {
return {
...super.serializeFormData(),
applicationId: this.props.applicationId
};
}

/**
* @override
*/
onSuccessfulSubmit() {
// Let the server display a confirmation page as appropriate
window.location.reload(true);
}

/**
* @override
*/
shouldShowSubmit() {
return super.shouldShowSubmit() ||
this.state.data.teacherAcceptSeat === TeacherSeatAcceptanceOptions.decline;
}
}