Skip to content

Commit

Permalink
Merge branch 'fix/campaign-page-back-button-GIVE-2142' of github.com:…
Browse files Browse the repository at this point in the history
…impress-org/give into fix/campaign-page-back-button-GIVE-2142
  • Loading branch information
kjohnson committed Feb 21, 2025
2 parents 696010d + 7724d66 commit ef36b0b
Show file tree
Hide file tree
Showing 49 changed files with 977 additions and 97 deletions.
25 changes: 25 additions & 0 deletions src/Campaigns/Actions/AssociateCampaignPageWithCampaign.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Give\Campaigns\Actions;

use Exception;
use Give\Campaigns\Models\Campaign;
use Give\Campaigns\Models\CampaignPage;

/**
* @unreleased
*/
class AssociateCampaignPageWithCampaign
{
/**
* @throws Exception
*/
public function __invoke(CampaignPage $campaignPage){
$campaign = Campaign::find($campaignPage->campaignId);

if ($campaign) {
$campaign->pageId = $campaignPage->id;
$campaign->save();
}
}
}
1 change: 1 addition & 0 deletions src/Campaigns/Actions/ConvertQueryDataToCampaign.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public function __invoke(object $queryObject): Campaign
{
return new Campaign([
'id' => (int)$queryObject->id,
'pageId' => (int)$queryObject->pageId,
'defaultFormId' => (int)$queryObject->defaultFormId,
'type' => new CampaignType($queryObject->type),
'enableCampaignPage' => (bool)$queryObject->enableCampaignPage,
Expand Down
8 changes: 0 additions & 8 deletions src/Campaigns/Actions/LoadCampaignDetailsAssets.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
30 changes: 30 additions & 0 deletions src/Campaigns/Actions/LoadCampaignOptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Give\Campaigns\Actions;

/**
* The purpose of this action is to have a centralized place for localizing options used on many different places
* by campaign scripts (list tables, blocks, etc.)
*
* @unreleased
*/
class LoadCampaignOptions
{
public function __invoke()
{
wp_register_script('give-campaign-options', false);

wp_localize_script('give-campaign-options', 'GiveCampaignOptions',
[
'adminUrl' => 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');
}
}
1 change: 0 additions & 1 deletion src/Campaigns/Actions/RegisterCampaignBlocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ private function enqueueAdminBlocksAssets(): void
wp_enqueue_style(
$handleName,
GIVE_PLUGIN_URL . 'build/campaignBlocks.css',
/** @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-components/#usage */
['wp-components'],
$scriptAsset['version']
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

$blockInlineStyles = sprintf(
'--givewp-primary-color: %s; --givewp-secondary-color: %s;',
esc_attr('#0b72d9'),
esc_attr('#27ae60')
esc_attr($campaign->primaryColor ?? '#0b72d9'),
esc_attr($campaign->secondaryColor ?? '#27ae60')
);
?>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

$blockInlineStyles = sprintf(
'--givewp-primary-color: %s; --givewp-secondary-color: %s;',
esc_attr('#0b72d9'),
esc_attr('#27ae60')
esc_attr($campaign->primaryColor ?? '#0b72d9'),
esc_attr($campaign->secondaryColor ?? '#27ae60')
);
?>
<div
Expand Down
26 changes: 26 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/app.tsx
Original file line number Diff line number Diff line change
@@ -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 <App campaign={campaign} />;
}

/**
* @unreleased
*/
const nodeList = document.querySelectorAll('[data-givewp-campaign-goal]');

if (nodeList) {
const containers = Array.from(nodeList);

containers.map((container: any) => {
return render(<BlockApp campaignId={container.dataset?.id} />, container);
});
}
34 changes: 34 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/app/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="givewp-campaign-goal">
<div className="givewp-campaign-goal__container">
<div className="givewp-campaign-goal__container-item">
<span>{getGoalDescription(campaign.goalType)}</span>
<strong>
{getGoalFormattedValue(campaign.goalType, campaign.goalStats.actual)}
</strong>
</div>
<div className="givewp-campaign-goal__container-item">
<span>{__('Our goal', 'give')}</span>
<strong>
{getGoalFormattedValue(campaign.goalType, campaign.goal)}
</strong>
</div>
</div>
<div className="givewp-campaign-goal__progress-bar">
<div className="givewp-campaign-goal__progress-bar-container">
<div
className="givewp-campaign-goal__progress-bar-progress"
style={{width: `${campaign.goalStats.percentage}%`}}>
</div>
</div>
</div>
</div>
);
}
51 changes: 51 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/app/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.givewp-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;
}
}
}
24 changes: 24 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$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"
}
},
"textdomain": "give",
"viewScript": "file:../../../../build/campaignGoalBlockApp.js",
"style": "file:../../../../build/campaignGoalBlockApp.css",
"render": "file:./render.php"
}
53 changes: 53 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/edit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {__} from '@wordpress/i18n';
import {useSelect} from '@wordpress/data';
import {InspectorControls, useBlockProps} from '@wordpress/block-editor';
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 {getGoalDescription} from './utils';

