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 |