add votes

This commit is contained in:
Aditya Siregar 2025-08-16 00:43:50 +07:00
parent 2fcc239808
commit c167df391f

View File

@ -42,19 +42,31 @@ import { Checkbox } from "@/components/ui/checkbox"
interface User { interface User {
id: string id: string
username: string
name: string name: string
email: string email: string
is_active: boolean is_active: boolean
created_at: string created_at: string
updated_at: string updated_at: string
roles: Array<{ roles?: Array<{
id: string id: string
name: string name: string
code: string code: string
}> }> | null
department_response?: { department_response?: {
name: string name: string
} | null } | null
profile?: {
user_id: string
full_name: string
timezone: string
locale: string
preferences: any
notification_prefs: any
created_at: string
updated_at: string
roles: any
} | null
} }
interface ApiResponse { interface ApiResponse {
@ -164,6 +176,13 @@ function MembersPageContent() {
} }
}, [user]) }, [user])
// Reset search when changing pages since search is limited to current page
useEffect(() => {
if (user && currentPage > 1) {
setSearchTerm("")
}
}, [currentPage])
// Reset to first page when filters change // Reset to first page when filters change
useEffect(() => { useEffect(() => {
if (user && (searchTerm || statusFilter !== "all")) { if (user && (searchTerm || statusFilter !== "all")) {
@ -181,11 +200,18 @@ function MembersPageContent() {
if (data.success) { if (data.success) {
setUsers(data.data.users) setUsers(data.data.users)
setTotalUsers(data.data.pagination.total_count) setTotalUsers(data.data.pagination.total_count)
setCurrentPage(page) setCurrentPage(data.data.pagination.page)
console.log('📊 Pagination Info:', {
currentPage: data.data.pagination.page,
totalCount: data.data.pagination.total_count,
totalPages: data.data.pagination.total_pages,
limit: data.data.pagination.limit
})
toast({ toast({
title: "Success", title: "Success",
description: `Fetched ${data.data.users.length} users`, description: `Fetched ${data.data.users.length} users (Page ${data.data.pagination.page} of ${data.data.pagination.total_pages})`,
}) })
} else { } else {
toast({ toast({
@ -434,6 +460,7 @@ function MembersPageContent() {
const filteredUsers = users.filter((user) => { const filteredUsers = users.filter((user) => {
const matchesSearch = const matchesSearch =
user.name.toLowerCase().includes(searchTerm.toLowerCase()) || user.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.username.toLowerCase().includes(searchTerm.toLowerCase()) ||
user.email.toLowerCase().includes(searchTerm.toLowerCase()) || user.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
(user.department_response?.name || "").toLowerCase().includes(searchTerm.toLowerCase()) (user.department_response?.name || "").toLowerCase().includes(searchTerm.toLowerCase())
@ -473,7 +500,7 @@ function MembersPageContent() {
<Users className="h-4 w-4 text-muted-foreground" /> <Users className="h-4 w-4 text-muted-foreground" />
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="text-2xl font-bold">{users.length}</div> <div className="text-2xl font-bold">{totalUsers}</div>
</CardContent> </CardContent>
</Card> </Card>
@ -485,6 +512,7 @@ function MembersPageContent() {
<CardContent> <CardContent>
<div className="text-2xl font-bold text-green-600"> <div className="text-2xl font-bold text-green-600">
{users.filter(u => u.is_active).length} {users.filter(u => u.is_active).length}
<span className="text-sm text-gray-500 ml-1">/ {totalUsers}</span>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
@ -497,6 +525,7 @@ function MembersPageContent() {
<CardContent> <CardContent>
<div className="text-2xl font-bold text-yellow-600"> <div className="text-2xl font-bold text-yellow-600">
{users.filter(u => !u.is_active).length} {users.filter(u => !u.is_active).length}
<span className="text-sm text-gray-500 ml-1">/ {totalUsers}</span>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
@ -527,11 +556,14 @@ function MembersPageContent() {
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" /> <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
<Input <Input
id="search" id="search"
placeholder="Search by name, email, or department..." placeholder="Search by username, name, email, or department..."
value={searchTerm} value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)} onChange={(e) => setSearchTerm(e.target.value)}
className="pl-10" className="pl-10"
/> />
<p className="text-xs text-gray-500 mt-1">
Search is limited to the current page. Use pagination to view more users.
</p>
</div> </div>
</div> </div>
@ -623,7 +655,7 @@ function MembersPageContent() {
<CardTitle>Users List</CardTitle> <CardTitle>Users List</CardTitle>
<CardDescription> <CardDescription>
Showing {startIndex}-{endIndex} of {totalUsers} total users Showing {startIndex}-{endIndex} of {totalUsers} total users
{filteredUsers.length !== users.length && ` (${filteredUsers.length} filtered)`} {filteredUsers.length !== users.length && ` (${filteredUsers.length} filtered from current page)`}
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
@ -640,38 +672,42 @@ function MembersPageContent() {
</div> </div>
) : ( ) : (
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>Name</TableHead> <TableHead>Username</TableHead>
<TableHead>Email</TableHead> <TableHead>Name</TableHead>
<TableHead>Department</TableHead> <TableHead>Email</TableHead>
<TableHead>Role</TableHead> <TableHead>Department</TableHead>
<TableHead>Status</TableHead> <TableHead>Role</TableHead>
<TableHead>Created</TableHead> <TableHead>Status</TableHead>
</TableRow> <TableHead>Created</TableHead>
</TableHeader>
<TableBody>
{filteredUsers.map((user) => (
<TableRow key={user.id}>
<TableCell className="font-medium">{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>
{user.department_response?.name || "N/A"}
</TableCell>
<TableCell>
{getRoleBadge(user.roles)}
</TableCell>
<TableCell>
{getStatusBadge(user.is_active)}
</TableCell>
<TableCell>
{new Date(user.created_at).toLocaleDateString()}
</TableCell>
</TableRow> </TableRow>
))} </TableHeader>
</TableBody> <TableBody>
</Table> {filteredUsers.map((user) => (
<TableRow key={user.id}>
<TableCell className="font-mono text-sm">
{user.username}
</TableCell>
<TableCell className="font-medium">{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>
{user.department_response?.name || "N/A"}
</TableCell>
<TableCell>
{getRoleBadge(user.roles)}
</TableCell>
<TableCell>
{getStatusBadge(user.is_active)}
</TableCell>
<TableCell>
{new Date(user.created_at).toLocaleDateString()}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div> </div>
)} )}