Skip to content

Commit d4be67b

Browse files
authored
Merge pull request wevote#4539 from DaleMcGrew/Dale_WebApp_Sept22-2025
Added ability to save politician profile photo and official statement Moved some of the new features to only show when nextReleaseFeaturesEnabled is true. Updated VoterPhotoUpload to support both Voter profile photo and Politician profile photo.
2 parents 3bbda27 + c133c4a commit d4be67b

19 files changed

Lines changed: 749 additions & 527 deletions

src/js/actions/VoterActions.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,8 @@ export default {
393393
});
394394
},
395395

396-
voterPhotoTooBigReset () {
397-
Dispatcher.dispatch({ type: 'voterPhotoTooBigReset', payload: true });
396+
profilePhotoTooBigReset () {
397+
Dispatcher.dispatch({ type: 'profilePhotoTooBigReset', payload: true });
398398
},
399399

400400
voterRetrieve (mergeFromVoterWeVoteId = '', mergeToVoterWeVoteId = '') {

src/js/common/actions/PoliticianActions.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Dispatcher from '../dispatcher/Dispatcher';
2+
import arrayContains from '../utils/arrayContains';
23

34
export default {
45
politicianNameSave (politicianWeVoteId, politicianName) {
@@ -10,13 +11,52 @@ export default {
1011
});
1112
},
1213

14+
politicianPhotoDelete (politicianWeVoteId) {
15+
Dispatcher.loadEndpoint('politicianSave',
16+
{
17+
politician_photo_from_file_reader: '',
18+
politician_photo_delete: true,
19+
politician_photo_delete_changed: true,
20+
politician_we_vote_id: politicianWeVoteId,
21+
});
22+
},
23+
24+
politicianPhotoQueuedToSave (politicianPhotoFromFileReader) {
25+
Dispatcher.dispatch({ type: 'politicianPhotoQueuedToSave', payload: politicianPhotoFromFileReader });
26+
},
27+
28+
politicianPhotoSave (politicianWeVoteId = '', politicianPhotoQueuedToSave = '', politicianPhotoQueuedToSaveSet = false, profileImageTypeCurrentlyActive = '') {
29+
const profileImageTypeCurrentlyActiveSet = arrayContains(profileImageTypeCurrentlyActive, ['BALLOTPEDIA', 'FACEBOOK', 'LINKEDIN', 'TWITTER', 'UPLOADED', 'VOTE_USA', 'WIKIPEDIA']);
30+
Dispatcher.loadEndpoint('politicianSave',
31+
{
32+
profile_image_type_currently_active: profileImageTypeCurrentlyActive,
33+
profile_image_type_currently_active_changed: profileImageTypeCurrentlyActiveSet,
34+
politician_photo_from_file_reader: politicianPhotoQueuedToSave,
35+
politician_photo_changed: politicianPhotoQueuedToSaveSet,
36+
politician_we_vote_id: politicianWeVoteId,
37+
});
38+
},
39+
40+
profilePhotoTooBigReset () {
41+
Dispatcher.dispatch({ type: 'profilePhotoTooBigReset', payload: true });
42+
},
43+
1344
politicianRetrieve (politicianWeVoteId) {
1445
Dispatcher.loadEndpoint('politicianRetrieve',
1546
{
1647
politician_we_vote_id: politicianWeVoteId,
1748
});
1849
},
1950

51+
politicianStatementSave (politicianWeVoteId, politicianStatement) {
52+
Dispatcher.loadEndpoint('politicianSave',
53+
{
54+
ballot_guide_official_statement: politicianStatement,
55+
ballot_guide_official_statement_changed: true,
56+
politician_we_vote_id: politicianWeVoteId,
57+
});
58+
},
59+
2060
politiciansQuery (electionDay = '', raceOfficeLevelList = '', stateCode = '', searchText = '') {
2161
Dispatcher.loadEndpoint('politiciansQuery',
2262
{

src/js/common/components/Politician/UpdatePoliticianInformation/UpdatePoliticianInformation.jsx

Lines changed: 42 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import PropTypes from 'prop-types';
2-
import React, { useState, Suspense } from 'react';
2+
import React, { useState } from 'react';
33
import styled from 'styled-components';
44
import { Close, EditOutlined, ExpandMoreRounded } from '@mui/icons-material';
55
import { Button, IconButton } from '@mui/material';
@@ -9,15 +9,8 @@ import DesignTokenColors from '../../Style/DesignTokenColors';
99
import VerifyOtherWaysModal from './VerifyOtherWaysModal';
1010
import VerifyWithEmailModal from './VerifyWithEmailModal';
1111
import AppObservableStore from '../../../stores/AppObservableStore';
12-
import webAppConfig from '../../../../config';
1312
import useVoterCanEditPolitician from '../../../../hooks/useVoterCanEditPolitician';
1413

15-
const nextReleaseFeaturesEnabled = webAppConfig.ENABLE_NEXT_RELEASE_FEATURES === undefined ? false : webAppConfig.ENABLE_NEXT_RELEASE_FEATURES;
16-
17-
18-
const OpenExternalWebSite = React.lazy(() => import(/* webpackChunkName: 'OpenExternalWebSite' */ '../../Widgets/OpenExternalWebSite'));
19-
20-
const updateCandidateInformationLink = 'https://docs.google.com/forms/d/e/1FAIpQLSePdeW32PClaSO1pUWBJnQ75wFGPOtviNaqOABBYps7NIH3hA/viewform?usp=sf_link';
2114
const CustomTooltip = muiStyled(({ className, ...props }) => (
2215
<Tooltip {...props} classes={{ popper: className }} />
2316
))(() => ({
@@ -52,78 +45,50 @@ const UpdatePoliticianInformation = ({ politicianName, politicianWeVoteId }) =>
5245
<UpdateInformationWrapper>
5346
{!!(politicianName) && (
5447
<>
55-
{nextReleaseFeaturesEnabled ? (
56-
<>
57-
{voterCanEditPoliticianProfile ? (
58-
<CustomTooltip
59-
interactive
60-
arrow
61-
placement="right"
62-
open={tooltipOpen}
63-
onOpen={() => setTooltipOpen(true)}
64-
onClose={() => setTooltipOpen(false)}
65-
title={(
66-
<TooltipContent>
67-
<CloseButton size="small" onClick={() => setTooltipOpen(false)}>
68-
<Close fontSize="small" />
69-
</CloseButton>
70-
Edit your candidate’s profile here
71-
<GotItButton onClick={() => setTooltipOpen(false)}>
72-
GOT IT
73-
</GotItButton>
74-
</TooltipContent>
75-
)}
76-
>
77-
<EditProfileWrapper
78-
onMouseEnter={() => setTooltipOpen(true)}
79-
onClick={handleEditProfile}
80-
>
81-
<EditOutlined fontSize="small" style={{ marginRight: 4 }} />
82-
Edit profile
83-
</EditProfileWrapper>
84-
</CustomTooltip>
85-
) : (
86-
<CandidateStaffAccessButton
87-
onClick={handleOpenVerifyWithEmailModal}
88-
>
89-
Candidate staff access
90-
<ExpandMoreRounded />
91-
</CandidateStaffAccessButton>
48+
{voterCanEditPoliticianProfile ? (
49+
<CustomTooltip
50+
interactive
51+
arrow
52+
placement="right"
53+
open={tooltipOpen}
54+
onOpen={() => setTooltipOpen(true)}
55+
onClose={() => setTooltipOpen(false)}
56+
title={(
57+
<TooltipContent>
58+
<CloseButton size="small" onClick={() => setTooltipOpen(false)}>
59+
<Close fontSize="small" />
60+
</CloseButton>
61+
Edit your candidate’s profile here
62+
<GotItButton onClick={() => setTooltipOpen(false)}>
63+
GOT IT
64+
</GotItButton>
65+
</TooltipContent>
9266
)}
93-
<VerifyOtherWaysModal
94-
politicianName={politicianName}
95-
politicianWeVoteId={politicianWeVoteId}
96-
/>
97-
<VerifyWithEmailModal
98-
politicianName={politicianName}
99-
politicianWeVoteId={politicianWeVoteId}
100-
/>
101-
</>
67+
>
68+
<EditProfileWrapper
69+
onMouseEnter={() => setTooltipOpen(true)}
70+
onClick={handleEditProfile}
71+
>
72+
<EditOutlined fontSize="small" style={{ marginRight: 4 }} />
73+
Edit profile
74+
</EditProfileWrapper>
75+
</CustomTooltip>
10276
) : (
103-
<Suspense fallback={<></>}>
104-
<FlexLayoutDiv>
105-
<CandidateStaffText>
106-
For candidate staff:&nbsp;
107-
</CandidateStaffText>
108-
<AddInfoLink>
109-
<OpenExternalWebSite
110-
linkIdAttribute="updateCandidateInformation"
111-
url={updateCandidateInformationLink}
112-
target="_blank"
113-
className="u-link-color"
114-
body={(
115-
<div>
116-
Add info
117-
</div>
118-
)}
119-
destinationPageName="PoliticianEditForm"
120-
destinationPageType="politician"
121-
trackingOn
122-
/>
123-
</AddInfoLink>
124-
</FlexLayoutDiv>
125-
</Suspense>
77+
<CandidateStaffAccessButton
78+
onClick={handleOpenVerifyWithEmailModal}
79+
>
80+
Candidate staff access
81+
<ExpandMoreRounded />
82+
</CandidateStaffAccessButton>
12683
)}
84+
<VerifyOtherWaysModal
85+
politicianName={politicianName}
86+
politicianWeVoteId={politicianWeVoteId}
87+
/>
88+
<VerifyWithEmailModal
89+
politicianName={politicianName}
90+
politicianWeVoteId={politicianWeVoteId}
91+
/>
12792
</>
12893
)}
12994
</UpdateInformationWrapper>
@@ -135,10 +100,6 @@ UpdatePoliticianInformation.propTypes = {
135100
politicianWeVoteId: PropTypes.string,
136101
};
137102

138-
const AddInfoLink = styled('div')`
139-
font-size: 12px;
140-
`;
141-
142103
const CandidateStaffAccessButton = styled('button')`
143104
background: transparent;
144105
border: none;
@@ -147,22 +108,12 @@ const CandidateStaffAccessButton = styled('button')`
147108
margin-top: -3px;
148109
`;
149110

150-
const CandidateStaffText = styled('div')`
151-
color:${DesignTokenColors.neutralUI100};
152-
font-size: 10px;
153-
`;
154-
155111
const EditProfileWrapper = styled('div')`
156112
color: ${DesignTokenColors.primary500};
157113
cursor: pointer;
158114
font-size: 12px;
159115
`;
160116

161-
const FlexLayoutDiv = styled('div')`
162-
display: flex;
163-
align-items: flex-end;
164-
`;
165-
166117
const UpdateInformationWrapper = styled('div')`
167118
align-items: flex-start;
168119
display: flex;

src/js/common/components/Politician/UpdatePoliticianInformation/VerifyOtherWaysModal.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,11 @@ const VerifyOtherWaysModal = ({ politicianName }) => {
9999
<VerifyStepLetter>
100100
a
101101
</VerifyStepLetter>
102-
<VerifyStepLabelSmall
102+
<VerifyStepLabel
103103
htmlFor="candidate-campaign-related-email"
104104
>
105105
Your candidate/campaign related email?
106-
</VerifyStepLabelSmall>
106+
</VerifyStepLabel>
107107
</VerifyStepFlexTopMarginContainer>
108108
<VerifyFullInput
109109
id="candidate-campaign-related-email"
@@ -151,11 +151,11 @@ const VerifyOtherWaysModal = ({ politicianName }) => {
151151
<VerifyStepLetter>
152152
c
153153
</VerifyStepLetter>
154-
<VerifyStepLabelSmall
154+
<VerifyStepLabel
155155
htmlFor="candidate-additional-information"
156156
>
157157
Additional information to help us verify you
158-
</VerifyStepLabelSmall>
158+
</VerifyStepLabel>
159159
</VerifyStepFlexTopMarginContainer>
160160
<AdditionalInformationTextArea
161161
id="candidate-additional-information"

0 commit comments

Comments
 (0)