"use client"; import { useState } from "react"; import { PlusCircle, Search, Filter, MoreHorizontal, X, ChevronDown, UserPlus, Mail, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { useQuery } from "@tanstack/react-query"; import { fetchUsers } from "@/app/protected/(admin)/dashboard/user-management/action"; import { User } from "@/src/models/users/users.model"; import { toast } from "sonner"; import { DataTable } from "./data-table"; import { InviteUserDialog } from "./invite-user"; import { AddUserDialog } from "./add-user-dialog"; import { UserDetailsSheet } from "./sheet"; export default function UserManagement() { const [searchQuery, setSearchQuery] = useState(""); const [selectedUser, setSelectedUser] = useState(null); const [isSheetOpen, setIsSheetOpen] = useState(false); const [isAddUserOpen, setIsAddUserOpen] = useState(false); const [isInviteUserOpen, setIsInviteUserOpen] = useState(false); // Use React Query to fetch users const { data: users = [], isLoading, refetch, } = useQuery({ queryKey: ["users"], queryFn: async () => { try { return await fetchUsers(); } catch (error) { toast.error("Failed to fetch users"); return []; } }, }); const handleUserClick = (user: User) => { setSelectedUser(user); setIsSheetOpen(true); }; const handleUserUpdate = () => { refetch(); setIsSheetOpen(false); }; const filteredUsers = users.filter((user) => { if (!searchQuery) return true; const query = searchQuery.toLowerCase(); return ( user.email?.toLowerCase().includes(query) || user.phone?.toLowerCase().includes(query) || user.id.toLowerCase().includes(query) ); }); const columns = [ { id: "email", header: "Email", cell: ({ row }: { row: { original: User } }) => (
{row.original.email?.[0]?.toUpperCase() || "?"}
{row.original.email || "No email"}
{row.original.id}
), filterFn: (row: any, id: string, value: string) => { return row.original.email?.toLowerCase().includes(value.toLowerCase()); }, }, { id: "phone", header: "Phone", cell: ({ row }: { row: { original: User } }) => row.original.phone || "-", filterFn: (row: any, id: string, value: string) => { return row.original.phone?.toLowerCase().includes(value.toLowerCase()); }, }, { id: "lastSignIn", header: "Last Sign In", cell: ({ row }: { row: { original: User } }) => { return row.original.last_sign_in_at ? new Date(row.original.last_sign_in_at).toLocaleString() : "Never"; }, }, { id: "createdAt", header: "Created At", cell: ({ row }: { row: { original: User } }) => { return new Date(row.original.created_at).toLocaleString(); }, }, { id: "status", header: "Status", cell: ({ row }: { row: { original: User } }) => { if (row.original.banned_until) { return Banned; } if (!row.original.email_confirmed_at) { return Unconfirmed; } return Active; }, filterFn: (row: any, id: string, value: string) => { const status = row.original.banned_until ? "banned" : !row.original.email_confirmed_at ? "unconfirmed" : "active"; return status.includes(value.toLowerCase()); }, }, { id: "actions", header: "", cell: ({ row }: { row: { original: User } }) => ( ), }, ]; return (
setSearchQuery(e.target.value)} /> {searchQuery && ( )}
setIsAddUserOpen(true)}> Create new user setIsInviteUserOpen(true)}> Send invitation
handleUserClick(user)} /> {selectedUser && ( )} refetch()} /> refetch()} />
); }