Added a dropdown button to select different actions to be performed

This commit is contained in:
atyabbin 2024-06-18 18:40:40 +05:30
parent 326e673d12
commit a5b0bc259d
3 changed files with 118 additions and 51 deletions

View File

@ -1,23 +1,12 @@
.sidebar button {
margin-right: 10px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: #009879;
color: white;
border: none;
border-radius: 5px;
.fetch-button-container {
margin-right: 180px;
margin-left: 10px;
}
.content-wrapper {
display: flex;
align-items: flex-start; /* Ensure items start at the top */
margin-left: 70px; /* Adjusts margin to move content towards the right */
}
/* Adjust .fetch-button-container margin to ensure proper spacing */
.fetch-button-container {
margin-right: 20px; /* Adjust as needed */
align-items: flex-start;
margin-left: 175px;
}
.fetch-button-container button {
@ -30,16 +19,14 @@
border-radius: 5px;
margin-top: 20px;
}
.fetch-button-container button:hover {
background-color: #007c6c;
}
.sidebar button:hover {
background-color: #007c6c;
}
.sidebar {
padding: 20px;
flex: 0 0 auto; /* Prevent sidebar from growing and affecting other elements */
flex: 0 0 auto;
}
.button-container {
@ -56,6 +43,7 @@ button {
margin-top: 20px;
color: red;
}
.message {
position: fixed;
bottom: 10px;
@ -76,3 +64,61 @@ button {
background-color: #4caf50;
color: white;
}
.dropdown-container {
margin-bottom: 20px;
position: relative; /* Ensure relative positioning for dropdown menu */
}
.more-button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: #009879;
color: white;
border: none;
border-radius: 5px;
margin-top: 1px;
}
.more-button:hover {
background-color: #007c6c;
}
.dropdown-menu {
position: absolute;
top: calc(100% + 5px); /* Position right below the More button */
left: 0;
z-index: 100;
display: block;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
max-height: 150px; /* Example: Set max height for scrollability */
overflow-y: auto; /* Enable vertical scroll */
}
/* Remove bullets from unordered list */
.dropdown-menu ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.dropdown-menu button {
display: block;
width: 100%;
padding: 8px 16px;
font-size: 14px;
color: #333;
background-color: transparent;
border: none;
cursor: pointer;
transition: background-color 0.3s ease;
}
.dropdown-menu button:hover {
background-color: #f0f0f0;
}

View File

@ -3,6 +3,7 @@ import "./App.css";
import { Sidebar } from "./components/Sidebar";
import { apiOrigin } from "./services/support";
import S from "./utils/strings";
type User = Record<
string,
string | number | boolean | null | undefined | Record<string, unknown>
@ -14,6 +15,7 @@ export const App: React.FC = () => {
const [email, setEmail] = useState<string>("");
const [userData, setUserData] = useState<UserData | null>(null);
const [error, setError] = useState<string | null>(null);
const [isDataFetched, setIsDataFetched] = useState<boolean>(false); // Track if data has been fetched successfully
useEffect(() => {
const storedToken = localStorage.getItem("token");
@ -44,9 +46,11 @@ export const App: React.FC = () => {
console.log("API Response:", userDataResponse);
setUserData(userDataResponse);
setError(null);
setIsDataFetched(true); // Set to true when data is successfully fetched
} catch (error) {
console.error("Error fetching data:", error);
setError((error as Error).message);
setIsDataFetched(false); // Set to false if there's an error fetching data
}
};
@ -187,7 +191,7 @@ export const App: React.FC = () => {
</div>
</form>
<div className="content-wrapper">
<Sidebar email={email} token={token} />
{isDataFetched && <Sidebar token={token} email={email} />}
<div className="fetch-button-container">
<button
onClick={() => {

View File

@ -17,6 +17,8 @@ export const Sidebar: React.FC<SidebarProps> = ({ token, email }) => {
const [, /*userId*/ setUserId] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const [message, setMessage] = useState<string | null>(null);
const [dropdownVisible, setDropdownVisible] = useState<boolean>(false);
interface ApiResponse {
data: {
userId: string;
@ -30,7 +32,9 @@ export const Sidebar: React.FC<SidebarProps> = ({ token, email }) => {
}
try {
const url = `${apiOrigin}/admin/user?email=${encodeURIComponent(email)}&token=${encodeURIComponent(token)}`;
const url = `${apiOrigin}/admin/user?email=${encodeURIComponent(
email,
)}&token=${encodeURIComponent(token)}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error("Network response was not ok");
@ -62,11 +66,13 @@ export const Sidebar: React.FC<SidebarProps> = ({ token, email }) => {
try {
const actionUrls: Record<string, string> = {
Disable2FA: "/admin/user/disable-2fa",
Passkeys: "/admin/user/disable-passkeys",
DisablePasskeys: "/admin/user/disable-passkeys",
Closefamily: "/admin/user/close-family",
};
const url = `${apiOrigin}${actionUrls[action]}?id=${encodeURIComponent(userId)}&token=${encodeURIComponent(token)}`;
const url = `${apiOrigin}${actionUrls[action]}?id=${encodeURIComponent(
userId,
)}&token=${encodeURIComponent(token)}`;
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
@ -87,6 +93,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ token, email }) => {
setTimeout(() => {
setMessage(null);
}, 1000);
setDropdownVisible(false);
} catch (error) {
console.error(`Error ${action}:`, error);
setError(
@ -125,36 +132,46 @@ export const Sidebar: React.FC<SidebarProps> = ({ token, email }) => {
}
};
const toggleDropdown = () => {
setDropdownVisible(!dropdownVisible);
};
const dropdownOptions = [
{ value: "Disable2FA", label: "Disable 2FA" },
{ value: "Closefamily", label: "Close Family" },
{ value: "DisablePasskeys", label: "Disable Passkeys" },
];
return (
<div className="sidebar">
<div className="button-container">
<div className="dropdown-container">
<button className="more-button" onClick={toggleDropdown}>
More
</button>
{dropdownVisible && (
<div className="dropdown-menu">
<ul>
{dropdownOptions.map((option) => (
<li key={option.value}>
<button
onClick={() => {
handleActionClick("Disable2FA").catch((e: unknown) =>
console.error(e),
handleActionClick(
option.value,
).catch((error: unknown) =>
console.error(
"Error handling action:",
error,
),
);
}}
>
Disable 2FA
</button>
<button
onClick={() => {
handleActionClick("Closefamily").catch((e: unknown) =>
console.error(e),
);
}}
>
Close Family
</button>
<button
onClick={() => {
handleActionClick("Passkeys").catch((e: unknown) =>
console.error(e),
);
}}
>
Disable Passkeys
{option.label}
</button>
</li>
))}
</ul>
</div>
)}
</div>
{(error ?? message) && (
<div className={`message ${error ? "error" : "success"}`}>