Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: add campaign goal types for recurring donations #7567

Merged
2 changes: 1 addition & 1 deletion src/Campaigns/Migrations/Tables/CreateCampaignsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function run()
primary_color VARCHAR(7) NOT NULL,
secondary_color VARCHAR(7) NOT NULL,
campaign_goal INT UNSIGNED NOT NULL,
goal_type VARCHAR(12) NOT NULL DEFAULT 'amount',
goal_type VARCHAR(24) NOT NULL DEFAULT 'amount',
status VARCHAR(12) NOT NULL,
start_date DATETIME NULL,
end_date DATETIME NULL,
Expand Down
76 changes: 73 additions & 3 deletions src/Campaigns/Routes/RegisterCampaignRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,14 @@ public function getSchema(): array
'errorMessage' => esc_html__('Must be a number', 'give'),
],
'goalType' => [
'enum' => ['amount', 'donation', 'donors'],
'enum' => [
'amount',
'donations',
'donors',
'amountFromSubscriptions',
'subscriptions',
'donorsFromSubscriptions',
],
'description' => esc_html__('Campaign goal type', 'give'),
],
],
Expand All @@ -247,6 +254,27 @@ public function getSchema(): array
],
],
],
[
'if' => [
'properties' => [
'goalType' => [
'const' => 'donations',
],
],
],
'then' => [
'properties' => [
'goal' => [
'minimum' => 1,
],
],
'errorMessage' => [
'properties' => [
'goal' => esc_html__('Number of donations must be greater than 0', 'give'),
],
],
],
],
[
'if' => [
'properties' => [
Expand All @@ -272,7 +300,7 @@ public function getSchema(): array
'if' => [
'properties' => [
'goalType' => [
'const' => 'donation',
'const' => 'amountFromSubscriptions',
],
],
],
Expand All @@ -284,7 +312,49 @@ public function getSchema(): array
],
'errorMessage' => [
'properties' => [
'goal' => esc_html__('Number of donations must be greater than 0', 'give'),
'goal' => esc_html__('Goal recurring amount must be greater than 0', 'give'),
],
],
],
],
[
'if' => [
'properties' => [
'goalType' => [
'const' => 'subscriptions',
],
],
],
'then' => [
'properties' => [
'goal' => [
'minimum' => 1,
],
],
'errorMessage' => [
'properties' => [
'goal' => esc_html__('Number of recurring donations must be greater than 0', 'give'),
],
],
],
],
[
'if' => [
'properties' => [
'goalType' => [
'const' => 'donorsFromSubscriptions',
],
],
],
'then' => [
'properties' => [
'goal' => [
'minimum' => 1,
],
],
'errorMessage' => [
'properties' => [
'goal' => esc_html__('Number of recurring donors must be greater than 0', 'give'),
],
],
],
Expand Down
19 changes: 14 additions & 5 deletions src/Campaigns/ValueObjects/CampaignGoalType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,25 @@
/**
* @unreleased
*
* @method static CampaignType AMOUNT()
* @method static CampaignType DONATION()
* @method static CampaignType DONORS()
* @method static CampaignGoalType AMOUNT()
* @method static CampaignGoalType DONATIONS()
* @method static CampaignGoalType DONORS()
* @method static CampaignGoalType AMOUNT_FROM_SUBSCRIPTIONS()
* @method static CampaignGoalType SUBSCRIPTIONS()
* @method static CampaignGoalType DONORS_FROM_SUBSCRIPTIONS()
* @method bool isAmount()
* @method bool isDonation()
* @method bool isDonations()
* @method bool isDonors()
* @method bool isAmountFromSubscriptions()
* @method bool isSubscriptions()
* @method bool isDonorsFromSubscriptions()
*/
class CampaignGoalType extends Enum
{
const AMOUNT = 'amount';
const DONATION = 'donation';
const DONATIONS = 'donations';
const DONORS = 'donors';
const AMOUNT_FROM_SUBSCRIPTIONS = 'amountFromSubscriptions';
const SUBSCRIPTIONS = 'subscriptions';
const DONORS_FROM_SUBSCRIPTIONS = 'donorsFromSubscriptions';
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,25 @@ export default () => {
switch (type) {
case 'amount':
return __(
'Your goal progress is measured by the total amount raised based on the goal amount. (e.g. $500 of $1,000 raised)',
'Your goal progress is measured by the total amount of funds raised eg. $500 of $1,000 raised.',
'give'
);
case 'donation':
return __('The total number of donations made for the campaign', 'give');
case 'donations':
return __('Your goal progress is measured by the number of donations. eg. 1 of 5 donations.', 'give');
case 'donors':
return __('The total number of unique donors who have donated to the campaign', 'give');
return __(
'Your goal progress is measured by the number of donors. eg. 10 of 50 donors have given.',
'give'
);
case 'amountFromSubscriptions':
return __('Only the first donation amount of a recurring donation is counted toward the goal.', 'give');
case 'subscriptions':
return __('Only the first donation of a recurring donation is counted toward the goal.', 'give');
case 'donorsFromSubscriptions':
return __(
'Only the donors that subscribed to a recurring donation are counted toward the goal.',
'give'
);
default:
return null;
}
Expand Down Expand Up @@ -111,8 +123,11 @@ export default () => {

<select {...register('goalType')}>
<option value="amount">{__('Amount raised', 'give')}</option>
<option value="donation">{__('Number of Donations', 'give')}</option>
<option value="donors">{__('Number of Donors', 'give')}</option>
<option value="donations">{__('Number of donations', 'give')}</option>
<option value="donors">{__('Number of donors', 'give')}</option>
<option value="amountFromSubscriptions">{__('Recurring amount raised', 'give')}</option>
glaubersilva marked this conversation as resolved.
Show resolved Hide resolved
<option value="subscriptions">{__('Number of recurring donations', 'give')}</option>
<option value="donorsFromSubscriptions">{__('Number of recurring donors', 'give')}</option>
</select>

<div className={styles.sectionFieldDescription}>{goalDescription(goalType)}</div>
Expand All @@ -125,7 +140,7 @@ export default () => {
{__('Let us know the target amount you’re aiming for in your campaign.', 'give')}
</div>

{goalType === 'amount' ? (
{goalType === 'amount' || goalType === 'amountFromSubscriptions' ? (
<Currency name="goal" currency={window.GiveCampaignDetails.currency} />
) : (
<input type="number" {...register('goal', {valueAsNumber: true})} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,12 @@

.goalTypeOptionIcon {

svg {
width: 2.5rem;
height: 2.5rem;
}
line-height: 0.875rem;
margin-top: 0.175rem;

path {
stroke: #9CA0AF;
svg {
width: 1.5rem;
height: 1.5rem;
}
}

Expand All @@ -57,9 +56,14 @@
cursor: pointer;
}

span {
> label {
font-size: 0.875rem !important;
}

> span {
font-size: 0.75rem !important;
margin-top: 0.2rem;
display: inline-block;
display: none;
line-height: 1rem !important;
}

Expand All @@ -77,16 +81,25 @@
background-color: #374151;

.goalTypeOptionIcon {
svg path {

svg path:not([fill]) {
stroke: #F9FAFB;
}

svg path:not([stroke]) {
fill: #F9FAFB;
}
}

.goalTypeOptionText {
label,
span {
color: #F9FAFB !important;
}

span {
display: inline-block;
}
}
}
}
Expand Down
Loading
Loading