-
Notifications
You must be signed in to change notification settings - Fork 194
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: Add Campaign Donors block (#7700)
- Loading branch information
1 parent
d149099
commit 3056b51
Showing
24 changed files
with
1,018 additions
and
316 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,16 @@ | ||
import metadata from './block.json'; | ||
import schema from './block.json'; | ||
import Edit from './edit'; | ||
import initBlock from '../shared/utils/init-block'; | ||
import {GalleryIcon} from './Icon'; | ||
|
||
const {name} = metadata; | ||
|
||
export {metadata, name}; | ||
export const settings = { | ||
edit: Edit, | ||
/** | ||
* @unreleased | ||
*/ | ||
const settings = { | ||
icon: <GalleryIcon />, | ||
edit: Edit, | ||
}; | ||
|
||
export const init = () => initBlock({name, metadata, settings}); | ||
export default { | ||
schema, | ||
settings, | ||
}; |
66 changes: 66 additions & 0 deletions
66
src/Campaigns/Blocks/CampaignDonors/CampaignDonorsBlockViewModel.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
|
||
namespace Give\Campaigns\Blocks\CampaignDonors; | ||
|
||
use Give\Campaigns\Models\Campaign; | ||
use Give\Framework\Support\ValueObjects\Money; | ||
use Give\Framework\Views\View; | ||
|
||
/** | ||
* @unreleased | ||
*/ | ||
class CampaignDonorsBlockViewModel | ||
{ | ||
/** | ||
* @var Campaign $campaign | ||
*/ | ||
private $campaign; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private $donors; | ||
|
||
/** | ||
* @var array $attributes | ||
*/ | ||
private $attributes; | ||
|
||
/** | ||
* @unreleased | ||
*/ | ||
public function __construct(Campaign $campaign, array $donors, array $attributes) | ||
{ | ||
$this->attributes = $attributes; | ||
$this->campaign = $campaign; | ||
$this->donors = $donors; | ||
} | ||
|
||
/** | ||
* @unreleased | ||
*/ | ||
public function render(): void | ||
{ | ||
View::render('Campaigns/Blocks/CampaignDonors.render', [ | ||
'campaign' => $this->campaign, | ||
'donors' => $this->formatDonorsData($this->donors), | ||
'attributes' => $this->attributes, | ||
]); | ||
} | ||
|
||
|
||
/** | ||
* @unreleased | ||
*/ | ||
private function formatDonorsData(array $donors): array | ||
{ | ||
return array_map(static function ($entry) { | ||
if (isset($entry->date)) { | ||
$entry->date = human_time_diff(strtotime($entry->date)); | ||
} | ||
$entry->amount = Money::fromDecimal($entry->amount, give_get_currency()); | ||
|
||
return $entry; | ||
}, $donors); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import './styles.scss'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{ | ||
"$schema": "https://schemas.wp.org/trunk/block.json", | ||
"apiVersion": 3, | ||
"name": "givewp/campaign-donors", | ||
"version": "1.0.0", | ||
"title": "Campaign Donors", | ||
"category": "give", | ||
"description": "Display all the donors associated with a campaign.", | ||
"attributes": { | ||
"campaignId": { | ||
"type": "integer" | ||
}, | ||
"showAnonymous": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"showCompanyName": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"showAvatar": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"showButton": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"donateButtonText": { | ||
"type": "string", | ||
"default": "Join the list" | ||
}, | ||
"sortBy": { | ||
"type": "string", | ||
"default": "top-donors" | ||
}, | ||
"donorsPerPage": { | ||
"type": "number", | ||
"default": 5 | ||
}, | ||
"loadMoreButtonText": { | ||
"type": "string", | ||
"default": "Load more" | ||
} | ||
}, | ||
"supports": { | ||
"className": true | ||
}, | ||
"textdomain": "give", | ||
"render": "file:./render.php", | ||
"style": "file:../../../../build/campaignDonorsBlockApp.css" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import {InspectorControls, useBlockProps} from '@wordpress/block-editor'; | ||
import {BlockEditProps} from '@wordpress/blocks'; | ||
import { | ||
__experimentalNumberControl as NumberControl, | ||
PanelBody, | ||
SelectControl, | ||
TextControl, | ||
ToggleControl, | ||
} from '@wordpress/components'; | ||
import {__} from '@wordpress/i18n'; | ||
import ServerSideRender from '@wordpress/server-side-render'; | ||
import {CampaignSelector} from '../shared/components/CampaignSelector'; | ||
import useCampaign from '../shared/hooks/useCampaign'; | ||
|
||
export default function Edit({ | ||
attributes, | ||
setAttributes, | ||
}: BlockEditProps<{ | ||
campaignId: number; | ||
showAnonymous: boolean; | ||
showCompanyName: boolean; | ||
showAvatar: boolean; | ||
showButton: boolean; | ||
donateButtonText: string; | ||
sortBy: string; | ||
donorsPerPage: number; | ||
loadMoreButtonText: string; | ||
}>) { | ||
const blockProps = useBlockProps(); | ||
const {campaign, hasResolved} = useCampaign(attributes.campaignId); | ||
|
||
const { | ||
showAnonymous, | ||
showCompanyName, | ||
showAvatar, | ||
showButton, | ||
donateButtonText, | ||
sortBy, | ||
donorsPerPage, | ||
loadMoreButtonText, | ||
} = attributes; | ||
|
||
return ( | ||
<div {...blockProps}> | ||
<CampaignSelector attributes={attributes} setAttributes={setAttributes}> | ||
<ServerSideRender block="givewp/campaign-donors" attributes={attributes} /> | ||
</CampaignSelector> | ||
|
||
{hasResolved && campaign?.id && ( | ||
<InspectorControls> | ||
<PanelBody title={__('Display Elements', 'give')} initialOpen={true}> | ||
<ToggleControl | ||
label={__('Show anonymous', 'give')} | ||
checked={showAnonymous} | ||
onChange={(value) => setAttributes({showAnonymous: value})} | ||
/> | ||
<ToggleControl | ||
label={__('Show company name', 'give')} | ||
checked={showCompanyName} | ||
onChange={(value) => setAttributes({showCompanyName: value})} | ||
/> | ||
<ToggleControl | ||
label={__('Show avatar', 'give')} | ||
checked={showAvatar} | ||
onChange={(value) => setAttributes({showAvatar: value})} | ||
/> | ||
<ToggleControl | ||
label={__('Show button', 'give')} | ||
checked={showButton} | ||
onChange={(value) => setAttributes({showButton: value})} | ||
/> | ||
<TextControl | ||
label={__('Donate Button', 'give')} | ||
value={donateButtonText} | ||
onChange={(value) => setAttributes({donateButtonText: value})} | ||
help={__('This shows on the header', 'give')} | ||
/> | ||
</PanelBody> | ||
|
||
<PanelBody title={__('Settings', 'give')} initialOpen={true}> | ||
<SelectControl | ||
label={__('Sort by', 'give')} | ||
value={sortBy} | ||
options={[ | ||
{label: __('Top Donors', 'give'), value: 'top-donors'}, | ||
{label: __('Recent Donors', 'give'), value: 'recent-donors'}, | ||
]} | ||
onChange={(value) => setAttributes({sortBy: value})} | ||
help={__('The order donors are displayed in.', 'give')} | ||
/> | ||
{/* TODO: Revert the label and help text back to what are in the designs once the backend for pagination is ready */} | ||
<NumberControl | ||
label={__('Limit', 'give')} | ||
value={donorsPerPage} | ||
min={1} | ||
max={100} | ||
onChange={(value) => setAttributes({donorsPerPage: parseInt(value)})} | ||
help={__('The maximum number of donors to display.', 'give')} | ||
/> | ||
{/* TODO: Revert the field back once the backend for pagination is ready | ||
<TextControl | ||
label={__('Load More Button', 'give')} | ||
value={loadMoreButtonText} | ||
onChange={(value) => setAttributes({loadMoreButtonText: value})} | ||
/> | ||
*/} | ||
</PanelBody> | ||
</InspectorControls> | ||
)} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {paragraph as icon} from '@wordpress/icons'; | ||
import schema from './block.json'; | ||
import Edit from './edit'; | ||
|
||
/** | ||
* @unreleased | ||
*/ | ||
const settings = { | ||
icon, | ||
edit: Edit, | ||
}; | ||
|
||
export default { | ||
schema, | ||
settings, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
namespace Give\Campaigns\Blocks\CampaignDonors; | ||
|
||
use DateTime; | ||
use Give\Campaigns\CampaignDonationQuery; | ||
use Give\Campaigns\Models\Campaign; | ||
use Give\Campaigns\Repositories\CampaignRepository; | ||
use Give\Donations\ValueObjects\DonationMetaKeys; | ||
|
||
/** | ||
* @unreleased | ||
* | ||
* @var array $attributes | ||
*/ | ||
|
||
if ( ! isset($attributes['campaignId'])) { | ||
return; | ||
} | ||
|
||
/** @var Campaign $campaign */ | ||
$campaign = give(CampaignRepository::class)->getById($attributes['campaignId']); | ||
|
||
if ( ! $campaign) { | ||
return; | ||
} | ||
|
||
$sortBy = $attributes['sortBy'] ?? 'top-donors'; | ||
$query = (new CampaignDonationQuery($campaign)) | ||
->joinDonationMeta(DonationMetaKeys::DONOR_ID, 'donorIdMeta') | ||
->joinDonationMeta(DonationMetaKeys::AMOUNT, 'amountMeta') | ||
->leftJoin('give_donors', 'donorIdMeta.meta_value', 'donors.id', 'donors') | ||
->limit($attributes['donorsPerPage'] ?? 5); | ||
|
||
if ($sortBy === 'top-donors') { | ||
$query->select( | ||
'donorIdMeta.meta_value as id', | ||
'SUM(amountMeta.meta_value) as amount', | ||
'donors.name as name' | ||
) | ||
->groupBy('donorIdMeta.meta_value') | ||
->orderBy('amount', 'DESC'); | ||
} else { | ||
$query->joinDonationMeta(DonationMetaKeys::COMPANY, 'companyMeta') | ||
->select( | ||
'donation.ID as donationID', | ||
'donorIdMeta.meta_value as id', | ||
'companyMeta.meta_value as company', | ||
'donation.post_date as date', | ||
'amountMeta.meta_value as amount', | ||
'donors.name as name' | ||
) | ||
->orderBy('donation.ID', 'DESC'); | ||
} | ||
|
||
if ( ! $attributes['showAnonymous']) { | ||
$query->joinDonationMeta(DonationMetaKeys::ANONYMOUS, 'anonymousMeta') | ||
->where('anonymousMeta.meta_value', '0'); | ||
} | ||
|
||
(new CampaignDonorsBlockViewModel($campaign, $query->getAll(), $attributes))->render(); |
7 changes: 7 additions & 0 deletions
7
src/Campaigns/Blocks/CampaignDonors/resources/icons/empty-state.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions
6
src/Campaigns/Blocks/CampaignDonors/resources/icons/ribbon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.