Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 1d104aa

Browse files
committed
Refactored Report Popup to more general EmailPopup
Replaced email logic for extension request with Email Popup
1 parent 3fb3593 commit 1d104aa

File tree

17 files changed

+201
-125
lines changed

17 files changed

+201
-125
lines changed

config/dev.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ module.exports = {
99
*/
1010
CONNECT_WEBSITE_URL: "https://connect.topcoder-dev.com",
1111

12-
/**
13-
* Email to request extension
14-
*/
15-
EMAIL_REQUEST_EXTENSION: "[email protected]",
16-
1712
API: {
1813
V5: "https://api.topcoder-dev.com/v5",
1914
V3: "https://api.topcoder-dev.com/v3",

config/prod.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ module.exports = {
99
*/
1010
CONNECT_WEBSITE_URL: "https://connect.topcoder.com",
1111

12-
/**
13-
* Email to request extension
14-
*/
15-
EMAIL_REQUEST_EXTENSION: "[email protected]",
16-
1712
API: {
1813
V5: "https://api.topcoder.com/v5",
1914
V3: "https://api.topcoder.com/v3",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Report popup actions
3+
*/
4+
import { ACTION_TYPE } from "constants";
5+
6+
/**
7+
* Action to create an email popup and open it
8+
* @param {Object} popupOptions Options to customize popup appearance and behaviour
9+
* @param {Object} data Data to send to server with email text
10+
*/
11+
export const openEmailPopup = (popupOptions, data) => ({
12+
type: ACTION_TYPE.OPEN_EMAIL_POPUP,
13+
payload: { popupOptions, data },
14+
});
15+
16+
/**
17+
* Action to close an email popup
18+
*/
19+
export const closeEmailPopup = () => ({
20+
type: ACTION_TYPE.CLOSE_EMAIL_POPUP,
21+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Use email popup hook
3+
*/
4+
5+
import { useDispatch } from "react-redux";
6+
import { openEmailPopup } from "../actions";
7+
8+
/**
9+
* Hook to allow email popup to be opened by any other component
10+
* (as long as it is mounted somewhere in the tree)
11+
*
12+
* @returns func A wrapper around the open report dispatch
13+
*/
14+
export const useEmailPopup = () => {
15+
const dispatch = useDispatch();
16+
17+
return (popupOptions, data) => {
18+
dispatch(openEmailPopup(popupOptions, data));
19+
};
20+
};
Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,49 @@
11
/**
2-
* A report popup used to report issues with teams or team members
2+
* An email popup used to format and send emails for reporting issues
3+
* and requesting extensions
34
*/
45

56
import React, { useCallback, useState } from "react";
7+
import _ from "lodash";
68
import { useSelector, useDispatch } from "react-redux";
79
import { toastr } from "react-redux-toastr";
8-
import { closeReport } from "./actions";
10+
import { closeEmailPopup } from "./actions";
911
import BaseModal from "components/BaseModal";
1012
import TextArea from "components/TextArea";
1113
import Button from "../Button";
12-
import { postReport } from "services/teams";
14+
import { postEmail } from "services/teams";
1315
import CenteredSpinner from "components/CenteredSpinner";
1416

15-
function ReportPopup() {
16-
const { isOpen, teamName, teamId, memberHandle } = useSelector(
17-
(state) => state.reportPopup
17+
function EmailPopup() {
18+
const { isOpen, popupOptions, data } = useSelector(
19+
(state) => state.emailPopup
1820
);
1921

2022
const dispatch = useDispatch();
2123
const [textVal, setTextVal] = useState("");
2224
const [isLoading, setIsLoading] = useState(false);
2325

24-
const submitReport = () => {
26+
const submitEmail = () => {
2527
setIsLoading(true);
2628

27-
postReport(teamName, teamId, textVal, memberHandle)
29+
_.set(data, popupOptions.textDataField, textVal);
30+
31+
postEmail(data)
2832
.then(() => {
2933
setIsLoading(false);
3034
closeModal();
31-
toastr.success("Report submitted successfully");
35+
toastr.success("Email submitted successfully");
3236
})
3337
.catch((err) => {
3438
setIsLoading(false);
3539

36-
toastr.error("Report failed", err.message);
40+
toastr.error("Email failed to send", err.message);
3741
});
3842
};
3943

4044
const button = (
4145
<Button
42-
onClick={() => submitReport()}
46+
onClick={() => submitEmail()}
4347
size="medium"
4448
isSubmit
4549
disabled={textVal.trim().length < 1 || isLoading}
@@ -49,17 +53,15 @@ function ReportPopup() {
4953
);
5054

5155
const closeModal = useCallback(() => {
52-
dispatch(closeReport());
56+
dispatch(closeEmailPopup());
5357
setTextVal("");
5458
}, [dispatch]);
5559

5660
return (
5761
<BaseModal
5862
open={isOpen}
5963
onClose={closeModal}
60-
title={`Issue Report - ${teamName}${
61-
memberHandle ? " - " + memberHandle : ""
62-
}`}
64+
title={popupOptions.title}
6365
button={button}
6466
disabled={isLoading}
6567
>
@@ -69,11 +71,11 @@ function ReportPopup() {
6971
<TextArea
7072
value={textVal}
7173
onChange={setTextVal}
72-
placeholder="Describe your issue"
74+
placeholder={popupOptions.textPlaceholder}
7375
/>
7476
)}
7577
</BaseModal>
7678
);
7779
}
7880

79-
export default ReportPopup;
81+
export default EmailPopup;

src/components/ReportPopup/reducers/index.js renamed to src/components/EmailPopup/reducers/index.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
/**
2-
* Reducer for Report popup
2+
* Reducer for Email popup
33
*/
44

55
import { ACTION_TYPE } from "constants";
66

77
const initialState = {
8-
teamName: undefined,
9-
teamId: undefined,
10-
memberHandle: undefined,
118
isOpen: false,
9+
popupOptions: {
10+
title: "",
11+
textPlaceholder: "",
12+
textDataField: "",
13+
},
14+
data: null,
1215
};
1316

1417
const reducer = (state = initialState, action) => {
1518
switch (action.type) {
16-
case ACTION_TYPE.OPEN_REPORT:
19+
case ACTION_TYPE.OPEN_EMAIL_POPUP:
1720
return {
1821
...state,
1922
...action.payload,
2023
isOpen: true,
2124
};
2225

23-
case ACTION_TYPE.CLOSE_REPORT:
26+
case ACTION_TYPE.CLOSE_EMAIL_POPUP:
2427
return {
2528
...state,
2629
isOpen: false,

src/components/ReportPopup/actions/index.js

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/components/ReportPopup/hooks/useReportPopup.js

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/constants/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,10 @@ export const ACTION_TYPE = {
183183
AUTH_CLEAR_TEAM_MEMBERS: "AUTH_CLEAR_TEAM_MEMBERS",
184184

185185
/*
186-
Report Popup
186+
Email Popup
187187
*/
188-
OPEN_REPORT: "OPEN_REPORT",
189-
CLOSE_REPORT: "CLOSE_REPORT",
188+
OPEN_EMAIL_POPUP: "OPEN_EMAIL_POPUP",
189+
CLOSE_EMAIL_POPUP: "CLOSE_EMAIL_POPUP",
190190

191191
/*
192192
Team (project) Members

src/reducers/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { combineReducers } from "redux";
55
import { reducer as toastrReducer } from "react-redux-toastr";
66
import positionDetailsReducer from "../routes/PositionDetails/reducers";
77
import teamMembersReducer from "../routes/TeamAccess/reducers";
8-
import reportPopupReducer from "../components/ReportPopup/reducers";
8+
import emailPopupReducer from "../components/EmailPopup/reducers";
99
import authUserReducer from "../hoc/withAuthentication/reducers";
1010

1111
const rootReducer = combineReducers({
1212
toastr: toastrReducer,
1313
positionDetails: positionDetailsReducer,
1414
teamMembers: teamMembersReducer,
15-
reportPopup: reportPopupReducer,
15+
emailPopup: emailPopupReducer,
1616
authUser: authUserReducer,
1717
});
1818

src/routes/MyTeamsDetails/components/TeamMembers/index.jsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,22 @@ import { TEAM_MEMBERS_PER_PAGE } from "constants";
1919
import {
2020
formatDateRange,
2121
formatMoney,
22-
formatRequestExtensionUrl,
22+
formatReportData,
23+
formatReportPopup,
24+
formatExtensionData,
25+
formatExtensionPopup,
2326
} from "utils/format";
2427
import Input from "components/Input";
2528
import { skillShape } from "components/SkillsList";
26-
import { useReportPopup } from "components/ReportPopup/hooks/useReportPopup";
29+
import { useEmailPopup } from "components/EmailPopup/hooks/useEmailPopup";
2730
import { hasPermission } from "utils/permissions";
2831
import { PERMISSIONS } from "constants/permissions";
2932

3033
const TeamMembers = ({ team }) => {
3134
const { resources, jobs } = team;
3235
const [filter, setFilter] = useState("");
3336

34-
const showReportPopup = useReportPopup();
37+
const showEmailPopup = useEmailPopup();
3538

3639
const filteredMembers = useMemo(
3740
() =>
@@ -158,24 +161,38 @@ const TeamMembers = ({ team }) => {
158161
`/taas/myteams/${team.id}/rb/${member.id}/edit`
159162
);
160163
},
161-
hidden: !hasPermission(PERMISSIONS.UPDATE_RESOURCE_BOOKING),
164+
hidden: !hasPermission(
165+
PERMISSIONS.UPDATE_RESOURCE_BOOKING
166+
),
162167
},
163168
{
164169
separator: true,
165-
hidden: !hasPermission(PERMISSIONS.UPDATE_RESOURCE_BOOKING),
170+
hidden: !hasPermission(
171+
PERMISSIONS.UPDATE_RESOURCE_BOOKING
172+
),
166173
},
167174
{
168175
label: "Report an Issue",
169176
action: () => {
170-
showReportPopup(team.name, team.id, member.handle);
177+
showEmailPopup(
178+
formatReportPopup(team.name, member.handle),
179+
formatReportData(
180+
team.name,
181+
team.id,
182+
member.handle
183+
)
184+
);
171185
},
172186
},
173187
{
174188
label: "Request an Extension",
175189
action: () => {
176-
window.open(
177-
formatRequestExtensionUrl(
178-
`Request extension for ${member.handle} on ${team.name}`
190+
showEmailPopup(
191+
formatExtensionPopup(team.name, member.handle),
192+
formatExtensionData(
193+
team.name,
194+
team.id,
195+
member.handle
179196
)
180197
);
181198
},

src/routes/MyTeamsDetails/components/TeamSummary/index.jsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,19 @@ import {
1010
formatConnectProjectUrl,
1111
formatMoney,
1212
formatRemainingTimeForTeam,
13+
formatReportPopup,
14+
formatReportData,
1315
} from "utils/format";
1416
import IconClock from "../../../../assets/images/icon-clock.svg";
1517
import IconMoney from "../../../../assets/images/icon-money.svg";
1618
// import IconRating from "../../../../assets/images/icon-rating.svg";
1719
import Button from "components/Button";
18-
import { useReportPopup } from "components/ReportPopup/hooks/useReportPopup";
20+
import { useEmailPopup } from "components/EmailPopup/hooks/useEmailPopup";
1921
// import Rating from "components/Rating";
2022
import "./styles.module.scss";
2123

2224
const TeamSummary = ({ team }) => {
23-
const showReportPopup = useReportPopup();
25+
const showReportPopup = useEmailPopup();
2426

2527
return (
2628
<div styleName="team-summary">
@@ -61,7 +63,10 @@ const TeamSummary = ({ team }) => {
6163
type="warning"
6264
size="medium"
6365
onClick={() => {
64-
showReportPopup(team.name, team.id);
66+
showReportPopup(
67+
formatReportPopup(team.name),
68+
formatReportData(team.name, team.id)
69+
);
6570
}}
6671
target="_blank"
6772
>

src/routes/MyTeamsDetails/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import TeamSummary from "./components/TeamSummary";
1515
import TeamMembers from "./components/TeamMembers";
1616
import TeamPositions from "./components/TeamPositions";
1717
import withAuthentication from "../../hoc/withAuthentication";
18-
import ReportPopup from "components/ReportPopup";
18+
import EmailPopup from "components/EmailPopup";
1919

2020
const MyTeamsDetails = ({ teamId }) => {
2121
const [team, loadingError] = useData(getTeamById, teamId);
@@ -36,7 +36,7 @@ const MyTeamsDetails = ({ teamId }) => {
3636
/>
3737
</>
3838
)}
39-
<ReportPopup />
39+
<EmailPopup />
4040
</Page>
4141
);
4242
};

0 commit comments

Comments
 (0)