feat: Enhance provider components with detailed documentation and comments
- Added comprehensive comments and JSDoc-style documentation to NotificationProvider, ThemeProvider, UserProvider, and WebsiteThemeProvider for better clarity and maintainability. - Improved type definitions in index.ts for better code understanding and usage. - Introduced Docker support with Dockerfiles for various services including AI server, signaling server, and browser-use service. - Created a docker-compose.yml file to orchestrate multiple services including PostgreSQL, AI, scraper, and frontend. - Added a startup guide (startup.txt) for setting up the CRM environment on Ubuntu with Docker. - Included a .dockerignore file to exclude unnecessary files from Docker builds.
This commit is contained in:
@@ -1,3 +1,14 @@
|
||||
// ───────────────────────────────────────────────
|
||||
// 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"
|
||||
@@ -10,6 +21,16 @@ 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<User[]>([])
|
||||
@@ -17,6 +38,7 @@ export default function UsersPage() {
|
||||
const [createOpen, setCreateOpen] = useState(false)
|
||||
const [search, setSearch] = useState("")
|
||||
|
||||
// ── Fetch all users ──
|
||||
const fetchUsers = useCallback(async () => {
|
||||
try {
|
||||
const res = await fetch("/api/users")
|
||||
@@ -35,6 +57,7 @@ export default function UsersPage() {
|
||||
fetchUsers()
|
||||
}, [fetchUsers])
|
||||
|
||||
// ── Derived stats ──
|
||||
const activeUsers = users.filter((u) => u.active !== false)
|
||||
const admins = users.filter((u) => u.role === "admin")
|
||||
|
||||
@@ -45,6 +68,7 @@ export default function UsersPage() {
|
||||
{ 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()
|
||||
@@ -53,6 +77,7 @@ export default function UsersPage() {
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* ── Header with "Add User" action ── */}
|
||||
<PageHeader
|
||||
title="Users"
|
||||
description="Manage team members and their roles"
|
||||
@@ -63,6 +88,7 @@ export default function UsersPage() {
|
||||
</Button>
|
||||
</PageHeader>
|
||||
|
||||
{/* ── Summary stat cards ── */}
|
||||
<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">
|
||||
@@ -81,6 +107,7 @@ export default function UsersPage() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* ── Search input ── */}
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
||||
<Input
|
||||
@@ -91,10 +118,12 @@ export default function UsersPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* ── Users data table ── */}
|
||||
<div className="rounded-lg border bg-card">
|
||||
<UsersTable data={filtered} loading={loading} onUserDeleted={fetchUsers} />
|
||||
</div>
|
||||
|
||||
{/* ── Create-user dialog ── */}
|
||||
<UserFormDialog
|
||||
open={createOpen}
|
||||
onOpenChange={setCreateOpen}
|
||||
|
||||
Reference in New Issue
Block a user