Skip to content

Commit 3aee0b6

Browse files
authored
Merge pull request #4863 from DaleMcGrew/Dale_WebApp_Jul11-2026
Centralized the way we call "Complete Your Profile" modal, and prevented this modal from opening when you stop supporting or stop opposing. Fixed singular vs. plural issue in HeartFavoriteToggle.
2 parents 80ce01e + 3183885 commit 3aee0b6

24 files changed

Lines changed: 367 additions & 150 deletions

src/js/common/components/CampaignSupport/CampaignSupportThermometer.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class CampaignSupportThermometer extends React.Component {
152152

153153
render () {
154154
renderLog('CampaignSupportThermometer'); // Set LOG_RENDER_EVENTS to log all renders
155-
const { campaignXWeVoteId, inCompressedMode } = this.props;
155+
const { campaignXWeVoteId, inCompressedMode, supportPolitician } = this.props;
156156
const { finalElectionDateInPast, supportersCount, supportersCountNextGoal, voterOpposesCampaignX } = this.state;
157157
let calculatedPercentage = 0;
158158
if (supportersCount && supportersCountNextGoal) {
@@ -189,7 +189,7 @@ class CampaignSupportThermometer extends React.Component {
189189
<CampaignSupportThermometerWrapper>
190190
<HeartPlusDetailsWrapper>
191191
<HeartWrapper>
192-
<HeartFavoriteToggleLoader campaignXWeVoteId={campaignXWeVoteId} />
192+
<HeartFavoriteToggleLoader campaignXWeVoteId={campaignXWeVoteId} supportPolitician={supportPolitician} />
193193
</HeartWrapper>
194194
<HeartDetailsWrapper>
195195
{showLoadingSkeleton ? (
@@ -230,6 +230,7 @@ class CampaignSupportThermometer extends React.Component {
230230
CampaignSupportThermometer.propTypes = {
231231
campaignXWeVoteId: PropTypes.string,
232232
inCompressedMode: PropTypes.bool,
233+
supportPolitician: PropTypes.bool,
233234
};
234235

235236
const styles = () => ({

src/js/common/components/CampaignSupport/SupportButton.jsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,22 @@ class SupportButton extends Component {
7676
console.log('SupportButton submitSupportButtonDesktop: missing campaignXWeVoteId:', campaignXWeVoteId);
7777
} else if (!voterFirstName || !voterLastName || !voterSignedInWithEmail) {
7878
// Open complete your profile modal
79-
AppObservableStore.setShowCompleteYourProfileModal(true);
79+
const modalDictionary = {
80+
becomeMember: false,
81+
campaignXWeVoteId,
82+
challengeWeVoteId: '',
83+
clickSource: 'SUPPORT_BUTTON ',
84+
isOppose: false,
85+
isStopOpposing: false,
86+
isStopSupporting: false,
87+
isSupport: true,
88+
politicianWeVoteId: '',
89+
showModal: true,
90+
startCampaign: false,
91+
supportCampaign: true,
92+
supportPolitician: false,
93+
};
94+
AppObservableStore.setShowCompleteYourProfileModalDict(modalDictionary);
8095
} else {
8196
// Mark that voter supports this campaign
8297
AppObservableStore.setBlockCampaignXRedirectOnSignIn(false);

src/js/common/components/CardForListBody.jsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@ function CardForListBody (props) {
3939
hideItemActionBar, isClaimedProfile, limitCardWidth, linkedCampaignXWeVoteId, officeName,
4040
photoLargeUrl, politicalParty, politicianBasePath,
4141
politicianDescription, politicianWeVoteId, profileImageBackgroundColor,
42-
searchText, showPoliticianOpenInNewWindow, stateCode, tagIdBaseName,
42+
searchText, showPoliticianOpenInNewWindow, stateCode,
43+
supportPolitician, tagIdBaseName,
4344
ultimateElectionDate,
4445
useCampaignSupportThermometer, useOfficeHeld,
4546
usePoliticianWeVoteIdForBallotItem, useVerticalCard,
4647
} = props;
48+
// console.log('CardForListBody supportPolitician: ', supportPolitician, ', useCampaignSupportThermometer:', useCampaignSupportThermometer);
4749

4850
// const supportersCountNextGoal = supportersCountNextGoalRaw || 0;
4951
// let supportersCountNextGoalWithFloor = supportersCountNextGoal || CampaignStore.getCampaignXSupportersCountNextGoalDefault();
@@ -136,11 +138,16 @@ function CardForListBody (props) {
136138
<YearAndHeartDiv>
137139
<ElectionYear largeDisplay={!useCampaignSupportThermometer}>
138140
{!!(electionDateYear) && (
139-
<>{electionDateYear}</>
141+
<>
142+
{electionDateYear}
143+
</>
140144
)}
141145
</ElectionYear>
142146
{!useCampaignSupportThermometer && (
143-
<HeartFavoriteToggleLoader campaignXWeVoteId={linkedCampaignXWeVoteId} />
147+
<>
148+
{/* {source} */}
149+
<HeartFavoriteToggleLoader campaignXWeVoteId={linkedCampaignXWeVoteId} supportPolitician={supportPolitician} />
150+
</>
144151
)}
145152
</YearAndHeartDiv>
146153
<SpaceBeforeThermometer />
@@ -160,6 +167,7 @@ function CardForListBody (props) {
160167
<CampaignSupportThermometer
161168
campaignXWeVoteId={linkedCampaignXWeVoteId}
162169
finalElectionDateInPast={finalElectionDateInPast}
170+
supportPolitician={supportPolitician}
163171
/>
164172
</Suspense>
165173
)}
@@ -484,6 +492,7 @@ function CardForListBody (props) {
484492
);
485493
}
486494
CardForListBody.propTypes = {
495+
source: PropTypes.string,
487496
ballotItemDisplayName: PropTypes.string.isRequired, // Changed to be required due to error where this shows as undefined [WV-379] when fetching from PoliticianStore 7/18/2024
488497
candidateWeVoteId: PropTypes.string,
489498
classes: PropTypes.object,
@@ -504,6 +513,7 @@ CardForListBody.propTypes = {
504513
searchText: PropTypes.string,
505514
showPoliticianOpenInNewWindow: PropTypes.bool,
506515
stateCode: PropTypes.string,
516+
supportPolitician: PropTypes.bool,
507517
// supportersCount: PropTypes.number.isRequired,
508518
// supportersCountNextGoalRaw: PropTypes.number,
509519
tagIdBaseName: PropTypes.string,

src/js/common/components/Settings/CompleteYourProfile.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ class CompleteYourProfile extends Component {
293293
);
294294
}
295295

296+
// console.log('CompleteYourProfile supportCampaign:', supportCampaign, ', supportCampaignOnCampaignHome: ', supportCampaignOnCampaignHome);
296297
// console.log('CompleteYourProfile render voter found');
297298
let buttonText = 'Continue';
298299
let introductionText = null;

src/js/common/components/Settings/CompleteYourProfileModal.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class CompleteYourProfileModal extends Component {
6868
supportPolitician,
6969
} = this.props;
7070

71+
// console.log('CompleteYourProfileModal supportCampaign:', supportCampaign, ', supportPolitician:', supportPolitician);
7172
const { voter } = this.state;
7273
if (!voter) {
7374
// console.log('CompleteYourProfileModal render voter NOT found');
@@ -79,8 +80,12 @@ class CompleteYourProfileModal extends Component {
7980
completeProfileTitle = <span>becomeMember</span>;
8081
} else if (startCampaign) {
8182
completeProfileTitle = <span>Complete your profile</span>;
82-
} else if (supportCampaign || supportPolitician) {
83+
} else if (supportCampaign) {
8384
completeProfileTitle = <span>Complete your support</span>;
85+
} else if (supportPolitician) {
86+
completeProfileTitle = <span>Complete your profile</span>;
87+
} else {
88+
completeProfileTitle = <span>Complete your profile</span>;
8489
}
8590
return (
8691
<Dialog
@@ -114,6 +119,7 @@ class CompleteYourProfileModal extends Component {
114119
functionToUseWhenProfileComplete={this.props.functionToUseWhenProfileComplete}
115120
startCampaign={startCampaign}
116121
supportCampaign={supportCampaign}
122+
supportPolitician={supportPolitician}
117123
/>
118124
</section>
119125
</DialogContent>
Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import React, { Component } from 'react';
2-
import PropTypes from 'prop-types';
32
import AppObservableStore, { messageService } from '../../stores/AppObservableStore';
43
import CompleteYourProfileModal from './CompleteYourProfileModal';
54
import { renderLog } from '../../utils/logging';
5+
import saveCampaignSupportAndGoToNextPage from '../../utils/saveCampaignSupportAndGoToNextPage';
6+
import CampaignSupporterStore from '../../stores/CampaignSupporterStore';
7+
import initializejQuery from '../../utils/initializejQuery';
8+
import CampaignSupporterActions from '../../actions/CampaignSupporterActions';
9+
import CampaignStartActions from '../../actions/CampaignStartActions';
10+
import historyPush from '../../utils/historyPush';
611

712
class CompleteYourProfileModalController extends Component {
813
constructor (props) {
@@ -14,42 +19,94 @@ class CompleteYourProfileModalController extends Component {
1419
componentDidMount () {
1520
// console.log('CompleteYourProfileModalController, componentDidMount');
1621
this.appStateSubscription = messageService.getMessage().subscribe(() => this.onAppObservableStoreChange());
17-
const showCompleteYourProfileModal = AppObservableStore.showCompleteYourProfileModal();
18-
this.setState({
19-
showCompleteYourProfileModal,
20-
});
22+
const showCompleteYourProfileModalDict = AppObservableStore.showCompleteYourProfileModalDict();
23+
// console.log('CompleteYourProfileModalController componentDidMount:', showCompleteYourProfileModalDict);
24+
this.setState(showCompleteYourProfileModalDict);
2125
}
2226

2327
componentWillUnmount () {
2428
this.appStateSubscription.unsubscribe();
2529
}
2630

2731
onAppObservableStoreChange () {
28-
const showCompleteYourProfileModal = AppObservableStore.showCompleteYourProfileModal();
29-
this.setState({
30-
showCompleteYourProfileModal,
31-
});
32+
const showCompleteYourProfileModalDict = AppObservableStore.showCompleteYourProfileModalDict();
33+
// console.log('CompleteYourProfileModalController onAppObservableStoreChange', showCompleteYourProfileModalDict);
34+
this.setState(showCompleteYourProfileModalDict);
3235
}
3336

37+
functionToUseWhenProfileComplete = () => {
38+
const { campaignXWeVoteId, challengeWeVoteId, startCampaign, supportCampaign, supportPolitician } = this.state;
39+
if (supportCampaign) {
40+
if (campaignXWeVoteId) {
41+
const campaignSupported = true;
42+
const campaignSupportedChanged = true;
43+
// From this page we always send value for 'visibleToPublic'
44+
let visibleToPublic = CampaignSupporterStore.getVisibleToPublic();
45+
const visibleToPublicChanged = CampaignSupporterStore.getVisibleToPublicQueuedToSaveSet();
46+
if (visibleToPublicChanged) {
47+
// If it has changed, use new value
48+
visibleToPublic = CampaignSupporterStore.getVisibleToPublicQueuedToSave();
49+
}
50+
// console.log('functionToUseWhenProfileComplete, blockCampaignXRedirectOnSignIn:', AppObservableStore.blockCampaignXRedirectOnSignIn());
51+
const saveVisibleToPublic = true;
52+
if (!AppObservableStore.blockCampaignXRedirectOnSignIn()) {
53+
initializejQuery(() => {
54+
CampaignSupporterActions.supportCampaignSave(campaignXWeVoteId, campaignSupported, campaignSupportedChanged, visibleToPublic, saveVisibleToPublic); // campaignSupporterSave
55+
}, this.goToNextPage());
56+
}
57+
} else {
58+
console.log('CompleteYourProfileModalController supportCampaign functionToUseWhenProfileComplete campaignXWeVoteId not found');
59+
}
60+
} else if (supportPolitician) {
61+
if (campaignXWeVoteId) {
62+
saveCampaignSupportAndGoToNextPage(campaignXWeVoteId); // campaignXBasePath
63+
} else if (challengeWeVoteId) {
64+
saveCampaignSupportAndGoToNextPage(challengeWeVoteId); // challengeBasePath
65+
} else {
66+
console.log('CompleteYourProfileModalController supportPolitician functionToUseWhenProfileComplete neither campaignXWeVoteId nor challengeWeVoteId found');
67+
}
68+
} else if (startCampaign) {
69+
CampaignStartActions.inDraftModeSave('', false);
70+
historyPush('/profile/started');
71+
} else {
72+
console.log('CompleteYourProfileModalController functionToUseWhenProfileComplete WeVoteId not found');
73+
}
74+
};
75+
3476
closeModal () {
3577
// console.log('CompleteYourProfileModalController closeModal');
36-
AppObservableStore.setShowCompleteYourProfileModal(false);
78+
const modalDictionary = {
79+
becomeMember: false,
80+
campaignXWeVoteId: '',
81+
challengeWeVoteId: '',
82+
clickSource: 'COMPLETE_YOUR_PROFILE_MODAL_CONTROLLER ',
83+
isOppose: false,
84+
isStopOpposing: false,
85+
isStopSupporting: false,
86+
isSupport: false,
87+
politicianWeVoteId: '',
88+
showModal: false,
89+
startCampaign: false,
90+
supportCampaign: false,
91+
supportPolitician: false,
92+
};
93+
AppObservableStore.setShowCompleteYourProfileModalDict(modalDictionary);
3794
}
3895

3996
render () {
4097
renderLog('CompleteYourProfileModalController'); // Set LOG_RENDER_EVENTS to log all renders
4198

42-
const { becomeMember, campaignXWeVoteId, startCampaign, supportCampaign, supportPolitician } = this.props;
43-
const { showCompleteYourProfileModal } = this.state;
99+
const { becomeMember, campaignXWeVoteId, showModal, startCampaign, supportCampaign, supportPolitician } = this.state;
100+
// console.log('CompleteYourProfileModalController render', showModal, ', supportCampaign:', supportCampaign, ', supportPolitician:', supportPolitician);
44101
return (
45102
<div>
46-
{showCompleteYourProfileModal && (
103+
{showModal && (
47104
<CompleteYourProfileModal
48105
becomeMember={becomeMember}
49106
campaignXWeVoteId={campaignXWeVoteId}
50107
closeFunction={this.closeModal}
51-
functionToUseWhenProfileComplete={this.props.functionToUseWhenProfileComplete}
52-
show={showCompleteYourProfileModal}
108+
functionToUseWhenProfileComplete={this.functionToUseWhenProfileComplete}
109+
show={showModal}
53110
startCampaign={startCampaign}
54111
supportCampaign={supportCampaign}
55112
supportPolitician={supportPolitician}
@@ -59,13 +116,5 @@ class CompleteYourProfileModalController extends Component {
59116
);
60117
}
61118
}
62-
CompleteYourProfileModalController.propTypes = {
63-
becomeMember: PropTypes.bool,
64-
campaignXWeVoteId: PropTypes.string,
65-
functionToUseWhenProfileComplete: PropTypes.func.isRequired,
66-
startCampaign: PropTypes.bool,
67-
supportCampaign: PropTypes.bool,
68-
supportPolitician: PropTypes.bool,
69-
};
70119

71120
export default CompleteYourProfileModalController;

src/js/common/components/Widgets/HeartFavoriteToggle/HeartFavoriteToggleBase.jsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ class HeartFavoriteToggleBase extends Component {
124124
voterSupportsDelayed: false,
125125
voterOpposesDelayed: false,
126126
});
127-
this.timer = setTimeout(() => {
127+
// this.timer =
128+
setTimeout(() => {
128129
if (voterOpposesDelayed) {
129130
this.handleOpposeClick();
130131
} else if (voterSupportsDelayed) {
@@ -416,11 +417,11 @@ class HeartFavoriteToggleBase extends Component {
416417
return 'Favoriting helps us match you to other candidates who share your values.';
417418
} else if (voterOpposesLocalPrevious) {
418419
if (organizationWeVoteId) {
419-
return `Favorited by ${supportersCount} people. Favoriting helps us match you to candidates who share your values.`;
420+
return `Favorited by ${supportersCount} ${supportersCount === 1 ? 'person' : 'people'}. Favoriting helps us match you to candidates who share your values.`;
420421
} else if (campaignXWeVoteId) {
421-
return `Favorited by ${supportersCount} people. Favoriting helps us match you to other candidates who share your values.`;
422+
return `Favorited by ${supportersCount} ${supportersCount === 1 ? 'person' : 'people'}. Favoriting helps us match you to other candidates who share your values.`;
422423
}
423-
return `Favorited by ${supportersCount} people. Favoriting helps us match you to other candidates who share your values.`;
424+
return `Favorited by ${supportersCount} ${supportersCount === 1 ? 'person' : 'people'}. Favoriting helps us match you to other candidates who share your values.`;
424425
} else {
425426
return 'Remove Favorite';
426427
}
@@ -438,18 +439,18 @@ class HeartFavoriteToggleBase extends Component {
438439

439440
if (!voterOpposesLocalPrevious && !voterSupportsLocalPrevious) {
440441
if (organizationWeVoteId) {
441-
return `Disliked by ${opposersCount} people. Disliking helps us match you to candidates who share your values.`;
442+
return `Disliked by ${opposersCount} ${opposersCount === 1 ? 'person' : 'people'}. Disliking helps us match you to candidates who share your values.`;
442443
} else if (campaignXWeVoteId) {
443-
return `Disliked by ${opposersCount} people. Disliking helps us match you to other candidates who share your values.`;
444+
return `Disliked by ${opposersCount} ${opposersCount === 1 ? 'person' : 'people'}. Disliking helps us match you to other candidates who share your values.`;
444445
}
445-
return `Disliked by ${opposersCount} people. Disliking helps us match you to other candidates who share your values.`;
446+
return `Disliked by ${opposersCount} ${opposersCount === 1 ? 'person' : 'people'}. Disliking helps us match you to other candidates who share your values.`;
446447
} else if (voterSupportsLocalPrevious) {
447448
if (organizationWeVoteId) {
448-
return `Disliked by ${opposersCount} people. Disliking helps us match you to candidates who share your values.`;
449+
return `Disliked by ${opposersCount} ${opposersCount === 1 ? 'person' : 'people'}. Disliking helps us match you to candidates who share your values.`;
449450
} else if (campaignXWeVoteId) {
450-
return `Disliked by ${opposersCount} people. Disliking helps us match you to other candidates who share your values.`;
451+
return `Disliked by ${opposersCount} ${opposersCount === 1 ? 'person' : 'people'}. Disliking helps us match you to other candidates who share your values.`;
451452
}
452-
return `Disliked by ${opposersCount} people. Disliking helps us match you to other candidates who share your values.`;
453+
return `Disliked by ${opposersCount} ${opposersCount === 1 ? 'person' : 'people'}. Disliking helps us match you to other candidates who share your values.`;
453454
} else {
454455
return 'Remove Dislike';
455456
}

0 commit comments

Comments
 (0)