| 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 |
updatePasswordWithAPI(newPassword) |
| 101 |
setNewPassword(''); |
| 102 |
setPasswordUpdated(true); |
| 103 |
}; |
| 104 |
|
| 105 |
useEffect(() => { |
| 106 |
setUpdated(false); |
| 107 |
}, [ |
| 108 |
titlePrefix, |
| 109 |
firstName, |
| 110 |
lastName, |
| 111 |
company, |
| 112 |
primaryEmail, |
| 113 |
additionalEmails, |
| 114 |
primaryAddress, |
| 115 |
additionalAddresses, |
| 116 |
isAnonymous, |
| 117 |
]); |
| 118 |
|
| 119 |
useEffect(() => { |
| 120 |
if (avatarFile !== null) { |
| 121 |
setUpdated(false); |
| 122 |
} |
| 123 |
}, [avatarFile]); |
| 124 |
|
| 125 |
const handleUpdate = async () => { |
| 126 |
setIsUpdating(true); |
| 127 |
await updateProfileWithAPI({ |
| 128 |
titlePrefix, |
| 129 |
firstName, |
| 130 |
lastName, |
| 131 |
company, |
| 132 |
primaryEmail, |
| 133 |
additionalEmails, |
| 134 |
primaryAddress, |
| 135 |
additionalAddresses, |
| 136 |
avatarFile, |
| 137 |
isAnonymous, |
| 138 |
id, |
| 139 |
}); |
| 140 |
setUpdated(true); |
| 141 |
setIsUpdating(false); |
| 142 |
}; |
| 143 |
|
| 144 |
return ( |
| 145 |
<Fragment> |
| 146 |
<Heading>{__('Profile Information', 'give')}</Heading> |
| 147 |
<Divider /> |
| 148 |
<AvatarControl url={avatarUrl} file={avatarFile} onChange={(value) => setAvatarFile(value)} /> |
| 149 |
<FieldRow> |
| 150 |
<SelectControl |
| 151 |
label={__('Prefix', 'give')} |
| 152 |
value={titlePrefix} |
| 153 |
onChange={(value) => setTitlePrefix(value)} |
| 154 |
options={titlePrefixOptions} |
| 155 |
placeholder="--" |
| 156 |
width="120px" |
| 157 |
isClearable={true} |
| 158 |
/> |
| 159 |
<TextControl |
| 160 |
label={__('First Name', 'give')} |
| 161 |
value={firstName} |
| 162 |
onChange={(value) => setFirstName(value)} |
| 163 |
icon="user" |
| 164 |
/> |
| 165 |
<TextControl |
| 166 |
label={__('Last Name', 'give')} |
| 167 |
value={lastName} |
| 168 |
onChange={(value) => setLastName(value)} |
| 169 |
/> |
| 170 |
</FieldRow> |
| 171 |
<TextControl label={__('Company', 'give')} value={company} onChange={(value) => setCompany(value)} /> |
| 172 |
<EmailControls |
| 173 |
primaryEmail={primaryEmail} |
| 174 |
additionalEmails={additionalEmails} |
| 175 |
onChangePrimaryEmail={(value) => setPrimaryEmail(value)} |
| 176 |
onChangeAdditionalEmails={(value) => setAdditionalEmails(value)} |
| 177 |
/> |
| 178 |
<AddressControls |
| 179 |
primaryAddress={primaryAddress} |
| 180 |
additionalAddresses={additionalAddresses} |
| 181 |
onChangePrimaryAddress={(value) => setPrimaryAddress(value)} |
| 182 |
onChangeAdditionalAddresses={(value) => setAdditionalAddresses(value)} |
| 183 |
/> |
| 184 |
<Heading>{__('Additional Info', 'give')}</Heading> |
| 185 |
<Divider /> |
| 186 |
<RadioControl |
| 187 |
label={__('Anonymous Giving', 'give')} |
| 188 |
description={__( |
| 189 |
'This will prevent your avatar, first name, donation comments, and other information from appearing publicly on this organization’s website.', |
| 190 |
'give' |
| 191 |
)} |
| 192 |
options={anonymousOptions} |
| 193 |
onChange={(value) => setIsAnonymous(value)} |
| 194 |
value={isAnonymous} |
| 195 |
/> |
| 196 |
<Button onClick={() => handleUpdate()}> |
| 197 |
{updated ? ( |
| 198 |
<Fragment> |
| 199 |
{__('Updated', 'give')} <FontAwesomeIcon icon="check" fixedWidth /> |
| 200 |
</Fragment> |
| 201 |
) : ( |
| 202 |
<Fragment> |
| 203 |
{__('Update Profile', 'give')}{' '} |
| 204 |
<FontAwesomeIcon |
| 205 |
className={isUpdating ? 'give-donor-dashboard__edit-profile-spinner' : ''} |
| 206 |
icon={isUpdating ? 'spinner' : 'save'} |
| 207 |
fixedWidth |
| 208 |
/> |
| 209 |
</Fragment> |
| 210 |
)} |
| 211 |
</Button> |
| 212 |
|
| 213 |
<Heading>{__('Update Password', 'give')}</Heading> |
| 214 |
<Divider /> |
| 215 |
<TextControl |
| 216 |
type="password" |
| 217 |
label={__('New Password', 'give')} |
| 218 |
value={newPassword} |
| 219 |
onChange={(value) => setNewPassword(value)} |
| 220 |
/> |
| 221 |
<Button onClick={() => handlePasswordUpdate()}> |
| 222 |
{passwordUpdated ? ( |
| 223 |
<Fragment> |
| 224 |
{__('Updated', 'give')} <FontAwesomeIcon icon="check" fixedWidth /> |
| 225 |
</Fragment> |
| 226 |
) : ( |
| 227 |
<Fragment> |
| 228 |
{__('Update Password', 'give')}{' '} |
| 229 |
<FontAwesomeIcon |
| 230 |
className={isUpdating ? 'give-donor-dashboard__edit-profile-spinner' : ''} |
| 231 |
icon={isUpdating ? 'spinner' : 'save'} |
| 232 |
fixedWidth |
| 233 |
/> |
| 234 |
</Fragment> |
| 235 |
)} |
| 236 |
</Button> |
| 237 |
</Fragment> |
| 238 |
); |
| 239 |
}; |
| 240 |
export default Content; |
| 241 |
|