@@ -77,7 +77,7 @@ preact-render-spy (1 nodes)
`;
-exports[` EmailTermsConditionsForm renders properly 1`] = `
+exports[` EmailPreferencesForm renders properly 1`] = `
preact-render-spy (1 nodes)
-------
@@ -102,53 +102,12 @@ preact-render-spy (1 nodes)
-
+
diff --git a/app/javascript/onboarding/components/EmailListTermsConditionsForm.jsx b/app/javascript/onboarding/components/EmailListTermsConditionsForm.jsx
deleted file mode 100644
index 8ec704b7f..000000000
--- a/app/javascript/onboarding/components/EmailListTermsConditionsForm.jsx
+++ /dev/null
@@ -1,223 +0,0 @@
-/* eslint camelcase: "off" */
-
-import { h, Component } from 'preact';
-import PropTypes from 'prop-types';
-
-import Navigation from './Navigation';
-import { getContentOfToken, updateOnboarding } from '../utilities';
-
-/* eslint-disable camelcase */
-
-class EmailTermsConditionsForm extends Component {
- constructor(props) {
- super(props);
-
- this.handleChange = this.handleChange.bind(this);
- this.onSubmit = this.onSubmit.bind(this);
- this.checkRequirements = this.checkRequirements.bind(this);
-
- this.state = {
- checked_code_of_conduct: false,
- checked_terms_and_conditions: false,
- email_newsletter: true,
- email_digest_periodic: true,
- message: '',
- textShowing: null,
- };
- }
-
- componentDidMount() {
- updateOnboarding('emails, COC and T&C form');
- }
-
- onSubmit() {
- if (!this.checkRequirements()) return;
- const csrfToken = getContentOfToken('csrf-token');
-
- fetch('/onboarding_checkbox_update', {
- method: 'PATCH',
- headers: {
- 'X-CSRF-Token': csrfToken,
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ user: this.state }),
- credentials: 'same-origin',
- }).then((response) => {
- if (response.ok) {
- localStorage.setItem('shouldRedirectToOnboarding', false);
- const { next } = this.props;
- next();
- }
- });
- }
-
- checkRequirements() {
- const {
- checked_code_of_conduct,
- checked_terms_and_conditions,
- } = this.state;
- if (!checked_code_of_conduct) {
- this.setState({
- message: 'You must agree to our Code of Conduct before continuing.',
- });
- return false;
- }
- if (!checked_terms_and_conditions) {
- this.setState({
- message:
- 'You must agree to our Terms and Conditions before continuing.',
- });
- return false;
- }
- return true;
- }
-
- handleChange(event) {
- const { name } = event.target;
- this.setState((currentState) => ({
- [name]: !currentState[name],
- }));
- }
-
- handleShowText(event, id) {
- event.preventDefault();
- this.setState({ textShowing: document.getElementById(id).innerHTML });
- }
-
- backToSlide() {
- this.setState({ textShowing: null });
- }
-
- render() {
- const {
- message,
- checked_code_of_conduct,
- checked_terms_and_conditions,
- email_newsletter,
- email_digest_periodic,
- textShowing,
- } = this.state;
- const { prev } = this.props;
- if (textShowing) {
- return (
-
-
-
-
-
-
- );
- }
- return (
-
-
-
-
- Getting started
- Let's review a few things first
-
-
- {message && (
-
- {message}
-
- )}
-
-
-
-
- );
- }
-}
-
-EmailTermsConditionsForm.propTypes = {
- prev: PropTypes.func.isRequired,
- next: PropTypes.string.isRequired,
-};
-
-export default EmailTermsConditionsForm;
diff --git a/app/javascript/onboarding/components/EmailPreferencesForm.jsx b/app/javascript/onboarding/components/EmailPreferencesForm.jsx
new file mode 100644
index 000000000..17ca42552
--- /dev/null
+++ b/app/javascript/onboarding/components/EmailPreferencesForm.jsx
@@ -0,0 +1,111 @@
+import { h, Component } from 'preact';
+import PropTypes from 'prop-types';
+
+import Navigation from './Navigation';
+import { getContentOfToken, updateOnboarding } from '../utilities';
+
+/* eslint-disable camelcase */
+class EmailPreferencesForm extends Component {
+ constructor(props) {
+ super(props);
+
+ this.handleChange = this.handleChange.bind(this);
+ this.onSubmit = this.onSubmit.bind(this);
+
+ this.state = {
+ email_newsletter: true,
+ email_digest_periodic: true,
+ };
+ }
+
+ componentDidMount() {
+ updateOnboarding('v2: email preferences form');
+ }
+
+ onSubmit() {
+ const csrfToken = getContentOfToken('csrf-token');
+
+ fetch('/onboarding_checkbox_update', {
+ method: 'PATCH',
+ headers: {
+ 'X-CSRF-Token': csrfToken,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ user: this.state }),
+ credentials: 'same-origin',
+ }).then((response) => {
+ if (response.ok) {
+ localStorage.setItem('shouldRedirectToOnboarding', false);
+ const { next } = this.props;
+ next();
+ }
+ });
+ }
+
+ handleChange(event) {
+ const { name } = event.target;
+ this.setState((currentState) => ({
+ [name]: !currentState[name],
+ }));
+ }
+
+ render() {
+ const { email_newsletter, email_digest_periodic } = this.state;
+ const { prev } = this.props;
+ return (
+
+
+
+
+ Almost there!
+
+ Review your email preferences before we continue.
+
+
+
+
+
+
+ );
+ }
+}
+
+EmailPreferencesForm.propTypes = {
+ prev: PropTypes.func.isRequired,
+ next: PropTypes.string.isRequired,
+};
+
+export default EmailPreferencesForm;
+
+/* eslint-enable camelcase */
diff --git a/app/javascript/onboarding/components/FollowTags.jsx b/app/javascript/onboarding/components/FollowTags.jsx
index 5eeb6028a..0ff9a91aa 100644
--- a/app/javascript/onboarding/components/FollowTags.jsx
+++ b/app/javascript/onboarding/components/FollowTags.jsx
@@ -32,7 +32,7 @@ class FollowTags extends Component {
'Content-Type': 'application/json',
},
body: JSON.stringify({
- user: { last_onboarding_page: 'follow tags page' },
+ user: { last_onboarding_page: 'v2: follow tags page' },
}),
credentials: 'same-origin',
});
diff --git a/app/javascript/onboarding/components/FollowUsers.jsx b/app/javascript/onboarding/components/FollowUsers.jsx
index e2e91840f..fadae911d 100644
--- a/app/javascript/onboarding/components/FollowUsers.jsx
+++ b/app/javascript/onboarding/components/FollowUsers.jsx
@@ -38,7 +38,7 @@ class FollowUsers extends Component {
'Content-Type': 'application/json',
},
body: JSON.stringify({
- user: { last_onboarding_page: 'follow users page' },
+ user: { last_onboarding_page: 'v2: follow users page' },
}),
credentials: 'same-origin',
});
diff --git a/app/javascript/onboarding/components/IntroSlide.jsx b/app/javascript/onboarding/components/IntroSlide.jsx
index b1b3f1418..44292fc61 100644
--- a/app/javascript/onboarding/components/IntroSlide.jsx
+++ b/app/javascript/onboarding/components/IntroSlide.jsx
@@ -2,27 +2,94 @@ import { h, Component } from 'preact';
import PropTypes from 'prop-types';
import Navigation from './Navigation';
-import { userData, updateOnboarding } from '../utilities';
+import { getContentOfToken, userData, updateOnboarding } from '../utilities';
+/* eslint-disable camelcase */
class IntroSlide extends Component {
constructor(props) {
super(props);
+ this.handleChange = this.handleChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.user = userData();
+
+ this.state = {
+ checked_code_of_conduct: false,
+ checked_terms_and_conditions: false,
+ text: null,
+ };
}
componentDidMount() {
- updateOnboarding('intro slide');
+ updateOnboarding('v2: intro, code of conduct, terms & conditions');
}
onSubmit() {
const { next } = this.props;
- next();
+ const csrfToken = getContentOfToken('csrf-token');
+
+ fetch('/onboarding_checkbox_update', {
+ method: 'PATCH',
+ headers: {
+ 'X-CSRF-Token': csrfToken,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ user: this.state }),
+ credentials: 'same-origin',
+ }).then((response) => {
+ if (response.ok) {
+ localStorage.setItem('shouldRedirectToOnboarding', false);
+ next();
+ }
+ });
+ }
+
+ handleChange(event) {
+ const { name } = event.target;
+ this.setState((currentState) => ({
+ [name]: !currentState[name],
+ }));
+ }
+
+ handleShowText(event, id) {
+ event.preventDefault();
+ this.setState({ text: document.getElementById(id).innerHTML });
+ }
+
+ isButtonDisabled() {
+ const {
+ checked_code_of_conduct,
+ checked_terms_and_conditions,
+ } = this.state;
+
+ return !checked_code_of_conduct || !checked_terms_and_conditions;
}
render() {
const { prev } = this.props;
+ const {
+ checked_code_of_conduct,
+ checked_terms_and_conditions,
+ text,
+ } = this.state;
+
+ if (text) {
+ return (
+
+
+
+
+
+
+ );
+ }
return (
@@ -43,7 +110,65 @@ class IntroSlide extends Component {
DEV is where programmers share ideas and help each other grow.
-
+
+
);
}
@@ -55,3 +180,5 @@ IntroSlide.propTypes = {
};
export default IntroSlide;
+
+/* eslint-enable camelcase */
diff --git a/app/javascript/onboarding/components/Navigation.jsx b/app/javascript/onboarding/components/Navigation.jsx
index 92b11e326..0280e9136 100644
--- a/app/javascript/onboarding/components/Navigation.jsx
+++ b/app/javascript/onboarding/components/Navigation.jsx
@@ -1,16 +1,36 @@
import { h } from 'preact';
import PropTypes from 'prop-types';
-const Navigation = ({ next, prev, hideNext, hidePrev }) => (
-