Skip to content

Commit c5ac5cc

Browse files
committed
fixes for #5341
1 parent 3012dd7 commit c5ac5cc

File tree

8 files changed

+134
-135
lines changed

8 files changed

+134
-135
lines changed

__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -37,78 +37,5 @@ exports[`renders email preferences setting page correctly 1`] = `
3737
Resubscribe
3838
</ThemedButton>
3939
</div>
40-
<div
41-
className="src-shared-components-Settings-Preferences-Email-___styles__sub-title___2Fh1W"
42-
>
43-
Newsletters
44-
</div>
45-
<div
46-
className="src-shared-components-Settings-Preferences-Email-___styles__preferences-container___38AVF"
47-
>
48-
<ToggleableItem
49-
disabled={true}
50-
id="9f950b43a1"
51-
onToggle={[Function]}
52-
primaryText="Challenge Pipeline"
53-
secondaryText="Subscribe to this newsletter if you want to get updates on the types of challenges coming up in the future. To view these challenges at your leisure you can always visit the <a href=\\"https://www.topcoder.com/community/pipeline\\" style=\\"color:#0d61bf;text-decoration:underline\\">Challenge Pipeline</a> page."
54-
value="9f950b43a1"
55-
/>
56-
<ToggleableItem
57-
disabled={true}
58-
id="d0c48e9da3"
59-
onToggle={[Function]}
60-
primaryText="Gig Work"
61-
secondaryText="This newsletter gets sent out at various times, specifically when we have an opportunity of mass appeal. For more information you can visit the <a href=\\"https://www.topcoder.com/community/taas\\" style=\\"color:#0d61bf;text-decoration:underline\\">Gig Work</a> page."
62-
value="d0c48e9da3"
63-
/>
64-
<ToggleableItem
65-
disabled={true}
66-
id="a8f858cdf1"
67-
onToggle={[Function]}
68-
primaryText="Monthly Newsletter"
69-
secondaryText="This newsletter gets sent out at the end of every month and contains a variety of important information across all of our tracks."
70-
value="a8f858cdf1"
71-
/>
72-
<ToggleableItem
73-
disabled={true}
74-
id="5e67dba327"
75-
onToggle={[Function]}
76-
primaryText="Marathon Match Reminders"
77-
secondaryText="Receive updates whenever a new marathon match is scheduled."
78-
value="5e67dba327"
79-
/>
80-
<ToggleableItem
81-
disabled={true}
82-
id="9091b438cc"
83-
onToggle={[Function]}
84-
primaryText="Single Round Match (SRM) Reminders"
85-
secondaryText="Attention Competitive Programmers! If there is any newsletter you are subscribing too, it better be this one. Receive updates when a new SRM event is scheduled."
86-
value="9091b438cc"
87-
/>
88-
<ToggleableItem
89-
disabled={true}
90-
id="603c900c32"
91-
onToggle={[Function]}
92-
primaryText="TCO Newsletter"
93-
secondaryText="For all the latest updates surrounding the <a href=\\"https://www.topcoder.com/community/member-programs/topcoder-open\\" style=\\"color:#0d61bf;text-decoration:underline\\">Topcoder Open</a> you should definitely be subscribing to this one. Expect an update in your mailbox every Tuesday!"
94-
value="603c900c32"
95-
/>
96-
<ToggleableItem
97-
disabled={true}
98-
id="3460574ddd"
99-
onToggle={[Function]}
100-
primaryText="Rapid Development Match (RDM) Reminders"
101-
secondaryText="Receive notifications of our brand new RDMs! These rated, development matches will be a fun new way to engage with us!"
102-
value="3460574ddd"
103-
/>
104-
</div>
105-
<div
106-
className="src-shared-components-Settings-Preferences-Email-___styles__sub-title-2___1GflT"
107-
>
108-
Programs
109-
</div>
110-
<div
111-
className="src-shared-components-Settings-Preferences-Email-___styles__preferences-container___38AVF"
112-
/>
11340
</div>
11441
`;

