From f7b29b7106db97f646e4c39976afef1b2b48a4c4 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 22 Jan 2025 17:56:42 +0100 Subject: [PATCH 01/28] initial commit --- src/Campaigns/Blocks/DonateButton/block.json | 35 ++++++++ src/Campaigns/Blocks/DonateButton/edit.tsx | 84 +++++++++++++++++++ src/Campaigns/Blocks/DonateButton/index.ts | 13 +++ src/Campaigns/Blocks/DonateButton/save.tsx | 0 src/Campaigns/Blocks/blocks.ts | 6 +- .../Blocks/shared/hooks/useCampaign.ts | 26 +++++- .../Controllers/CampaignRequestController.php | 5 ++ 7 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 src/Campaigns/Blocks/DonateButton/block.json create mode 100644 src/Campaigns/Blocks/DonateButton/edit.tsx create mode 100644 src/Campaigns/Blocks/DonateButton/index.ts create mode 100644 src/Campaigns/Blocks/DonateButton/save.tsx diff --git a/src/Campaigns/Blocks/DonateButton/block.json b/src/Campaigns/Blocks/DonateButton/block.json new file mode 100644 index 0000000000..53c6e62bee --- /dev/null +++ b/src/Campaigns/Blocks/DonateButton/block.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json.schemastore.org/block.json", + "apiVersion": 2, + "name": "givewp/campaign-donate-button", + "version": "1.0.0", + "title": "Donate Button", + "category": "give", + "icon": "button", + "description": "The GiveWP Donate Button inserts an donate button into the page.", + "supports": { + "align": [ + "wide", + "full" + ] + }, + "attributes": { + "campaignId": { + "type": "number" + }, + "useDefaultForm": { + "type": "boolean", + "default": true + }, + "selectedForm": { + "type": "string" + }, + "buttonText": { + "type": "string", + "default": "Donate now" + } + }, + "textdomain": "give", + "editorStyle": "file:../../../../build/campaignDonateButtonBlock.css", + "editorScript": "file:../../../../build/campaignDonateButtonBlock.js" +} diff --git a/src/Campaigns/Blocks/DonateButton/edit.tsx b/src/Campaigns/Blocks/DonateButton/edit.tsx new file mode 100644 index 0000000000..cf580f6052 --- /dev/null +++ b/src/Campaigns/Blocks/DonateButton/edit.tsx @@ -0,0 +1,84 @@ +import {__} from '@wordpress/i18n'; +import {useSelect} from '@wordpress/data'; +import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; +import {BlockEditProps} from '@wordpress/blocks'; +import {PanelBody, SelectControl, TextControl, ToggleControl} from '@wordpress/components'; +import useCampaign from '../shared/hooks/useCampaign'; +import {CampaignSelector} from '../shared/components/CampaignSelector'; + +export default function Edit({attributes, setAttributes,}: BlockEditProps<{ + campaignId: number; + buttonText: string; + useDefaultForm: boolean; + selectedForm: string; +}>) { + const blockProps = useBlockProps(); + const {campaign, hasResolved} = useCampaign(attributes.campaignId); + + const adminBaseUrl = useSelect( + // @ts-ignore + (select) => select('core').getSite()?.url + '/wp-admin/edit.php?post_type=give_forms&page=give-campaigns', + [] + ); + + const campaignForms = (() => { + const {forms, isLoading} = campaign.forms(); + + if (isLoading) { + return [] + } + + return forms.map((form: { name: string, id: string }) => ({ + label: form.name, + value: form.id + })) + })(); + + return ( +
+ + +
+ {attributes.buttonText} +
+
+ + {hasResolved && campaign?.id && ( + + + setAttributes({buttonText})} + /> + setAttributes({useDefaultForm})} + help={ + <> + {__('Uses the campaign’s default form', 'give')}. + {` `} + + {__('Change default form', 'give')} + + + } + /> + setAttributes({selectedForm})} + options={campaignForms} + value={attributes.selectedForm} + /> + + + )} +
+ ); +} diff --git a/src/Campaigns/Blocks/DonateButton/index.ts b/src/Campaigns/Blocks/DonateButton/index.ts new file mode 100644 index 0000000000..a30e39d8fb --- /dev/null +++ b/src/Campaigns/Blocks/DonateButton/index.ts @@ -0,0 +1,13 @@ +import metadata from './block.json'; +import Edit from './edit'; +import initBlock from '../shared/utils/init-block'; + +const {name} = metadata; + +export const init = () => initBlock({ + name, + metadata, + settings: { + edit: Edit, + } +}); diff --git a/src/Campaigns/Blocks/DonateButton/save.tsx b/src/Campaigns/Blocks/DonateButton/save.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Campaigns/Blocks/blocks.ts b/src/Campaigns/Blocks/blocks.ts index a42f34ca1d..bce55c2358 100644 --- a/src/Campaigns/Blocks/blocks.ts +++ b/src/Campaigns/Blocks/blocks.ts @@ -1,7 +1,11 @@ import * as campaignTitleBlock from './CampaignTitleBlock'; +import * as campaignDonateButton from './DonateButton'; const getAllBlocks = () => { - return [campaignTitleBlock]; + return [ + campaignTitleBlock, + campaignDonateButton + ]; }; getAllBlocks().forEach((block) => { diff --git a/src/Campaigns/Blocks/shared/hooks/useCampaign.ts b/src/Campaigns/Blocks/shared/hooks/useCampaign.ts index a7cf2b57ea..380b70114d 100644 --- a/src/Campaigns/Blocks/shared/hooks/useCampaign.ts +++ b/src/Campaigns/Blocks/shared/hooks/useCampaign.ts @@ -1,11 +1,31 @@ import {useEntityRecord} from '@wordpress/core-data'; import {Campaign} from '@givewp/campaigns/admin/components/types'; +import apiFetch from '@wordpress/api-fetch'; +import {addQueryArgs} from '@wordpress/url'; +import useSWR from 'swr'; export default function useCampaign(campaignId: number) { - const data = useEntityRecord('givewp', 'campaign', campaignId); + const campaignData = useEntityRecord('givewp', 'campaign', campaignId); return { - campaign: data?.record as Campaign, - hasResolved: data?.hasResolved, + campaign: { + ...campaignData?.record as Campaign, + forms: (params: FormsApiParams = {status: 'publish'}) => { + const {data, isLoading}: { data: { items: [] }, isLoading: boolean } = useSWR( + addQueryArgs('/give-api/v2/admin/forms', {campaignId, ...params}), + path => apiFetch({path}) + ) + + return { + forms: data?.items || [], + isLoading + } + } + }, + hasResolved: campaignData?.hasResolved, }; } + +interface FormsApiParams { + status?: 'publish' | 'draft' | 'pending' | 'trash' | 'upgraded' | 'any' +} diff --git a/src/Campaigns/Controllers/CampaignRequestController.php b/src/Campaigns/Controllers/CampaignRequestController.php index e8fd8e30be..65dcb05738 100644 --- a/src/Campaigns/Controllers/CampaignRequestController.php +++ b/src/Campaigns/Controllers/CampaignRequestController.php @@ -58,6 +58,11 @@ public function getCampaigns(WP_REST_Request $request): WP_REST_Response $totalCampaigns = empty($campaigns) ? 0 : Campaign::query()->count(); $totalPages = (int)ceil($totalCampaigns / $perPage); + // todo: remove - temporary solution + $campaigns = array_map(function ($campaign) { + return $campaign->toArray(); + }, $campaigns); + $response = rest_ensure_response($campaigns); $response->header('X-WP-Total', $totalCampaigns); $response->header('X-WP-TotalPages', $totalPages); From 9c6d894ec438add489a9fcd38856c978f69f9e54 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 23 Jan 2025 12:16:40 +0100 Subject: [PATCH 02/28] feature: render block --- src/Campaigns/Blocks/DonateButton/block.json | 4 +-- src/Campaigns/Blocks/DonateButton/edit.tsx | 2 +- src/Campaigns/Blocks/DonateButton/index.ts | 2 +- src/Campaigns/Blocks/DonateButton/render.php | 27 ++++++++++++++++++++ src/Campaigns/Blocks/DonateButton/save.tsx | 0 5 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 src/Campaigns/Blocks/DonateButton/render.php delete mode 100644 src/Campaigns/Blocks/DonateButton/save.tsx diff --git a/src/Campaigns/Blocks/DonateButton/block.json b/src/Campaigns/Blocks/DonateButton/block.json index 53c6e62bee..f05b771487 100644 --- a/src/Campaigns/Blocks/DonateButton/block.json +++ b/src/Campaigns/Blocks/DonateButton/block.json @@ -30,6 +30,6 @@ } }, "textdomain": "give", - "editorStyle": "file:../../../../build/campaignDonateButtonBlock.css", - "editorScript": "file:../../../../build/campaignDonateButtonBlock.js" + "editorScript": "file:../../../../build/campaignDonateButtonBlock.js", + "render": "file:./render.php" } diff --git a/src/Campaigns/Blocks/DonateButton/edit.tsx b/src/Campaigns/Blocks/DonateButton/edit.tsx index cf580f6052..5ed0ae875a 100644 --- a/src/Campaigns/Blocks/DonateButton/edit.tsx +++ b/src/Campaigns/Blocks/DonateButton/edit.tsx @@ -6,7 +6,7 @@ import {PanelBody, SelectControl, TextControl, ToggleControl} from '@wordpress/c import useCampaign from '../shared/hooks/useCampaign'; import {CampaignSelector} from '../shared/components/CampaignSelector'; -export default function Edit({attributes, setAttributes,}: BlockEditProps<{ +export default function Edit({attributes, setAttributes}: BlockEditProps<{ campaignId: number; buttonText: string; useDefaultForm: boolean; diff --git a/src/Campaigns/Blocks/DonateButton/index.ts b/src/Campaigns/Blocks/DonateButton/index.ts index a30e39d8fb..80242fade3 100644 --- a/src/Campaigns/Blocks/DonateButton/index.ts +++ b/src/Campaigns/Blocks/DonateButton/index.ts @@ -8,6 +8,6 @@ export const init = () => initBlock({ name, metadata, settings: { - edit: Edit, + edit: Edit } }); diff --git a/src/Campaigns/Blocks/DonateButton/render.php b/src/Campaigns/Blocks/DonateButton/render.php new file mode 100644 index 0000000000..c202651817 --- /dev/null +++ b/src/Campaigns/Blocks/DonateButton/render.php @@ -0,0 +1,27 @@ +getById($attributes['campaignId']) +) { + return; +} + +$params = [ + 'formId' => $attributes['useDefaultForm'] + ? $campaign->defaultFormId + : $attributes['selectedForm'], + 'openFormButton' => $attributes['buttonText'], + 'formFormat' => 'modal', +]; + +echo (new BlockRenderController())->render($params); diff --git a/src/Campaigns/Blocks/DonateButton/save.tsx b/src/Campaigns/Blocks/DonateButton/save.tsx deleted file mode 100644 index e69de29bb2..0000000000 From 088e26eda431d66f078e4c38ab35370bbdbc3653 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 23 Jan 2025 12:29:45 +0100 Subject: [PATCH 03/28] feature: add icon and btn --- src/Campaigns/Blocks/DonateButton/block.json | 1 - src/Campaigns/Blocks/DonateButton/edit.tsx | 6 +++--- src/Campaigns/Blocks/DonateButton/{index.ts => index.tsx} | 5 ++++- 3 files changed, 7 insertions(+), 5 deletions(-) rename src/Campaigns/Blocks/DonateButton/{index.ts => index.tsx} (62%) diff --git a/src/Campaigns/Blocks/DonateButton/block.json b/src/Campaigns/Blocks/DonateButton/block.json index f05b771487..a1307417f8 100644 --- a/src/Campaigns/Blocks/DonateButton/block.json +++ b/src/Campaigns/Blocks/DonateButton/block.json @@ -5,7 +5,6 @@ "version": "1.0.0", "title": "Donate Button", "category": "give", - "icon": "button", "description": "The GiveWP Donate Button inserts an donate button into the page.", "supports": { "align": [ diff --git a/src/Campaigns/Blocks/DonateButton/edit.tsx b/src/Campaigns/Blocks/DonateButton/edit.tsx index 5ed0ae875a..fc60a1cb5f 100644 --- a/src/Campaigns/Blocks/DonateButton/edit.tsx +++ b/src/Campaigns/Blocks/DonateButton/edit.tsx @@ -3,6 +3,7 @@ import {useSelect} from '@wordpress/data'; import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; import {BlockEditProps} from '@wordpress/blocks'; import {PanelBody, SelectControl, TextControl, ToggleControl} from '@wordpress/components'; +import {Button} from 'react-aria-components'; import useCampaign from '../shared/hooks/useCampaign'; import {CampaignSelector} from '../shared/components/CampaignSelector'; @@ -36,11 +37,10 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ return (
- -
+
+
{hasResolved && campaign?.id && ( diff --git a/src/Campaigns/Blocks/DonateButton/index.ts b/src/Campaigns/Blocks/DonateButton/index.tsx similarity index 62% rename from src/Campaigns/Blocks/DonateButton/index.ts rename to src/Campaigns/Blocks/DonateButton/index.tsx index 80242fade3..245e417373 100644 --- a/src/Campaigns/Blocks/DonateButton/index.ts +++ b/src/Campaigns/Blocks/DonateButton/index.tsx @@ -1,6 +1,7 @@ import metadata from './block.json'; import Edit from './edit'; import initBlock from '../shared/utils/init-block'; +import GiveIcon from '@givewp/components/GiveIcon'; const {name} = metadata; @@ -8,6 +9,8 @@ export const init = () => initBlock({ name, metadata, settings: { - edit: Edit + edit: Edit, + save: () => null, + icon: , } }); From 673c59de371b437b0ebfab00693170660cca9694 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 23 Jan 2025 12:37:42 +0100 Subject: [PATCH 04/28] feature: add description and hide select component if default form is selected --- src/Campaigns/Blocks/DonateButton/edit.tsx | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Campaigns/Blocks/DonateButton/edit.tsx b/src/Campaigns/Blocks/DonateButton/edit.tsx index fc60a1cb5f..6619be2185 100644 --- a/src/Campaigns/Blocks/DonateButton/edit.tsx +++ b/src/Campaigns/Blocks/DonateButton/edit.tsx @@ -29,10 +29,15 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ return [] } - return forms.map((form: { name: string, id: string }) => ({ + const options = forms.map((form: { name: string, id: string }) => ({ label: form.name, value: form.id })) + + return [ + {label: __('Select form', 'give'), value: ''}, + ...options + ]; })(); return ( @@ -57,7 +62,7 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ onChange={(useDefaultForm: boolean) => setAttributes({useDefaultForm})} help={ <> - {__('Uses the campaign’s default form', 'give')}. + {__('Uses the campaign’s default form.', 'give')} {` `} } /> - setAttributes({selectedForm})} - options={campaignForms} - value={attributes.selectedForm} - /> + {!attributes.useDefaultForm && ( + setAttributes({selectedForm})} + options={campaignForms} + value={attributes.selectedForm} + help={__('Donations are collected through this form.', 'give')} + /> + )} )} From 76ead3fc4c7e0e6f94dd4c1d0b2fe4ceb3e8bb02 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 23 Jan 2025 12:42:02 +0100 Subject: [PATCH 05/28] chore: add unreleased tags --- src/Campaigns/Blocks/DonateButton/edit.tsx | 3 +++ src/Campaigns/Blocks/DonateButton/index.tsx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Campaigns/Blocks/DonateButton/edit.tsx b/src/Campaigns/Blocks/DonateButton/edit.tsx index 6619be2185..fb87f734a5 100644 --- a/src/Campaigns/Blocks/DonateButton/edit.tsx +++ b/src/Campaigns/Blocks/DonateButton/edit.tsx @@ -7,6 +7,9 @@ import {Button} from 'react-aria-components'; import useCampaign from '../shared/hooks/useCampaign'; import {CampaignSelector} from '../shared/components/CampaignSelector'; +/** + * @unreleased + */ export default function Edit({attributes, setAttributes}: BlockEditProps<{ campaignId: number; buttonText: string; diff --git a/src/Campaigns/Blocks/DonateButton/index.tsx b/src/Campaigns/Blocks/DonateButton/index.tsx index 245e417373..52ff3c7346 100644 --- a/src/Campaigns/Blocks/DonateButton/index.tsx +++ b/src/Campaigns/Blocks/DonateButton/index.tsx @@ -5,6 +5,9 @@ import GiveIcon from '@givewp/components/GiveIcon'; const {name} = metadata; +/** + * @unreleased + */ export const init = () => initBlock({ name, metadata, From 572a3774fd194c37eb45d4ade2eaf51f7406264f Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 29 Jan 2025 15:02:38 +0100 Subject: [PATCH 06/28] refactor: move campaign forms fetching logic outside the useCampaign hook --- src/Campaigns/Blocks/DonateButton/edit.tsx | 13 +++++++++--- .../Blocks/shared/hooks/useCampaign.ts | 20 +------------------ 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/Campaigns/Blocks/DonateButton/edit.tsx b/src/Campaigns/Blocks/DonateButton/edit.tsx index fb87f734a5..7ea4dfbc94 100644 --- a/src/Campaigns/Blocks/DonateButton/edit.tsx +++ b/src/Campaigns/Blocks/DonateButton/edit.tsx @@ -1,5 +1,8 @@ import {__} from '@wordpress/i18n'; import {useSelect} from '@wordpress/data'; +import {addQueryArgs} from '@wordpress/url'; +import apiFetch from '@wordpress/api-fetch'; +import useSWR from 'swr'; import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; import {BlockEditProps} from '@wordpress/blocks'; import {PanelBody, SelectControl, TextControl, ToggleControl} from '@wordpress/components'; @@ -7,6 +10,7 @@ import {Button} from 'react-aria-components'; import useCampaign from '../shared/hooks/useCampaign'; import {CampaignSelector} from '../shared/components/CampaignSelector'; + /** * @unreleased */ @@ -26,13 +30,16 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ ); const campaignForms = (() => { - const {forms, isLoading} = campaign.forms(); + const {data, isLoading}: { data: { items: [] }, isLoading: boolean } = useSWR( + addQueryArgs('/give-api/v2/admin/forms', {campaignId: attributes.campaignId, status: 'publish'}), + path => apiFetch({path}) + ) if (isLoading) { - return [] + return [{label: __('Loading...', 'give'), value: ''}] } - const options = forms.map((form: { name: string, id: string }) => ({ + const options = data.items.map((form: { name: string, id: string }) => ({ label: form.name, value: form.id })) diff --git a/src/Campaigns/Blocks/shared/hooks/useCampaign.ts b/src/Campaigns/Blocks/shared/hooks/useCampaign.ts index 380b70114d..3d0ed8f3ad 100644 --- a/src/Campaigns/Blocks/shared/hooks/useCampaign.ts +++ b/src/Campaigns/Blocks/shared/hooks/useCampaign.ts @@ -1,31 +1,13 @@ import {useEntityRecord} from '@wordpress/core-data'; import {Campaign} from '@givewp/campaigns/admin/components/types'; -import apiFetch from '@wordpress/api-fetch'; -import {addQueryArgs} from '@wordpress/url'; -import useSWR from 'swr'; export default function useCampaign(campaignId: number) { const campaignData = useEntityRecord('givewp', 'campaign', campaignId); return { campaign: { - ...campaignData?.record as Campaign, - forms: (params: FormsApiParams = {status: 'publish'}) => { - const {data, isLoading}: { data: { items: [] }, isLoading: boolean } = useSWR( - addQueryArgs('/give-api/v2/admin/forms', {campaignId, ...params}), - path => apiFetch({path}) - ) - - return { - forms: data?.items || [], - isLoading - } - } + ...campaignData?.record as Campaign }, hasResolved: campaignData?.hasResolved, }; } - -interface FormsApiParams { - status?: 'publish' | 'draft' | 'pending' | 'trash' | 'upgraded' | 'any' -} From f66d535352003207bb0858a1596b17b47a3770aa Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 30 Jan 2025 15:00:53 +0100 Subject: [PATCH 07/28] initial commit --- src/Campaigns/Actions/CampaignOptions.php | 29 +++++ src/Campaigns/Blocks/CampaignGoal/block.json | 42 +++++++ src/Campaigns/Blocks/CampaignGoal/edit.tsx | 108 ++++++++++++++++++ src/Campaigns/Blocks/CampaignGoal/icon.jsx | 11 ++ src/Campaigns/Blocks/CampaignGoal/index.tsx | 21 ++++ src/Campaigns/Blocks/CampaignGoal/render.php | 27 +++++ src/Campaigns/Blocks/CampaignGoal/styles.scss | 51 +++++++++ src/Campaigns/Blocks/blocks.ts | 4 +- src/Campaigns/ServiceProvider.php | 10 ++ .../CampaignDetailsPage/Tabs/Settings.tsx | 2 +- src/Campaigns/resources/types.ts | 14 +++ 11 files changed, 317 insertions(+), 2 deletions(-) create mode 100644 src/Campaigns/Actions/CampaignOptions.php create mode 100644 src/Campaigns/Blocks/CampaignGoal/block.json create mode 100644 src/Campaigns/Blocks/CampaignGoal/edit.tsx create mode 100644 src/Campaigns/Blocks/CampaignGoal/icon.jsx create mode 100644 src/Campaigns/Blocks/CampaignGoal/index.tsx create mode 100644 src/Campaigns/Blocks/CampaignGoal/render.php create mode 100644 src/Campaigns/Blocks/CampaignGoal/styles.scss diff --git a/src/Campaigns/Actions/CampaignOptions.php b/src/Campaigns/Actions/CampaignOptions.php new file mode 100644 index 0000000000..760986c506 --- /dev/null +++ b/src/Campaigns/Actions/CampaignOptions.php @@ -0,0 +1,29 @@ + give_get_currency(), + 'currencySymbol' => give_currency_symbol(), + 'isRecurringEnabled' => defined('GIVE_RECURRING_VERSION') + ? GIVE_RECURRING_VERSION + : null, + ] + ); + + wp_enqueue_script('give-campaign-options'); + } +} diff --git a/src/Campaigns/Blocks/CampaignGoal/block.json b/src/Campaigns/Blocks/CampaignGoal/block.json new file mode 100644 index 0000000000..fe3fbee113 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/block.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://json.schemastore.org/block.json", + "apiVersion": 2, + "name": "givewp/campaign-goal", + "version": "1.0.0", + "title": "Campaign Goal", + "category": "give", + "description": "Displays the goal of the campaign.", + "supports": { + "align": [ + "wide", + "full" + ] + }, + "attributes": { + "campaignId": { + "type": "number" + }, + "goalType": { + "type": "string", + "enum": [ + "amount", + "donations", + "donors", + "amountFromSubscriptions", + "subscriptions", + "donorsFromSubscriptions" + ], + "default": "amount" + }, + "selectedForm": { + "type": "string" + }, + "buttonText": { + "type": "string", + "default": "Donate now" + } + }, + "textdomain": "give", + "editorScript": "file:../../../../build/campaignGoalBlock.js", + "render": "file:./render.php" +} diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx new file mode 100644 index 0000000000..bd5585de27 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -0,0 +1,108 @@ +import {__} from '@wordpress/i18n'; +import {useSelect} from '@wordpress/data'; +import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; +import {BlockEditProps} from '@wordpress/blocks'; +import {PanelBody, SelectControl} from '@wordpress/components'; +import {ExternalLink} from '@wordpress/components'; +import useCampaign from '../shared/hooks/useCampaign'; +import {CampaignSelector} from '../shared/components/CampaignSelector'; + +import './styles.scss'; + +const goalOptions = () => { + const options = [ + {value: 'amount', label: __('Amount raised', 'give')}, + {value: 'donations', label: __('Number of donations', 'give')}, + {value: 'donors', label: __('Number of donors', 'give')}, + ] + + if (!window.GiveCampaignOptions.isRecurringEnabled) { + return [ + ...options, + {value: 'amountFromSubscriptions', label: __('Recurring amount raised', 'give')}, + {value: 'subscriptions', label: __('Number of recurring donations', 'give')}, + {value: 'donorsFromSubscriptions', label: __('Number of recurring donors', 'give')}, + ] + } + + return options; +} + +const currency = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: window.GiveCampaignOptions.currency, +}) + +/** + * @unreleased + */ +export default function Edit({attributes, setAttributes}: BlockEditProps<{ + campaignId: number; + goalType: string; +}>) { + const {campaign, hasResolved} = useCampaign(attributes.campaignId); + + + const blockProps = useBlockProps(); + + const adminBaseUrl = useSelect( + // @ts-ignore + (select) => select('core').getSite()?.url + '/wp-admin/edit.php?post_type=give_forms&page=give-campaigns', + [] + ); + + if (!hasResolved) { + return null; + } + + console.log(campaign) + + return ( +
+ +
+
+
+ {__('Amount raised', 'give')} + + {currency.format(campaign.goalProgress)} + +
+
+ {__('Our goal', 'give')} + {currency.format(campaign.goal || 0)} +
+
+
+
+
100 ? '100%' : `${campaign.goalProgress}%`}}> +
+
+
+
+
+ + {hasResolved && campaign?.id && ( + + + setAttributes({goalType})} + options={goalOptions()} + value={attributes.goalType} + help={ + + {__('Edit campaign goal', 'give')} + + } + /> + + + )} +
+ ); +} diff --git a/src/Campaigns/Blocks/CampaignGoal/icon.jsx b/src/Campaigns/Blocks/CampaignGoal/icon.jsx new file mode 100644 index 0000000000..fd153a0135 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/icon.jsx @@ -0,0 +1,11 @@ +export default () => ( + + + + + +) diff --git a/src/Campaigns/Blocks/CampaignGoal/index.tsx b/src/Campaigns/Blocks/CampaignGoal/index.tsx new file mode 100644 index 0000000000..fc3a47942a --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/index.tsx @@ -0,0 +1,21 @@ +import metadata from './block.json'; +import Edit from './edit'; +import Icon from './icon'; +import initBlock from '../shared/utils/init-block'; + +const {name} = metadata; + +/** + * @unreleased + */ +export const init = () => initBlock({ + name, + metadata, + settings: { + edit: Edit, + save: () => null, + icon: , + } +}); + + diff --git a/src/Campaigns/Blocks/CampaignGoal/render.php b/src/Campaigns/Blocks/CampaignGoal/render.php new file mode 100644 index 0000000000..c202651817 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/render.php @@ -0,0 +1,27 @@ +getById($attributes['campaignId']) +) { + return; +} + +$params = [ + 'formId' => $attributes['useDefaultForm'] + ? $campaign->defaultFormId + : $attributes['selectedForm'], + 'openFormButton' => $attributes['buttonText'], + 'formFormat' => 'modal', +]; + +echo (new BlockRenderController())->render($params); diff --git a/src/Campaigns/Blocks/CampaignGoal/styles.scss b/src/Campaigns/Blocks/CampaignGoal/styles.scss new file mode 100644 index 0000000000..c7ccc61bb1 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/styles.scss @@ -0,0 +1,51 @@ +.give-campaign-goal { + display: flex; + flex-direction: column; + gap: 0.5rem; + + &__container { + display: flex; + flex-direction: row; + justify-content: space-between; + + &-item { + display: flex; + flex-direction: column; + gap: 0.2rem; + + span { + text-transform: uppercase; + font-size: 12px; + line-height: 18px; + color: #4b5563; + } + + strong { + font-size: 20px; + line-height: 32px; + color: #060c1a; + } + } + } + + &__progress-bar { + display: flex; + + &-container { + display: flex; + height: 8px; + flex-grow: 1; + border-radius: 14px; + box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.09); + background-color: #f2f2f2; + } + + &-progress { + display: flex; + height: 8px; + border-radius: 14px; + box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.09); + background-color: #2d802f; + } + } +} diff --git a/src/Campaigns/Blocks/blocks.ts b/src/Campaigns/Blocks/blocks.ts index bce55c2358..c06a25c5c7 100644 --- a/src/Campaigns/Blocks/blocks.ts +++ b/src/Campaigns/Blocks/blocks.ts @@ -1,10 +1,12 @@ import * as campaignTitleBlock from './CampaignTitleBlock'; import * as campaignDonateButton from './DonateButton'; +import * as campaignGoal from './CampaignGoal'; const getAllBlocks = () => { return [ campaignTitleBlock, - campaignDonateButton + campaignDonateButton, + campaignGoal, ]; }; diff --git a/src/Campaigns/ServiceProvider.php b/src/Campaigns/ServiceProvider.php index c6c7f6282c..212bed8a58 100644 --- a/src/Campaigns/ServiceProvider.php +++ b/src/Campaigns/ServiceProvider.php @@ -3,6 +3,7 @@ namespace Give\Campaigns; use Give\Campaigns\Actions\AddCampaignFormFromRequest; +use Give\Campaigns\Actions\CampaignOptions; use Give\Campaigns\Actions\CreateDefaultCampaignForm; use Give\Campaigns\Actions\DeleteCampaignPage; use Give\Campaigns\Actions\FormInheritsCampaignGoal; @@ -49,6 +50,7 @@ public function boot(): void $this->registerCampaignEntity(); $this->registerCampaignBlocks(); $this->setupCampaignForms(); + $this->loadCampaignOptions(); } /** @@ -158,4 +160,12 @@ private function registerCampaignBlocks() Hooks::addAction('rest_api_init', Actions\RegisterCampaignIdRestField::class); Hooks::addAction('init', Actions\RegisterCampaignBlocks::class); } + + /** + * @unreleased + */ + private function loadCampaignOptions() + { + Hooks::addAction('admin_init', CampaignOptions::class); + } } diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx index 214b23eedc..1fccee6c04 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx @@ -151,7 +151,7 @@ export default () => {
{/* Campaign Goal */} -
+
{__('Campaign Goal', 'give')}
diff --git a/src/Campaigns/resources/types.ts b/src/Campaigns/resources/types.ts index 944af2a414..8d74bf99a4 100644 --- a/src/Campaigns/resources/types.ts +++ b/src/Campaigns/resources/types.ts @@ -1,3 +1,5 @@ +import {GiveCampaignDetails} from "@givewp/campaigns/admin/components/CampaignDetailsPage/types"; + export type Notification = { id: string; content: string | JSX.Element | Function; @@ -21,3 +23,15 @@ declare module "@wordpress/data" { dismissNotification(id: string): void }; } + +declare global { + interface Window { + GiveCampaignOptions: { + currency: string; + currencySymbol: string; + isRecurringEnabled: boolean; + }; + } +} + + From 298b35b2bf6f3188ab77cd36e06917b540329643 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 30 Jan 2025 19:07:50 +0100 Subject: [PATCH 08/28] refactor: remove unused attributes --- src/Campaigns/Blocks/CampaignGoal/block.json | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/block.json b/src/Campaigns/Blocks/CampaignGoal/block.json index fe3fbee113..d96d436b57 100644 --- a/src/Campaigns/Blocks/CampaignGoal/block.json +++ b/src/Campaigns/Blocks/CampaignGoal/block.json @@ -15,25 +15,6 @@ "attributes": { "campaignId": { "type": "number" - }, - "goalType": { - "type": "string", - "enum": [ - "amount", - "donations", - "donors", - "amountFromSubscriptions", - "subscriptions", - "donorsFromSubscriptions" - ], - "default": "amount" - }, - "selectedForm": { - "type": "string" - }, - "buttonText": { - "type": "string", - "default": "Donate now" } }, "textdomain": "give", From 9385381e9cef0d14d3c7d0a0fa8373aaa6ed06a6 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 30 Jan 2025 19:08:29 +0100 Subject: [PATCH 09/28] feature: add helper functions for displaying goal values and description --- src/Campaigns/Blocks/CampaignGoal/edit.tsx | 69 +++++++++++----------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx index bd5585de27..740c69d92a 100644 --- a/src/Campaigns/Blocks/CampaignGoal/edit.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -9,23 +9,31 @@ import {CampaignSelector} from '../shared/components/CampaignSelector'; import './styles.scss'; -const goalOptions = () => { - const options = [ - {value: 'amount', label: __('Amount raised', 'give')}, - {value: 'donations', label: __('Number of donations', 'give')}, - {value: 'donors', label: __('Number of donors', 'give')}, - ] - - if (!window.GiveCampaignOptions.isRecurringEnabled) { - return [ - ...options, - {value: 'amountFromSubscriptions', label: __('Recurring amount raised', 'give')}, - {value: 'subscriptions', label: __('Number of recurring donations', 'give')}, - {value: 'donorsFromSubscriptions', label: __('Number of recurring donors', 'give')}, - ] +const getGoalDescription = (goalType: string) => { + switch (goalType) { + case 'amount': + return __('Amount raised', 'give'); + case 'donations': + return __('Number of donations', 'give'); + case 'donors': + return __('Number of donors', 'give'); + case 'amountFromSubscriptions': + return __('Recurring amount raised', 'give'); + case 'subscriptions': + return __('Number of recurring donations', 'give'); + case 'donorsFromSubscriptions': + return __('Number of recurring donors', 'give'); } +} - return options; +const getValue = (goalType: string, value: number) => { + switch (goalType) { + case 'amount': + case 'amountFromSubscriptions': + return currency.format(value); + default: + return value; + } } const currency = new Intl.NumberFormat('en-US', { @@ -42,7 +50,6 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ }>) { const {campaign, hasResolved} = useCampaign(attributes.campaignId); - const blockProps = useBlockProps(); const adminBaseUrl = useSelect( @@ -55,28 +62,26 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ return null; } - console.log(campaign) - return (
- {__('Amount raised', 'give')} + {getGoalDescription(campaign.goalType)} - {currency.format(campaign.goalProgress)} + {getValue(campaign.goalType, campaign.goalStats.actual)}
{__('Our goal', 'give')} - {currency.format(campaign.goal || 0)} + {getValue(campaign.goalType, campaign.goal)}
100 ? '100%' : `${campaign.goalProgress}%`}}> + style={{width: `${campaign.goalStats.percentage}%`}}>
@@ -86,20 +91,12 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ {hasResolved && campaign?.id && ( - setAttributes({goalType})} - options={goalOptions()} - value={attributes.goalType} - help={ - - {__('Edit campaign goal', 'give')} - - } - /> + + {__('Edit campaign goal settings', 'give')} + )} From 7f1a0407b23b9d6ad1c5c11fdea2e19aac2211f6 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 30 Jan 2025 19:09:08 +0100 Subject: [PATCH 10/28] refactor: add goalStats prop --- src/Campaigns/Controllers/CampaignRequestController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Campaigns/Controllers/CampaignRequestController.php b/src/Campaigns/Controllers/CampaignRequestController.php index 65dcb05738..f3cd3688e4 100644 --- a/src/Campaigns/Controllers/CampaignRequestController.php +++ b/src/Campaigns/Controllers/CampaignRequestController.php @@ -34,7 +34,7 @@ public function getCampaign(WP_REST_Request $request) return new WP_REST_Response( array_merge($campaign->toArray(), [ - 'goalProgress' => $campaign->goalProgress(), + 'goalStats' => $campaign->getGoalStats(), 'defaultFormTitle' => $campaign->defaultForm()->title ]) ); From 6859f65ce8d11f284fd56530205cb2aee6e81b6f Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 30 Jan 2025 19:10:30 +0100 Subject: [PATCH 11/28] refactor: use CampaignGoalData instead of CampaignDonationQuery for goal stats --- src/Campaigns/Models/Campaign.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Campaigns/Models/Campaign.php b/src/Campaigns/Models/Campaign.php index 23d086d901..5e5762c649 100644 --- a/src/Campaigns/Models/Campaign.php +++ b/src/Campaigns/Models/Campaign.php @@ -5,7 +5,7 @@ use DateTime; use Exception; use Give\Campaigns\Actions\ConvertQueryDataToCampaign; -use Give\Campaigns\CampaignDonationQuery; +use Give\Campaigns\DataTransferObjects\CampaignGoalData; use Give\Campaigns\Factories\CampaignFactory; use Give\Campaigns\Repositories\CampaignPageRepository; use Give\Campaigns\Repositories\CampaignRepository; @@ -174,10 +174,9 @@ public function merge(Campaign ...$campaignsToMerge): bool return give(CampaignRepository::class)->mergeCampaigns($this, ...$campaignsToMerge); } - public function goalProgress() + public function getGoalStats(): array { - $query = new CampaignDonationQuery($this); - return $query->sumIntendedAmount(); + return (new CampaignGoalData($this))->toArray(); } /** From 86ee2a8c493157cb79dfcb437a953e94902bd854 Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 30 Jan 2025 19:11:02 +0100 Subject: [PATCH 12/28] refactor: use the new goalStats prop --- .../CampaignDetailsPage/Components/CampaignStats/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx index 1de9b3d5b8..7bdedd1fa4 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx @@ -150,7 +150,7 @@ const GoalProgressWidget = () => { {__('Goal progress', 'give')} {__('Show your campaign performance', 'give')} - +
) } From 50343448da09bf5a66e2e7663f4b00acb1deab9c Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 30 Jan 2025 19:11:23 +0100 Subject: [PATCH 13/28] feature: add goalStats props --- src/Campaigns/resources/admin/components/types.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Campaigns/resources/admin/components/types.ts b/src/Campaigns/resources/admin/components/types.ts index c866cedc1e..09d3adb448 100644 --- a/src/Campaigns/resources/admin/components/types.ts +++ b/src/Campaigns/resources/admin/components/types.ts @@ -10,7 +10,11 @@ export type Campaign = { secondaryColor: string; goalType: string; goal: number; - goalProgress: number; + goalStats: { + actual: number, + percentage: number, + goal: number, + }; status: string; startDateTime: { date: string; From 069c39d230bff31d2d24571c2c49c7ee13e99e15 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 31 Jan 2025 12:23:37 +0100 Subject: [PATCH 14/28] feature: render block --- src/Campaigns/Blocks/CampaignGoal/render.php | 61 +++++++++++++++++--- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/render.php b/src/Campaigns/Blocks/CampaignGoal/render.php index c202651817..d0dccc68b4 100644 --- a/src/Campaigns/Blocks/CampaignGoal/render.php +++ b/src/Campaigns/Blocks/CampaignGoal/render.php @@ -1,8 +1,10 @@ $attributes['useDefaultForm'] - ? $campaign->defaultFormId - : $attributes['selectedForm'], - 'openFormButton' => $attributes['buttonText'], - 'formFormat' => 'modal', -]; +$stats = (new CampaignGoalData($campaign))->toArray(); + +$getGoalDescription = function(CampaignGoalType $goalType) { + $data = [ + 'amount' => __('Amount raised', 'give'), + 'donations' => __('Number of donations', 'give'), + 'donors' => __('Number of donors', 'give'), + 'amountFromSubscriptions' => __('Recurring amount raised', 'give'), + 'subscriptions' => __('Number of recurring donations', 'give'), + 'donorsFromSubscriptions' => __('Number of recurring donors', 'give'), + ]; + + return $data[$goalType->getvalue()]; +}; + +$getGoalFormattedValue = function($goalType, $value) { + switch ($goalType) { + case 'amount': + case 'amountFromSubscriptions': + $amount = Money::fromDecimal($value, give_get_currency()); + return $amount->formatToLocale(); + default: + return $value; + } +}; + +?> + +
+
+
+ goalType); ?> + + goalType, $stats['actual']); ?> + +
+
+ + goalType, $campaign->goal); ?> +
+
+
+
+
+
+
+
+
-echo (new BlockRenderController())->render($params); From 15f0721113b1d271f323727263814028af7d803c Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 3 Feb 2025 12:57:11 +0100 Subject: [PATCH 15/28] fix: missing campaign goal stats --- src/Campaigns/Blocks/CampaignGoal/edit.tsx | 3 +-- src/Campaigns/Controllers/CampaignRequestController.php | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx index 740c69d92a..2e54ef4348 100644 --- a/src/Campaigns/Blocks/CampaignGoal/edit.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -2,8 +2,7 @@ import {__} from '@wordpress/i18n'; import {useSelect} from '@wordpress/data'; import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; import {BlockEditProps} from '@wordpress/blocks'; -import {PanelBody, SelectControl} from '@wordpress/components'; -import {ExternalLink} from '@wordpress/components'; +import {ExternalLink, PanelBody} from '@wordpress/components'; import useCampaign from '../shared/hooks/useCampaign'; import {CampaignSelector} from '../shared/components/CampaignSelector'; diff --git a/src/Campaigns/Controllers/CampaignRequestController.php b/src/Campaigns/Controllers/CampaignRequestController.php index f3cd3688e4..b48f7983af 100644 --- a/src/Campaigns/Controllers/CampaignRequestController.php +++ b/src/Campaigns/Controllers/CampaignRequestController.php @@ -60,7 +60,9 @@ public function getCampaigns(WP_REST_Request $request): WP_REST_Response // todo: remove - temporary solution $campaigns = array_map(function ($campaign) { - return $campaign->toArray(); + return array_merge($campaign->toArray(), [ + 'goalStats' => $campaign->getGoalStats(), + ]); }, $campaigns); $response = rest_ensure_response($campaigns); From ca7d6c90ad6ee37d54e878102f61580a4612a616 Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 3 Feb 2025 13:09:29 +0100 Subject: [PATCH 16/28] feature: add text control with goal description --- src/Campaigns/Blocks/CampaignGoal/edit.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx index 2e54ef4348..e7b011582b 100644 --- a/src/Campaigns/Blocks/CampaignGoal/edit.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -2,7 +2,7 @@ import {__} from '@wordpress/i18n'; import {useSelect} from '@wordpress/data'; import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; import {BlockEditProps} from '@wordpress/blocks'; -import {ExternalLink, PanelBody} from '@wordpress/components'; +import {ExternalLink, PanelBody, TextControl} from '@wordpress/components'; import useCampaign from '../shared/hooks/useCampaign'; import {CampaignSelector} from '../shared/components/CampaignSelector'; @@ -90,6 +90,7 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ {hasResolved && campaign?.id && ( + Date: Mon, 3 Feb 2025 13:18:24 +0100 Subject: [PATCH 17/28] refactor: fix undefined campaign goalStats; use campaign method to get stats --- src/Campaigns/Blocks/CampaignGoal/edit.tsx | 4 ++-- src/Campaigns/Blocks/CampaignGoal/render.php | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx index e7b011582b..6712bc8a1f 100644 --- a/src/Campaigns/Blocks/CampaignGoal/edit.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -69,7 +69,7 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{
{getGoalDescription(campaign.goalType)} - {getValue(campaign.goalType, campaign.goalStats.actual)} + {getValue(campaign.goalType, campaign?.goalStats?.actual)}
@@ -80,7 +80,7 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{
+ style={{width: `${campaign?.goalStats?.percentage}%`}}>
diff --git a/src/Campaigns/Blocks/CampaignGoal/render.php b/src/Campaigns/Blocks/CampaignGoal/render.php index d0dccc68b4..2dba87832a 100644 --- a/src/Campaigns/Blocks/CampaignGoal/render.php +++ b/src/Campaigns/Blocks/CampaignGoal/render.php @@ -1,6 +1,5 @@ toArray(); +$stats = $campaign->getGoalStats(); $getGoalDescription = function(CampaignGoalType $goalType) { $data = [ From e2cd89482b26b90150eb78098d2092ac0610bfb2 Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 3 Feb 2025 17:20:09 +0100 Subject: [PATCH 18/28] feature: set language using navigator object --- src/Campaigns/Blocks/CampaignGoal/edit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx index 6712bc8a1f..427ac62cb4 100644 --- a/src/Campaigns/Blocks/CampaignGoal/edit.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -35,7 +35,7 @@ const getValue = (goalType: string, value: number) => { } } -const currency = new Intl.NumberFormat('en-US', { +const currency = new Intl.NumberFormat(navigator.language || navigator.languages[0], { style: 'currency', currency: window.GiveCampaignOptions.currency, }) From 0926bad9c9a7a234e7ed3ed19c7813241d591d4a Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 3 Feb 2025 17:28:23 +0100 Subject: [PATCH 19/28] refactor: render block using ssr --- src/Campaigns/Blocks/CampaignGoal/edit.tsx | 38 ++-------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx index 427ac62cb4..ab5b615c08 100644 --- a/src/Campaigns/Blocks/CampaignGoal/edit.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -1,6 +1,7 @@ import {__} from '@wordpress/i18n'; import {useSelect} from '@wordpress/data'; import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; +import ServerSideRender from '@wordpress/server-side-render'; import {BlockEditProps} from '@wordpress/blocks'; import {ExternalLink, PanelBody, TextControl} from '@wordpress/components'; import useCampaign from '../shared/hooks/useCampaign'; @@ -25,21 +26,6 @@ const getGoalDescription = (goalType: string) => { } } -const getValue = (goalType: string, value: number) => { - switch (goalType) { - case 'amount': - case 'amountFromSubscriptions': - return currency.format(value); - default: - return value; - } -} - -const currency = new Intl.NumberFormat(navigator.language || navigator.languages[0], { - style: 'currency', - currency: window.GiveCampaignOptions.currency, -}) - /** * @unreleased */ @@ -64,27 +50,7 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ return (
-
-
-
- {getGoalDescription(campaign.goalType)} - - {getValue(campaign.goalType, campaign?.goalStats?.actual)} - -
-
- {__('Our goal', 'give')} - {getValue(campaign.goalType, campaign.goal)} -
-
-
-
-
-
-
-
-
+
{hasResolved && campaign?.id && ( From 04cbdd1908ad68cc6ab536c99128d75da4b5b819 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 7 Feb 2025 10:39:29 +0100 Subject: [PATCH 20/28] refactor: block settings --- src/Campaigns/Blocks/CampaignGoal/index.tsx | 22 ++++++++------------- src/Campaigns/Blocks/blocks.ts | 9 ++++++++- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/index.tsx b/src/Campaigns/Blocks/CampaignGoal/index.tsx index fc3a47942a..034f5fc8a5 100644 --- a/src/Campaigns/Blocks/CampaignGoal/index.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/index.tsx @@ -1,21 +1,15 @@ -import metadata from './block.json'; -import Edit from './edit'; -import Icon from './icon'; -import initBlock from '../shared/utils/init-block'; - -const {name} = metadata; +import edit from './edit'; +import icon from './icon'; +import schema from './block.json'; /** * @unreleased */ -export const init = () => initBlock({ - name, - metadata, +export default { + schema, settings: { - edit: Edit, - save: () => null, - icon: , + icon, + edit } -}); - +}; diff --git a/src/Campaigns/Blocks/blocks.ts b/src/Campaigns/Blocks/blocks.ts index 089894d298..65f873165f 100644 --- a/src/Campaigns/Blocks/blocks.ts +++ b/src/Campaigns/Blocks/blocks.ts @@ -14,7 +14,14 @@ import campaignTitle from './CampaignTitle'; import campaignGoal from './CampaignGoal'; export const getAllBlocks = () => { - return [campaignCover, campaignDonateButton, campaignDonations, campaignDonors, campaignTitle, campaignGoal]; + return [ + campaignCover, + campaignDonateButton, + campaignDonations, + campaignDonors, + campaignTitle, + campaignGoal + ]; }; getAllBlocks().forEach((block) => { From 47542804c542296f65da1fd4039aea2479866f51 Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 10 Feb 2025 20:28:14 +0100 Subject: [PATCH 21/28] refactor: everything --- src/Campaigns/Blocks/CampaignGoal/app.tsx | 26 ++++++++++ .../Blocks/CampaignGoal/app/index.tsx | 34 +++++++++++++ .../Blocks/CampaignGoal/{ => app}/styles.scss | 0 src/Campaigns/Blocks/CampaignGoal/block.json | 2 + src/Campaigns/Blocks/CampaignGoal/edit.tsx | 26 ++-------- src/Campaigns/Blocks/CampaignGoal/render.php | 51 +------------------ src/Campaigns/Blocks/CampaignGoal/utils.ts | 29 +++++++++++ wordpress-scripts-webpack.config.js | 1 + 8 files changed, 97 insertions(+), 72 deletions(-) create mode 100644 src/Campaigns/Blocks/CampaignGoal/app.tsx create mode 100644 src/Campaigns/Blocks/CampaignGoal/app/index.tsx rename src/Campaigns/Blocks/CampaignGoal/{ => app}/styles.scss (100%) create mode 100644 src/Campaigns/Blocks/CampaignGoal/utils.ts diff --git a/src/Campaigns/Blocks/CampaignGoal/app.tsx b/src/Campaigns/Blocks/CampaignGoal/app.tsx new file mode 100644 index 0000000000..dbc5e8e636 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/app.tsx @@ -0,0 +1,26 @@ +import {render} from '@wordpress/element'; +import useCampaign from '../shared/hooks/useCampaign'; +import App from './app/index'; + +const BlockApp = ({campaignId}: { campaignId: number }) => { + const {campaign, hasResolved} = useCampaign(campaignId); + + if (!hasResolved || !campaignId) { + return null; + } + + return ; +} + +/** + * @unreleased + */ +const nodeList = document.querySelectorAll('.give-campaigns-goalBlock-container'); + +if (nodeList) { + const containers = Array.from(nodeList); + + containers.map((container: any) => { + return render(, container); + }); +} diff --git a/src/Campaigns/Blocks/CampaignGoal/app/index.tsx b/src/Campaigns/Blocks/CampaignGoal/app/index.tsx new file mode 100644 index 0000000000..70b1266c63 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/app/index.tsx @@ -0,0 +1,34 @@ +import {__} from '@wordpress/i18n'; +import {Campaign} from '@givewp/campaigns/admin/components/types'; +import {getGoalDescription, getGoalFormattedValue} from '../utils'; + +import './styles.scss'; + +export default ({campaign}: { campaign: Campaign }) => { + return ( +
+
+
+ {getGoalDescription(campaign.goalType)} + + {getGoalFormattedValue(campaign.goalType, campaign.goalStats.actual)} + +
+
+ {__('Our goal', 'give')} + + {getGoalFormattedValue(campaign.goalType, campaign.goal)} + +
+
+
+
+
+
+
+
+
+ ); +} diff --git a/src/Campaigns/Blocks/CampaignGoal/styles.scss b/src/Campaigns/Blocks/CampaignGoal/app/styles.scss similarity index 100% rename from src/Campaigns/Blocks/CampaignGoal/styles.scss rename to src/Campaigns/Blocks/CampaignGoal/app/styles.scss diff --git a/src/Campaigns/Blocks/CampaignGoal/block.json b/src/Campaigns/Blocks/CampaignGoal/block.json index d96d436b57..f3f9fc998b 100644 --- a/src/Campaigns/Blocks/CampaignGoal/block.json +++ b/src/Campaigns/Blocks/CampaignGoal/block.json @@ -19,5 +19,7 @@ }, "textdomain": "give", "editorScript": "file:../../../../build/campaignGoalBlock.js", + "viewScript": "file:../../../../build/campaignGoalBlockApp.js", + "style": "file:../../../../build/campaignGoalBlockApp.css", "render": "file:./render.php" } diff --git a/src/Campaigns/Blocks/CampaignGoal/edit.tsx b/src/Campaigns/Blocks/CampaignGoal/edit.tsx index ab5b615c08..ed200bbb18 100644 --- a/src/Campaigns/Blocks/CampaignGoal/edit.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/edit.tsx @@ -1,30 +1,12 @@ import {__} from '@wordpress/i18n'; import {useSelect} from '@wordpress/data'; import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; -import ServerSideRender from '@wordpress/server-side-render'; import {BlockEditProps} from '@wordpress/blocks'; import {ExternalLink, PanelBody, TextControl} from '@wordpress/components'; import useCampaign from '../shared/hooks/useCampaign'; +import CampaignGoalApp from './app/index'; import {CampaignSelector} from '../shared/components/CampaignSelector'; - -import './styles.scss'; - -const getGoalDescription = (goalType: string) => { - switch (goalType) { - case 'amount': - return __('Amount raised', 'give'); - case 'donations': - return __('Number of donations', 'give'); - case 'donors': - return __('Number of donors', 'give'); - case 'amountFromSubscriptions': - return __('Recurring amount raised', 'give'); - case 'subscriptions': - return __('Number of recurring donations', 'give'); - case 'donorsFromSubscriptions': - return __('Number of recurring donors', 'give'); - } -} +import {getGoalDescription} from './utils'; /** * @unreleased @@ -50,10 +32,10 @@ export default function Edit({attributes, setAttributes}: BlockEditProps<{ return (
- + - {hasResolved && campaign?.id && ( + {campaign?.id && ( diff --git a/src/Campaigns/Blocks/CampaignGoal/render.php b/src/Campaigns/Blocks/CampaignGoal/render.php index 2dba87832a..d17f9eae08 100644 --- a/src/Campaigns/Blocks/CampaignGoal/render.php +++ b/src/Campaigns/Blocks/CampaignGoal/render.php @@ -2,8 +2,6 @@ use Give\Campaigns\Models\Campaign; use Give\Campaigns\Repositories\CampaignRepository; -use Give\Campaigns\ValueObjects\CampaignGoalType; -use Give\Framework\Support\ValueObjects\Money; /** * @var array $attributes @@ -17,53 +15,6 @@ return; } -$stats = $campaign->getGoalStats(); - -$getGoalDescription = function(CampaignGoalType $goalType) { - $data = [ - 'amount' => __('Amount raised', 'give'), - 'donations' => __('Number of donations', 'give'), - 'donors' => __('Number of donors', 'give'), - 'amountFromSubscriptions' => __('Recurring amount raised', 'give'), - 'subscriptions' => __('Number of recurring donations', 'give'), - 'donorsFromSubscriptions' => __('Number of recurring donors', 'give'), - ]; - - return $data[$goalType->getvalue()]; -}; - -$getGoalFormattedValue = function($goalType, $value) { - switch ($goalType) { - case 'amount': - case 'amountFromSubscriptions': - $amount = Money::fromDecimal($value, give_get_currency()); - return $amount->formatToLocale(); - default: - return $value; - } -}; - ?> -
-
-
- goalType); ?> - - goalType, $stats['actual']); ?> - -
-
- - goalType, $campaign->goal); ?> -
-
-
-
-
-
-
-
-
- +
diff --git a/src/Campaigns/Blocks/CampaignGoal/utils.ts b/src/Campaigns/Blocks/CampaignGoal/utils.ts new file mode 100644 index 0000000000..0971ebefa2 --- /dev/null +++ b/src/Campaigns/Blocks/CampaignGoal/utils.ts @@ -0,0 +1,29 @@ +import {__} from '@wordpress/i18n'; + +export const getGoalDescription = (goalType: string) => { + switch (goalType) { + case 'amount': + return __('Amount raised', 'give'); + case 'donations': + return __('Number of donations', 'give'); + case 'donors': + return __('Number of donors', 'give'); + case 'amountFromSubscriptions': + return __('Recurring amount raised', 'give'); + case 'subscriptions': + return __('Number of recurring donations', 'give'); + case 'donorsFromSubscriptions': + return __('Number of recurring donors', 'give'); + } +} + + +export const getGoalFormattedValue = (goalType: string, value: number) => { + switch (goalType) { + case 'amount': + case 'amountFromSubscriptions': + + default: + return value; + } +} diff --git a/wordpress-scripts-webpack.config.js b/wordpress-scripts-webpack.config.js index 1e4e4c3b1a..dce7097b6a 100644 --- a/wordpress-scripts-webpack.config.js +++ b/wordpress-scripts-webpack.config.js @@ -66,6 +66,7 @@ module.exports = { campaignBlocks: srcPath('Campaigns/Blocks/blocks.ts'), campaignDonationsBlockApp: srcPath('Campaigns/Blocks/CampaignDonations/app.tsx'), campaignDonorsBlockApp: srcPath('Campaigns/Blocks/CampaignDonors/app.tsx'), + campaignGoalBlockApp: srcPath('Campaigns/Blocks/CampaignGoal/app.tsx'), }, }; From 0c409e512d1864371619e7e8e095288bb869446e Mon Sep 17 00:00:00 2001 From: alaca Date: Tue, 11 Feb 2025 07:58:22 +0100 Subject: [PATCH 22/28] refactor: remove leftover --- src/Campaigns/Blocks/CampaignGoal/block.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/block.json b/src/Campaigns/Blocks/CampaignGoal/block.json index f3f9fc998b..0145bccb61 100644 --- a/src/Campaigns/Blocks/CampaignGoal/block.json +++ b/src/Campaigns/Blocks/CampaignGoal/block.json @@ -18,7 +18,6 @@ } }, "textdomain": "give", - "editorScript": "file:../../../../build/campaignGoalBlock.js", "viewScript": "file:../../../../build/campaignGoalBlockApp.js", "style": "file:../../../../build/campaignGoalBlockApp.css", "render": "file:./render.php" From c88ad97830e12cc9ad6be16a5aecf6fb9e9e0b83 Mon Sep 17 00:00:00 2001 From: alaca Date: Tue, 11 Feb 2025 07:59:03 +0100 Subject: [PATCH 23/28] feature: format currency --- src/Campaigns/Blocks/CampaignGoal/utils.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Campaigns/Blocks/CampaignGoal/utils.ts b/src/Campaigns/Blocks/CampaignGoal/utils.ts index 0971ebefa2..b58572d787 100644 --- a/src/Campaigns/Blocks/CampaignGoal/utils.ts +++ b/src/Campaigns/Blocks/CampaignGoal/utils.ts @@ -22,6 +22,12 @@ export const getGoalFormattedValue = (goalType: string, value: number) => { switch (goalType) { case 'amount': case 'amountFromSubscriptions': + const currency = new Intl.NumberFormat(navigator.language, { + style: 'currency', + currency: window.GiveCampaignOptions.currency, + }) + + return currency.format(value); default: return value; From b1b67c0485dc351f5e00cfe84894ceb2a2eab9b1 Mon Sep 17 00:00:00 2001 From: alaca Date: Tue, 11 Feb 2025 08:00:59 +0100 Subject: [PATCH 24/28] refactor: load campaign options on both admin and frontend --- src/Campaigns/ServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Campaigns/ServiceProvider.php b/src/Campaigns/ServiceProvider.php index 212bed8a58..027d52997e 100644 --- a/src/Campaigns/ServiceProvider.php +++ b/src/Campaigns/ServiceProvider.php @@ -166,6 +166,6 @@ private function registerCampaignBlocks() */ private function loadCampaignOptions() { - Hooks::addAction('admin_init', CampaignOptions::class); + Hooks::addAction('init', CampaignOptions::class); } } From da65f7d87874209e69bc42e76f7bba1fcd7a6a22 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 14 Feb 2025 07:46:18 +0100 Subject: [PATCH 25/28] refactor: getCampaignDetailsWindowData --- .../Actions/LoadCampaignDetailsAssets.php | 8 ----- src/Campaigns/Actions/LoadCampaignOptions.php | 30 +++++++++++++++++++ src/Campaigns/Blocks/CampaignGoal/utils.ts | 10 +++---- src/Campaigns/CampaignsAdminPage.php | 2 +- src/Campaigns/ServiceProvider.php | 4 +-- .../common/getCampaignDetailsWindowData.ts | 9 ------ src/Campaigns/resources/admin/common/index.ts | 1 - .../Components/CampaignStats/index.tsx | 5 ++-- .../Components/GoalProgressChart/index.tsx | 5 ++-- .../CampaignDetailsPage/Tabs/Settings.tsx | 5 ++-- .../components/CampaignDetailsPage/index.tsx | 8 ++--- src/Campaigns/resources/types.ts | 17 ++++------- src/Campaigns/resources/utils.ts | 11 +++++++ 13 files changed, 64 insertions(+), 51 deletions(-) create mode 100644 src/Campaigns/Actions/LoadCampaignOptions.php delete mode 100644 src/Campaigns/resources/admin/common/getCampaignDetailsWindowData.ts delete mode 100644 src/Campaigns/resources/admin/common/index.ts diff --git a/src/Campaigns/Actions/LoadCampaignDetailsAssets.php b/src/Campaigns/Actions/LoadCampaignDetailsAssets.php index 9f70322c04..8e0ec03ed0 100644 --- a/src/Campaigns/Actions/LoadCampaignDetailsAssets.php +++ b/src/Campaigns/Actions/LoadCampaignDetailsAssets.php @@ -27,14 +27,6 @@ public function __invoke() true ); - wp_localize_script($handleName, 'GiveCampaignDetails', - [ - 'adminUrl' => admin_url(), - 'currency' => give_get_currency(), - 'isRecurringEnabled' => defined('GIVE_RECURRING_VERSION') ? GIVE_RECURRING_VERSION : null - ] - ); - wp_enqueue_script($handleName); wp_enqueue_style('givewp-design-system-foundation'); wp_enqueue_style( diff --git a/src/Campaigns/Actions/LoadCampaignOptions.php b/src/Campaigns/Actions/LoadCampaignOptions.php new file mode 100644 index 0000000000..680325871a --- /dev/null +++ b/src/Campaigns/Actions/LoadCampaignOptions.php @@ -0,0 +1,30 @@ + admin_url(), + 'currency' => give_get_currency(), + 'currencySymbol' => give_currency_symbol(), + 'isRecurringEnabled' => defined('GIVE_RECURRING_VERSION') + ? GIVE_RECURRING_VERSION + : null, + ] + ); + + wp_enqueue_script('give-campaign-options'); + } +} diff --git a/src/Campaigns/Blocks/CampaignGoal/utils.ts b/src/Campaigns/Blocks/CampaignGoal/utils.ts index b58572d787..8a81a38016 100644 --- a/src/Campaigns/Blocks/CampaignGoal/utils.ts +++ b/src/Campaigns/Blocks/CampaignGoal/utils.ts @@ -1,4 +1,6 @@ import {__} from '@wordpress/i18n'; +import {getCampaignOptionsWindowData, amountFormatter} from '@givewp/campaigns/utils'; + export const getGoalDescription = (goalType: string) => { switch (goalType) { @@ -22,12 +24,10 @@ export const getGoalFormattedValue = (goalType: string, value: number) => { switch (goalType) { case 'amount': case 'amountFromSubscriptions': - const currency = new Intl.NumberFormat(navigator.language, { - style: 'currency', - currency: window.GiveCampaignOptions.currency, - }) + const {currency} = getCampaignOptionsWindowData() + const currencyFormatter = amountFormatter(currency); - return currency.format(value); + return currencyFormatter.format(value); default: return value; diff --git a/src/Campaigns/CampaignsAdminPage.php b/src/Campaigns/CampaignsAdminPage.php index b4152cafc2..cf6be15b93 100644 --- a/src/Campaigns/CampaignsAdminPage.php +++ b/src/Campaigns/CampaignsAdminPage.php @@ -39,7 +39,7 @@ public function renderCampaignsPage() wp_die(__('Campaign not found', 'give'), 404); } - give(LoadCampaignDetailsAssets::class)($campaign); + give(LoadCampaignDetailsAssets::class)(); } else { give(LoadCampaignsListTableAssets::class)(); } diff --git a/src/Campaigns/ServiceProvider.php b/src/Campaigns/ServiceProvider.php index 6bf76e02c5..4c627756aa 100644 --- a/src/Campaigns/ServiceProvider.php +++ b/src/Campaigns/ServiceProvider.php @@ -3,11 +3,11 @@ namespace Give\Campaigns; use Give\Campaigns\Actions\AddCampaignFormFromRequest; -use Give\Campaigns\Actions\CampaignOptions; use Give\Campaigns\Actions\AssociateCampaignPageWithCampaign; use Give\Campaigns\Actions\CreateDefaultCampaignForm; use Give\Campaigns\Actions\DeleteCampaignPage; use Give\Campaigns\Actions\FormInheritsCampaignGoal; +use Give\Campaigns\Actions\LoadCampaignOptions; use Give\Campaigns\Migrations\Donations\AddCampaignId as DonationsAddCampaignId; use Give\Campaigns\Migrations\MigrateFormsToCampaignForms; use Give\Campaigns\Migrations\P2P\SetCampaignType; @@ -168,6 +168,6 @@ private function registerCampaignBlocks() */ private function loadCampaignOptions() { - Hooks::addAction('init', CampaignOptions::class); + Hooks::addAction('init', LoadCampaignOptions::class); } } diff --git a/src/Campaigns/resources/admin/common/getCampaignDetailsWindowData.ts b/src/Campaigns/resources/admin/common/getCampaignDetailsWindowData.ts deleted file mode 100644 index 6de3dc4aed..0000000000 --- a/src/Campaigns/resources/admin/common/getCampaignDetailsWindowData.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type {GiveCampaignDetails} from '@givewp/campaigns/admin/components/CampaignDetailsPage/types'; - -declare const window: { - GiveCampaignDetails: GiveCampaignDetails; -} & Window; - -export default function getCampaignDetailsWindowData(): GiveCampaignDetails { - return window.GiveCampaignDetails; -} diff --git a/src/Campaigns/resources/admin/common/index.ts b/src/Campaigns/resources/admin/common/index.ts deleted file mode 100644 index 6e1ea7e07f..0000000000 --- a/src/Campaigns/resources/admin/common/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {default as getCampaignDetailsWindowData} from './getCampaignDetailsWindowData'; diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx index fc1d8c620d..101915be04 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/CampaignStats/index.tsx @@ -7,14 +7,13 @@ import {addQueryArgs} from '@wordpress/url'; import HeaderText from '../HeaderText'; import HeaderSubText from '../HeaderSubText'; import DefaultFormWidget from "../DefaultForm"; -import {useCampaignEntityRecord, amountFormatter} from '@givewp/campaigns/utils'; -import {getCampaignDetailsWindowData} from '@givewp/campaigns/admin/common'; +import {useCampaignEntityRecord, amountFormatter, getCampaignOptionsWindowData} from '@givewp/campaigns/utils'; import styles from "./styles.module.scss" const campaignId = new URLSearchParams(window.location.search).get('id'); -const {currency} = getCampaignDetailsWindowData(); +const {currency} = getCampaignOptionsWindowData(); const currencyFormatter = amountFormatter(currency); const pluck = (array: any[], property: string) => array.map(element => element[property]) diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/GoalProgressChart/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/GoalProgressChart/index.tsx index cbe04bba06..cd4d479788 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/GoalProgressChart/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/GoalProgressChart/index.tsx @@ -3,10 +3,9 @@ import Chart from "react-apexcharts"; import React from "react"; import styles from "./styles.module.scss" -import {getCampaignDetailsWindowData} from '@givewp/campaigns/admin/common'; -import {amountFormatter} from '@givewp/campaigns/utils'; +import {getCampaignOptionsWindowData, amountFormatter} from '@givewp/campaigns/utils'; -const {currency} = getCampaignDetailsWindowData(); +const {currency} = getCampaignOptionsWindowData(); const currencyFormatter = amountFormatter(currency); const GoalProgressChart = ({ value, goal }) => { diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx index c7299eeb26..6d45cc4134 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Tabs/Settings.tsx @@ -5,11 +5,10 @@ import styles from '../CampaignDetailsPage.module.scss'; import {ToggleControl} from '@wordpress/components'; import campaignPageImage from './images/campaign-page.svg'; import {WarningIcon} from '@givewp/campaigns/admin/components/Icons'; -import {getCampaignDetailsWindowData} from '@givewp/campaigns/admin/common'; -import {amountFormatter} from '@givewp/campaigns/utils'; +import {getCampaignOptionsWindowData, amountFormatter} from '@givewp/campaigns/utils'; import ColorControl from '@givewp/campaigns/admin/components/CampaignDetailsPage/Components/ColorControl'; -const {currency, isRecurringEnabled} = getCampaignDetailsWindowData(); +const {currency, isRecurringEnabled} = getCampaignOptionsWindowData(); const currencyFormatter = amountFormatter(currency); /** diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx index 6806ea2c63..af082b7039 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx @@ -5,7 +5,7 @@ import {useEntityRecord} from '@wordpress/core-data'; import apiFetch from '@wordpress/api-fetch'; import {JSONSchemaType} from 'ajv'; import {ajvResolver} from '@hookform/resolvers/ajv'; -import {GiveCampaignDetails} from './types'; +import {GiveCampaignOptions} from '@givewp/campaigns/types'; import {Campaign} from '../types'; import {FormProvider, SubmitHandler, useForm} from 'react-hook-form'; import {Spinner as GiveSpinner} from '@givewp/components'; @@ -21,7 +21,7 @@ import {useCampaignEntityRecord} from '@givewp/campaigns/utils'; import styles from './CampaignDetailsPage.module.scss'; declare const window: { - GiveCampaignDetails: GiveCampaignDetails; + GiveCampaignOptions: GiveCampaignOptions; } & Window; interface Show { @@ -203,7 +203,7 @@ export default function CampaignsDetailsPage({campaignId}) {
{__('Campaigns', 'give')} @@ -220,7 +220,7 @@ export default function CampaignsDetailsPage({campaignId}) { {enableCampaignPage && ( diff --git a/src/Campaigns/resources/types.ts b/src/Campaigns/resources/types.ts index 8d74bf99a4..61a2e042ff 100644 --- a/src/Campaigns/resources/types.ts +++ b/src/Campaigns/resources/types.ts @@ -1,5 +1,3 @@ -import {GiveCampaignDetails} from "@givewp/campaigns/admin/components/CampaignDetailsPage/types"; - export type Notification = { id: string; content: string | JSX.Element | Function; @@ -24,14 +22,9 @@ declare module "@wordpress/data" { }; } -declare global { - interface Window { - GiveCampaignOptions: { - currency: string; - currencySymbol: string; - isRecurringEnabled: boolean; - }; - } +export type GiveCampaignOptions = { + adminUrl: string; + currency: string; + isRecurringEnabled: boolean; + defaultForm: string; } - - diff --git a/src/Campaigns/resources/utils.ts b/src/Campaigns/resources/utils.ts index d69909c062..14e93d41de 100644 --- a/src/Campaigns/resources/utils.ts +++ b/src/Campaigns/resources/utils.ts @@ -1,5 +1,10 @@ import {useEntityRecord} from '@wordpress/core-data'; import {Campaign} from '@givewp/campaigns/admin/components/types'; +import type {GiveCampaignOptions} from '@givewp/campaigns/types'; + +declare const window: { + GiveCampaignOptions: GiveCampaignOptions; +} & Window; /** * @unreleased @@ -22,6 +27,12 @@ export function useCampaignEntityRecord(campaignId?: number) { return {campaign, hasResolved, save, edit}; } +/** + * @unreleased + */ +export function getCampaignOptionsWindowData(): GiveCampaignOptions { + return window.GiveCampaignOptions; +} /** * @unreleased From eca68539d45ba2ee4d6198b8e1a9002d2f8730f6 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 14 Feb 2025 07:51:39 +0100 Subject: [PATCH 26/28] refactor: remove leftover --- src/Campaigns/Actions/CampaignOptions.php | 29 ----------------------- 1 file changed, 29 deletions(-) delete mode 100644 src/Campaigns/Actions/CampaignOptions.php diff --git a/src/Campaigns/Actions/CampaignOptions.php b/src/Campaigns/Actions/CampaignOptions.php deleted file mode 100644 index 760986c506..0000000000 --- a/src/Campaigns/Actions/CampaignOptions.php +++ /dev/null @@ -1,29 +0,0 @@ - give_get_currency(), - 'currencySymbol' => give_currency_symbol(), - 'isRecurringEnabled' => defined('GIVE_RECURRING_VERSION') - ? GIVE_RECURRING_VERSION - : null, - ] - ); - - wp_enqueue_script('give-campaign-options'); - } -} From b85d99badf275fb0d12385d03b53beb46f696f66 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 14 Feb 2025 06:56:48 +0100 Subject: [PATCH 27/28] refactor: use data attribute instead of class --- src/Campaigns/Blocks/CampaignGoal/app.tsx | 2 +- src/Campaigns/Blocks/CampaignGoal/render.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/app.tsx b/src/Campaigns/Blocks/CampaignGoal/app.tsx index dbc5e8e636..968b9b5a6b 100644 --- a/src/Campaigns/Blocks/CampaignGoal/app.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/app.tsx @@ -15,7 +15,7 @@ const BlockApp = ({campaignId}: { campaignId: number }) => { /** * @unreleased */ -const nodeList = document.querySelectorAll('.give-campaigns-goalBlock-container'); +const nodeList = document.querySelectorAll('[data-givewp-campaign-goal]'); if (nodeList) { const containers = Array.from(nodeList); diff --git a/src/Campaigns/Blocks/CampaignGoal/render.php b/src/Campaigns/Blocks/CampaignGoal/render.php index d17f9eae08..7b507bdf08 100644 --- a/src/Campaigns/Blocks/CampaignGoal/render.php +++ b/src/Campaigns/Blocks/CampaignGoal/render.php @@ -17,4 +17,4 @@ ?> -
+
From 376eba218ed324e6623d439bfda1034404b20f21 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 14 Feb 2025 06:56:27 +0100 Subject: [PATCH 28/28] refactor: use givewp instead of give --- src/Campaigns/Blocks/CampaignGoal/app/index.tsx | 14 +++++++------- src/Campaigns/Blocks/CampaignGoal/app/styles.scss | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Campaigns/Blocks/CampaignGoal/app/index.tsx b/src/Campaigns/Blocks/CampaignGoal/app/index.tsx index 70b1266c63..37fa61bdcd 100644 --- a/src/Campaigns/Blocks/CampaignGoal/app/index.tsx +++ b/src/Campaigns/Blocks/CampaignGoal/app/index.tsx @@ -6,25 +6,25 @@ import './styles.scss'; export default ({campaign}: { campaign: Campaign }) => { return ( -
-
-
+
+
+
{getGoalDescription(campaign.goalType)} {getGoalFormattedValue(campaign.goalType, campaign.goalStats.actual)}
-
+
{__('Our goal', 'give')} {getGoalFormattedValue(campaign.goalType, campaign.goal)}
-
-
+
+
diff --git a/src/Campaigns/Blocks/CampaignGoal/app/styles.scss b/src/Campaigns/Blocks/CampaignGoal/app/styles.scss index c7ccc61bb1..b98f4b8b2f 100644 --- a/src/Campaigns/Blocks/CampaignGoal/app/styles.scss +++ b/src/Campaigns/Blocks/CampaignGoal/app/styles.scss @@ -1,4 +1,4 @@ -.give-campaign-goal { +.givewp-campaign-goal { display: flex; flex-direction: column; gap: 0.5rem;