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:
Ace
2026-07-13 13:05:30 +02:00
parent dba4c84cd5
commit d35c806d5b
167 changed files with 3474 additions and 102 deletions
+29
View File
@@ -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}