Neah_Front/components/users/users-table.tsx
2025-04-08 14:45:23 +02:00

286 lines
8.8 KiB
TypeScript

"use client";
import { useState, useEffect, useMemo } from "react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { useSession } from "next-auth/react";
import { AddUserButton } from "./add-user-button";
import { SimplePagination } from "@/components/ui/pagination";
import { Input } from "@/components/ui/input";
import { MoreHorizontal, Trash, Edit, UserPlus } from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
interface User {
id: string;
username: string;
firstName: string;
lastName: string;
email: string;
createdTimestamp: number;
roles: string[];
}
interface UsersTableProps {
userRole?: string[];
}
// Constants for role names
const ROLES = {
ADMIN: "Admin",
TEACHER: "Teacher",
STUDENT: "Students"
} as const;
const ITEMS_PER_PAGE = 10;
export function UsersTable({ userRole = [] }: UsersTableProps) {
const { data: session, status } = useSession();
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [currentPage, setCurrentPage] = useState(1);
const [searchTerm, setSearchTerm] = useState("");
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
try {
setLoading(true);
const response = await fetch("/api/users");
const data = await response.json();
console.log("Fetched users:", data);
console.log("Current user role:", session?.user?.role); // Debug log
setUsers(data);
} catch (error) {
console.error("Error fetching users:", error);
} finally {
setLoading(false);
}
};
const filterUsers = (users: User[]) => {
console.log("Filtering users with role:", userRole); // Debug log
if (!Array.isArray(users)) return [];
// If no role specified or user is admin, show all users
if (!userRole?.length || userRole.includes(ROLES.ADMIN)) {
console.log("Showing all users - admin or no role");
return users;
}
// If user is teacher, show teachers and students
if (userRole.includes(ROLES.TEACHER)) {
console.log("Filtering for teacher view");
return users.filter(user =>
user.roles?.includes(ROLES.TEACHER) || user.roles?.includes(ROLES.STUDENT)
);
}
// If user is student, show only students
if (userRole.includes(ROLES.STUDENT)) {
console.log("Filtering for student view");
return users.filter(user => user.roles?.includes(ROLES.STUDENT));
}
// Default: show all users
console.log("Default case: showing all users");
return users;
};
const canDelete = (targetUserRole: string[]) => {
if (!userRole?.length) return false;
if (userRole.includes(ROLES.ADMIN)) return true;
if (userRole.includes(ROLES.TEACHER)) {
return targetUserRole.includes(ROLES.STUDENT);
}
return false;
};
const handleDelete = async (userId: string) => {
try {
const response = await fetch(`/api/users/${userId}`, {
method: "DELETE",
});
const data = await response.json();
if (!response.ok) {
console.error("Delete error:", data);
// You might want to show an error message to the user here
return;
}
// Remove the user from the local state
setUsers(prevUsers => prevUsers.filter(user => user.id !== userId));
// Optional: Show success message
console.log("User deleted successfully");
} catch (error) {
console.error("Error deleting user:", error);
// You might want to show an error message to the user here
}
};
const filteredUsers = useMemo(() => {
let filtered = filterUsers(users);
// Apply search filter
if (searchTerm) {
filtered = filtered.filter(user =>
user.username.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.firstName.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.lastName.toLowerCase().includes(searchTerm.toLowerCase())
);
}
return filtered;
}, [users, searchTerm, userRole]);
// Calculate pagination
const totalPages = Math.ceil(filteredUsers.length / ITEMS_PER_PAGE);
const paginatedUsers = filteredUsers.slice(
(currentPage - 1) * ITEMS_PER_PAGE,
currentPage * ITEMS_PER_PAGE
);
const handlePageChange = (page: number) => {
setCurrentPage(page);
};
const handleAddUser = (newUser: User) => {
setUsers(prev => {
const updated = [...prev, newUser];
// Sort users by username
return updated.sort((a, b) => a.username.localeCompare(b.username));
});
// Reset to first page when adding new user
setCurrentPage(1);
};
// First, let's debug the roles
console.log("Current session:", {
role: session?.user?.role,
isAdmin: session?.user?.role?.includes("Admin"),
isTeacher: session?.user?.role?.includes("Teacher")
});
// Add this function for editing user
const handleEdit = async (userId: string) => {
// TODO: Implement edit functionality
console.log("Edit user:", userId);
};
// Add this function for managing roles
const handleManageRoles = async (userId: string) => {
// TODO: Implement role management
console.log("Manage roles for user:", userId);
};
if (!session) return null;
if (loading) return <div className="text-center p-4">Loading...</div>;
return (
<div>
{/* Search and Add User row */}
<div className="flex justify-between items-center mb-6">
<input
type="text"
placeholder="Rechercher un utilisateur..."
className="bg-black/20 border-0 rounded-md text-white/80 w-96"
/>
<Button variant="secondary">
Ajouter un utilisateur
</Button>
</div>
{/* Table content */}
<div className="space-y-4">
<Table>
<TableHeader>
<TableRow>
<TableHead>Nom d'utilisateur</TableHead>
<TableHead>Prénom</TableHead>
<TableHead>Nom</TableHead>
<TableHead>Email</TableHead>
<TableHead>Date d'inscription</TableHead>
<TableHead>Roles</TableHead>
<TableHead className="text-right">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{paginatedUsers.map((user) => (
<TableRow key={user.id}>
<TableCell>{user.username}</TableCell>
<TableCell>{user.firstName}</TableCell>
<TableCell>{user.lastName}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>
{new Date(user.createdTimestamp).toLocaleDateString()}
</TableCell>
<TableCell>{user.roles.join(", ")}</TableCell>
<TableCell className="text-right">
<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">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem onClick={() => handleEdit(user.id)}>
<Edit className="mr-2 h-4 w-4" />
Modifier
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleManageRoles(user.id)}>
<UserPlus className="mr-2 h-4 w-4" />
Gérer les rôles
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="text-red-600"
onClick={() => handleDelete(user.id)}
>
<Trash className="mr-2 h-4 w-4" />
Supprimer
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<SimplePagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
/>
<div className="text-sm text-gray-500 text-center mt-2">
Affichage de {Math.min(currentPage * ITEMS_PER_PAGE, filteredUsers.length)} sur {filteredUsers.length} utilisateurs
</div>
</div>
</div>
);
}