PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.5
GiveWP – Donation Plugin and Fundraising Platform v4.16.5
4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / Campaigns / resources / admin / components / CampaignDetailsPage / Components / CampaignStats / index.tsx
give / src / Campaigns / resources / admin / components / CampaignDetailsPage / Components / CampaignStats Last commit date
DateRangeFilters.tsx 1 year ago PercentChangePill.tsx 1 year ago StatWidget.tsx 1 year ago index.tsx 9 months ago styles.module.scss 1 year ago types.ts 1 year ago
index.tsx
127 lines
1 import {__} from '@wordpress/i18n';
2 import {useEffect, useState} from 'react';
3 import RevenueChart from '../RevenueChart';
4 import GoalProgressChart from '../GoalProgressChart';
5 import apiFetch from '@wordpress/api-fetch';
6 import {addQueryArgs} from '@wordpress/url';
7 import HeaderText from '../HeaderText';
8 import HeaderSubText from '../HeaderSubText';
9 import DefaultFormWidget from '../DefaultForm';
10 import StatWidget from './StatWidget';
11 import DateRangeFilters from './DateRangeFilters';
12 import {amountFormatter, getCampaignOptionsWindowData, useCampaignEntityRecord} from '@givewp/campaigns/utils';
13 import type {CampaignOverViewStat} from './types';
14 import styles from './styles.module.scss';
15 import CampaignDetailsErrorBoundary
16 from '@givewp/campaigns/admin/components/CampaignDetailsPage/Components/CampaignDetailsErrorBoundary';
17
18 const campaignId = new URLSearchParams(window.location.search).get('id');
19
20 const {currency} = getCampaignOptionsWindowData();
21 const currencyFormatter = amountFormatter(currency);
22
23 export const filterOptions = [
24 {label: __('Today', 'give'), value: 1, description: __('from today', 'give')},
25 {label: __('Last 7 days', 'give'), value: 7, description: __('from the last 7 days', 'give')},
26 {label: __('Last 30 days', 'give'), value: 30, description: __('from the last 30 days', 'give')},
27 {label: __('Last 90 days', 'give'), value: 90, description: __('from the last 90 days', 'give')},
28 {label: __('All-time', 'give'), value: 0, description: __('total for all-time', 'give')},
29 ];
30
31 const fetchCampaignOverviewStats = async (days: number, setLoading: Function, setStats: Function) => {
32 setLoading(true);
33
34 try {
35 const response = await apiFetch({
36 path: addQueryArgs(`/givewp/v3/campaigns/${campaignId}/statistics`, {rangeInDays: days}),
37 });
38
39 setStats(response as CampaignOverViewStat[]);
40 setLoading(false);
41 } catch (error) {
42 console.error('Error fetching campaign stats:', error);
43 setLoading(false);
44 }
45 };
46
47 const CampaignStats = () => {
48 const [dayRange, setDayRange] = useState<number>(0);
49 /**
50 * The stats array is currently either an array size of 1 or 2
51 * if the array size is 1 it means all-time stats
52 * if the array size is 2 it means the stats for the day range was selected
53 * the second element in the array is the query for the previous day range
54 */
55 const [stats, setStats] = useState<CampaignOverViewStat[]>([]);
56 const {record: campaign} = useCampaignEntityRecord();
57 const [loading, setLoading] = useState<boolean>(false);
58
59 useEffect(() => {
60 fetchCampaignOverviewStats(dayRange, setLoading, setStats);
61 }, [dayRange]);
62
63 const widgetDescription = filterOptions.find((option) => option.value === dayRange)?.description;
64
65 const amountRaised = stats.length > 0 ? stats[0].amountRaised : 0;
66 const previousAmountRaised = stats.length > 1 ? stats[1].amountRaised : null;
67 const donationCount = stats.length > 0 ? stats[0].donationCount : 0;
68 const previousDonationCount = stats.length > 1 ? stats[1].donationCount : null;
69 const donorCount = stats.length > 0 ? stats[0].donorCount : 0;
70 const previousDonorCount = stats.length > 1 ? stats[1].donorCount : null;
71
72 return (
73 <>
74 <DateRangeFilters selected={dayRange} options={filterOptions} onSelect={(value) => setDayRange(value)} />
75 <div className={styles.mainGrid}>
76 <StatWidget
77 label={__('Amount raised', 'give')}
78 value={amountRaised}
79 previousValue={previousAmountRaised}
80 description={widgetDescription}
81 formatter={currencyFormatter}
82 loading={loading}
83 />
84 <StatWidget
85 label={__('Number of donations', 'give')}
86 value={donationCount}
87 previousValue={previousDonationCount}
88 description={widgetDescription}
89 loading={loading}
90 />
91 <StatWidget
92 label={__('Number of donors', 'give')}
93 value={donorCount}
94 previousValue={previousDonorCount}
95 description={widgetDescription}
96 loading={loading}
97 />
98 <div className={styles.revenueWidget}>
99 <header className={styles.headerSpacing}>
100 <HeaderText>{__('Revenue', 'give')}</HeaderText>
101 <HeaderSubText>
102 {__('This graph shows revenue for the campaign over its lifetime.', 'give')}
103 </HeaderSubText>
104 </header>
105 <CampaignDetailsErrorBoundary>
106 <RevenueChart />
107 </CampaignDetailsErrorBoundary>
108 </div>
109 <div className={styles.nestedGrid}>
110 <div className={styles.progressWidget}>
111 <header className={styles.headerSpacing}>
112 <HeaderText>{__('Goal progress', 'give')}</HeaderText>
113 <HeaderSubText>{__('This chart shows your campaign goal progress.', 'give')}</HeaderSubText>
114 </header>
115 <CampaignDetailsErrorBoundary>
116 <GoalProgressChart value={campaign.goalStats.actual} goal={campaign.goal} goalType={campaign.goalType} />
117 </CampaignDetailsErrorBoundary>
118 </div>
119 <DefaultFormWidget defaultForm={campaign.defaultFormTitle} />
120 </div>
121 </div>
122 </>
123 );
124 };
125
126 export default CampaignStats;
127