@automattic/newspack-blocks 1.37.0 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cache/babel/00255e6096be9e31ec354db849dfefaa.json.gz +0 -0
- package/.cache/babel/0265bee20d709ac92f56456637727f4b.json.gz +0 -0
- package/.cache/babel/02986ba19dc461a152ea1c45f3f36a27.json.gz +0 -0
- package/.cache/babel/06a1700c1a4a989fc7886c86bf6223f7.json.gz +0 -0
- package/.cache/babel/07169c73863508b392f15022920bd0b6.json.gz +0 -0
- package/.cache/babel/0a5083e561829e3884cb5c71388adc3f.json.gz +0 -0
- package/.cache/babel/0a713997b6e4f45849ed6a4bff79cca5.json.gz +0 -0
- package/.cache/babel/0a9506bf649ffbe854e75459cf6b8972.json.gz +0 -0
- package/.cache/babel/0c12c4398bbbf2d771b13dd1d0e64097.json.gz +0 -0
- package/.cache/babel/0f8c18da204f4cc2777ca3191f10c309.json.gz +0 -0
- package/.cache/babel/0fced15ed787cc4239bb53c1d12892e6.json.gz +0 -0
- package/.cache/babel/10faf7c74a89e9aa4d8b9528a654913e.json.gz +0 -0
- package/.cache/babel/1353b411b65a123b5dc35012db11aa1d.json.gz +0 -0
- package/.cache/babel/1729336f326db1cf54b9c1671dc5e36c.json.gz +0 -0
- package/.cache/babel/17a433ab631a32d0712f3f75cf85ea99.json.gz +0 -0
- package/.cache/babel/1948e72d907f681ff771881ad6800ee1.json.gz +0 -0
- package/.cache/babel/1ab4bf44aa14d2eb7e6911900a3b2c12.json.gz +0 -0
- package/.cache/babel/1decfd137cac87a75bd83ffbd39c9106.json.gz +0 -0
- package/.cache/babel/2143ceff6d186bc13bc902e0f1f33dbf.json.gz +0 -0
- package/.cache/babel/23c63332718e167968a7c2a8a5f730eb.json.gz +0 -0
- package/.cache/babel/24bf53676e12293cbf88d01e649fd167.json.gz +0 -0
- package/.cache/babel/26ba0bb46844575022e54a8819fbf405.json.gz +0 -0
- package/.cache/babel/281ca171ce8947f87f574df11059e00b.json.gz +0 -0
- package/.cache/babel/28700b83434e4dbfb9a20d7ec0a7e7a4.json.gz +0 -0
- package/.cache/babel/29cf8eeea8630ade027e34459f2e49ee.json.gz +0 -0
- package/.cache/babel/2b0dd254a46223a93e6259d2b797a7e7.json.gz +0 -0
- package/.cache/babel/2da6786ede3ddda4c86eeac524a6a796.json.gz +0 -0
- package/.cache/babel/2e7ce10fdee94274b48d528f94c32b34.json.gz +0 -0
- package/.cache/babel/2f93fed1706a40d82122281cc3677074.json.gz +0 -0
- package/.cache/babel/3a59b710e9745ef93148d6d74ee7d16f.json.gz +0 -0
- package/.cache/babel/3b2c440027c793c8f7978d7622cbfca0.json.gz +0 -0
- package/.cache/babel/3ca939ace4af88e266942d93837ab37a.json.gz +0 -0
- package/.cache/babel/3e671670c4d395cd1804ef4be31955e4.json.gz +0 -0
- package/.cache/babel/3e69fe002d9973c0030152a51da9477a.json.gz +0 -0
- package/.cache/babel/3f5f8ea603fd57850c6683c750fe53d8.json.gz +0 -0
- package/.cache/babel/41abaaadb68b0657a95fa0c356873def.json.gz +0 -0
- package/.cache/babel/421ac952d6b472ba18e1cb95ef65f42a.json.gz +0 -0
- package/.cache/babel/424185dd50e91d8dee5fdae43086010e.json.gz +0 -0
- package/.cache/babel/427a6423ebde76bcb488747127e47351.json.gz +0 -0
- package/.cache/babel/43e800659f23430a181fb4fc328eb6ef.json.gz +0 -0
- package/.cache/babel/469651017a2b6f3b9f63fda034974b3a.json.gz +0 -0
- package/.cache/babel/480d26447b7ee019a37e4e18422403e9.json.gz +0 -0
- package/.cache/babel/4b58fad313d90a4c1577a2766e6c924c.json.gz +0 -0
- package/.cache/babel/4d2d42fea63650192d1a3a5648b621c5.json.gz +0 -0
- package/.cache/babel/4d8c26a76e77fa64d01f30a5f2d62f85.json.gz +0 -0
- package/.cache/babel/4f606ce6656565507a74aaac8dc21eea.json.gz +0 -0
- package/.cache/babel/505f37592f4c601ccdc1581ca89d9009.json.gz +0 -0
- package/.cache/babel/50aaf34aa54b2cd3058518e42850bb62.json.gz +0 -0
- package/.cache/babel/51fbf389462feb111228ba7ec64c631d.json.gz +0 -0
- package/.cache/babel/51fc90ae5fe129a095172032f304dc2c.json.gz +0 -0
- package/.cache/babel/53dbf5484c5601528c2fd8d7fe728b78.json.gz +0 -0
- package/.cache/babel/58e4535574062eb2d8fa56d002e7190d.json.gz +0 -0
- package/.cache/babel/5aa5e8d1492938c62999de022c4b220e.json.gz +0 -0
- package/.cache/babel/5d64e475284e52c104df17e26066b17b.json.gz +0 -0
- package/.cache/babel/6333c664d69f13036f42bcf575c8e65d.json.gz +0 -0
- package/.cache/babel/635c439786b8522888342779b28ee9ee.json.gz +0 -0
- package/.cache/babel/648cffdd5ec4a2446f8935a17b98080b.json.gz +0 -0
- package/.cache/babel/64b0dd478e6f2dd51de5ee20e311aee7.json.gz +0 -0
- package/.cache/babel/6531721abbc0b3906b28b268ed7914af.json.gz +0 -0
- package/.cache/babel/66bf5585c7901a76c7d4014fa9ffed40.json.gz +0 -0
- package/.cache/babel/6ef313cb6d3a59f73a6b78e1a729fb13.json.gz +0 -0
- package/.cache/babel/6f14eed506421f15710d3dfafe3dcd93.json.gz +0 -0
- package/.cache/babel/70f6c01d8c6bc3efc41c97eaf49f7617.json.gz +0 -0
- package/.cache/babel/72321dde68f0bb9c334d90d6f4584be8.json.gz +0 -0
- package/.cache/babel/76c815fab58595f57e01af6591791d57.json.gz +0 -0
- package/.cache/babel/7c10f4d554daa8efe1e0a4457fb6d27b.json.gz +0 -0
- package/.cache/babel/7dffccddd9780ab37fb79f809947c2cd.json.gz +0 -0
- package/.cache/babel/7e5162e3319cd5d6fca6c0db0516aaeb.json.gz +0 -0
- package/.cache/babel/803192c922f7d419648bab7e1201b22e.json.gz +0 -0
- package/.cache/babel/81f3f0f896d29cdf88f8543dedb77787.json.gz +0 -0
- package/.cache/babel/84c019d3d643195fb37d08110f15f8c9.json.gz +0 -0
- package/.cache/babel/853c31db7c4351f2f36d1021c667224d.json.gz +0 -0
- package/.cache/babel/88ec99735ea4f314937736f04360ff8c.json.gz +0 -0
- package/.cache/babel/8959ab8fcfa783cb56e9418b99c0951c.json.gz +0 -0
- package/.cache/babel/8b9624d721f8706682e33fe1853c8287.json.gz +0 -0
- package/.cache/babel/8de5c373bbc4b6fbeec373d582935887.json.gz +0 -0
- package/.cache/babel/8f24517cff634d2e91c19e51be8816cc.json.gz +0 -0
- package/.cache/babel/901e1bb823eca196b594baa35a35a81c.json.gz +0 -0
- package/.cache/babel/90dbc666ff9fa3b88f305fe90a9917bf.json.gz +0 -0
- package/.cache/babel/91b62dfd9475df7a39dc08fbd43847f9.json.gz +0 -0
- package/.cache/babel/956daf27323e3b87bf8bf9bbf58881ed.json.gz +0 -0
- package/.cache/babel/959e9b81103c539a9d85ac60955451b9.json.gz +0 -0
- package/.cache/babel/963b1e44be998c4dcc6845745c377369.json.gz +0 -0
- package/.cache/babel/966b41ac1317b3e03ca1e59f7eb57e8c.json.gz +0 -0
- package/.cache/babel/969d5992cc682e3b43761ef02c10b851.json.gz +0 -0
- package/.cache/babel/99df128bb528d0f95a56b311801d14c1.json.gz +0 -0
- package/.cache/babel/9b33e7d21f3fc4955a536a033cced71b.json.gz +0 -0
- package/.cache/babel/9c5ec84f77314a621c01ad77da7ccb58.json.gz +0 -0
- package/.cache/babel/9d325af12a88623602a5f8c2fce04847.json.gz +0 -0
- package/.cache/babel/a413e4d325543836d0800684bb26ed04.json.gz +0 -0
- package/.cache/babel/a5405f86b8d1485e62a125275507e60f.json.gz +0 -0
- package/.cache/babel/a7f7461321ca6fd4360df04bb894c106.json.gz +0 -0
- package/.cache/babel/a8a6812e1c7b65cc6d0bdebe2a35c8ca.json.gz +0 -0
- package/.cache/babel/aa89cfc4c88fcc465b8d74af824e7f6b.json.gz +0 -0
- package/.cache/babel/adbaeb5ddf5612b3dcd233a3f6f17bf2.json.gz +0 -0
- package/.cache/babel/ae18cd6ec42a3366c73435b62a9f5f70.json.gz +0 -0
- package/.cache/babel/aea149ee1ec6fa3ca7839c63f5edd78d.json.gz +0 -0
- package/.cache/babel/af1b34067a69854e109c0b0e45d90e43.json.gz +0 -0
- package/.cache/babel/b3a335ab950f502914013810b43b0ad5.json.gz +0 -0
- package/.cache/babel/b6cfba15cda3404d4b1041df448ed2b2.json.gz +0 -0
- package/.cache/babel/ba711530bd319618a0510d8361bebb45.json.gz +0 -0
- package/.cache/babel/ba77e682225df6126b636458055601d9.json.gz +0 -0
- package/.cache/babel/bab8189a74eee8d72702d1510b52b3b3.json.gz +0 -0
- package/.cache/babel/bd8741020db56bb5d999252812d1d717.json.gz +0 -0
- package/.cache/babel/beaa874c5e01203d9dbe23cb89405276.json.gz +0 -0
- package/.cache/babel/c196c9b8c21953c474acdaa9029b3cbf.json.gz +0 -0
- package/.cache/babel/c1e31e6c217023eb3d3fd5d3de486ac3.json.gz +0 -0
- package/.cache/babel/c3aa996443e7f377aa423bcc03ffc617.json.gz +0 -0
- package/.cache/babel/c481eae84d69b65405a44af442dbfea7.json.gz +0 -0
- package/.cache/babel/c4a817d6c4bf6eb3687ffccc5c2df801.json.gz +0 -0
- package/.cache/babel/c8b10cf6f706fb669d6dd7564385768d.json.gz +0 -0
- package/.cache/babel/caa2f98ba4af6eba0605543f690693c6.json.gz +0 -0
- package/.cache/babel/cada4b2cecb2c1fcc48b7a7ecda54907.json.gz +0 -0
- package/.cache/babel/d1bed5404789c427c32965ac6ecad0d9.json.gz +0 -0
- package/.cache/babel/d395e8c0a9c63680f2dcf90ca0e91d4a.json.gz +0 -0
- package/.cache/babel/d4672090e0dd9a73bfb00bd770b23643.json.gz +0 -0
- package/.cache/babel/d4c81f65fe6d78cdbdcf1ef901b7ba1b.json.gz +0 -0
- package/.cache/babel/d515ddc0797ea256ff7271507737e9ce.json.gz +0 -0
- package/.cache/babel/d742848d263503f79168f1a6b8a52097.json.gz +0 -0
- package/.cache/babel/d834b41d7028519ecd0cbc8c65d33dde.json.gz +0 -0
- package/.cache/babel/d9060b9162e7caf974db0b90b6134727.json.gz +0 -0
- package/.cache/babel/d946975b9beac51a39f600461e84b1b6.json.gz +0 -0
- package/.cache/babel/daf0af780cff2270b1ae0e4b97a5a4ab.json.gz +0 -0
- package/.cache/babel/db5215643b0737dc5245972a5c25f736.json.gz +0 -0
- package/.cache/babel/dd57b8d31664b147b9f1e3f5cd18cc2a.json.gz +0 -0
- package/.cache/babel/e0c78bdaae19f15e2dd4a773e842422b.json.gz +0 -0
- package/.cache/babel/e1a2c7e4fc3afe9cc6e03d60f4e4a23d.json.gz +0 -0
- package/.cache/babel/e210ff9aa99df972b8d81c4bda70f642.json.gz +0 -0
- package/.cache/babel/e259a73f84d5b92b94e6d094719264c3.json.gz +0 -0
- package/.cache/babel/e6ce03a9908c9c4dc2c723531f1073f6.json.gz +0 -0
- package/.cache/babel/e8a1501dd8e4b3389ecdc8f722622359.json.gz +0 -0
- package/.cache/babel/eb3bb371036da362c42db50248d0b180.json.gz +0 -0
- package/.cache/babel/eb854e03c810bdb969497b2a36119bfa.json.gz +0 -0
- package/.cache/babel/ec25bb53826070b7f301e64f02355b8c.json.gz +0 -0
- package/.cache/babel/edbaca20e4a65f850c3d8321c1945718.json.gz +0 -0
- package/.cache/babel/f059f1ca9e49d5c3e655d20339860dce.json.gz +0 -0
- package/.cache/babel/f24c559fb42ef906405966598baf5f80.json.gz +0 -0
- package/.cache/babel/f2f333c3c546ad711d722d782decd450.json.gz +0 -0
- package/.cache/babel/f42c854ce8f1dc1a6e6fe7c510b033a5.json.gz +0 -0
- package/.cache/babel/f5211608f22c2e12594eafdbc4e66aa5.json.gz +0 -0
- package/.cache/babel/f645b8c88a49718cd778e3595212d4eb.json.gz +0 -0
- package/.cache/babel/f66dda5c4e4e9d04eb6b7411fcb12a65.json.gz +0 -0
- package/.cache/babel/f9d5b6f3f5438342dba75c2ce6143eef.json.gz +0 -0
- package/.cache/babel/fc9c60ee1d2e8783ba4c08db5cf97d40.json.gz +0 -0
- package/.cache/babel/fd558798cea72d04fb826468a89d72aa.json.gz +0 -0
- package/.cache/babel/fe735cbd0f6e131e28d8b6eb1f39141b.json.gz +0 -0
- package/.eslintrc.js +3 -26
- package/.nvmrc +1 -0
- package/CHANGELOG.md +422 -0
- package/babel.config.js +6 -0
- package/block-list.json +1 -1
- package/composer.json +2 -2
- package/composer.lock +446 -161
- package/dist/author-list/view.asset.php +1 -0
- package/dist/author-list/view.css +1 -0
- package/dist/author-list/view.js +1 -0
- package/dist/author-list/view.rtl.css +1 -0
- package/dist/author-profile/view.asset.php +1 -0
- package/dist/author-profile/view.css +1 -0
- package/dist/author-profile/view.js +1 -0
- package/dist/author-profile/view.rtl.css +1 -0
- package/dist/block_styles.asset.php +1 -0
- package/dist/block_styles.css +1 -0
- package/dist/block_styles.js +1 -0
- package/dist/block_styles.rtl.css +1 -0
- package/dist/carousel/view.asset.php +1 -0
- package/dist/carousel/view.css +1 -0
- package/dist/carousel/view.js +1 -0
- package/dist/carousel/view.rtl.css +1 -0
- package/dist/donate/view.asset.php +1 -0
- package/dist/donate/view.css +1 -0
- package/dist/donate/view.js +1 -0
- package/dist/donate/view.rtl.css +1 -0
- package/dist/donateStreamlined.asset.php +1 -0
- package/dist/donateStreamlined.css +1 -0
- package/dist/donateStreamlined.js +1 -0
- package/dist/donateStreamlined.rtl.css +1 -0
- package/dist/editor.asset.php +1 -0
- package/dist/editor.css +1 -0
- package/dist/editor.js +41 -0
- package/dist/editor.rtl.css +1 -0
- package/dist/homepage-articles/view.asset.php +1 -0
- package/dist/homepage-articles/view.css +1 -0
- package/dist/homepage-articles/view.js +1 -0
- package/dist/homepage-articles/view.rtl.css +1 -0
- package/dist/iframe/view.asset.php +1 -0
- package/dist/iframe/view.css +1 -0
- package/dist/iframe/view.js +1 -0
- package/dist/iframe/view.rtl.css +1 -0
- package/includes/class-newspack-blocks-api.php +14 -69
- package/includes/class-newspack-blocks-patterns.php +4 -1
- package/includes/class-newspack-blocks.php +421 -95
- package/newspack-blocks.php +26 -2
- package/package.json +31 -129
- package/postcss.config.js +11 -0
- package/src/block-patterns/subscribe-2.php +1 -1
- package/src/block-patterns/subscribe-3.php +1 -1
- package/src/block-patterns/subscribe-7.php +12 -0
- package/src/block-patterns/subscribe-8.php +12 -0
- package/src/block-patterns/subscribe-9.php +12 -0
- package/src/block-styles/core/columns/editor.scss +5 -8
- package/src/block-styles/core/columns/view.scss +83 -42
- package/src/blocks/author-list/block.json +82 -0
- package/src/blocks/author-list/class-wp-rest-newspack-author-list-controller.php +387 -0
- package/src/blocks/author-list/edit.js +527 -0
- package/src/blocks/author-list/editor.js +7 -0
- package/src/blocks/author-list/editor.scss +1 -0
- package/src/blocks/author-list/index.js +45 -0
- package/src/blocks/author-list/view.js +5 -0
- package/src/blocks/author-list/view.php +175 -0
- package/src/blocks/author-list/view.scss +46 -0
- package/src/blocks/author-profile/block.json +8 -0
- package/src/blocks/author-profile/class-wp-rest-newspack-authors-controller.php +69 -14
- package/src/blocks/author-profile/edit.js +212 -189
- package/src/blocks/author-profile/editor.scss +1 -1
- package/src/blocks/author-profile/single-author.js +100 -0
- package/src/blocks/author-profile/view.php +38 -92
- package/src/blocks/author-profile/view.scss +120 -1
- package/src/blocks/carousel/create-swiper.js +14 -5
- package/src/blocks/carousel/edit.js +4 -2
- package/src/blocks/carousel/editor.scss +3 -12
- package/src/blocks/carousel/view.js +1 -1
- package/src/blocks/carousel/view.php +9 -5
- package/src/blocks/carousel/view.scss +29 -3
- package/src/blocks/donate/class-wp-rest-newspack-donate-controller.php +22 -24
- package/src/blocks/donate/edit.js +49 -42
- package/src/blocks/donate/editor.scss +27 -3
- package/src/blocks/donate/index.js +31 -4
- package/src/blocks/donate/streamlined/index.js +248 -0
- package/src/blocks/donate/streamlined/index.test.js +125 -0
- package/src/blocks/donate/streamlined/style.scss +324 -0
- package/src/blocks/donate/streamlined/utils.js +174 -0
- package/src/blocks/donate/streamlined/utils.test.js +18 -0
- package/src/blocks/donate/view.php +77 -36
- package/src/blocks/donate/view.scss +291 -0
- package/src/blocks/homepage-articles/block.json +8 -0
- package/src/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php +24 -78
- package/src/blocks/homepage-articles/edit.js +26 -0
- package/src/blocks/homepage-articles/store.js +11 -1
- package/src/blocks/homepage-articles/templates/article.php +31 -3
- package/src/blocks/homepage-articles/templates/articles-loop.php +6 -5
- package/src/blocks/homepage-articles/utils.js +11 -10
- package/src/blocks/homepage-articles/view.php +4 -1
- package/src/blocks/homepage-articles/view.scss +69 -24
- package/src/blocks/iframe/block.json +34 -0
- package/src/blocks/iframe/class-wp-rest-newspack-iframe-controller.php +345 -0
- package/src/blocks/iframe/edit.js +252 -0
- package/src/blocks/iframe/editor.js +7 -0
- package/src/blocks/iframe/editor.scss +84 -0
- package/src/blocks/iframe/icons.js +10 -0
- package/src/blocks/iframe/iframe-placeholder.js +180 -0
- package/src/blocks/iframe/index.js +48 -0
- package/src/blocks/iframe/view.js +5 -0
- package/src/blocks/iframe/view.php +130 -0
- package/src/blocks/iframe/view.scss +9 -0
- package/src/blocks/video-playlist/view.php +4 -3
- package/src/components/query-controls.js +5 -4
- package/src/setup/editor.js +0 -1
- package/src/shared/js/utils.js +1 -1
- package/src/templates/author-profile-card.php +99 -0
- package/vendor/autoload.php +7 -0
- package/vendor/composer/ClassLoader.php +572 -0
- package/vendor/composer/InstalledVersions.php +350 -0
- package/vendor/composer/LICENSE +21 -0
- package/vendor/composer/autoload_classmap.php +10 -0
- package/vendor/composer/autoload_namespaces.php +9 -0
- package/vendor/composer/autoload_psr4.php +9 -0
- package/vendor/composer/autoload_real.php +55 -0
- package/vendor/composer/autoload_static.php +20 -0
- package/vendor/composer/installed.json +5 -0
- package/vendor/composer/installed.php +23 -0
- package/webpack.config.js +2 -3
- package/.circleci/config.yml +0 -96
- package/.distignore +0 -36
- package/.editorconfig +0 -22
- package/.github/ISSUE_TEMPLATE/Bug_report.md +0 -21
- package/.github/ISSUE_TEMPLATE/Enhancement.md +0 -17
- package/.github/ISSUE_TEMPLATE/Feature_request.md +0 -17
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -29
- package/.github/workflows/main.yml +0 -15
- package/.phpcs.xml.dist +0 -55
- package/.prettierrc +0 -10
- package/.stylelintrc +0 -21
- package/.travis.yml +0 -67
- package/phpunit.xml.dist +0 -16
- package/src/blocks/author-profile/shared.scss +0 -95
- package/src/blocks/donate/streamlined.js +0 -180
- package/src/blocks/donate/streamlined.scss +0 -124
- package/src/setup/public-path.js +0 -13
- package/src/setup/view.js +0 -4
- package/tests/bootstrap.php +0 -31
- package/tests/test-sample.php +0 -20
|
@@ -8,7 +8,7 @@ import classNames from 'classnames';
|
|
|
8
8
|
*/
|
|
9
9
|
import { __, sprintf } from '@wordpress/i18n';
|
|
10
10
|
import apiFetch from '@wordpress/api-fetch';
|
|
11
|
-
import { Component
|
|
11
|
+
import { Component } from '@wordpress/element';
|
|
12
12
|
import {
|
|
13
13
|
PanelBody,
|
|
14
14
|
ExternalLink,
|
|
@@ -320,12 +320,16 @@ class Edit extends Component {
|
|
|
320
320
|
const { buttonText } = attributes;
|
|
321
321
|
return (
|
|
322
322
|
<button type="submit" onClick={ evt => evt.preventDefault() }>
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
323
|
+
{ this.isRenderingStreamlinedBlock() ? (
|
|
324
|
+
__( 'Donate with card', 'newspack-blocks' )
|
|
325
|
+
) : (
|
|
326
|
+
<RichText
|
|
327
|
+
onChange={ value => setAttributes( { buttonText: value } ) }
|
|
328
|
+
placeholder={ __( 'Button text…', 'newspack-blocks' ) }
|
|
329
|
+
value={ buttonText }
|
|
330
|
+
tagName="span"
|
|
331
|
+
/>
|
|
332
|
+
) }
|
|
329
333
|
</button>
|
|
330
334
|
);
|
|
331
335
|
}
|
|
@@ -346,7 +350,12 @@ class Edit extends Component {
|
|
|
346
350
|
{ this.isRenderingStreamlinedBlock() ? (
|
|
347
351
|
<div className="wp-block-newspack-blocks-donate__stripe stripe-payment">
|
|
348
352
|
<div className="stripe-payment__row stripe-payment__row--flex stripe-payment__footer">
|
|
349
|
-
|
|
353
|
+
<div className="stripe-payment__methods">
|
|
354
|
+
<div className="stripe-payment__request-button">
|
|
355
|
+
{ __( 'Apple/Google Pay Button', 'newspack-blocks' ) }
|
|
356
|
+
</div>
|
|
357
|
+
{ this.renderButton() }
|
|
358
|
+
</div>
|
|
350
359
|
<a
|
|
351
360
|
target="_blank"
|
|
352
361
|
rel="noreferrer"
|
|
@@ -421,7 +430,7 @@ class Edit extends Component {
|
|
|
421
430
|
const { setAttributes } = this.props;
|
|
422
431
|
const { currencySymbol, suggestedAmounts, suggestedAmountUntiered, tiered } = this.blockData();
|
|
423
432
|
return (
|
|
424
|
-
|
|
433
|
+
<>
|
|
425
434
|
<ToggleControl
|
|
426
435
|
key="tiered"
|
|
427
436
|
checked={ tiered }
|
|
@@ -429,7 +438,7 @@ class Edit extends Component {
|
|
|
429
438
|
label={ __( 'Tiered', 'newspack-blocks' ) }
|
|
430
439
|
/>
|
|
431
440
|
{ tiered && (
|
|
432
|
-
|
|
441
|
+
<>
|
|
433
442
|
<TextControl
|
|
434
443
|
key="low-tier"
|
|
435
444
|
/* Translators: %s: the symbol for the current currency */
|
|
@@ -480,7 +489,7 @@ class Edit extends Component {
|
|
|
480
489
|
} )
|
|
481
490
|
}
|
|
482
491
|
/>
|
|
483
|
-
|
|
492
|
+
</>
|
|
484
493
|
) }
|
|
485
494
|
{ ! tiered && (
|
|
486
495
|
<TextControl
|
|
@@ -496,7 +505,7 @@ class Edit extends Component {
|
|
|
496
505
|
}
|
|
497
506
|
/>
|
|
498
507
|
) }
|
|
499
|
-
|
|
508
|
+
</>
|
|
500
509
|
);
|
|
501
510
|
}
|
|
502
511
|
|
|
@@ -504,38 +513,11 @@ class Edit extends Component {
|
|
|
504
513
|
const { setAttributes } = this.props;
|
|
505
514
|
const { manual, campaign, defaultFrequency } = this.blockData();
|
|
506
515
|
return (
|
|
507
|
-
|
|
516
|
+
<>
|
|
508
517
|
{ this.renderPlaceholder() }
|
|
509
518
|
{ this.renderForm() }
|
|
510
519
|
<InspectorControls>
|
|
511
|
-
<PanelBody>
|
|
512
|
-
<ToggleControl
|
|
513
|
-
key="manual"
|
|
514
|
-
checked={ manual }
|
|
515
|
-
onChange={ this.manualChanged }
|
|
516
|
-
label={ __( 'Configure manually', 'newspack-blocks' ) }
|
|
517
|
-
/>
|
|
518
|
-
{ ! manual && (
|
|
519
|
-
<Fragment>
|
|
520
|
-
<p>
|
|
521
|
-
{ __(
|
|
522
|
-
'The Donate Block allows you to collect donations from readers. The fields are automatically defined based on your donation settings.',
|
|
523
|
-
'newspack-blocks'
|
|
524
|
-
) }
|
|
525
|
-
</p>
|
|
526
|
-
|
|
527
|
-
<ExternalLink href="/wp-admin/admin.php?page=newspack-reader-revenue-wizard#/donations">
|
|
528
|
-
{ __( 'Edit donation settings.', 'newspack-blocks' ) }
|
|
529
|
-
</ExternalLink>
|
|
530
|
-
</Fragment>
|
|
531
|
-
) }
|
|
532
|
-
</PanelBody>
|
|
533
|
-
{ manual && (
|
|
534
|
-
<PanelBody title={ __( 'Manual Settings', 'newspack-blocks' ) }>
|
|
535
|
-
{ this.renderManualControls() }
|
|
536
|
-
</PanelBody>
|
|
537
|
-
) }
|
|
538
|
-
<PanelBody>
|
|
520
|
+
<PanelBody title={ __( 'Donate Settings', 'newspack-blocks' ) }>
|
|
539
521
|
<SelectControl
|
|
540
522
|
label={ __( 'Default Tab', 'newspack' ) }
|
|
541
523
|
value={ defaultFrequency }
|
|
@@ -559,7 +541,32 @@ class Edit extends Component {
|
|
|
559
541
|
} );
|
|
560
542
|
} }
|
|
561
543
|
/>
|
|
544
|
+
<ToggleControl
|
|
545
|
+
key="manual"
|
|
546
|
+
checked={ manual }
|
|
547
|
+
onChange={ this.manualChanged }
|
|
548
|
+
label={ __( 'Configure manually', 'newspack-blocks' ) }
|
|
549
|
+
/>
|
|
550
|
+
{ ! manual && (
|
|
551
|
+
<>
|
|
552
|
+
<p>
|
|
553
|
+
{ __(
|
|
554
|
+
'The Donate Block allows you to collect donations from readers. The fields are automatically defined based on your donation settings.',
|
|
555
|
+
'newspack-blocks'
|
|
556
|
+
) }
|
|
557
|
+
</p>
|
|
558
|
+
|
|
559
|
+
<ExternalLink href="/wp-admin/admin.php?page=newspack-reader-revenue-wizard#/donations">
|
|
560
|
+
{ __( 'Edit donation setting', 'newspack-blocks' ) }
|
|
561
|
+
</ExternalLink>
|
|
562
|
+
</>
|
|
563
|
+
) }
|
|
562
564
|
</PanelBody>
|
|
565
|
+
{ manual && (
|
|
566
|
+
<PanelBody title={ __( 'Donation Amount', 'newspack-blocks' ) }>
|
|
567
|
+
{ this.renderManualControls() }
|
|
568
|
+
</PanelBody>
|
|
569
|
+
) }
|
|
563
570
|
<PanelBody title={ __( 'Campaign', 'newspack-blocks' ) } initialOpen={ false }>
|
|
564
571
|
<TextControl
|
|
565
572
|
label={ __( 'Campaign ID', 'newspack-blocks' ) }
|
|
@@ -572,7 +579,7 @@ class Edit extends Component {
|
|
|
572
579
|
/>
|
|
573
580
|
</PanelBody>
|
|
574
581
|
</InspectorControls>
|
|
575
|
-
|
|
582
|
+
</>
|
|
576
583
|
);
|
|
577
584
|
}
|
|
578
585
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
@import '../../shared/sass/colors';
|
|
2
2
|
@import '../../shared/sass/variables';
|
|
3
3
|
|
|
4
|
-
@import './streamlined.scss';
|
|
4
|
+
@import './streamlined/style.scss';
|
|
5
5
|
|
|
6
6
|
.wp-block-newspack-blocks-donate {
|
|
7
7
|
button[type='submit'] {
|
|
8
|
-
background: $color__secondary;
|
|
9
8
|
border: none;
|
|
10
9
|
border-radius: 5px;
|
|
11
10
|
box-sizing: border-box;
|
|
@@ -13,8 +12,33 @@
|
|
|
13
12
|
font-size: $font__size-sm;
|
|
14
13
|
font-weight: bold;
|
|
15
14
|
outline: none;
|
|
16
|
-
line-height:
|
|
15
|
+
line-height: 3;
|
|
17
16
|
padding-left: 20px;
|
|
18
17
|
padding-right: 20px;
|
|
19
18
|
}
|
|
19
|
+
.stripe-payment {
|
|
20
|
+
&__methods {
|
|
21
|
+
> * {
|
|
22
|
+
line-height: 46px !important;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
&__request-button {
|
|
26
|
+
font-size: 0.8em;
|
|
27
|
+
border-radius: 5px;
|
|
28
|
+
color: $color__secondary;
|
|
29
|
+
border: $color__secondary 1px dashed;
|
|
30
|
+
padding: 0 20px;
|
|
31
|
+
opacity: 0.5;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.block-editor-block-list__layout
|
|
37
|
+
.block-editor-block-list__block
|
|
38
|
+
.wp-block-newspack-blocks-donate.tiered.is-style-minimal
|
|
39
|
+
.wp-block-newspack-blocks-donate__tiers
|
|
40
|
+
input[type='radio']:checked
|
|
41
|
+
+ .tier-select-label {
|
|
42
|
+
background: transparent;
|
|
43
|
+
color: $color__text-main;
|
|
20
44
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
+
import { ExternalLink } from '@wordpress/components';
|
|
4
5
|
import { __ } from '@wordpress/i18n';
|
|
5
|
-
import {
|
|
6
|
+
import { registerBlockStyle } from '@wordpress/blocks';
|
|
7
|
+
import { payment } from '@wordpress/icons';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Internal dependencies
|
|
@@ -21,7 +23,7 @@ export const title = __( 'Donate', 'newspack-blocks' );
|
|
|
21
23
|
export const settings = {
|
|
22
24
|
title,
|
|
23
25
|
icon: {
|
|
24
|
-
src:
|
|
26
|
+
src: payment,
|
|
25
27
|
foreground: '#36f',
|
|
26
28
|
},
|
|
27
29
|
category: 'newspack',
|
|
@@ -30,7 +32,19 @@ export const settings = {
|
|
|
30
32
|
__( 'memberships', 'newspack-blocks' ),
|
|
31
33
|
__( 'subscriptions', 'newspack-blocks' ),
|
|
32
34
|
],
|
|
33
|
-
description:
|
|
35
|
+
description: (
|
|
36
|
+
<>
|
|
37
|
+
<p>
|
|
38
|
+
{ __(
|
|
39
|
+
'Manually place a donation block on any post or page on your site.',
|
|
40
|
+
'newspack-blocks'
|
|
41
|
+
) }
|
|
42
|
+
</p>
|
|
43
|
+
<ExternalLink href={ __( 'https://newspack.pub/support/blocks/donate-block/' ) }>
|
|
44
|
+
{ __( 'Support reference', 'newspack-blocks' ) }
|
|
45
|
+
</ExternalLink>
|
|
46
|
+
</>
|
|
47
|
+
),
|
|
34
48
|
attributes: {
|
|
35
49
|
className: {
|
|
36
50
|
type: 'string',
|
|
@@ -59,7 +73,7 @@ export const settings = {
|
|
|
59
73
|
},
|
|
60
74
|
buttonText: {
|
|
61
75
|
type: 'string',
|
|
62
|
-
default: __( 'Donate
|
|
76
|
+
default: __( 'Donate Now', 'newspack-blocks' ),
|
|
63
77
|
},
|
|
64
78
|
defaultFrequency: {
|
|
65
79
|
type: 'string',
|
|
@@ -73,3 +87,16 @@ export const settings = {
|
|
|
73
87
|
edit,
|
|
74
88
|
save: () => null, // to use view.php
|
|
75
89
|
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Block Styles
|
|
93
|
+
*/
|
|
94
|
+
registerBlockStyle( 'newspack-blocks/donate', {
|
|
95
|
+
name: 'alternate',
|
|
96
|
+
label: __( 'Alternate', 'newapack-blocks' ),
|
|
97
|
+
} );
|
|
98
|
+
|
|
99
|
+
registerBlockStyle( 'newspack-blocks/donate', {
|
|
100
|
+
name: 'minimal',
|
|
101
|
+
label: __( 'Minimal', 'newapack-blocks' ),
|
|
102
|
+
} );
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* External dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { loadStripe } from '@stripe/stripe-js/pure';
|
|
10
|
+
import 'regenerator-runtime'; // Required in WP >=5.8.
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
import * as utils from './utils';
|
|
16
|
+
import './style.scss';
|
|
17
|
+
|
|
18
|
+
export const processStreamlinedElements = ( parentElement = document ) =>
|
|
19
|
+
[ ...parentElement.querySelectorAll( '.stripe-payment' ) ].forEach( async el => {
|
|
20
|
+
let stripe, cardElement, paymentRequest, paymentMethod, paymentRequestToken;
|
|
21
|
+
|
|
22
|
+
const formElement = el.closest( 'form' );
|
|
23
|
+
const messagesEl = el.querySelector( '.stripe-payment__messages' );
|
|
24
|
+
|
|
25
|
+
const settings = utils.getSettings( formElement );
|
|
26
|
+
|
|
27
|
+
const disableForm = () => el.classList.add( 'stripe-payment--disabled' );
|
|
28
|
+
const enableForm = () => el.classList.remove( 'stripe-payment--disabled' );
|
|
29
|
+
enableForm();
|
|
30
|
+
|
|
31
|
+
// Universal payment handling, for both card and payment request button flows.
|
|
32
|
+
// In card flow, this will happen after user submits their card data in the HTML form.
|
|
33
|
+
// In payment request flow, this will happen after the user validates the payment in
|
|
34
|
+
// the browser/OS UI.
|
|
35
|
+
const payWithToken = async (
|
|
36
|
+
token,
|
|
37
|
+
/**
|
|
38
|
+
* Overrides for sent donation data. In a card flow the data is
|
|
39
|
+
* provided explicitly by the user (via the form), but in payment request flow
|
|
40
|
+
* the data is from the payment request event.
|
|
41
|
+
*/
|
|
42
|
+
requestPayloadOverrides = {}
|
|
43
|
+
) => {
|
|
44
|
+
const formValues = utils.getFormValues( formElement );
|
|
45
|
+
const apiRequestPayload = {
|
|
46
|
+
tokenData: token,
|
|
47
|
+
amount: utils.getTotalAmount( formElement ),
|
|
48
|
+
email: formValues.email,
|
|
49
|
+
full_name: formValues.full_name,
|
|
50
|
+
frequency: formValues.donation_frequency,
|
|
51
|
+
newsletter_opt_in: Boolean( formValues.newsletter_opt_in ),
|
|
52
|
+
clientId: formValues.cid,
|
|
53
|
+
...requestPayloadOverrides,
|
|
54
|
+
};
|
|
55
|
+
const chargeResultData = await utils.sendAPIRequest( '/donate', apiRequestPayload );
|
|
56
|
+
|
|
57
|
+
// Error handling.
|
|
58
|
+
if ( chargeResultData.data?.status !== 200 && chargeResultData.message ) {
|
|
59
|
+
utils.renderMessages( [ chargeResultData.message ], messagesEl );
|
|
60
|
+
return { error: true };
|
|
61
|
+
}
|
|
62
|
+
if ( chargeResultData.error ) {
|
|
63
|
+
utils.renderMessages( [ chargeResultData.error ], messagesEl );
|
|
64
|
+
return { error: true };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const exitWithError = errorMessage => {
|
|
68
|
+
utils.renderMessages( [ errorMessage ], messagesEl );
|
|
69
|
+
enableForm();
|
|
70
|
+
return { error: true };
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Additional steps handling.
|
|
74
|
+
if ( chargeResultData.client_secret && paymentMethod ) {
|
|
75
|
+
const confirmationResult = await stripe.confirmCardPayment(
|
|
76
|
+
chargeResultData.client_secret,
|
|
77
|
+
{
|
|
78
|
+
payment_method: paymentMethod,
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
if ( confirmationResult.error ) {
|
|
83
|
+
return exitWithError( confirmationResult.error.message );
|
|
84
|
+
} else if ( confirmationResult.paymentIntent.status === 'succeeded' ) {
|
|
85
|
+
utils.renderSuccessMessageWithEmail( apiRequestPayload.email, messagesEl );
|
|
86
|
+
} else if ( confirmationResult.paymentIntent.status === 'requires_action' ) {
|
|
87
|
+
// Could not test this flow (with 3D Secure test cards), but it's listed in the docs:
|
|
88
|
+
// https://stripe.com/docs/stripe-js/elements/payment-request-button#html-js-complete-payment
|
|
89
|
+
const { error: confirmationError } = await stripe.confirmCardPayment(
|
|
90
|
+
chargeResultData.client_secret
|
|
91
|
+
);
|
|
92
|
+
if ( confirmationError ) {
|
|
93
|
+
return exitWithError( confirmationError.message );
|
|
94
|
+
}
|
|
95
|
+
utils.renderSuccessMessageWithEmail( apiRequestPayload.email, messagesEl );
|
|
96
|
+
} else {
|
|
97
|
+
return exitWithError(
|
|
98
|
+
__(
|
|
99
|
+
'Something went wrong with the payment. Please try again later.',
|
|
100
|
+
'newspack-blocks'
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if ( chargeResultData.status === 'success' ) {
|
|
107
|
+
utils.renderSuccessMessageWithEmail( apiRequestPayload.email, messagesEl );
|
|
108
|
+
}
|
|
109
|
+
return {};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const initStripe = async () => {
|
|
113
|
+
stripe = await loadStripe( settings.stripePublishableKey );
|
|
114
|
+
|
|
115
|
+
const elements = stripe.elements();
|
|
116
|
+
|
|
117
|
+
// Handle card element.
|
|
118
|
+
cardElement = elements.create( 'card' );
|
|
119
|
+
cardElement.mount( el.querySelector( '.stripe-payment__card' ) );
|
|
120
|
+
|
|
121
|
+
// Handle payment request button (Apple/Google Pay). This has to be initialised to see if
|
|
122
|
+
// such payments are available in the browser (canMakePayment method).
|
|
123
|
+
paymentRequest = stripe.paymentRequest( {
|
|
124
|
+
country: settings.countryCode,
|
|
125
|
+
currency: settings.currency,
|
|
126
|
+
total: utils.getPaymentRequestTotal( formElement ),
|
|
127
|
+
// Docs: Use the requestPayerName parameter to collect the payer’s billing address for Apple Pay.
|
|
128
|
+
requestPayerName: true,
|
|
129
|
+
requestPayerEmail: true,
|
|
130
|
+
} );
|
|
131
|
+
|
|
132
|
+
const rendersPaymentRequestButton = await paymentRequest.canMakePayment();
|
|
133
|
+
if ( rendersPaymentRequestButton ) {
|
|
134
|
+
paymentRequest.on( 'token', async event => {
|
|
135
|
+
paymentRequestToken = event.token;
|
|
136
|
+
} );
|
|
137
|
+
paymentRequest.on( 'paymentmethod', async event => {
|
|
138
|
+
// Save payment method ID to use it in payWithToken if a client secret is returned.
|
|
139
|
+
paymentMethod = event.paymentMethod.id;
|
|
140
|
+
const result = await payWithToken( paymentRequestToken, {
|
|
141
|
+
email: event.payerEmail,
|
|
142
|
+
full_name: event.payerName,
|
|
143
|
+
payment_method_id: paymentMethod,
|
|
144
|
+
} );
|
|
145
|
+
// The UI messages are handled in payWithToken, this event listener only
|
|
146
|
+
// has to notify the browser that the payment is done.
|
|
147
|
+
event.complete( result.error ? 'fail' : 'success' );
|
|
148
|
+
} );
|
|
149
|
+
// Update payment request when the form values are updated.
|
|
150
|
+
formElement.addEventListener( 'change', () => {
|
|
151
|
+
paymentRequest.update( {
|
|
152
|
+
total: utils.getPaymentRequestTotal( formElement ),
|
|
153
|
+
} );
|
|
154
|
+
} );
|
|
155
|
+
// Create and mount the payment request button.
|
|
156
|
+
const prButton = elements.create( 'paymentRequestButton', {
|
|
157
|
+
paymentRequest,
|
|
158
|
+
style: {
|
|
159
|
+
paymentRequestButton: {
|
|
160
|
+
type: 'donate',
|
|
161
|
+
height: '46px',
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
} );
|
|
165
|
+
const prButtonElement = el.querySelector( '.stripe-payment__request-button' );
|
|
166
|
+
prButton.mount( prButtonElement );
|
|
167
|
+
prButtonElement.classList.remove( 'stripe-payment--hidden' );
|
|
168
|
+
setTimeout( () => {
|
|
169
|
+
prButtonElement.classList.remove( 'stripe-payment__request-button--invisible' );
|
|
170
|
+
}, 0 );
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
el.classList.remove( 'stripe-payment--invisible' );
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
initStripe();
|
|
177
|
+
|
|
178
|
+
// Card form unravelling.
|
|
179
|
+
const submitButtonEl = el.querySelector( 'button[type="submit"]' );
|
|
180
|
+
submitButtonEl.onclick = e => {
|
|
181
|
+
const inputsHiddenEl = el.querySelector( '.stripe-payment__inputs.stripe-payment--hidden' );
|
|
182
|
+
if ( inputsHiddenEl ) {
|
|
183
|
+
e.preventDefault();
|
|
184
|
+
inputsHiddenEl.classList.remove( 'stripe-payment--hidden' );
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const updateFeesAmount = () => {
|
|
189
|
+
const feesAmountEl = el.querySelector( '#stripe-fees-amount' );
|
|
190
|
+
if ( feesAmountEl ) {
|
|
191
|
+
const formValues = Object.fromEntries( new FormData( formElement ) );
|
|
192
|
+
const feeAmount = utils.getFeeAmount( formElement );
|
|
193
|
+
feesAmountEl.innerHTML = `(${ settings.currencySymbol }${ feeAmount.toFixed(
|
|
194
|
+
2
|
|
195
|
+
) } ${ settings.frequencies[ formValues.donation_frequency ].toLowerCase() })`;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
updateFeesAmount();
|
|
200
|
+
formElement.addEventListener( 'change', updateFeesAmount );
|
|
201
|
+
|
|
202
|
+
// Card payment flow – on form submission.
|
|
203
|
+
formElement.addEventListener( 'submit', async e => {
|
|
204
|
+
e.preventDefault();
|
|
205
|
+
disableForm();
|
|
206
|
+
utils.renderMessages(
|
|
207
|
+
[ __( 'Processing payment…', 'newspack-blocks' ) ],
|
|
208
|
+
messagesEl,
|
|
209
|
+
'info'
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
const formValues = utils.getFormValues( formElement );
|
|
213
|
+
const validationErrors = Object.values( utils.validateFormData( formValues ) );
|
|
214
|
+
if ( validationErrors.length > 0 ) {
|
|
215
|
+
utils.renderMessages( validationErrors, messagesEl );
|
|
216
|
+
enableForm();
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const handleStripeSDKError = error => {
|
|
221
|
+
validationErrors.push( error.message );
|
|
222
|
+
utils.renderMessages( validationErrors, messagesEl );
|
|
223
|
+
enableForm();
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const stripeTokenCreationResult = await stripe.createToken( cardElement );
|
|
227
|
+
if ( stripeTokenCreationResult.error ) {
|
|
228
|
+
handleStripeSDKError( stripeTokenCreationResult.error );
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const paymentMethodCreationResult = await stripe.createPaymentMethod( {
|
|
232
|
+
type: 'card',
|
|
233
|
+
card: cardElement,
|
|
234
|
+
billing_details: { name: formValues.full_name, email: formValues.email },
|
|
235
|
+
} );
|
|
236
|
+
if ( paymentMethodCreationResult.error ) {
|
|
237
|
+
handleStripeSDKError( paymentMethodCreationResult.error );
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// Save payment method ID to use it in payWithToken if a client secret is returned.
|
|
241
|
+
paymentMethod = { card: cardElement };
|
|
242
|
+
await payWithToken( stripeTokenCreationResult.token, {
|
|
243
|
+
payment_method_id: paymentMethodCreationResult.paymentMethod.id,
|
|
244
|
+
} );
|
|
245
|
+
} );
|
|
246
|
+
} );
|
|
247
|
+
|
|
248
|
+
processStreamlinedElements();
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as testingLibrary from '@testing-library/dom';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import fetchMock from 'fetch-mock-jest';
|
|
4
|
+
import { encode } from 'html-entities';
|
|
5
|
+
|
|
6
|
+
import { processStreamlinedElements } from '.';
|
|
7
|
+
|
|
8
|
+
const MONTHLY_AMOUNT = 7;
|
|
9
|
+
|
|
10
|
+
const createDOM = settings => {
|
|
11
|
+
const parentElement = document.createElement( 'div' );
|
|
12
|
+
parentElement.innerHTML = `
|
|
13
|
+
<style>.stripe-payment--hidden {display:none;}</style>
|
|
14
|
+
<form data-settings="${ encode( JSON.stringify( settings ) ) }">
|
|
15
|
+
<div class='frequencies'>
|
|
16
|
+
<div class='frequency'>
|
|
17
|
+
<input type="radio" value="once" id="once" name="donation_frequency">
|
|
18
|
+
<label for="once">Once</label>
|
|
19
|
+
<input type="number" name="donation_value_once" value="${ MONTHLY_AMOUNT * 12 }" />
|
|
20
|
+
</div>
|
|
21
|
+
<div class='frequency'>
|
|
22
|
+
<input type="radio" value="month" id="month" name="donation_frequency" checked>
|
|
23
|
+
<label for="month">Monthly</label>
|
|
24
|
+
<input type="number" name="donation_value_month" value="${ MONTHLY_AMOUNT }" />
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="stripe-payment">
|
|
28
|
+
<div class="stripe-payment__inputs stripe-payment--hidden">
|
|
29
|
+
<input required="" placeholder="Email" type="email" name="email" value="">
|
|
30
|
+
<input required="" placeholder="Full Name" type="text" name="full_name" value="">
|
|
31
|
+
</div>
|
|
32
|
+
<label>
|
|
33
|
+
<input type="checkbox" name="agree_to_pay_fees" checked value="true">Agree to pay fees?
|
|
34
|
+
<span id="stripe-fees-amount">($0)</span>
|
|
35
|
+
</label>
|
|
36
|
+
<div class="stripe-payment__messages"></div>
|
|
37
|
+
<button type="submit">Donate</button>
|
|
38
|
+
</div>
|
|
39
|
+
<input name="cid" type="hidden" value="amp-123" />
|
|
40
|
+
</form>
|
|
41
|
+
`;
|
|
42
|
+
document.body.appendChild( parentElement );
|
|
43
|
+
return document.body;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
fetchMock.post( '/wp-json/newspack-blocks/v1/donate', () => {
|
|
47
|
+
return { status: 'success', client_secret: 'sec_123' };
|
|
48
|
+
} );
|
|
49
|
+
|
|
50
|
+
const frequencies = { once: 'Once', month: 'Monthly', year: 'Annually' };
|
|
51
|
+
const feeMultiplier = '2.9';
|
|
52
|
+
const feeStatic = '0.3';
|
|
53
|
+
const settings = [ 'USD', '$', 'Testing Site', false, 'US', frequencies, feeMultiplier, feeStatic ];
|
|
54
|
+
|
|
55
|
+
describe( 'Streamlined Donate block processing', () => {
|
|
56
|
+
const container = createDOM( settings );
|
|
57
|
+
processStreamlinedElements( container );
|
|
58
|
+
|
|
59
|
+
const button = testingLibrary.getByText( container, 'Donate' );
|
|
60
|
+
const emailInput = testingLibrary.getByPlaceholderText( container, 'Email' );
|
|
61
|
+
const nameInput = testingLibrary.getByPlaceholderText( container, 'Full Name' );
|
|
62
|
+
|
|
63
|
+
it( 'additional inputs are initially hidden and displayed after user clicks the button', async () => {
|
|
64
|
+
expect( emailInput ).not.toBeVisible();
|
|
65
|
+
await userEvent.click( button );
|
|
66
|
+
expect( emailInput ).toBeVisible();
|
|
67
|
+
} );
|
|
68
|
+
|
|
69
|
+
it( 'form submission with invalid values triggers validation errors', async () => {
|
|
70
|
+
await userEvent.click( button );
|
|
71
|
+
expect(
|
|
72
|
+
testingLibrary.getByText( container, 'Email address is invalid.' )
|
|
73
|
+
).toBeInTheDocument();
|
|
74
|
+
expect(
|
|
75
|
+
testingLibrary.getByText( container, 'Full name should be provided.' )
|
|
76
|
+
).toBeInTheDocument();
|
|
77
|
+
|
|
78
|
+
await userEvent.type( emailInput, 'foo@bar.com' );
|
|
79
|
+
await userEvent.click( button );
|
|
80
|
+
expect(
|
|
81
|
+
testingLibrary.queryByText( container, 'Email address is invalid.' )
|
|
82
|
+
).not.toBeInTheDocument();
|
|
83
|
+
} );
|
|
84
|
+
|
|
85
|
+
it( 'the fee amount is updated', () => {
|
|
86
|
+
expect( testingLibrary.getByText( container, '($0.52 monthly)' ) ).toBeInTheDocument();
|
|
87
|
+
} );
|
|
88
|
+
|
|
89
|
+
it( 'form can be submitted after validation passes', async () => {
|
|
90
|
+
await userEvent.type( nameInput, 'Bax' );
|
|
91
|
+
await userEvent.click( button );
|
|
92
|
+
expect(
|
|
93
|
+
testingLibrary.queryByText( container, 'Full name should be provided.' )
|
|
94
|
+
).not.toBeInTheDocument();
|
|
95
|
+
expect( testingLibrary.getByText( container, 'Processing payment…' ) ).toBeInTheDocument();
|
|
96
|
+
} );
|
|
97
|
+
|
|
98
|
+
it( 'final success message is displayed', () => {
|
|
99
|
+
expect(
|
|
100
|
+
testingLibrary.getByText(
|
|
101
|
+
container,
|
|
102
|
+
'Your payment has been processed. Thank you for your contribution! You will receive a confirmation email at foo@bar.com.'
|
|
103
|
+
)
|
|
104
|
+
).toBeInTheDocument();
|
|
105
|
+
} );
|
|
106
|
+
|
|
107
|
+
it( 'correct payload was sent to the API', () => {
|
|
108
|
+
expect( fetchMock ).toHaveLastFetched(
|
|
109
|
+
'/wp-json/newspack-blocks/v1/donate',
|
|
110
|
+
{
|
|
111
|
+
body: {
|
|
112
|
+
tokenData: 'abc',
|
|
113
|
+
amount: 7.52,
|
|
114
|
+
email: 'foo@bar.com',
|
|
115
|
+
full_name: 'Bax',
|
|
116
|
+
frequency: 'month',
|
|
117
|
+
newsletter_opt_in: false,
|
|
118
|
+
clientId: 'amp-123',
|
|
119
|
+
payment_method_id: 'pm_123',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
'post'
|
|
123
|
+
);
|
|
124
|
+
} );
|
|
125
|
+
} );
|