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 / DonorDashboards / resources / js / app / tabs / edit-profile / content.js
give / src / DonorDashboards / resources / js / app / tabs / edit-profile Last commit date
address-controls 4 years ago address-fields 4 years ago email-controls 4 years ago utils 2 years ago content.js 2 weeks ago index.js 4 years ago style.scss 2 weeks ago
content.js
244 lines
1 import Heading from '../../components/heading';
2 import Divider from '../../components/divider';
3 import AvatarControl from '../../components/avatar-control';
4 import FieldRow from '../../components/field-row';
5 import SelectControl from '../../components/select-control';
6 import TextControl from '../../components/text-control';
7 import RadioControl from '../../components/radio-control';
8 import Button from '../../components/button';
9 import {updateProfileWithAPI, updatePasswordWithAPI} from './utils';
10 import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
11
12 import EmailControls from './email-controls';
13 import AddressControls from './address-controls';
14
15 import {Fragment, useState, useEffect} from 'react';
16 import {useSelector} from 'react-redux';
17 import {__} from '@wordpress/i18n';
18
19 import './style.scss';
20
21 const Content = () => {
22 const id = useSelector((state) => state.id);
23 const storedProfile = useSelector((state) => state.profile);
24 const [isUpdating, setIsUpdating] = useState(false);
25 const [updated, setUpdated] = useState(false);
26
27 useEffect(() => {
28 setAvatarFile(null);
29 setAvatarUrl(storedProfile.avatarUrl);
30 }, [storedProfile]);
31
32 const [titlePrefix, setTitlePrefix] = useState(storedProfile.titlePrefix);
33 const titlePrefixOptions = [
34 {
35 value: 'Mr.',
36 label: __('Mr.', 'give'),
37 },
38 {
39 value: 'Ms.',
40 label: __('Ms.', 'give'),
41 },
42 {
43 value: 'Mrs.',
44 label: __('Mrs.', 'give'),
45 },
46 ];
47
48 const [avatarFile, setAvatarFile] = useState(null);
49 const [avatarUrl, setAvatarUrl] = useState(storedProfile.avatarUrl);
50
51 const [firstName, setFirstName] = useState(storedProfile.firstName);
52 const [lastName, setLastName] = useState(storedProfile.lastName);
53
54 const [company, setCompany] = useState(storedProfile.company);
55
56 const [primaryEmail, setPrimaryEmail] = useState(storedProfile.emails ? storedProfile.emails.primary : '');
57
58 const reducedAdditionalEmails = storedProfile.emails
59 ? Object.keys(storedProfile.emails).reduce((newArray, key) => {
60 if (key !== 'primary') {
61 newArray.push(storedProfile.emails[key]);
62 }
63 return newArray;
64 }, [])
65 : [];
66
67 const [additionalEmails, setAdditionalEmails] = useState(reducedAdditionalEmails);
68
69 const [primaryAddress, setPrimaryAddress] = useState(
70 storedProfile.addresses && storedProfile.addresses.billing ? storedProfile.addresses.billing[0] : null
71 );
72
73 const reducedAdditionalAddresses =
74 storedProfile.addresses && storedProfile.addresses.billing
75 ? Object.values(storedProfile.addresses.billing).reduce((newArray, address, index) => {
76 if (index !== 0) {
77 newArray.push(address);
78 }
79 return newArray;
80 }, [])
81 : [];
82
83 const [additionalAddresses, setAdditionalAddresses] = useState(reducedAdditionalAddresses);
84
85 const [isAnonymous, setIsAnonymous] = useState(storedProfile.isAnonymous);
86 const anonymousOptions = [
87 {
88 value: '0',
89 label: __('Public - show my donations publicly', 'give'),
90 },
91 {
92 value: '1',
93 label: __('Private - only organization admins can view my info', 'give'),
94 },
95 ];
96
97 const [newPassword, setNewPassword] = useState('');
98 const [passwordUpdated, setPasswordUpdated] = useState(false);
99 const handlePasswordUpdate = async () => {
100 if (!newPassword.trim()) {
101 return;
102 }
103 updatePasswordWithAPI(newPassword);
104 setNewPassword('');
105 setPasswordUpdated(true);
106 };
107
108 useEffect(() => {
109 setUpdated(false);
110 }, [
111 titlePrefix,
112 firstName,
113 lastName,
114 company,
115 primaryEmail,
116 additionalEmails,
117 primaryAddress,
118 additionalAddresses,
119 isAnonymous,
120 ]);
121
122 useEffect(() => {
123 if (avatarFile !== null) {
124 setUpdated(false);
125 }
126 }, [avatarFile]);
127
128 const handleUpdate = async () => {
129 setIsUpdating(true);
130 await updateProfileWithAPI({
131 titlePrefix,
132 firstName,
133 lastName,
134 company,
135 primaryEmail,
136 additionalEmails,
137 primaryAddress,
138 additionalAddresses,
139 avatarFile,
140 isAnonymous,
141 id,
142 });
143 setUpdated(true);
144 setIsUpdating(false);
145 };
146
147 return (
148 <Fragment>
149 <Heading>{__('Profile Information', 'give')}</Heading>
150 <Divider />
151 <AvatarControl url={avatarUrl} file={avatarFile} onChange={(value) => setAvatarFile(value)} />
152 <FieldRow>
153 <SelectControl
154 label={__('Prefix', 'give')}
155 value={titlePrefix}
156 onChange={(value) => setTitlePrefix(value)}
157 options={titlePrefixOptions}
158 placeholder="--"
159 width="120px"
160 isClearable={true}
161 />
162 <TextControl
163 label={__('First Name', 'give')}
164 value={firstName}
165 onChange={(value) => setFirstName(value)}
166 icon="user"
167 />
168 <TextControl
169 label={__('Last Name', 'give')}
170 value={lastName}
171 onChange={(value) => setLastName(value)}
172 />
173 </FieldRow>
174 <TextControl label={__('Company', 'give')} value={company} onChange={(value) => setCompany(value)} />
175 <EmailControls
176 primaryEmail={primaryEmail}
177 additionalEmails={additionalEmails}
178 onChangePrimaryEmail={(value) => setPrimaryEmail(value)}
179 onChangeAdditionalEmails={(value) => setAdditionalEmails(value)}
180 />
181 <AddressControls
182 primaryAddress={primaryAddress}
183 additionalAddresses={additionalAddresses}
184 onChangePrimaryAddress={(value) => setPrimaryAddress(value)}
185 onChangeAdditionalAddresses={(value) => setAdditionalAddresses(value)}
186 />
187 <Heading>{__('Additional Info', 'give')}</Heading>
188 <Divider />
189 <RadioControl
190 label={__('Anonymous Giving', 'give')}
191 description={__(
192 'This will prevent your avatar, first name, donation comments, and other information from appearing publicly on this organization’s website.',
193 'give'
194 )}
195 options={anonymousOptions}
196 onChange={(value) => setIsAnonymous(value)}
197 value={isAnonymous}
198 />
199 <Button onClick={() => handleUpdate()}>
200 {updated ? (
201 <Fragment>
202 {__('Updated', 'give')} <FontAwesomeIcon icon="check" fixedWidth />
203 </Fragment>
204 ) : (
205 <Fragment>
206 {__('Update Profile', 'give')}{' '}
207 <FontAwesomeIcon
208 className={isUpdating ? 'give-donor-dashboard__edit-profile-spinner' : ''}
209 icon={isUpdating ? 'spinner' : 'save'}
210 fixedWidth
211 />
212 </Fragment>
213 )}
214 </Button>
215
216 <Heading>{__('Update Password', 'give')}</Heading>
217 <Divider />
218 <TextControl
219 type="password"
220 label={__('New Password', 'give')}
221 value={newPassword}
222 onChange={(value) => setNewPassword(value)}
223 />
224 <Button onClick={() => handlePasswordUpdate()} disabled={!newPassword.trim()}>
225 {passwordUpdated ? (
226 <Fragment>
227 {__('Updated', 'give')} <FontAwesomeIcon icon="check" fixedWidth />
228 </Fragment>
229 ) : (
230 <Fragment>
231 {__('Update Password', 'give')}{' '}
232 <FontAwesomeIcon
233 className={isUpdating ? 'give-donor-dashboard__edit-profile-spinner' : ''}
234 icon={isUpdating ? 'spinner' : 'save'}
235 fixedWidth
236 />
237 </Fragment>
238 )}
239 </Button>
240 </Fragment>
241 );
242 };
243 export default Content;
244