// ─────────────────────────────────────────────── // Users Page (/(dashboard)/users) // ─────────────────────────────────────────────── // Route: /users // Purpose: Team management — list, search, and // create users. Shows summary stats cards and // a searchable table. // Layout: PageHeader + stat grid + search bar + // UsersTable + inline UserFormDialog. // ─────────────────────────────────────────────── "use client" import { useState, useEffect, useCallback } from "react" import { PageHeader } from "@/components/shared/page-header" import { UsersTable } from "@/components/users/users-table" import { UserFormDialog } from "@/components/users/user-form-dialog" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { useUser } from "@/providers/user-provider" import { Plus, Users as UsersIcon, Search } from "lucide-react" import type { User } from "@/types" /** * UsersPage * ───────── * Fetches all users on mount, computes summary * stats (total / active / admins / sales), and * renders a searchable table. "Add User" button * opens a modal dialog for creation. * * @returns Users management layout. */ export default function UsersPage() { const { user } = useUser() const [users, setUsers] = useState([]) const [loading, setLoading] = useState(true) const [createOpen, setCreateOpen] = useState(false) const [search, setSearch] = useState("") // ── Fetch all users ── const fetchUsers = useCallback(async () => { try { const res = await fetch("/api/users") if (res.ok) { const data = await res.json() setUsers(data.users || []) } } catch { console.warn("Failed to fetch users in users page") } finally { setLoading(false) } }, []) useEffect(() => { fetchUsers() }, [fetchUsers]) // ── Derived stats ── const activeUsers = users.filter((u) => u.active !== false) const admins = users.filter((u) => u.role === "admin") const stats = [ { label: "Total Users", value: users.length, color: "bg-blue-500/10", textColor: "text-blue-500" }, { label: "Active", value: activeUsers.length, color: "bg-green-500/10", textColor: "text-green-500" }, { label: "Admins", value: admins.length, color: "bg-purple-500/10", textColor: "text-purple-500" }, { label: "Sales", value: users.filter((u) => u.role === "sales").length, color: "bg-orange-500/10", textColor: "text-orange-500" }, ] // ── Client-side search filter by name/email ── const filtered = users.filter((u) => { if (!search) return true const q = search.toLowerCase() return u.name?.toLowerCase().includes(q) || u.email?.toLowerCase().includes(q) }) return (
{/* ── Header with "Add User" action ── */} {/* ── Summary stat cards ── */}
{stats.map((s) => (

{s.value}

{s.label}

))}
{/* ── Search input ── */}
setSearch(e.target.value)} className="h-9 pl-9" />
{/* ── Users data table ── */}
{/* ── Create-user dialog ── */}
) }