Skip to content

Commit 484a70f

Browse files
authored
[staff] Update staff dashboard (#4205)
## Description ## Tests
2 parents 25e6c2c + 51aa4cf commit 484a70f

File tree

3 files changed

+316
-38
lines changed

3 files changed

+316
-38
lines changed

infra/staff/src/App.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ interface Security {
4747
isTwoFactorEnabled: boolean;
4848
passkeys: string;
4949
passkeyCount: number;
50+
canDisableEmailMFA: boolean;
5051
}
5152

5253
interface UserResponse {
@@ -189,6 +190,10 @@ const App: React.FC = () => {
189190
0) > 0
190191
? "Enabled"
191192
: "Disabled",
193+
"Can Disable EmailMFA": userDataResponse.details
194+
?.profileData.canDisableEmailMFA
195+
? "Yes"
196+
: "No",
192197
AuthCodes: `${userDataResponse.authCodes ?? 0}`,
193198
},
194199
};
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import {
2+
Button,
3+
Dialog,
4+
DialogActions,
5+
DialogContent,
6+
DialogContentText,
7+
DialogTitle,
8+
Paper,
9+
} from "@mui/material";
10+
import React, { useState } from "react";
11+
import { getEmail, getToken } from "../App"; // Import getEmail and getToken functions
12+
import { apiOrigin } from "../services/support";
13+
14+
interface UserData {
15+
subscription?: {
16+
userID: string;
17+
// Add other properties as per your API response structure
18+
};
19+
// Add other properties as per your API response structure
20+
}
21+
22+
interface ToggleEmailMFAProps {
23+
open: boolean;
24+
handleClose: () => void;
25+
handleToggleEmailMFA: (status: boolean) => void; // Callback to handle toggling Email MFA
26+
}
27+
28+
const ToggleEmailMFA: React.FC<ToggleEmailMFAProps> = ({
29+
open,
30+
handleClose,
31+
handleToggleEmailMFA,
32+
}) => {
33+
const [loading, setLoading] = useState(false);
34+
35+
const handleToggle = async (enable: boolean) => {
36+
try {
37+
setLoading(true);
38+
const email = getEmail();
39+
const token = getToken();
40+
41+
if (!email) {
42+
throw new Error("Email not found");
43+
}
44+
45+
if (!token) {
46+
throw new Error("Token not found");
47+
}
48+
49+
const encodedEmail = encodeURIComponent(email);
50+
51+
// Fetch user data
52+
const userUrl = `${apiOrigin}/admin/user?email=${encodedEmail}`;
53+
const userResponse = await fetch(userUrl, {
54+
method: "GET",
55+
headers: {
56+
"Content-Type": "application/json",
57+
"X-Auth-Token": token,
58+
},
59+
});
60+
if (!userResponse.ok) {
61+
throw new Error("Failed to fetch user data");
62+
}
63+
const userData = (await userResponse.json()) as UserData;
64+
const userId = userData.subscription?.userID;
65+
66+
if (!userId) {
67+
throw new Error("User ID not found");
68+
}
69+
70+
// Toggle Email MFA action
71+
const toggleEmailMFAUrl = `${apiOrigin}/admin/user/update-email-mfa`;
72+
const body = JSON.stringify({ userID: userId, emailMFA: enable });
73+
const toggleEmailMFAResponse = await fetch(toggleEmailMFAUrl, {
74+
method: "POST",
75+
headers: {
76+
"Content-Type": "application/json",
77+
"X-Auth-Token": token,
78+
},
79+
body: body,
80+
});
81+
82+
if (!toggleEmailMFAResponse.ok) {
83+
const errorResponse = await toggleEmailMFAResponse.text();
84+
throw new Error(`Failed to update Email MFA: ${errorResponse}`);
85+
}
86+
87+
handleToggleEmailMFA(enable); // Notify parent component of successful action with status
88+
handleClose(); // Close dialog on successful action
89+
console.log(
90+
`Email MFA ${enable ? "enabled" : "disabled"} successfully`,
91+
);
92+
} catch (error) {
93+
if (error instanceof Error) {
94+
alert(error.message);
95+
} else {
96+
alert("Failed to update Email MFA");
97+
}
98+
} finally {
99+
setLoading(false);
100+
}
101+
};
102+
103+
const handleCancel = () => {
104+
handleClose(); // Close dialog
105+
};
106+
107+
return (
108+
<div>
109+
<Dialog
110+
open={open}
111+
onClose={handleClose}
112+
aria-labelledby="alert-dialog-title"
113+
aria-describedby="alert-dialog-description"
114+
PaperComponent={Paper}
115+
sx={{
116+
width: "499px",
117+
height: "286px",
118+
margin: "auto",
119+
display: "flex",
120+
flexDirection: "column",
121+
alignItems: "center",
122+
justifyContent: "center",
123+
}}
124+
BackdropProps={{
125+
style: {
126+
backgroundColor: "rgba(255, 255, 255, 0.9)", // Semi-transparent backdrop
127+
},
128+
}}
129+
>
130+
<DialogTitle id="alert-dialog-title">
131+
{"Toggle Email MFA"}
132+
</DialogTitle>
133+
<DialogContent>
134+
<DialogContentText id="alert-dialog-description">
135+
Do you want to enable or disable Email MFA for this
136+
account?
137+
</DialogContentText>
138+
</DialogContent>
139+
<DialogActions sx={{ justifyContent: "center" }}>
140+
<Button
141+
onClick={handleCancel}
142+
sx={{
143+
bgcolor: "white",
144+
color: "black",
145+
"&:hover": { bgcolor: "#FAFAFA" },
146+
}}
147+
>
148+
Cancel
149+
</Button>
150+
<Button
151+
onClick={() => {
152+
handleToggle(true).catch((error: unknown) =>
153+
console.error(error),
154+
);
155+
}}
156+
sx={{
157+
bgcolor: "#4CAF50",
158+
color: "white",
159+
"&:hover": { bgcolor: "#45A049" },
160+
}}
161+
disabled={loading}
162+
>
163+
{loading ? "Processing..." : "Enable Email MFA"}
164+
</Button>
165+
<Button
166+
onClick={() => {
167+
handleToggle(false).catch((error: unknown) =>
168+
console.error(error),
169+
);
170+
}}
171+
sx={{
172+
bgcolor: "#F4473D",
173+
color: "white",
174+
"&:hover": { bgcolor: "#E53935" },
175+
}}
176+
disabled={loading}
177+
>
178+
{loading ? "Processing..." : "Disable Email MFA"}
179+
</Button>
180+
</DialogActions>
181+
</Dialog>
182+
</div>
183+
);
184+
};
185+
186+
export default ToggleEmailMFA;

0 commit comments

Comments
 (0)