Skip to content

Commit

Permalink
Replaced newsletter signup form in PNI product creep vote section wit…
Browse files Browse the repository at this point in the history
…h the new implementation approach (#11791)

* Replaced newsletter signup form in PNI product creep vote section with the new implementation approach

* Remove obsolete code

* code improvement

* make sure Creep Vote section shows vote result after user has successfully signed up for newsletter
  • Loading branch information
mmmavis authored Feb 6, 2024
1 parent 097ab4e commit 4b46b83
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 86 deletions.
35 changes: 25 additions & 10 deletions source/js/buyers-guide/components/creep-vote/creep-vote.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, Fragment } from "react";
import Creepometer from "../creepometer/creepometer.jsx";
import CreepChart from "../creepiness-chart/creepiness-chart.jsx";
import SocialShare from "../social-share/social-share.jsx";
import JoinUs from "../../../components/join/join.jsx";
import DefaultLayoutSignup from "../../../components/newsletter-signup/organisms/default-layout-signup.jsx";
import { getText } from "../../../components/petition/locales";

import CREEPINESS_LABELS from "../creepiness-labels.js";
Expand Down Expand Up @@ -226,15 +226,30 @@ class CreepVote extends Component {
>
Close
</button>
<JoinUs
formPosition="flow"
flowHeading={getText(`You voted! You rock!`)}
flowText={getText(
`Now that you’re on a roll, why not join Mozilla? We’re not creepy (we promise). We actually fight back against creepy. And we need more people like you.`
)}
apiUrl={this.props.joinUsApiUrl}
handleSignUp={(successState) => this.handleSignUp(successState)}
/>
<div className="medium:tw-mx-12">
<DefaultLayoutSignup
formPosition="pni-product-quiz"
formStyle="pni-creep-vote"
showCountryFieldByDefault="true"
showLanguageFieldByDefault="true"
ctaHeader={getText(`You voted! You rock!`)}
ctaDescription={
<p>
{getText(`Now that you’re on a roll, why not join Mozilla? We’re
not creepy (we promise). We actually fight back against creepy.
And we need more people like you.`)}
</p>
}
apiUrl={this.props.joinUsApiUrl}
showQuitButton="true"
handleQuitButtonClick={(successState) =>
this.handleSignUp(successState)
}
handleSubmissionSuccess={(successState) =>
this.handleSignUp(successState)
}
/>
</div>
</Fragment>
);
}
Expand Down
62 changes: 5 additions & 57 deletions source/js/components/join/join.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,6 @@ class JoinUs extends Component {
* Render the signup CTA.
*/
render() {
if (this.state.apiSuccess && this.state.apiSubmitted && this.isFlowForm()) {
this.props.handleSignUp(true);
}

let signupState = classNames({
"signup-success": this.state.apiSuccess && this.state.apiSubmitted,
"signup-fail": !this.state.apiFailed && this.state.apiSubmitted,
Expand All @@ -266,7 +262,6 @@ class JoinUs extends Component {
"col-md-6": this.props.layout === `2-column` && !this.state.apiSuccess,
"col-sm-12 col-md-8":
this.props.layout === `2-column` && this.state.apiSuccess,
"col-md-11 m-auto": this.isFlowForm(),
});

return (
Expand All @@ -277,24 +272,6 @@ class JoinUs extends Component {
);
}

isFlowForm() {
return this.props.formPosition === "flow";
}

/**
* Render the CTA heading.
*/
renderFlowHeading() {
return [
<h2 className="tw-h3-heading text-center" key={`flowheading`}>
{this.props.flowHeading}
</h2>,
<p className="text-center" key={`flowheadingpara`}>
{this.props.flowText}
</p>,
];
}

/**
* Render the CTA heading.
*/
Expand Down Expand Up @@ -346,9 +323,6 @@ class JoinUs extends Component {
* Render the CTA heading.
*/
renderFormHeading() {
if (this.isFlowForm()) {
return this.renderFlowHeading();
}
return this.renderSnippetHeading();
}

Expand Down Expand Up @@ -382,18 +356,11 @@ class JoinUs extends Component {
"tw-h-24": this.props.formStyle == `pni`,
});

let errorWrapperClasses = classNames("glyph-container", {
"d-none": this.isFlowForm(),
});
let errorWrapperClasses = "glyph-container";

return (
<div className={wrapperClasses}>
<div className={classes}>
{this.isFlowForm() && (
<label className="font-weight-bold" htmlFor={this.id.userEmail}>
Email
</label>
)}
<input
name="userEmail"
type="email"
Expand All @@ -402,7 +369,7 @@ class JoinUs extends Component {
ref={(el) => (this.email = el)}
onFocus={(evt) => this.onInputFocus(evt)}
onInput={(evt) => this.toggleSubmitButton(evt)}
aria-label={!this.isFlowForm() ? "Email" : ""}
aria-label="Email"
id={this.id.userEmail}
/>
{this.state.userTriedSubmitting && !emailValidation.valid && (
Expand Down Expand Up @@ -526,8 +493,7 @@ class JoinUs extends Component {
</label>
{this.state.userTriedSubmitting &&
!this.state.apiSubmitted &&
!this.privacy.checked &&
!this.isFlowForm() && (
!this.privacy.checked && (
<span className="tw-form-error-glyph tw-flex tw-ml-2" />
)}
</div>
Expand Down Expand Up @@ -561,10 +527,7 @@ class JoinUs extends Component {
);
buttonText = getText("Sign up");
} else {
classnames = classNames("tw-btn", "tw-btn-primary", {
"w-100": !this.isFlowForm(),
"tw-flex-1 tw-mr-8": this.isFlowForm(),
});
classnames = "tw-btn tw-btn-primary w-100";
buttonText = getText("Sign up");
}

Expand Down Expand Up @@ -596,10 +559,6 @@ class JoinUs extends Component {
buttonsWrapperClass = `ml-md-3`;
}

if (this.props.formPosition === `flow`) {
buttonsWrapperClass = `d-flex`;
}

if (this.props.formStyle === `pop`) {
buttonsWrapperClass = `w-auto tw-text-right`;
}
Expand All @@ -622,18 +581,7 @@ class JoinUs extends Component {
{this.renderLocaleFields()}
{this.renderPrivacyField()}
</div>
<div className={buttonsWrapperClass}>
{this.renderSubmitButton()}
{this.isFlowForm() && (
<button
className="tw-btn tw-btn-primary btn-dismiss tw-flex-1"
onClick={() => this.props.handleSignUp(false)}
type="button"
>
No thanks
</button>
)}
</div>
<div className={buttonsWrapperClass}>{this.renderSubmitButton()}</div>
</form>
);
}
Expand Down
34 changes: 34 additions & 0 deletions source/js/components/newsletter-signup/atoms/button-quit.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import classNames from "classnames";
import PropTypes from "prop-types";

const ButtonQuit = ({
children,
buttonStyle = "primary",
widthClasses = `tw-w-full`,
handleQuitButtonClick,
}) => {
// [TODO]
// Ideally styling for this "atom" component should be pre-defined in a Tailwind config file.
// Because our design system still needs to be finalized,
// we are using hardcoded Tailwind classes directly here for now.
let classes = classNames(
`tw-btn tw-btn-${buttonStyle} btn-dismiss`,
widthClasses
);

return (
<button type="button" className={classes} onClick={handleQuitButtonClick}>
{children}
</button>
);
};

ButtonQuit.propTypes = {
children: PropTypes.node.isRequired,
buttonStyle: PropTypes.oneOf(["primary", "secondary"]),
widthClasses: PropTypes.string,
handleQuitButtonClick: PropTypes.func.isRequired,
};

export default ButtonQuit;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import InputText from "../atoms/input-text.jsx";
import Select from "../atoms/select.jsx";
import InputCheckboxWithLabel from "../molecules/input-checkbox-with-label.jsx";
import ButtonSubmit from "../atoms/button-submit.jsx";
import ButtonQuit from "../atoms/button-quit.jsx";
import withSubmissionLogic from "./with-submission-logic.jsx";
import utility from "../../../utility.js";
import { ReactGA } from "../../../common";
Expand Down Expand Up @@ -47,7 +48,8 @@ class DefaultSignupForm extends Component {
showCountryField:
this.props.showCountryFieldByDefault?.toLowerCase() === "true",
showLanguageField:
this.props.showCountryFieldByDefault?.toLowerCase() === "true",
this.props.showLanguageFieldByDefault?.toLowerCase() === "true",
showQuitButton: this.props.showQuitButton?.toLowerCase() === "true",
submitButtonDisabled: this.props.disableSubmitButtonByDefault,
};
}
Expand Down Expand Up @@ -268,6 +270,43 @@ class DefaultSignupForm extends Component {
);
}

renderButtons() {
let wrapperClasses = classNames({
"tw-flex-shrink-0 tw-mt-8 medium:tw-mt-0":
this.style.buttonPosition !== "bottom",
"tw-mt-24 medium:tw-mt-12 tw-text-right":
this.style.buttonPosition === "bottom",
});

let submitButton = (
<ButtonSubmit
buttonStyle={this.style.buttonStyle}
widthClasses={this.style.buttonWidthClasses}
disabled={this.state.submitButtonDisabled}
>
{this.buttonText}
</ButtonSubmit>
);

let buttons = submitButton;

if (this.state.showQuitButton) {
buttons = (
<div className="tw-flex tw-gap-x-4">
{submitButton}
<ButtonQuit
widthClasses={this.style.buttonWidthClasses}
handleQuitButtonClick={this.props.handleQuitButtonClick}
>
{getText(`No thanks`)}
</ButtonQuit>
</div>
);
}

return <div className={wrapperClasses}>{buttons}</div>;
}

renderForm() {
if (this.props.hideForm) return null;

Expand All @@ -276,13 +315,6 @@ class DefaultSignupForm extends Component {
this.style.buttonPosition !== "bottom",
});

let buttonWrapperClasses = classNames({
"tw-flex-shrink-0 tw-mt-8 medium:tw-mt-0":
this.style.buttonPosition !== "bottom",
"tw-mt-24 medium:tw-mt-12 tw-text-right":
this.style.buttonPosition === "bottom",
});

return (
<form
noValidate={this.props.noBrowserValidation}
Expand All @@ -299,16 +331,7 @@ class DefaultSignupForm extends Component {
</fieldset>
<fieldset>{this.renderPrivacyCheckbox()}</fieldset>
</div>
<div className={buttonWrapperClasses}>
<ButtonSubmit
buttonStyle={this.style.buttonStyle}
widthClasses={this.style.buttonWidthClasses}
disabled={this.state.submitButtonDisabled}
buttonCtaEvent={this.props.buttonCtaEvent}
>
{this.buttonText}
</ButtonSubmit>
</div>
{this.renderButtons()}
</div>
</form>
);
Expand Down Expand Up @@ -341,6 +364,9 @@ DefaultSignupForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
noBrowserValidation: PropTypes.bool,
hideForm: PropTypes.bool,
showCountryFieldByDefault: PropTypes.string,
showLanguageFieldByDefault: PropTypes.string,
showQuitButton: PropTypes.string,
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ export const FORM_STYLE = {
descriptionClass: `medium:tw-w-4/5`,
headingClass: "tw-h3-heading",
},
"pni-creep-vote": {
buttonPosition: "bottom",
buttonStyle: "primary",
buttonWidthClasses: "tw-w-1/2",
descriptionClass: "tw-text-center",
fieldStyle: "filled",
headingLevel: 2,
headingClass: "tw-h3-heading tw-text-center",
},
"pni-product-quiz": {
fieldStyle: "filled",
headingLevel: 4,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ function withSubmissionLogic(WrappedComponent) {
WithSubmissionLogicComponent.propTypes = {
apiUrl: PropTypes.string.isRequired,
ctaHeader: PropTypes.string.isRequired,
ctaDescription: PropTypes.string.isRequired,
ctaDescription: PropTypes.oneOfType([PropTypes.string, PropTypes.node])
.isRequired,
formPosition: PropTypes.string,
whenLoaded: PropTypes.func,
};
Expand Down

0 comments on commit 4b46b83

Please sign in to comment.