Files
CRM_backup/src/app/(dashboard)/users/page.tsx
T
Ace adbcc4b9af feat: add system monitor component and API for performance metrics
feat: implement conversations API with message retrieval and posting

feat: add avatar URL handling for users and update user role definitions

feat: create chat system tables in the database with initial seed data

fix: update user roles from "sales_user" to "sales" for consistency

chore: add middleware for system API route access

fixed fuckups on john's side, added a benchmark

Made Graphs actualy load from database and realtime data, graphs will update and percentages will be mathematically made,  and made realtime

added chatcart edits, made graphs glow.

added in some little small home feeling fuctions

added in a slide show, in login with qoutes from creators because i want to leave a print on it saying we made this shit, we built it brick for brick

login page added qoutes some random, and made them shuffle from left to right one dissapears other come in

adding shape to the textbox for the qoutes

Fixed my chat fuckups when it comes to chats
2026-06-18 22:48:03 +02:00

106 lines
3.5 KiB
TypeScript

"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"
export default function UsersPage() {
const { user } = useUser()
const [users, setUsers] = useState<User[]>([])
const [loading, setLoading] = useState(true)
const [createOpen, setCreateOpen] = useState(false)
const [search, setSearch] = useState("")
const fetchUsers = useCallback(async () => {
try {
const res = await fetch("/api/users")
if (res.ok) {
const data = await res.json()
setUsers(data.users || [])
}
} catch {
// ignore
} finally {
setLoading(false)
}
}, [])
useEffect(() => {
fetchUsers()
}, [fetchUsers])
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" },
]
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 (
<div className="space-y-4">
<PageHeader
title="Users"
description="Manage team members and their roles"
>
<Button className="gap-2" onClick={() => setCreateOpen(true)}>
<Plus className="h-4 w-4" />
Add User
</Button>
</PageHeader>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4 mb-6">
{stats.map((s) => (
<div key={s.label} className="rounded-lg border bg-card p-4">
<div className="flex items-center gap-3">
<div
className={`flex h-10 w-10 items-center justify-center rounded-lg ${s.color}`}
>
<UsersIcon className={`h-5 w-5 ${s.textColor}`} />
</div>
<div>
<p className="text-2xl font-bold">{s.value}</p>
<p className="text-xs text-muted-foreground">{s.label}</p>
</div>
</div>
</div>
))}
</div>
<div className="relative">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
placeholder="Search by name or email..."
value={search}
onChange={(e) => setSearch(e.target.value)}
className="h-9 pl-9"
/>
</div>
<div className="rounded-lg border bg-card">
<UsersTable data={filtered} loading={loading} onUserDeleted={fetchUsers} />
</div>
<UserFormDialog
open={createOpen}
onOpenChange={setCreateOpen}
onUserCreated={fetchUsers}
/>
</div>
)
}