src/server/routes/mailchimp.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ routes.post('/:listId/members', (req, res, next) => new MailchimpService().doReg
2020

2121
routes.get('/:listId/members/:emailHash', (req, res) => new MailchimpService().checkSubscription(req).then(res.send.bind(res)));
2222

23-
routes.put('/:listId/members/:emailHash', (req, res) => new MailchimpService().subscribeInterests(req).then(res.send.bind(res)));
23+
routes.put('/:listId/members/:emailHash', (req, res) => new MailchimpService().updateMember(req).then(res.send.bind(res)));
2424

2525
routes.post('/:listId/members/:emailHash/tags', (req, res) => new MailchimpService().subscribeTags(req).then(res.send.bind(res)));
2626

src/server/services/mailchimp.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export default class MailchimpService {
5151
return res.json();
5252
}
5353

54-
async subscribeInterests(req) {
54+
async updateMember(req) {
5555
const formData = JSON.stringify(req.body);
5656
const res = await fetch(`${this.mailchimpBaseUrl}/lists/${req.params.listId}/members/${req.params.emailHash}`, {
5757
method: 'PUT',

src/shared/actions/newsletterPreferences.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,53 @@ async function updateSubscriptionsDone(
9393
}
9494
}
9595

96+
/**
97+
* Resubscribe member for TC emails/list
98+
* @param {string} emailHash the email
99+
*/
100+
async function resubscribeDone(emailHash, listId = config.NEWSLETTER_SIGNUP.DEFAUL_LIST_ID) {
101+
try {
102+
let error = false;
103+
const fetchUrl = `${PROXY_ENDPOINT}/${listId}/members/${emailHash}`;
104+
105+
const data = {
106+
status: 'subscribed',
107+
};
108+
109+
const formData = JSON.stringify(data);
110+
// use proxy for avoid 'Access-Control-Allow-Origin' bug
111+
await fetch(fetchUrl, {
112+
method: 'PUT',
113+
headers: {
114+
'Content-Type': 'application/json',
115+
},
116+
body: formData,
117+
})
118+
.then((result) => {
119+
if (!result.ok) error = true;
120+
return result.json();
121+
});
122+
123+
return {
124+
email: emailHash,
125+
resubscribe: true,
126+
error,
127+
};
128+
} catch (error) {
129+
return {
130+
email: emailHash,
131+
error,
132+
};
133+
}
134+
}
135+
96136
export default createActions({
97137
NEWSLETTER_PREFERENCES: {
98138
FETCH_DATA_INIT: fetchDataInit,
99139
FETCH_DATA_DONE: fetchDataDone,
100140
UPDATE_TAG_INIT: _.identity,
101141
UPDATE_TAG_DONE: updateSubscriptionsDone,
142+
RESUBSCRIBE_INIT: _.identity,
143+
RESUBSCRIBE_DONE: resubscribeDone,
102144
},
103145
});

src/shared/components/Settings/Preferences/Email/index.jsx

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ export default class EmailPreferences extends React.Component {
9191
if (updated.error) {
9292
toastrError('Error! ', 'Failed to update Your email preferences :-(');
9393
}
94-
const { emailPreferences } = this.state;
94+
const { emailPreferences, status } = this.state;
9595
const { id, checked } = updated;
9696
emailPreferences[id] = checked;
9797

9898
// eslint-disable-next-line react/no-did-update-set-state
9999
this.setState({
100100
emailPreferences,
101+
status: updated.resubscribe ? 'subscribed' : status,
101102
});
102103
toastrSuccess('Success! ', 'Your email preferences were updated.');
103104
}
@@ -110,6 +111,7 @@ export default class EmailPreferences extends React.Component {
110111

111112
render() {
112113
const { emailPreferences, status } = this.state;
114+
const { resubscibeEmails, email } = this.props;
113115
return (
114116
<div styleName="EmailPreferences">
115117
<h1 styleName="title">
@@ -123,54 +125,56 @@ export default class EmailPreferences extends React.Component {
123125
please click the button below and fill out the form.
124126
</p>
125127
<PrimaryButton
126-
// eslint-disable-next-line no-return-assign
127-
onClick={() => window.location.href = 'https://topcoder.us13.list-manage.com/subscribe?u=65bd5a1857b73643aad556093&id=28bfd3c062'}
128+
onClick={() => resubscibeEmails(email)}
128129
>
129130
Resubscribe
130131
</PrimaryButton>
131132
</div>
132-
) : null
133+
) : (
134+
<React.Fragment>
135+
<div styleName="sub-title">Newsletters</div>
136+
<div styleName="preferences-container">
137+
{
138+
map(newsletters, (newsletter) => {
139+
const checked = emailPreferences[newsletter.id];
140+
return (
141+
<ToggleableItem
142+
key={newsletter.id}
143+
id={newsletter.id}
144+
value={newsletter.id}
145+
checked={checked}
146+
primaryText={newsletter.name}
147+
secondaryText={newsletter.desc}
148+
onToggle={e => this.onChange(newsletter.id, e.target.checked)}
149+
disabled={status !== 'subscribed'}
150+
/>
151+
);
152+
})
153+
}
154+
</div>
155+
<div styleName="sub-title-2">Programs</div>
156+
<div styleName="preferences-container">
157+
{
158+
map(programs, (program) => {
159+
const checked = emailPreferences[program.id];
160+
return (
161+
<ToggleableItem
162+
key={program.id}
163+
id={program.id}
164+
value={program.id}
165+
checked={checked}
166+
primaryText={program.name}
167+
secondaryText={program.desc}
168+
onToggle={e => this.onChange(program.id, e.target.checked)}
169+
disabled={status !== 'subscribed'}
170+
/>
171+
);
172+
})
173+
}
174+
</div>
175+
</React.Fragment>
176+
)
133177
}
134-
<div styleName="sub-title">Newsletters</div>
135-
<div styleName="preferences-container">
136-
{
137-
map(newsletters, (newsletter) => {
138-
const checked = emailPreferences[newsletter.id];
139-
return (
140-
<ToggleableItem
141-
key={newsletter.id}
142-
id={newsletter.id}
143-
value={newsletter.id}
144-
checked={checked}
145-
primaryText={newsletter.name}
146-
secondaryText={newsletter.desc}
147-
onToggle={e => this.onChange(newsletter.id, e.target.checked)}
148-
disabled={status !== 'subscribed'}
149-
/>
150-
);
151-
})
152-
}
153-
</div>
154-
<div styleName="sub-title-2">Programs</div>
155-
<div styleName="preferences-container">
156-
{
157-
map(programs, (program) => {
158-
const checked = emailPreferences[program.id];
159-
return checked && (
160-
<ToggleableItem
161-
key={program.id}
162-
id={program.id}
163-
value={program.id}
164-
checked={checked}
165-
primaryText={program.name}
166-
secondaryText={program.desc}
167-
onToggle={e => this.onChange(program.id, e.target.checked)}
168-
disabled={status !== 'subscribed'}
169-
/>
170-
);
171-
})
172-
}
173-
</div>
174178
</div>
175179
);
176180
}
@@ -187,4 +191,5 @@ EmailPreferences.propTypes = {
187191
saveEmailPreferences: PT.func.isRequired,
188192
updated: PT.shape(),
189193
status: PT.string,
194+
resubscibeEmails: PT.func.isRequired,
190195
};

src/shared/containers/EmailSubscribeForm/index.jsx

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,41 +32,42 @@ class SubscribeMailChimpTagContainer extends React.Component {
3232
this.setState((state) => {
3333
const { formData, formErrors } = state;
3434
if (_.isEmpty(formErrors)) {
35-
const { listId, tags } = this.props;
36-
const fetchUrl = `${PROXY_ENDPOINT}/${listId}/members/${formData.email}/tags`;
35+
const { listId, interests } = this.props;
36+
const fetchUrl = `${PROXY_ENDPOINT}/${listId}/members/${formData.email}`;
3737
const data = {
38-
email_address: formData.email,
3938
status: 'subscribed',
40-
tags: tags.map(t => ({ name: t, status: 'active' })),
41-
merge_fields: {
42-
FNAME: formData.fname,
43-
LNAME: formData.lname,
44-
},
39+
interests,
4540
};
4641
fetch(fetchUrl, {
47-
method: 'POST',
42+
method: 'PUT',
4843
headers: {
4944
'Content-Type': 'application/json',
5045
},
5146
body: JSON.stringify(data),
5247
}).then(result => result.json()).then((dataResponse) => {
53-
if (dataResponse.status === 204) {
48+
if (dataResponse.status === 'subscribed') {
5449
// regist success
5550
return this.setState({
5651
subscribing: false,
5752
subsribed: true,
5853
error: '',
5954
});
6055
}
61-
if (dataResponse.status === 404) {
56+
if (dataResponse.status === 400) {
6257
// new email register it for list and add tags
63-
data.tags = tags;
6458
return fetch(`${PROXY_ENDPOINT}/${listId}/members`, {
6559
method: 'POST',
6660
headers: {
6761
'Content-Type': 'application/json',
6862
},
69-
body: JSON.stringify(data),
63+
body: JSON.stringify({
64+
...data,
65+
email_address: formData.email,
66+
merge_fields: {
67+
FNAME: formData.fname,
68+
LNAME: formData.lname,
69+
},
70+
}),
7071
})
7172
.then(result => result.json()).then((rsp) => {
7273
this.setState({
@@ -79,7 +80,7 @@ class SubscribeMailChimpTagContainer extends React.Component {
7980
return this.setState({
8081
subscribing: false,
8182
subsribed: false,
82-
error: `Error ${dataResponse.status} when assigning tags to ${formData.email}`,
83+
error: `Error ${dataResponse.status} when subscribing ${formData.email}`,
8384
});
8485
})
8586
.catch((e) => {
@@ -209,7 +210,7 @@ SubscribeMailChimpTagContainer.defaultProps = {
209210

210211
SubscribeMailChimpTagContainer.propTypes = {
211212
listId: PT.string.isRequired,
212-
tags: PT.arrayOf(PT.string).isRequired,
213+
interests: PT.shape().isRequired,
213214
title: PT.string,
214215
btnText: PT.string,
215216
successTitle: PT.string,

src/shared/containers/NewsletterPreferences.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class NewsletterPreferencesContainer extends React.Component {
2020

2121
render() {
2222
const {
23-
loading, error, preferences, saveEmailPreferences, email, updated, status,
23+
loading, error, preferences, saveEmailPreferences, email, updated, status, resubscibeEmails,
2424
} = this.props;
2525
if (loading || !preferences) return <LoadingIndicator />;
2626
if (error) {
@@ -33,6 +33,7 @@ class NewsletterPreferencesContainer extends React.Component {
3333
saveEmailPreferences={saveEmailPreferences}
3434
updated={updated}
3535
status={status}
36+
resubscibeEmails={resubscibeEmails}
3637
/>
3738
);
3839
}
@@ -55,6 +56,7 @@ NewsletterPreferencesContainer.propTypes = {
5556
email: PT.string.isRequired,
5657
updated: PT.shape(),
5758
status: PT.string,
59+
resubscibeEmails: PT.func.isRequired,
5860
};
5961

6062
function mapStateToProps(state) {
@@ -81,6 +83,10 @@ function mapDispatchToProps(dispatch) {
8183
dispatch(actions.newsletterPreferences.updateTagInit());
8284
dispatch(actions.newsletterPreferences.updateTagDone(email, id, checked));
8385
},
86+
resubscibeEmails: (email) => {
87+
dispatch(actions.newsletterPreferences.resubscribeInit());
88+
dispatch(actions.newsletterPreferences.resubscribeDone(email));
89+
},
8490
};
8591
}
8692

0 commit comments

Comments
 (0)