Implemented signup terms and checkbox

refs https://github.com/TryGhost/Team/issues/2878

We've updated the signup page to display the signup terms and checkbox when
they've been set, as well as denying the signup from occuring if the checkbox
is required and not checked.

We've had to add a random value for the `key` property of the checkbox because
otherwise it isn't rendered correctly, unsure why that is at the moment.
Without the random key, the checkbox is never visually checked, even though the
internal state of both the component and the virtual DOM do say it should be
checked, it seems some kind of equality checker is broken.
This commit is contained in:
Fabien "egg" O'Carroll 2023-04-04 18:53:38 +07:00 committed by Fabien 'egg' O'Carroll
parent ab8304fa5c
commit c2a6bbfefa
2 changed files with 49 additions and 3 deletions

View File

@ -106,7 +106,6 @@ class PopupContent extends React.Component {
if (hasMode(['preview'])) {
return;
}
e.preventDefault();
if (e.target === e.currentTarget) {
this.context.onAction('closePopup');
}

View File

@ -227,7 +227,8 @@ class SignupPage extends React.Component {
name: '',
email: '',
plan: 'free',
showNewsletterSelection: false
showNewsletterSelection: false,
termsCheckboxChecked: false
};
}
@ -263,10 +264,20 @@ class SignupPage extends React.Component {
clearTimeout(this.timeoutId);
}
getFormErrors(state) {
const checkboxRequired = this.context.site.portal_signup_checkbox_required;
const checkboxError = checkboxRequired && !state.termsCheckboxChecked;
return {
...ValidateInputForm({fields: this.getInputFields({state})}),
checkbox: checkboxError
};
}
doSignup() {
this.setState((state) => {
return {
errors: ValidateInputForm({fields: this.getInputFields({state})})
errors: this.getFormErrors(state)
};
}, () => {
const {site, onAction} = this.context;
@ -382,6 +393,41 @@ class SignupPage extends React.Component {
return fields;
}
renderSignupTerms() {
const {site} = this.context;
if (site.portal_signup_terms_html === null || site.portal_signup_terms_html === '') {
return null;
}
const handleCheckboxChange = (e) => {
this.setState({
termsCheckboxChecked: e.target.checked
});
};
const checkbox = site.portal_signup_checkbox_required ? (
<input
type="checkbox"
checked={!!this.state.termsCheckboxChecked}
required={true}
onChange={handleCheckboxChange}
/>
) : null;
const errorClassName = this.state.errors?.checkbox ? 'gh-portal-error' : '';
const className = `gh-portal-signup-terms ${errorClassName}`;
return (
<div className={className}>
{checkbox}
<div className="gh-portal-signup-terms-content"
dangerouslySetInnerHTML={{__html: site.portal_signup_terms_html}}
></div>
</div>
);
}
renderSubmitButton() {
const {action, site, brandColor, pageQuery, t} = this.context;
@ -521,6 +567,7 @@ class SignupPage extends React.Component {
</div>
<div>
{this.renderProducts()}
{this.renderSignupTerms()}
{(hasOnlyFree ?
<div className={'gh-portal-btn-container' + (sticky ? ' sticky m24' : '')}>