All checks were successful
Build & Deploy Costco Grocery List / build (push) Successful in 1m10s
Build & Deploy Costco Grocery List / verify-images (push) Successful in 3s
Build & Deploy Costco Grocery List / deploy (push) Successful in 11s
Build & Deploy Costco Grocery List / notify (push) Successful in 1s
86 lines
2.7 KiB
JavaScript
86 lines
2.7 KiB
JavaScript
import { useEffect, useState } from "react";
|
|
import { getAllUsers, updateRole } from "../api/users";
|
|
import StoreManagement from "../components/admin/StoreManagement";
|
|
import UserRoleCard from "../components/common/UserRoleCard";
|
|
import useActionToast from "../hooks/useActionToast";
|
|
import getApiErrorMessage from "../lib/getApiErrorMessage";
|
|
import "../styles/UserRoleCard.css";
|
|
import "../styles/pages/AdminPanel.css";
|
|
|
|
export default function AdminPanel() {
|
|
const toast = useActionToast();
|
|
const [users, setUsers] = useState([]);
|
|
const [activeTab, setActiveTab] = useState("users");
|
|
|
|
async function loadUsers() {
|
|
try {
|
|
const allUsers = await getAllUsers();
|
|
setUsers(allUsers.data);
|
|
} catch (error) {
|
|
const message = getApiErrorMessage(error, "Failed to load users");
|
|
toast.error("Load users failed", `Load users failed: ${message}`);
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
loadUsers();
|
|
}, []);
|
|
|
|
const changeRole = async (id, role) => {
|
|
const selectedUser = users.find((user) => user.id === id);
|
|
const username = selectedUser?.username || `user #${id}`;
|
|
|
|
try {
|
|
const updated = await updateRole(id, role);
|
|
if (updated.status !== 200) {
|
|
toast.error("Update role failed", "Update role failed: unexpected response");
|
|
return;
|
|
}
|
|
toast.success("Updated user role", `Updated role for ${username} to ${role}`);
|
|
loadUsers();
|
|
} catch (error) {
|
|
const message = getApiErrorMessage(error, "Failed to update user role");
|
|
toast.error("Update role failed", `Update role failed: ${message}`);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="admin-panel-body">
|
|
<div className="admin-panel-container">
|
|
<h1 className="admin-panel-title">Admin Panel</h1>
|
|
|
|
<div className="admin-tabs">
|
|
<button
|
|
className={`admin-tab ${activeTab === "users" ? "active" : ""}`}
|
|
onClick={() => setActiveTab("users")}
|
|
>
|
|
User Management
|
|
</button>
|
|
<button
|
|
className={`admin-tab ${activeTab === "stores" ? "active" : ""}`}
|
|
onClick={() => setActiveTab("stores")}
|
|
>
|
|
Store Management
|
|
</button>
|
|
</div>
|
|
|
|
<div className="admin-content">
|
|
{activeTab === "users" && (
|
|
<div className="users-section">
|
|
{users.map((user) => (
|
|
<UserRoleCard
|
|
key={user.id}
|
|
user={user}
|
|
onRoleChange={changeRole}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{activeTab === "stores" && <StoreManagement />}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|