Files
gameui/src/pages/Dashboard.jsx
T

238 lines
7.6 KiB
React

import React, { useEffect, useState } from "react";
import config from "../config";
const thStyle = {
padding: "0.75rem",
backgroundColor: "#333",
borderBottom: "1px solid #555",
color: "#fff",
position: "sticky",
top: 0,
zIndex: 1,
textAlign: "center",
};
const tdStyle = {
padding: "0.5rem 1rem",
borderBottom: "1px solid #444",
textAlign: "center",
color: "#fff",
};
const Dashboard = () => {
const [role, setRole] = useState("");
const [currentUser, setCurrentUser] = useState("");
const [users, setUsers] = useState([]);
const [newRoles, setNewRoles] = useState({});
const [selectedUsers, setSelectedUsers] = useState([]);
useEffect(() => {
const storedRole = localStorage.getItem("role");
const storedUsername = localStorage.getItem("username");
setRole(storedRole);
setCurrentUser(storedUsername);
if (storedRole === "SUPER") {
fetchUsers();
}
}, []);
const fetchUsers = async () => {
const token = localStorage.getItem("token");
try {
const res = await fetch(`${config.apiBaseUrl}/api/Auth/users`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) throw new Error("Failed to fetch users");
const data = await res.json();
setUsers(data);
} catch (err) {
console.error("Error fetching users:", err);
}
};
const handleRoleChange = (username, value) => {
setNewRoles({ ...newRoles, [username]: value });
};
const updateUserRole = async (username) => {
const token = localStorage.getItem("token");
const newRole = newRoles[username];
try {
const res = await fetch(`${config.apiBaseUrl}/api/Auth/role`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ username, newRole }),
});
if (!res.ok) throw new Error("Failed to update role");
fetchUsers();
} catch (err) {
console.error("Error updating role:", err);
}
};
const deleteUser = async (username) => {
if (!window.confirm(`Are you sure you want to delete ${username}?`)) return;
const token = localStorage.getItem("token");
try {
const res = await fetch(`${config.apiBaseUrl}/api/User?username=${encodeURIComponent(username)}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) throw new Error("Failed to delete user");
fetchUsers();
} catch (err) {
console.error("Error deleting user:", err);
}
};
const toggleUserSelection = (username) => {
setSelectedUsers((prev) =>
prev.includes(username)
? prev.filter((u) => u !== username)
: [...prev, username]
);
};
return (
<div style={{ color: "#fff", textAlign: "center", marginTop: "2rem" }}>
<h1>Dashboard</h1>
<p>Welcome! You are logged in.</p>
{role === "SUPER" && (
<>
<p style={{ fontWeight: "bold" }}>You are SUPER</p>
<div
style={{
maxHeight: "320px",
overflowY: "auto",
margin: "2rem auto 0 auto",
width: "fit-content",
border: "1px solid #444",
borderRadius: "4px",
}}
>
<table style={{ borderCollapse: "collapse", minWidth: "600px" }}>
<thead>
<tr>
<th style={thStyle}></th>
<th style={thStyle}>Username</th>
<th style={thStyle}>Role</th>
{selectedUsers.length > 0 && <th style={thStyle}>Action</th>}
</tr>
</thead>
<tbody>
{users
.filter((user) => user.username !== currentUser)
.map((user) => {
const isSelected = selectedUsers.includes(user.username);
const currentNewRole = newRoles[user.username] ?? user.role;
return (
<tr key={user.username}>
<td style={tdStyle}>
<input
type="checkbox"
checked={isSelected}
onChange={() => toggleUserSelection(user.username)}
/>
</td>
<td style={tdStyle}>{user.username}</td>
<td style={tdStyle}>
{isSelected ? (
<select
value={currentNewRole}
onChange={(e) =>
handleRoleChange(
user.username,
e.target.value
)
}
style={{
padding: "0.3rem",
backgroundColor: "#2a2a2a",
color: "#fff",
border: "1px solid #444",
}}
>
<option value="USER">USER</option>
<option value="SUPER">SUPER</option>
</select>
) : (
user.role
)}
</td>
{selectedUsers.length > 0 && (
<td style={tdStyle}>
{isSelected && (
<div
style={{
display: "flex",
gap: "0.5rem",
justifyContent: "center",
}}
>
<button
onClick={() =>
updateUserRole(user.username)
}
style={{
padding: "0.4rem 0.8rem",
backgroundColor: "#444",
color: "#fff",
border: "none",
borderRadius: "4px",
cursor: "pointer",
}}
>
Update
</button>
<button
onClick={() => deleteUser(user.username)}
style={{
padding: "0.4rem 0.8rem",
backgroundColor: "#aa3333",
color: "#fff",
border: "none",
borderRadius: "4px",
cursor: "pointer",
}}
>
Delete
</button>
</div>
)}
</td>
)}
</tr>
);
})}
</tbody>
</table>
</div>
</>
)}
</div>
);
};
export default Dashboard;