Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
96a07ae
feat: set client id cookie; reader activation tweaks (#1780)
adekbadek Jul 15, 2022
aeb0b5b
feat(reader-activation): registration auth cookie control (#1787)
miguelpeixe Jul 19, 2022
17edf2a
fix(reader-activation): username generation handling (#1789)
adekbadek Jul 19, 2022
365aed9
feat(stripe): webhook auto-creation and validation
adekbadek Jul 8, 2022
b163664
feat(reader-activation): account link and auth form (#1754)
miguelpeixe Jul 20, 2022
c770a7d
feat: handle new frequency options in Campaigns dashbaord (#1779)
dkoo Jul 20, 2022
717b5b8
feat(registration-block): newsletter subscription (#1778)
miguelpeixe Jul 20, 2022
49dc14c
fix(popups): use new Campaigns method for creating donation events on…
dkoo Jul 22, 2022
3e69af1
feat(my-account): stripe billing portal link (#1761)
adekbadek Jul 25, 2022
ed79c5c
feat(registration-block): login with Google (#1781)
adekbadek Jul 25, 2022
89ecc75
chore(deps): bump @babel/preset-env from 7.18.6 to 7.18.9
dependabot[bot] Jul 25, 2022
789b26e
chore(deps): bump date-fns from 2.28.0 to 2.29.1
dependabot[bot] Jul 25, 2022
8a25e4f
chore(deps): bump @babel/plugin-transform-runtime from 7.18.6 to 7.18.9
dependabot[bot] Jul 25, 2022
a62951f
chore(deps): bump stripe/stripe-php from 8.10.0 to 8.11.0
dependabot[bot] Jul 25, 2022
9e4f2f6
feat: register anonymous single donors (#1795)
dkoo Jul 25, 2022
7dcea82
feat(registration-block): editable success state (#1785)
adekbadek Jul 26, 2022
1ccbb49
chore(release): merge in release v1.87.0
matticbot Jul 26, 2022
86c38f8
feat(registration-block): add success icon (#1804)
thomasguillot Jul 27, 2022
f8b5664
refactor: remove unneeded prop
adekbadek Jul 27, 2022
03a15ba
feat: send user metadata to AC (#1793)
adekbadek Jul 27, 2022
1bfe546
fix(registration-block): margin for success message (#1808)
thomasguillot Jul 28, 2022
fdc52fd
Reader Activation: auth form with third-party and lists subscriptions…
miguelpeixe Jul 28, 2022
d83448e
feat: tweak registration block styling
adekbadek Jul 28, 2022
1fe5ffa
feat(reader-auth): make password login the first option, instead of l…
adekbadek Jul 28, 2022
0a4b499
fix(reader-activation): reinitialize auth links after DOM load (#1812)
miguelpeixe Jul 28, 2022
e234e8b
fix: ensure scroll on smaller height (#1813)
miguelpeixe Jul 29, 2022
aaff0de
feat(reader-activation): settings wizard (#1773)
miguelpeixe Jul 29, 2022
67574d1
feat: handle contact update w/out lists selection (#1816)
adekbadek Jul 29, 2022
65e991e
chore: logger update (#1807)
adekbadek Jul 29, 2022
c806bfe
feat(reader-activation): disable 3rd party login buttons initially (#…
adekbadek Jul 29, 2022
7d49db4
feat(reader-activation): prevent updating user email in my-account
adekbadek Jul 29, 2022
ecbbc47
feat(reader-activation): activecampaign master list (#1818)
miguelpeixe Aug 1, 2022
f2c866b
chore(deps): bump stripe/stripe-php from 8.11.0 to 8.12.0
dependabot[bot] Aug 1, 2022
ddf61ad
fix(campaigns-wizard): segmentation wording
adekbadek Aug 1, 2022
321eff5
feat(rss): adds offset feature (#1790)
dnalla1928 Aug 1, 2022
23b0249
fix(reader-activation): handle no lists config available
adekbadek Aug 1, 2022
d9388ee
fix: fix fatal error when debug mode active (#1826)
claudiulodro Aug 1, 2022
f7b58ae
feat: reorganise donations wizard and use buttongroup for donation ty…
thomasguillot Aug 2, 2022
3704d9f
fix: google auth button type (#1829)
miguelpeixe Aug 2, 2022
8d4756c
fix(magic-links): fix email encoding on sent link (#1833)
miguelpeixe Aug 2, 2022
871300d
fix(registration-block): don't escape html for sign in labels (#1834)
miguelpeixe Aug 2, 2022
722724c
fix(reader-activation): add metadata to reader registered on donation
adekbadek Aug 3, 2022
87b9be9
fix(registration-block): render on preview (#1844)
miguelpeixe Aug 3, 2022
4131ca6
fix(reader-activation): remove async prop from library (#1846)
miguelpeixe Aug 3, 2022
3e384e1
feat(analytics): send GA events on the server side (#1828)
adekbadek Aug 4, 2022
6816799
fix(my account): handle legacy data (#1823)
adekbadek Aug 4, 2022
c2a0141
fix(reader-activation): handle modal conflict when auth is triggered …
adekbadek Aug 3, 2022
85c550a
feat(reader-activation): optimistic account link (#1847)
miguelpeixe Aug 4, 2022
0af9abf
fix(google-auth): ensure popup on user click event (#1831)
miguelpeixe Aug 4, 2022
34dd9a2
feat(active-campaigns): override is-new-contact for legacy contacts
adekbadek Aug 3, 2022
48883af
feat(active-campaign): metadata improvements (#1851)
adekbadek Aug 4, 2022
bf48bc4
feat: if registering an email that already has an account, show diffe…
dkoo Aug 4, 2022
f5b24c4
feat: replace WooCommerce’s login form with our own (#1854)
dkoo Aug 4, 2022
4cda57d
fix(newsletters): use international date format (#1855)
miguelpeixe Aug 5, 2022
8dcd45e
fix: tweak arguments for magic link client hash (#1862)
miguelpeixe Aug 5, 2022
b6aa894
feat(donations): remove defaultFrequency from the configuration (#1814)
adekbadek Aug 5, 2022
a936abd
fix(ga): cookie parsing (#1857)
adekbadek Aug 5, 2022
67640a5
fix(active-campaign): legacy contacts detection (#1858)
adekbadek Aug 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions assets/blocks/reader-registration/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,51 @@
"attributes": {
"placeholder": {
"type": "string",
"default": "Enter your email address"
"default": "Email Address"
},
"label": {
"type": "string",
"default": "Register"
"default": "Sign up",
"required": true
},
"privacyLabel": {
"type": "string",
"default": "By signing up, you agree to our Terms and Conditions."
},
"newsletterSubscription": {
"type": "boolean",
"default": false
},
"displayListDescription": {
"type": "boolean",
"default": true
},
"newsletterTitle": {
"type": "string",
"default": "Newsletters"
},
"newsletterLabel": {
"type": "string",
"default": "Subscribe to our newsletter"
},
"lists": {
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"haveAccountLabel": {
"type": "string",
"default": "Already have an account?"
},
"signInLabel": {
"type": "string",
"default": "Sign in"
},
"signedInLabel": {
"type": "string",
"default": "An account was already registered with this email. Please check your inbox for an authentication link."
}
},
"supports": {
Expand Down
302 changes: 289 additions & 13 deletions assets/blocks/reader-registration/edit.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,319 @@
/* global newspack_blocks */

/**
* External dependencies
*/
import { intersection } from 'lodash';

/**
* WordPress dependencies
*/
import apiFetch from '@wordpress/api-fetch';
import { __ } from '@wordpress/i18n';
import { TextControl, PanelBody } from '@wordpress/components';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { useState, useEffect } from '@wordpress/element';
import {
useBlockProps,
RichText,
InspectorControls,
useInnerBlocksProps,
InnerBlocks,
} from '@wordpress/block-editor';
import {
Spinner,
Notice,
TextControl,
ToggleControl,
PanelBody,
Button,
} from '@wordpress/components';

/**
* Internal dependencies
*/
import './editor.scss';

const editedStateOptions = [
{ label: __( 'Initial', 'newspack' ), value: 'initial' },
{ label: __( 'Registration Success', 'newspack' ), value: 'registration' },
{ label: __( 'Login Success', 'newspack' ), value: 'login' },
];
export default function ReaderRegistrationEdit( {
setAttributes,
attributes: { placeholder, label },
attributes: {
placeholder,
label,
privacyLabel,
newsletterSubscription,
displayListDescription,
newsletterTitle,
newsletterLabel,
haveAccountLabel,
signInLabel,
signedInLabel,
lists,
className,
},
} ) {
const blockProps = useBlockProps();
const [ editedState, setEditedState ] = useState( editedStateOptions[ 0 ].value );

const innerBlocksProps = useInnerBlocksProps(
{},
{
renderAppender: InnerBlocks.ButtonBlockAppender,
template: [
// Quirk: this will only get applied to the block (as inner blocks) if it's *rendered* in the editor.
// If the user never switches the state view, it will not be applied, so PHP code contains a fallback.
[
'core/paragraph',
{
align: 'center',
content: __(
'Thank you for registering!<br />Check your email for a confirmation link.',
'newspack'
),
},
],
],
}
);
const [ inFlight, setInFlight ] = useState( false );
const [ listConfig, setListConfig ] = useState( {} );

const fetchLists = () => {
if ( newspack_blocks.has_newsletters && newsletterSubscription ) {
setInFlight( true );
apiFetch( {
path: '/newspack-newsletters/v1/lists_config',
} )
.then( setListConfig )
.finally( () => setInFlight( false ) );
}
};

useEffect( fetchLists, [] );
useEffect( fetchLists, [ newsletterSubscription ] );

useEffect( () => {
const listIds = Object.keys( listConfig );
if ( listIds.length && ( ! lists.length || ! intersection( lists, listIds ).length ) ) {
setAttributes( { lists: [ Object.keys( listConfig )[ 0 ] ] } );
}
}, [ listConfig ] );

return (
<>
<InspectorControls>
<PanelBody title={ __( 'Form settings', 'newspack' ) }>
<TextControl
label={ __( 'Input placeholder', 'newspack' ) }
value={ placeholder }
disabled={ inFlight }
onChange={ value => setAttributes( { placeholder: value } ) }
/>
<TextControl
label={ __( 'Button label', 'newspack' ) }
value={ label }
onChange={ value => setAttributes( { label: value } ) }
/>
</PanelBody>
{ newspack_blocks.has_newsletters && (
<PanelBody title={ __( 'Newsletter Subscription', 'newspack' ) }>
<ToggleControl
label={ __( 'Enable newsletter subscription', 'newspack' ) }
checked={ !! newsletterSubscription }
disabled={ inFlight }
onChange={ () =>
setAttributes( { newsletterSubscription: ! newsletterSubscription } )
}
/>
{ newsletterSubscription && (
<>
{ inFlight && <Spinner /> }
{ ! inFlight && ! Object.keys( listConfig ).length && (
<div style={ { marginBottom: '1.5rem' } }>
<Notice isDismissible={ false } status="error">
{ __( 'You must enable lists for subscription.', 'newspack-newsletters' ) }
</Notice>
</div>
) }
<ToggleControl
label={ __( 'Display list description', 'newspack-newsletters' ) }
checked={ displayListDescription }
disabled={ inFlight }
onChange={ () =>
setAttributes( { displayListDescription: ! displayListDescription } )
}
/>
{ lists.length < 1 && (
<div style={ { marginBottom: '1.5rem' } }>
<Notice isDismissible={ false } status="error">
{ __( 'You must select at least one list.', 'newspack-newsletters' ) }
</Notice>
</div>
) }
{ Object.keys( listConfig ).length > 0 && <p>{ __( 'Lists', 'newspack' ) }:</p> }
{ Object.keys( listConfig ).map( listId => (
<ToggleControl
key={ listId }
label={ listConfig[ listId ].title }
checked={ lists.includes( listId ) }
disabled={ inFlight }
onChange={ () => {
if ( ! lists.includes( listId ) ) {
setAttributes( { lists: lists.concat( listId ) } );
} else {
setAttributes( { lists: lists.filter( id => id !== listId ) } );
}
} }
/>
) ) }
<p>
<a href={ newspack_blocks.newsletters_url }>
{ __( 'Manage your subscription lists', 'newspack-newsletters' ) }
</a>
</p>
</>
) }
</PanelBody>
) }
</InspectorControls>
<div { ...blockProps }>
<div className="newspack-reader-registration">
<form onSubmit={ ev => ev.preventDefault() }>
<input type="email" placeholder={ placeholder } />
<input type="submit" value={ label } />
</form>
<div className="newspack-registration__state-bar">
<span>{ __( 'Edited State', 'newspack' ) }</span>
<div>
{ editedStateOptions.map( option => (
<Button
key={ option.value }
data-is-active={ editedState === option.value }
onClick={ () => setEditedState( option.value ) }
>
{ option.label }
</Button>
) ) }
</div>
</div>
{ editedState === 'initial' && (
<div className={ `newspack-registration ${ className }` }>
<form onSubmit={ ev => ev.preventDefault() }>
<div className="newspack-registration__form-content">
{ newsletterSubscription && lists.length ? (
<div className="newspack-reader__lists">
{ lists?.length > 1 && (
<RichText
onChange={ value => setAttributes( { newsletterTitle: value } ) }
placeholder={ __( 'Newsletters title…', 'newspack' ) }
value={ newsletterTitle }
tagName="h3"
/>
) }
<ul>
{ lists.map( listId => (
<li key={ listId }>
<span className="newspack-reader__lists__checkbox">
<input type="checkbox" checked readOnly />
</span>
<span className="newspack-reader__lists__details">
<span className="newspack-reader__lists__label">
<span className="newspack-reader__lists__title">
{ lists.length === 1 ? (
<RichText
onChange={ value =>
setAttributes( { newsletterLabel: value } )
}
placeholder={ __( 'Subscribe to our newsletter', 'newspack' ) }
value={ newsletterLabel }
tagName="span"
/>
) : (
listConfig[ listId ]?.title
) }
</span>
{ displayListDescription && (
<span className="newspack-reader__lists__description">
{ listConfig[ listId ]?.description }
</span>
) }
</span>
</span>
</li>
) ) }
</ul>
</div>
) : null }
<div className="newspack-registration__main">
<div>
<div className="newspack-registration__inputs">
<input type="email" placeholder={ placeholder } />
<button type="submit">
<RichText
onChange={ value => setAttributes( { label: value } ) }
placeholder={ __( 'Sign up', 'newspack' ) }
value={ label }
tagName="span"
/>
</button>
</div>

{ newspack_blocks.has_google_oauth && (
<div className="newspack-reader__logins">
<div className="newspack-reader__logins__separator">
<div />
<div>{ __( 'OR', 'newspack' ) }</div>
<div />
</div>
<button className="newspack-reader__logins__google">
<span
dangerouslySetInnerHTML={ { __html: newspack_blocks.google_logo_svg } }
/>
<span>{ __( 'Sign in with Google', 'newspack' ) }</span>
</button>
</div>
) }
<div className="newspack-registration__response" />
</div>
<div className="newspack-registration__help-text">
<RichText
onChange={ value => setAttributes( { privacyLabel: value } ) }
placeholder={ __( 'Terms & Conditions statement…', 'newspack' ) }
value={ privacyLabel }
tagName="p"
/>
<p>
<RichText
onChange={ value => setAttributes( { haveAccountLabel: value } ) }
placeholder={ __( 'Already have an account?', 'newspack' ) }
value={ haveAccountLabel }
tagName="span"
/>{ ' ' }
<a href="/my-account" onClick={ ev => ev.preventDefault() }>
<RichText
onChange={ value => setAttributes( { signInLabel: value } ) }
placeholder={ __( 'Sign In', 'newspack' ) }
value={ signInLabel }
tagName="span"
/>
</a>
</p>
</div>
</div>
</div>
</form>
</div>
) }
{ editedState === 'registration' && (
<>
<div className="newspack-registration__icon" />
<div { ...innerBlocksProps } />
</>
) }
{ editedState === 'login' && (
<>
<div className="newspack-registration__icon" />
<RichText
align="center"
onChange={ value => setAttributes( { signedInLabel: value } ) }
placeholder={ __( 'Logged in message…', 'newspack' ) }
value={ signedInLabel }
tagName="p"
/>
</>
) }
</div>
</>
);
Expand Down
Loading