mirror of
https://github.com/ente-io/ente.git
synced 2025-08-07 23:18:10 +00:00
Added a dropdown button to select different actions to be performed
This commit is contained in:
parent
326e673d12
commit
a5b0bc259d
@ -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;
|
||||
}
|
||||
|
@ -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={() => {
|
||||
|
@ -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">
|
||||
<button
|
||||
onClick={() => {
|
||||
handleActionClick("Disable2FA").catch((e: unknown) =>
|
||||
console.error(e),
|
||||
);
|
||||
}}
|
||||
>
|
||||
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
|
||||
<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(
|
||||
option.value,
|
||||
).catch((error: unknown) =>
|
||||
console.error(
|
||||
"Error handling action:",
|
||||
error,
|
||||
),
|
||||
);
|
||||
}}
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{(error ?? message) && (
|
||||
<div className={`message ${error ? "error" : "success"}`}>
|
||||
|
Loading…
x
Reference in New Issue
Block a user