PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.6
GiveWP – Donation Plugin and Fundraising Platform v4.16.6
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 / index.tsx
give / src / Campaigns / resources / admin / components / CampaignDetailsPage Last commit date
Components 9 months ago Tabs 9 months ago CampaignDetailsPage.module.scss 9 months ago index.tsx 9 months ago types.ts 1 year ago
index.tsx
208 lines
1 import { createCampaignPage, getCampaignOptionsWindowData, updateCampaignStatus, useCampaignEntityRecord } from '@givewp/campaigns/utils';
2 import { useDispatch } from '@wordpress/data';
3 import { store as coreStore } from '@wordpress/core-data';
4 import { useEffect, useState } from '@wordpress/element';
5 import { __ } from '@wordpress/i18n';
6 import cx from 'classnames';
7 import { useForm } from 'react-hook-form';
8 import { ArrowReverse, TrashIcon, ViewIcon } from '../Icons';
9 import { Campaign } from '../types';
10 import ArchivedCampaignNotice from './Components/Notices/ArchivedCampaignNotice';
11 import styles from './CampaignDetailsPage.module.scss';
12 import AdminDetailsPage from '@givewp/components/AdminDetailsPage';
13 import ConfirmationDialog from '@givewp/components/AdminDetailsPage/ConfirmationDialog';
14 import tabDefinitions from './Tabs/definitions';
15 import '@givewp/campaigns/store';
16
17 const StatusBadge = ({ status }: { status: string }) => {
18 const statusMap = {
19 active: __('Active', 'give'),
20 archived: __('Archived', 'give'),
21 };
22
23 return (
24 <div className="interweave">
25 <div className={`statusBadge statusBadge--${status}`}>
26 <p>{statusMap[status]}</p>
27 </div>
28 </div>
29 );
30 };
31
32 export default function CampaignsDetailsPage({ campaignId }) {
33 const { adminUrl } = getCampaignOptionsWindowData();
34 const [isCreatingPage, setIsCreatingPage] = useState<boolean>(false);
35 const [showConfirmationDialog, setShowConfirmationDialog] = useState<string | null>(null);
36
37 const dispatch = useDispatch(`givewp/admin-details-page-notifications`);
38 const { receiveEntityRecords } = useDispatch(coreStore);
39
40 const { record: campaign } = useCampaignEntityRecord(campaignId);
41 const methods = useForm<Campaign>({
42 mode: 'onBlur',
43 shouldFocusError: true,
44 });
45 const { setValue } = methods;
46
47 // Show campaign archived notice
48 useEffect(() => {
49 if (campaign?.status !== 'archived') {
50 return;
51 }
52
53 dispatch.addNotice({
54 id: 'update-archive-notice',
55 type: 'warning',
56 content: (onDismiss) => (
57 <ArchivedCampaignNotice
58 handleClick={() => {
59 onDismiss();
60 updateStatus('active');
61 }}
62 />
63 ),
64 });
65 }, [campaign?.status]);
66
67 const updateStatus = async (status: 'archived' | 'active') => {
68 const campaignStatusResponse = await updateCampaignStatus(campaign.id, status);
69
70 if (campaignStatusResponse) {
71 receiveEntityRecords('givewp', 'campaign', campaignStatusResponse, undefined, false);
72 setValue('status', campaignStatusResponse?.status);
73 dispatch.addSnackbarNotice({
74 id: `save-success`,
75 content: getMessageByStatus(status),
76 });
77 } else {
78 dispatch.addSnackbarNotice({
79 id: `save-error`,
80 type: 'error',
81 content: __('Failed to update campaign status', 'give'),
82 });
83 }
84 };
85
86 async function handleCampaignPageCreation() {
87 setIsCreatingPage(true);
88 const campaignPageResponse = await createCampaignPage(campaign.id);
89 setIsCreatingPage(false);
90
91 if (campaignPageResponse) {
92 receiveEntityRecords('givewp', 'campaign', {...campaign, pageId: campaignPageResponse?.id}, undefined, false);
93 setValue('pageId', campaignPageResponse?.id);
94 dispatch.addSnackbarNotice({
95 id: `save-success`,
96 content: __('Campaign page created', 'give'),
97 });
98 } else {
99 dispatch.addSnackbarNotice({
100 id: `save-error`,
101 type: 'error',
102 content: __('Failed to create campaign page', 'give'),
103 });
104 }
105 }
106
107 const SecondaryActionButton = ({ className }: { className: string }) => {
108 return (
109 !isCreatingPage && campaign.pageId > 0 ? (
110 <a
111 className={`button button-secondary ${className}`}
112 href={`${adminUrl}post.php?post=${campaign.pageId}&action=edit`}
113 rel="noopener noreferrer"
114 >
115 {__('Edit campaign page', 'give')}
116 </a>
117 ) : (
118 <button
119 type="button"
120 className={`button button-tertiary ${className}`}
121 onClick={handleCampaignPageCreation}
122 disabled={isCreatingPage}
123 >
124 {isCreatingPage
125 ? __('Creating Campaign Page', 'give')
126 : __('Create Campaign Page', 'give')}
127 </button>
128 )
129 );
130 };
131
132 const ContextMenuItems = ({ className }: { className: string }) => {
133 return (
134 <>
135 {campaign.pagePermalink && (
136 <a
137 href={campaign.pagePermalink}
138 aria-label={__('View Campaign', 'give')}
139 className={className}
140 >
141 <ViewIcon /> {__('View Campaign', 'give')}
142 </a>
143 )}
144 {campaign.status === 'archived' ? (
145 <a
146 href="#"
147 className={cx(className, styles.draft)}
148 onClick={() => {
149 updateStatus('active');
150 dispatch.dismissNotification('update-archive-notice');
151 }}
152 >
153 <ArrowReverse /> {__('Move to Active', 'give')}
154 </a>
155 ) : (
156 <a
157 href="#"
158 className={cx(className, styles.archive)}
159 onClick={() => setShowConfirmationDialog('archive')}
160 >
161 <TrashIcon /> {__('Archive Campaign', 'give')}
162 </a>
163 )}
164 </>
165 );
166 };
167
168 return (
169 <AdminDetailsPage
170 objectId={campaign?.id}
171 objectType="campaign"
172 objectTypePlural="campaigns"
173 useObjectEntityRecord={useCampaignEntityRecord}
174 tabDefinitions={tabDefinitions}
175 breadcrumbUrl={`${adminUrl}edit.php?post_type=give_forms&page=give-campaigns`}
176 breadcrumbTitle={__('Campaigns', 'give')}
177 pageTitle={campaign?.title}
178 StatusBadge={() => <StatusBadge status={campaign?.status} />}
179 SecondaryActionButton={SecondaryActionButton}
180 ContextMenuItems={ContextMenuItems}
181 >
182 <ConfirmationDialog
183 title={__('Archive Campaign', 'give')}
184 actionLabel={__('Archive campaign', 'give')}
185 isOpen={showConfirmationDialog === 'archive'}
186 handleClose={() => setShowConfirmationDialog(null)}
187 handleConfirm={() => {
188 updateStatus('archived');
189 setShowConfirmationDialog(null);
190 }}
191 >
192 {__('Are you sure you want to archive your campaign? All forms associated with this campaign will be inaccessible to donors.', 'give')}
193 </ConfirmationDialog>
194 </AdminDetailsPage>
195 );
196 }
197
198 const getMessageByStatus = (status: string) => {
199 switch (status) {
200 case 'archived':
201 return __('Campaign is moved to archive', 'give');
202 case 'active':
203 return __('Campaign is now active', 'give');
204 }
205
206 return null;
207 };
208