251208:0010 Backend & Frontend Debug
This commit is contained in:
@@ -1,43 +1,27 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useUsers, useDeleteUser } from "@/hooks/use-users";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DataTable } from "@/components/common/data-table";
|
||||
import { DataTable } from "@/components/common/data-table"; // Reuse Data Table
|
||||
import { Plus, MoreHorizontal, Pencil, Trash } from "lucide-react"; // Import Icons
|
||||
import { useState } from "react";
|
||||
import { UserDialog } from "@/components/admin/user-dialog";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { MoreHorizontal, Plus, Loader2 } from "lucide-react";
|
||||
import { User } from "@/types/admin";
|
||||
import { adminApi } from "@/lib/api/admin";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
import { User } from "@/types/user";
|
||||
|
||||
export default function UsersPage() {
|
||||
const [users, setUsers] = useState<User[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { data: users, isLoading } = useUsers();
|
||||
const deleteMutation = useDeleteUser();
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [selectedUser, setSelectedUser] = useState<User | null>(null);
|
||||
|
||||
const fetchUsers = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await adminApi.getUsers();
|
||||
setUsers(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch users", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchUsers();
|
||||
}, []);
|
||||
|
||||
const columns: ColumnDef<User>[] = [
|
||||
{
|
||||
accessorKey: "username",
|
||||
@@ -48,95 +32,73 @@ export default function UsersPage() {
|
||||
header: "Email",
|
||||
},
|
||||
{
|
||||
accessorKey: "first_name",
|
||||
header: "Name",
|
||||
cell: ({ row }) => `${row.original.first_name} ${row.original.last_name}`,
|
||||
id: "name",
|
||||
header: "Name",
|
||||
cell: ({ row }) => `${row.original.first_name} ${row.original.last_name}`,
|
||||
},
|
||||
{
|
||||
accessorKey: "is_active",
|
||||
header: "Status",
|
||||
cell: ({ row }) => (
|
||||
<Badge variant={row.original.is_active ? "default" : "secondary"} className={row.original.is_active ? "bg-green-600 hover:bg-green-700" : ""}>
|
||||
<Badge variant={row.original.is_active ? "default" : "secondary"}>
|
||||
{row.original.is_active ? "Active" : "Inactive"}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "roles",
|
||||
header: "Roles",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex gap-1 flex-wrap">
|
||||
{row.original.roles?.map((role) => (
|
||||
<Badge key={role.role_id} variant="outline">
|
||||
{role.role_name}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
cell: ({ row }) => (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="sm">
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
setSelectedUser(row.original);
|
||||
setDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="text-destructive"
|
||||
onClick={() => alert("Deactivate not implemented in mock")}
|
||||
>
|
||||
{row.original.is_active ? "Deactivate" : "Activate"}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
),
|
||||
},
|
||||
id: "actions",
|
||||
header: "Actions",
|
||||
cell: ({ row }) => {
|
||||
const user = row.original;
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||
<span className="sr-only">Open menu</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => { setSelectedUser(user); setDialogOpen(true); }}>
|
||||
<Pencil className="mr-2 h-4 w-4" /> Edit
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="text-red-600"
|
||||
onClick={() => {
|
||||
if (confirm("Are you sure?")) deleteMutation.mutate(user.user_id);
|
||||
}}
|
||||
>
|
||||
<Trash className="mr-2 h-4 w-4" /> Delete
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
<div className="space-y-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">User Management</h1>
|
||||
<p className="text-muted-foreground mt-1">
|
||||
Manage system users and their roles
|
||||
</p>
|
||||
<p className="text-muted-foreground mt-1">Manage system users and roles</p>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setSelectedUser(null);
|
||||
setDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Add User
|
||||
<Button onClick={() => { setSelectedUser(null); setDialogOpen(true); }}>
|
||||
<Plus className="mr-2 h-4 w-4" /> Add User
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="flex justify-center py-12">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<div>Loading...</div>
|
||||
) : (
|
||||
<DataTable columns={columns} data={users} />
|
||||
<DataTable columns={columns} data={users || []} />
|
||||
)}
|
||||
|
||||
<UserDialog
|
||||
open={dialogOpen}
|
||||
onOpenChange={setDialogOpen}
|
||||
user={selectedUser}
|
||||
onSuccess={fetchUsers}
|
||||
open={dialogOpen}
|
||||
onOpenChange={setDialogOpen}
|
||||
user={selectedUser}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user