/**
* @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;
}

return (
<div {...blockProps}>
<CampaignSelector attributes={attributes} setAttributes={setAttributes}>
<CampaignGoalApp campaign={campaign} />
</CampaignSelector>

{campaign?.id && (
<InspectorControls>
<PanelBody title={__('Settings', 'give')} initialOpen={true}>
<TextControl value={getGoalDescription(campaign.goalType)} onChange={null} disabled={true} />
<ExternalLink
href={`${adminBaseUrl}&id=${attributes.campaignId}&tab=settings#campaign-goal`}
title={__('Edit campaign goal settings', 'give')}
>
{__('Edit campaign goal settings', 'give')}
</ExternalLink>
</PanelBody>
</InspectorControls>
)}
</div>
);
}
11 changes: 11 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/icon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default () => (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd"
d="M19.16 1.013a1 1 0 0 1 .734.54l.851 1.702 1.702.85a1 1 0 0 1 .26 1.602l-3 3A1 1 0 0 1 19 9h-2.586l-3.707 3.707a1 1 0 0 1-1.414-1.414L15 7.586V5a1 1 0 0 1 .293-.707l3-3a1 1 0 0 1 .867-.28z"
fill="#000" />
<path
d="M3 12a9 9 0 0 1 9-9 1 1 0 1 0 0-2C5.925 1 1 5.925 1 12s4.925 11 11 11 11-4.925 11-11a1 1 0 1 0-2 0 9 9 0 1 1-18 0z"
fill="#000" />
<path d="M8 12a4 4 0 0 1 4-4 1 1 0 1 0 0-2 6 6 0 1 0 6 6 1 1 0 1 0-2 0 4 4 0 0 1-8 0z" fill="#000" />
</svg>
)
15 changes: 15 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import edit from './edit';
import icon from './icon';
import schema from './block.json';

/**
* @unreleased
*/
export default {
schema,
settings: {
icon,
edit
}
};

20 changes: 20 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/render.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

use Give\Campaigns\Models\Campaign;
use Give\Campaigns\Repositories\CampaignRepository;

/**
* @var array $attributes
* @var Campaign $campaign
*/

if (
! isset($attributes['campaignId'])
|| ! $campaign = give(CampaignRepository::class)->getById($attributes['campaignId'])
) {
return;
}

?>

<div data-givewp-campaign-goal data-id="<?= $campaign->id; ?>"></div>
35 changes: 35 additions & 0 deletions src/Campaigns/Blocks/CampaignGoal/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {__} from '@wordpress/i18n';
import {getCampaignOptionsWindowData, amountFormatter} from '@givewp/campaigns/utils';


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':
const {currency} = getCampaignOptionsWindowData()
const currencyFormatter = amountFormatter(currency);

return currencyFormatter.format(value);

default:
return value;
}
}
Loading

0 comments on commit ef36b0b

Please sign in to comment.