PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.19.8
GiveWP – Donation Plugin and Fundraising Platform v2.19.8
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 / DonationForms / resources / components / DonationFormsTable.tsx
give / src / DonationForms / resources / components Last commit date
AdminDonationFormsPage.module.scss 4 years ago AdminDonationFormsPage.tsx 4 years ago DonationFormsTable.module.scss 4 years ago DonationFormsTable.tsx 4 years ago DonationFormsTableRows.module.scss 4 years ago DonationFormsTableRows.tsx 4 years ago Pagination.js 4 years ago Pagination.module.scss 4 years ago
DonationFormsTable.tsx
283 lines
1 import {useEffect, useState} from 'react';
2 import {__, _n} from '@wordpress/i18n';
3 import {useSWRConfig, unstable_serialize} from 'swr';
4 import cx from 'classnames';
5
6 import styles from './DonationFormsTable.module.scss';
7 import Pagination from './Pagination.js';
8 import DonationFormTableRows from './DonationFormsTableRows';
9 import {Spinner} from '../../../Views/Components';
10 import {fetchWithArgs, useDonationForms} from '../api';
11
12 export enum DonationStatus {
13 Any = 'any',
14 Publish = 'publish',
15 Pending = 'pending',
16 Draft = 'draft',
17 Trash = 'trash',
18 }
19
20 interface DonationFormsTableProps {
21 statusFilter: DonationStatus;
22 search: string;
23 }
24
25 export default function DonationFormsTable({statusFilter: status, search}: DonationFormsTableProps) {
26 const [page, setPage] = useState<number>(1);
27 const [perPage, setPerPage] = useState<number>(10);
28 const [errors, setErrors] = useState<[]>([]);
29 const [successes, setSuccesses] = useState<[]>([]);
30 const [initialLoad, setInitialLoad] = useState<boolean>(true);
31 const [loadingOverlay, setLoadingOverlay] = useState<any>(false);
32 const [errorOverlay, setErrorOverlay] = useState<any>(false);
33 const listParams = {
34 page,
35 perPage,
36 status,
37 search,
38 };
39 const {data, error, isValidating} = useDonationForms(listParams);
40 const {mutate, cache} = useSWRConfig();
41 const isEmpty = !error && data?.forms.length === 0;
42 useEffect(() => {
43 setPage(1);
44 }, [status, search]);
45 useEffect(() => {
46 initialLoad && data && setInitialLoad(false);
47 }, [data]);
48 useEffect(() => {
49 if (isValidating && !cache.get(unstable_serialize(listParams))) {
50 setLoadingOverlay(styles.appear);
51 }
52 if (!isValidating && loadingOverlay) {
53 setLoadingOverlay(styles.disappear);
54 const timeoutId = setTimeout(() => setLoadingOverlay(false), 100);
55 return () => clearTimeout(timeoutId);
56 }
57 }, [isValidating]);
58 useEffect(() => {
59 let timeoutId;
60 if (errors.length) {
61 setErrorOverlay(styles.appear);
62 timeoutId = setTimeout(
63 () =>
64 document.getElementById(styles.updateError).scrollIntoView?.({behavior: 'smooth', block: 'center'}),
65 100
66 );
67 } else if (errorOverlay) {
68 setErrorOverlay(styles.disappear);
69 timeoutId = setTimeout(() => setErrorOverlay(false), 100);
70 }
71 return () => clearTimeout(timeoutId);
72 }, [errors]);
73
74 async function mutateForm(ids, endpoint, method) {
75 try {
76 const response = await fetchWithArgs(endpoint, {ids}, method);
77 // if we just removed the last entry from the page and we're not on the first page, go back a page
78 if (
79 !response.errors.length &&
80 data.forms.length == 1 &&
81 data.totalPages > 1 &&
82 (endpoint == '/delete' || endpoint == '/trash' || endpoint == '/restore')
83 ) {
84 setPage(page - 1);
85 }
86 // otherwise, revalidate current page
87 else {
88 await mutate(listParams);
89 }
90 //revalidate all pages after the current page
91 const mutations = [];
92 for (let i = page + 1; i <= data.totalPages; i++) {
93 mutations.push(mutate({...listParams, page: i}));
94 }
95 setErrors(response.errors);
96 setSuccesses(response.successes);
97 return response;
98 } catch (error) {
99 setErrors(ids.split(','));
100 setSuccesses([]);
101 return {errors: ids.split(','), successes: []};
102 }
103 }
104
105 return (
106 <>
107 <div className={styles.pageActions}>
108 <Pagination
109 currentPage={page}
110 totalPages={data ? data.totalPages : 1}
111 disabled={!data}
112 totalItems={data ? parseInt(data.totalForms) : -1}
113 setPage={setPage}
114 />
115 </div>
116 {( initialLoad && !error ) ? (
117 <div className={styles.initialLoad}>
118 <div className={cx(styles.tableGroup)}>
119 <Spinner size={'large'} />
120 <h2>{__('Loading donation forms', 'give')}</h2>
121 </div>
122 </div>
123 ) : (
124 <div
125 role="group"
126 aria-labelledby="giveDonationFormsTableCaption"
127 aria-describedby="giveDonationFormsTableMessage"
128 className={styles.tableGroup}
129 >
130 <table className={styles.table}>
131 <caption id="giveDonationFormsTableCaption" className={styles.tableCaption}>
132 {__('Donation Forms', 'give')}
133 </caption>
134 <thead>
135 <tr>
136 <th scope="col" aria-sort="none" className={styles.tableColumnHeader} data-column="id">
137 {__('ID', 'give')}
138 </th>
139 <th
140 scope="col"
141 aria-sort="none"
142 className={styles.tableColumnHeader}
143 data-column="name"
144 >
145 {__('Name', 'give')}
146 </th>
147 <th
148 scope="col"
149 aria-sort="none"
150 className={styles.tableColumnHeader}
151 data-column="amount"
152 >
153 {__('Amount', 'give')}
154 </th>
155 <th
156 scope="col"
157 aria-sort="none"
158 className={styles.tableColumnHeader}
159 data-column="goal"
160 >
161 {__('Goal', 'give')}
162 </th>
163 <th
164 scope="col"
165 aria-sort="none"
166 className={styles.tableColumnHeader}
167 data-column="donations"
168 >
169 {__('Donations', 'give')}
170 </th>
171 <th
172 scope="col"
173 aria-sort="none"
174 className={styles.tableColumnHeader}
175 data-column="revenue"
176 >
177 {__('Revenue', 'give')}
178 </th>
179 <th
180 scope="col"
181 aria-sort="none"
182 className={styles.tableColumnHeader}
183 data-column="shortcode"
184 >
185 {__('Shortcode', 'give')}
186 </th>
187 <th
188 scope="col"
189 aria-sort="ascending"
190 className={styles.tableColumnHeader}
191 data-column="date"
192 >
193 {__('Date', 'give')}
194 </th>
195 <th
196 scope="col"
197 aria-sort="none"
198 className={styles.tableColumnHeader}
199 data-column="status"
200 >
201 {__('Status', 'give')}
202 </th>
203 </tr>
204 </thead>
205 <tbody className={styles.tableContent}>
206 <DonationFormTableRows listParams={listParams} mutateForm={mutateForm} status={status} />
207 </tbody>
208 </table>
209 {loadingOverlay && (
210 <div className={cx(styles.overlay, loadingOverlay)}>
211 <Spinner size={'medium'} />
212 </div>
213 )}
214 {errorOverlay && (
215 <div className={cx(styles.overlay, errorOverlay)}>
216 <div id={styles.updateError}>
217 {!!successes.length && (
218 <span>
219 {successes.length +
220 ' ' +
221 _n(
222 'form was updated successfully',
223 'forms were updated successfully.',
224 successes.length,
225 'give'
226 )}
227 </span>
228 )}
229 <span>
230 {errors.length +
231 ' ' +
232 _n(
233 "form couldn't be updated.",
234 "forms couldn't be updated.",
235 errors.length,
236 'give'
237 )}
238 </span>
239 <button
240 type="button"
241 className={cx('dashicons dashicons-dismiss', styles.dismiss)}
242 onClick={() => {
243 setErrors([]);
244 setSuccesses([]);
245 }}
246 >
247 <span className="give-visually-hidden">dismiss</span>
248 </button>
249 </div>
250 </div>
251 )}
252 <div id="giveDonationFormsTableMessage">
253 {isEmpty && (
254 <div className={styles.statusMessage}>{__('No donation forms found.', 'give')}</div>
255 )}
256 {error && (
257 <>
258 <div className={styles.statusMessage}>
259 {__('There was a problem retrieving the donation forms.', 'give')}
260 </div>
261 <div className={styles.statusMessage}>
262 {__('Click', 'give') + ' '}
263 <a href={'edit.php?post_type=give_forms&page=give-forms'}>{__('here', 'give')}</a>
264 {' ' + __('to reload the page.')}
265 </div>
266 </>
267 )}
268 </div>
269 </div>
270 )}
271 <div className={styles.pageActions}>
272 <Pagination
273 currentPage={page}
274 totalPages={data ? data.totalPages : 1}
275 disabled={!data}
276 totalItems={data ? parseInt(data.totalForms) : -1}
277 setPage={setPage}
278 />
279 </div>
280 </>
281 );
282 }
283