@burdenoff/microfe-proserviceworld 2026.525.1 → 2026.624.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/proserviceworld/pages/AdminReportsPage.js +28 -28
  2. package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
  3. package/dist/proserviceworld/pages/AdminUsersPage.js +19 -19
  4. package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
  5. package/dist/proserviceworld/pages/AnalyticsPage.js +27 -27
  6. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/proserviceworld/pages/BookingsPage.js +24 -24
  8. package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
  9. package/dist/proserviceworld/pages/DashboardPage.js +33 -33
  10. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  11. package/dist/proserviceworld/pages/DocumentsPage.js +29 -29
  12. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  13. package/dist/proserviceworld/pages/MessagesPage.js +15 -15
  14. package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
  15. package/dist/proserviceworld/pages/PaymentsPage.js +19 -19
  16. package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
  17. package/dist/proserviceworld/pages/ProjectsPage.js +36 -36
  18. package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
  19. package/dist/proserviceworld/pages/ProviderDetailPage.js +36 -36
  20. package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
  21. package/dist/proserviceworld/pages/ProvidersPage.js +19 -19
  22. package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ReviewsPage.js +22 -22
  24. package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/ServiceDetailsPage.js +35 -35
  26. package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
  27. package/dist/proserviceworld/pages/ServicesPage.js +14 -14
  28. package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
  29. package/dist/proserviceworld/pages/VerificationPage.js +23 -23
  30. package/dist/proserviceworld/pages/VerificationPage.js.map +1 -1
  31. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AdminUsersPage.js","names":[],"sources":["../../../src/proserviceworld/pages/AdminUsersPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Filter,\n Users,\n UserCheck,\n UserX,\n Shield,\n Star,\n CheckCircle2,\n XCircle,\n Clock,\n Ban,\n MoreHorizontal,\n Download,\n Plus,\n Mail,\n Calendar,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { AdminUserRole, AdminUserStatus } from '../types';\n\nconst roleConfig: Record<\n AdminUserRole,\n { label: string; variant: 'default' | 'secondary' | 'outline' | 'destructive' }\n> = {\n client: { label: 'Client', variant: 'secondary' },\n provider: { label: 'Provider', variant: 'default' },\n admin: { label: 'Admin', variant: 'destructive' },\n team_member: { label: 'Team', variant: 'outline' },\n};\n\nconst statusConfig: Record<\n AdminUserStatus,\n { label: string; icon: typeof CheckCircle2; color: string }\n> = {\n active: { label: 'Active', icon: CheckCircle2, color: 'text-green-600' },\n suspended: { label: 'Suspended', icon: Ban, color: 'text-orange-600' },\n pending: { label: 'Pending', icon: Clock, color: 'text-yellow-600' },\n banned: { label: 'Banned', icon: XCircle, color: 'text-red-600' },\n};\n\nexport function AdminUsersPage() {\n const { adminUsers } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [roleFilter, setRoleFilter] = useState<AdminUserRole | 'all'>('all');\n const [statusFilter, setStatusFilter] = useState<AdminUserStatus | 'all'>('all');\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n\n const filtered = useMemo(() => {\n let result = [...adminUsers];\n if (roleFilter !== 'all') result = result.filter((u) => u.role === roleFilter);\n if (statusFilter !== 'all') result = result.filter((u) => u.status === statusFilter);\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (u) => u.name.toLowerCase().includes(q) || u.email.toLowerCase().includes(q)\n );\n }\n return result;\n }, [adminUsers, roleFilter, statusFilter, searchQuery]);\n\n // Stats\n const totalUsers = adminUsers.length;\n const activeUsers = adminUsers.filter((u) => u.status === 'active').length;\n const providers = adminUsers.filter((u) => u.role === 'provider').length;\n const verifiedUsers = adminUsers.filter((u) => u.verified).length;\n\n const toggleSelect = (id: string) => {\n const next = new Set(selectedIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n setSelectedIds(next);\n };\n\n const toggleSelectAll = () => {\n if (selectedIds.size === filtered.length) setSelectedIds(new Set());\n else setSelectedIds(new Set(filtered.map((u) => u.id)));\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">User Management</h1>\n <p className=\"text-sm text-muted-foreground\">\n Admin panel to manage platform users, roles, and access.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-2 h-4 w-4\" /> Export\n </Button>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" /> Invite User\n </Button>\n </div>\n </div>\n\n {/* Stats */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-blue-100 p-2 dark:bg-blue-950\">\n <Users className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{totalUsers}</p>\n <p className=\"text-xs text-muted-foreground\">Total Users</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-green-100 p-2 dark:bg-green-950\">\n <UserCheck className=\"h-5 w-5 text-green-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{activeUsers}</p>\n <p className=\"text-xs text-muted-foreground\">Active Users</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-purple-100 p-2 dark:bg-purple-950\">\n <Shield className=\"h-5 w-5 text-purple-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{providers}</p>\n <p className=\"text-xs text-muted-foreground\">Providers</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-yellow-100 p-2 dark:bg-yellow-950\">\n <CheckCircle2 className=\"h-5 w-5 text-yellow-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{verifiedUsers}</p>\n <p className=\"text-xs text-muted-foreground\">Verified</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n placeholder=\"Search by name or email...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <Filter className=\"h-4 w-4 text-muted-foreground\" />\n <select\n className=\"rounded border bg-background px-2 py-1 text-sm\"\n value={roleFilter}\n onChange={(e) => setRoleFilter(e.target.value as AdminUserRole | 'all')}\n >\n <option value=\"all\">All Roles</option>\n <option value=\"client\">Client</option>\n <option value=\"provider\">Provider</option>\n <option value=\"admin\">Admin</option>\n <option value=\"team_member\">Team Member</option>\n </select>\n <select\n className=\"rounded border bg-background px-2 py-1 text-sm\"\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as AdminUserStatus | 'all')}\n >\n <option value=\"all\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"suspended\">Suspended</option>\n <option value=\"pending\">Pending</option>\n <option value=\"banned\">Banned</option>\n </select>\n </div>\n </div>\n\n {/* Bulk actions */}\n {selectedIds.size > 0 && (\n <div className=\"flex items-center gap-3 rounded-lg bg-primary/5 border border-primary/20 p-3\">\n <span className=\"text-sm font-medium\">{selectedIds.size} user(s) selected</span>\n <Button variant=\"outline\" size=\"sm\">\n Activate\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n Suspend\n </Button>\n <Button variant=\"destructive\" size=\"sm\">\n Ban\n </Button>\n </div>\n )}\n\n {/* User table */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-muted-foreground\">\n <th className=\"p-3\">\n <input\n type=\"checkbox\"\n checked={selectedIds.size === filtered.length && filtered.length > 0}\n onChange={toggleSelectAll}\n className=\"rounded\"\n />\n </th>\n <th className=\"p-3\">User</th>\n <th className=\"p-3\">Role</th>\n <th className=\"p-3\">Status</th>\n <th className=\"p-3\">Verified</th>\n <th className=\"p-3\">Joined</th>\n <th className=\"p-3\">Last Active</th>\n <th className=\"p-3 text-right\">Bookings</th>\n <th className=\"p-3 text-right\">Spent</th>\n <th className=\"p-3\">Rating</th>\n <th className=\"p-3 text-right\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {filtered.length === 0 ? (\n <tr>\n <td colSpan={11} className=\"p-8 text-center text-muted-foreground\">\n No users match your filters.\n </td>\n </tr>\n ) : (\n filtered.map((user) => {\n const sCfg = statusConfig[user.status];\n const StatusIcon = sCfg.icon;\n return (\n <tr key={user.id} className=\"border-b hover:bg-muted/50\">\n <td className=\"p-3\">\n <input\n type=\"checkbox\"\n checked={selectedIds.has(user.id)}\n onChange={() => toggleSelect(user.id)}\n className=\"rounded\"\n />\n </td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary\">\n {user.name.charAt(0)}\n </div>\n <div>\n <p className=\"font-medium\">{user.name}</p>\n <p className=\"text-xs text-muted-foreground\">{user.email}</p>\n </div>\n </div>\n </td>\n <td className=\"p-3\">\n <Badge variant={roleConfig[user.role].variant}>\n {roleConfig[user.role].label}\n </Badge>\n </td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-1\">\n <StatusIcon className={`h-4 w-4 ${sCfg.color}`} />\n <span className={`text-xs font-medium ${sCfg.color}`}>\n {sCfg.label}\n </span>\n </div>\n </td>\n <td className=\"p-3\">\n {user.verified ? (\n <CheckCircle2 className=\"h-4 w-4 text-green-500\" />\n ) : (\n <XCircle className=\"h-4 w-4 text-gray-300\" />\n )}\n </td>\n <td className=\"p-3 text-muted-foreground\">{user.joinedDate}</td>\n <td className=\"p-3 text-muted-foreground\">{user.lastActive}</td>\n <td className=\"p-3 text-right\">{user.bookingsCount}</td>\n <td className=\"p-3 text-right\">\n {user.totalSpent > 0 ? `$${user.totalSpent.toLocaleString()}` : '-'}\n </td>\n <td className=\"p-3\">\n {user.rating ? (\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 fill-yellow-400 text-yellow-400\" />\n <span className=\"text-xs font-medium\">{user.rating}</span>\n </div>\n ) : (\n <span className=\"text-xs text-muted-foreground\">-</span>\n )}\n </td>\n <td className=\"p-3 text-right\">\n <div className=\"flex justify-end gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <Mail className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <MoreHorizontal className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {/* Pagination hint */}\n <div className=\"mt-4 flex items-center justify-between border-t pt-4 text-sm text-muted-foreground\">\n <span>\n Showing {filtered.length} of {adminUsers.length} users\n </span>\n <div className=\"flex gap-1\">\n <Button variant=\"outline\" size=\"sm\" disabled>\n Previous\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled>\n Next\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminUsersPage.js","names":[],"sources":["../../../src/proserviceworld/pages/AdminUsersPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Filter,\n Users,\n UserCheck,\n UserX,\n Shield,\n Star,\n CheckCircle2,\n XCircle,\n Clock,\n Ban,\n MoreHorizontal,\n Download,\n Plus,\n Mail,\n Calendar,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { AdminUserRole, AdminUserStatus } from '../types';\n\nconst roleConfig: Record<\n AdminUserRole,\n { label: string; variant: 'default' | 'secondary' | 'outline' | 'destructive' }\n> = {\n client: { label: 'Client', variant: 'secondary' },\n provider: { label: 'Provider', variant: 'default' },\n admin: { label: 'Admin', variant: 'destructive' },\n team_member: { label: 'Team', variant: 'outline' },\n};\n\nconst statusConfig: Record<\n AdminUserStatus,\n { label: string; icon: typeof CheckCircle2; color: string }\n> = {\n active: { label: 'Active', icon: CheckCircle2, color: 'text-green-600' },\n suspended: { label: 'Suspended', icon: Ban, color: 'text-orange-600' },\n pending: { label: 'Pending', icon: Clock, color: 'text-yellow-600' },\n banned: { label: 'Banned', icon: XCircle, color: 'text-red-600' },\n};\n\nexport function AdminUsersPage() {\n const { adminUsers } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [roleFilter, setRoleFilter] = useState<AdminUserRole | 'all'>('all');\n const [statusFilter, setStatusFilter] = useState<AdminUserStatus | 'all'>('all');\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n\n const filtered = useMemo(() => {\n let result = [...adminUsers];\n if (roleFilter !== 'all') result = result.filter((u) => u.role === roleFilter);\n if (statusFilter !== 'all') result = result.filter((u) => u.status === statusFilter);\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (u) => u.name.toLowerCase().includes(q) || u.email.toLowerCase().includes(q)\n );\n }\n return result;\n }, [adminUsers, roleFilter, statusFilter, searchQuery]);\n\n // Stats\n const totalUsers = adminUsers.length;\n const activeUsers = adminUsers.filter((u) => u.status === 'active').length;\n const providers = adminUsers.filter((u) => u.role === 'provider').length;\n const verifiedUsers = adminUsers.filter((u) => u.verified).length;\n\n const toggleSelect = (id: string) => {\n const next = new Set(selectedIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n setSelectedIds(next);\n };\n\n const toggleSelectAll = () => {\n if (selectedIds.size === filtered.length) setSelectedIds(new Set());\n else setSelectedIds(new Set(filtered.map((u) => u.id)));\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">User Management</h1>\n <p className=\"text-sm text-text-secondary\">\n Admin panel to manage platform users, roles, and access.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-2 h-4 w-4\" /> Export\n </Button>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" /> Invite User\n </Button>\n </div>\n </div>\n\n {/* Stats */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-blue-100 p-2 dark:bg-blue-950\">\n <Users className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{totalUsers}</p>\n <p className=\"text-xs text-text-secondary\">Total Users</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-green-100 p-2 dark:bg-green-950\">\n <UserCheck className=\"h-5 w-5 text-green-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{activeUsers}</p>\n <p className=\"text-xs text-text-secondary\">Active Users</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-purple-100 p-2 dark:bg-purple-950\">\n <Shield className=\"h-5 w-5 text-purple-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{providers}</p>\n <p className=\"text-xs text-text-secondary\">Providers</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-yellow-100 p-2 dark:bg-yellow-950\">\n <CheckCircle2 className=\"h-5 w-5 text-yellow-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{verifiedUsers}</p>\n <p className=\"text-xs text-text-secondary\">Verified</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search by name or email...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <Filter className=\"h-4 w-4 text-text-secondary\" />\n <select\n className=\"rounded border bg-bg-surface px-2 py-1 text-sm\"\n value={roleFilter}\n onChange={(e) => setRoleFilter(e.target.value as AdminUserRole | 'all')}\n >\n <option value=\"all\">All Roles</option>\n <option value=\"client\">Client</option>\n <option value=\"provider\">Provider</option>\n <option value=\"admin\">Admin</option>\n <option value=\"team_member\">Team Member</option>\n </select>\n <select\n className=\"rounded border bg-bg-surface px-2 py-1 text-sm\"\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as AdminUserStatus | 'all')}\n >\n <option value=\"all\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"suspended\">Suspended</option>\n <option value=\"pending\">Pending</option>\n <option value=\"banned\">Banned</option>\n </select>\n </div>\n </div>\n\n {/* Bulk actions */}\n {selectedIds.size > 0 && (\n <div className=\"flex items-center gap-3 rounded-lg bg-action-primary-bg/5 border border-primary/20 p-3\">\n <span className=\"text-sm font-medium\">{selectedIds.size} user(s) selected</span>\n <Button variant=\"outline\" size=\"sm\">\n Activate\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n Suspend\n </Button>\n <Button variant=\"destructive\" size=\"sm\">\n Ban\n </Button>\n </div>\n )}\n\n {/* User table */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-text-secondary\">\n <th className=\"p-3\">\n <input\n type=\"checkbox\"\n checked={selectedIds.size === filtered.length && filtered.length > 0}\n onChange={toggleSelectAll}\n className=\"rounded\"\n />\n </th>\n <th className=\"p-3\">User</th>\n <th className=\"p-3\">Role</th>\n <th className=\"p-3\">Status</th>\n <th className=\"p-3\">Verified</th>\n <th className=\"p-3\">Joined</th>\n <th className=\"p-3\">Last Active</th>\n <th className=\"p-3 text-right\">Bookings</th>\n <th className=\"p-3 text-right\">Spent</th>\n <th className=\"p-3\">Rating</th>\n <th className=\"p-3 text-right\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {filtered.length === 0 ? (\n <tr>\n <td colSpan={11} className=\"p-8 text-center text-text-secondary\">\n No users match your filters.\n </td>\n </tr>\n ) : (\n filtered.map((user) => {\n const sCfg = statusConfig[user.status];\n const StatusIcon = sCfg.icon;\n return (\n <tr key={user.id} className=\"border-b hover:bg-bg-sunken/50\">\n <td className=\"p-3\">\n <input\n type=\"checkbox\"\n checked={selectedIds.has(user.id)}\n onChange={() => toggleSelect(user.id)}\n className=\"rounded\"\n />\n </td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-action-primary-bg/10 text-xs font-semibold text-primary\">\n {user.name.charAt(0)}\n </div>\n <div>\n <p className=\"font-medium\">{user.name}</p>\n <p className=\"text-xs text-text-secondary\">{user.email}</p>\n </div>\n </div>\n </td>\n <td className=\"p-3\">\n <Badge variant={roleConfig[user.role].variant}>\n {roleConfig[user.role].label}\n </Badge>\n </td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-1\">\n <StatusIcon className={`h-4 w-4 ${sCfg.color}`} />\n <span className={`text-xs font-medium ${sCfg.color}`}>\n {sCfg.label}\n </span>\n </div>\n </td>\n <td className=\"p-3\">\n {user.verified ? (\n <CheckCircle2 className=\"h-4 w-4 text-green-500\" />\n ) : (\n <XCircle className=\"h-4 w-4 text-gray-300\" />\n )}\n </td>\n <td className=\"p-3 text-text-secondary\">{user.joinedDate}</td>\n <td className=\"p-3 text-text-secondary\">{user.lastActive}</td>\n <td className=\"p-3 text-right\">{user.bookingsCount}</td>\n <td className=\"p-3 text-right\">\n {user.totalSpent > 0 ? `$${user.totalSpent.toLocaleString()}` : '-'}\n </td>\n <td className=\"p-3\">\n {user.rating ? (\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 fill-yellow-400 text-yellow-400\" />\n <span className=\"text-xs font-medium\">{user.rating}</span>\n </div>\n ) : (\n <span className=\"text-xs text-text-secondary\">-</span>\n )}\n </td>\n <td className=\"p-3 text-right\">\n <div className=\"flex justify-end gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <Mail className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <MoreHorizontal className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {/* Pagination hint */}\n <div className=\"mt-4 flex items-center justify-between border-t pt-4 text-sm text-text-secondary\">\n <span>\n Showing {filtered.length} of {adminUsers.length} users\n </span>\n <div className=\"flex gap-1\">\n <Button variant=\"outline\" size=\"sm\" disabled>\n Previous\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled>\n Next\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -41,7 +41,7 @@ function S() {
41
41
  className: "text-2xl font-semibold",
42
42
  children: "Analytics"
43
43
  }), /* @__PURE__ */ m("p", {
44
- className: "text-sm text-muted-foreground",
44
+ className: "text-sm text-text-secondary",
45
45
  children: "Insights and performance metrics for your professional services."
46
46
  })] }), /* @__PURE__ */ h("div", {
47
47
  className: "flex items-center gap-2",
@@ -54,7 +54,7 @@ function S() {
54
54
  "1y"
55
55
  ].map((e) => /* @__PURE__ */ m("button", {
56
56
  onClick: () => A(e),
57
- className: `px-3 py-1 text-xs font-medium ${k === e ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted/50"}`,
57
+ className: `px-3 py-1 text-xs font-medium ${k === e ? "bg-action-primary-bg text-action-primary-text" : "text-text-secondary hover:bg-bg-sunken/50"}`,
58
58
  children: e.toUpperCase()
59
59
  }, e))
60
60
  }), /* @__PURE__ */ h(_, {
@@ -68,7 +68,7 @@ function S() {
68
68
  className: "flex gap-1 border-b",
69
69
  children: j.map(({ key: e, label: t, icon: n }) => /* @__PURE__ */ h("button", {
70
70
  onClick: () => O(e),
71
- className: `flex items-center gap-2 border-b-2 px-4 py-2 text-sm font-medium transition-colors ${D === e ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`,
71
+ className: `flex items-center gap-2 border-b-2 px-4 py-2 text-sm font-medium transition-colors ${D === e ? "border-primary text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
72
72
  children: [/* @__PURE__ */ m(n, { className: "h-4 w-4" }), t]
73
73
  }, e))
74
74
  }),
@@ -80,7 +80,7 @@ function S() {
80
80
  /* @__PURE__ */ h("div", {
81
81
  className: "flex items-center justify-between",
82
82
  children: [/* @__PURE__ */ m("p", {
83
- className: "text-xs font-medium text-muted-foreground",
83
+ className: "text-xs font-medium text-text-secondary",
84
84
  children: e.label
85
85
  }), M(e.changeType)]
86
86
  }),
@@ -112,16 +112,16 @@ function S() {
112
112
  className: "flex items-center gap-3",
113
113
  children: [
114
114
  /* @__PURE__ */ m("span", {
115
- className: "w-10 text-xs text-muted-foreground",
115
+ className: "w-10 text-xs text-text-secondary",
116
116
  children: e.name
117
117
  }),
118
118
  /* @__PURE__ */ h("div", {
119
- className: "relative flex-1 h-6 bg-muted rounded overflow-hidden",
119
+ className: "relative flex-1 h-6 bg-bg-sunken rounded overflow-hidden",
120
120
  children: [e.prev !== void 0 && /* @__PURE__ */ m("div", {
121
121
  className: "absolute h-6 bg-muted-foreground/10 rounded",
122
122
  style: { width: `${e.prev / N * 100}%` }
123
123
  }), /* @__PURE__ */ m("div", {
124
- className: "relative h-6 bg-primary rounded",
124
+ className: "relative h-6 bg-action-primary-bg rounded",
125
125
  style: { width: `${e.value / N * 100}%` }
126
126
  })]
127
127
  }),
@@ -150,11 +150,11 @@ function S() {
150
150
  className: "flex items-center gap-3",
151
151
  children: [
152
152
  /* @__PURE__ */ m("span", {
153
- className: "w-10 text-xs text-muted-foreground",
153
+ className: "w-10 text-xs text-text-secondary",
154
154
  children: e.name
155
155
  }),
156
156
  /* @__PURE__ */ m("div", {
157
- className: "flex-1 h-6 bg-muted rounded overflow-hidden",
157
+ className: "flex-1 h-6 bg-bg-sunken rounded overflow-hidden",
158
158
  children: /* @__PURE__ */ m("div", {
159
159
  className: "h-6 bg-blue-500 rounded",
160
160
  style: { width: `${e.value / P * 100}%` }
@@ -182,13 +182,13 @@ function S() {
182
182
  children: [/* @__PURE__ */ h("div", {
183
183
  className: "flex items-center gap-4",
184
184
  children: [/* @__PURE__ */ m("div", {
185
- className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10",
185
+ className: "flex h-10 w-10 items-center justify-center rounded-lg bg-action-primary-bg/10",
186
186
  children: /* @__PURE__ */ m(o, { className: "h-5 w-5 text-primary" })
187
187
  }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h("p", {
188
188
  className: "font-medium",
189
189
  children: [e.name, " 2025"]
190
190
  }), /* @__PURE__ */ h("p", {
191
- className: "text-sm text-muted-foreground",
191
+ className: "text-sm text-text-secondary",
192
192
  children: [
193
193
  "Previous: $",
194
194
  ((e.prev ?? 0) / 1e3).toFixed(1),
@@ -240,7 +240,7 @@ function S() {
240
240
  children: [e.value, " clients"]
241
241
  })]
242
242
  }), /* @__PURE__ */ m("div", {
243
- className: "mt-2 h-2 overflow-hidden rounded-full bg-muted",
243
+ className: "mt-2 h-2 overflow-hidden rounded-full bg-bg-sunken",
244
244
  children: /* @__PURE__ */ m("div", {
245
245
  className: "h-2 rounded-full bg-blue-500",
246
246
  style: { width: `${e.value / P * 100}%` }
@@ -255,7 +255,7 @@ function S() {
255
255
  })
256
256
  })] }), /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ m(b, { children: /* @__PURE__ */ h("div", {
257
257
  className: "flex items-center gap-2",
258
- children: [/* @__PURE__ */ m(l, { className: "h-5 w-5 text-muted-foreground" }), /* @__PURE__ */ m(x, {
258
+ children: [/* @__PURE__ */ m(l, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ m(x, {
259
259
  className: "text-base",
260
260
  children: "Geographic Distribution"
261
261
  })]
@@ -264,7 +264,7 @@ function S() {
264
264
  children: /* @__PURE__ */ h("table", {
265
265
  className: "w-full text-sm",
266
266
  children: [/* @__PURE__ */ m("thead", { children: /* @__PURE__ */ h("tr", {
267
- className: "border-b text-left text-muted-foreground",
267
+ className: "border-b text-left text-text-secondary",
268
268
  children: [
269
269
  /* @__PURE__ */ m("th", {
270
270
  className: "p-3",
@@ -286,7 +286,7 @@ function S() {
286
286
  }) }), /* @__PURE__ */ m("tbody", { children: E.map((e) => {
287
287
  let t = E.reduce((e, t) => e + t.clients, 0), n = Math.round(e.clients / t * 100);
288
288
  return /* @__PURE__ */ h("tr", {
289
- className: "border-b hover:bg-muted/50",
289
+ className: "border-b hover:bg-bg-sunken/50",
290
290
  children: [
291
291
  /* @__PURE__ */ m("td", {
292
292
  className: "p-3 font-medium",
@@ -309,13 +309,13 @@ function S() {
309
309
  children: /* @__PURE__ */ h("div", {
310
310
  className: "flex items-center gap-2",
311
311
  children: [/* @__PURE__ */ m("div", {
312
- className: "h-2 flex-1 overflow-hidden rounded-full bg-muted",
312
+ className: "h-2 flex-1 overflow-hidden rounded-full bg-bg-sunken",
313
313
  children: /* @__PURE__ */ m("div", {
314
- className: "h-2 rounded-full bg-primary",
314
+ className: "h-2 rounded-full bg-action-primary-bg",
315
315
  style: { width: `${n}%` }
316
316
  })
317
317
  }), /* @__PURE__ */ h("span", {
318
- className: "w-10 text-right text-xs text-muted-foreground",
318
+ className: "w-10 text-right text-xs text-text-secondary",
319
319
  children: [n, "%"]
320
320
  })]
321
321
  })
@@ -334,7 +334,7 @@ function S() {
334
334
  children: [...T].sort((e, t) => t.value - e.value).map((e, t) => /* @__PURE__ */ h("div", {
335
335
  className: "flex items-center gap-4",
336
336
  children: [/* @__PURE__ */ h("span", {
337
- className: "w-6 text-sm font-medium text-muted-foreground",
337
+ className: "w-6 text-sm font-medium text-text-secondary",
338
338
  children: ["#", t + 1]
339
339
  }), /* @__PURE__ */ h("div", {
340
340
  className: "flex-1",
@@ -348,9 +348,9 @@ function S() {
348
348
  children: e.value
349
349
  })]
350
350
  }), /* @__PURE__ */ m("div", {
351
- className: "mt-1 h-3 overflow-hidden rounded-full bg-muted",
351
+ className: "mt-1 h-3 overflow-hidden rounded-full bg-bg-sunken",
352
352
  children: /* @__PURE__ */ m("div", {
353
- className: "h-3 rounded-full bg-primary transition-all",
353
+ className: "h-3 rounded-full bg-action-primary-bg transition-all",
354
354
  style: { width: `${e.value / F * 100}%` }
355
355
  })
356
356
  })]
@@ -372,7 +372,7 @@ function S() {
372
372
  className: "font-medium",
373
373
  children: e.name
374
374
  }), /* @__PURE__ */ h("span", {
375
- className: "text-muted-foreground",
375
+ className: "text-text-secondary",
376
376
  children: [
377
377
  "$",
378
378
  (e.value / 1e3).toFixed(1),
@@ -384,10 +384,10 @@ function S() {
384
384
  }), /* @__PURE__ */ h("div", {
385
385
  className: "flex gap-1",
386
386
  children: [/* @__PURE__ */ m("div", {
387
- className: "h-4 rounded bg-primary/30",
387
+ className: "h-4 rounded bg-action-primary-bg/30",
388
388
  style: { width: `${(e.prev ?? 0) / N * 100}%` }
389
389
  }), /* @__PURE__ */ m("div", {
390
- className: "h-4 rounded bg-primary",
390
+ className: "h-4 rounded bg-action-primary-bg",
391
391
  style: { width: `${e.value / N * 100 - (e.prev ?? 0) / N * 100}%` }
392
392
  })]
393
393
  })]
@@ -395,10 +395,10 @@ function S() {
395
395
  className: "mt-4 flex items-center gap-4 text-xs",
396
396
  children: [/* @__PURE__ */ h("span", {
397
397
  className: "flex items-center gap-1",
398
- children: [/* @__PURE__ */ m("div", { className: "h-3 w-3 rounded bg-primary/30" }), " Previous"]
398
+ children: [/* @__PURE__ */ m("div", { className: "h-3 w-3 rounded bg-action-primary-bg/30" }), " Previous"]
399
399
  }), /* @__PURE__ */ h("span", {
400
400
  className: "flex items-center gap-1",
401
- children: [/* @__PURE__ */ m("div", { className: "h-3 w-3 rounded bg-primary" }), " Current"]
401
+ children: [/* @__PURE__ */ m("div", { className: "h-3 w-3 rounded bg-action-primary-bg" }), " Current"]
402
402
  })]
403
403
  })]
404
404
  })] }), /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ m(b, { children: /* @__PURE__ */ m(x, {
@@ -411,7 +411,7 @@ function S() {
411
411
  children: [/* @__PURE__ */ h("div", {
412
412
  className: "flex items-center gap-3",
413
413
  children: [/* @__PURE__ */ m("div", {
414
- className: `flex h-8 w-8 items-center justify-center rounded-full ${t === 0 ? "bg-yellow-100 text-yellow-700" : t === 1 ? "bg-gray-100 text-gray-600" : t === 2 ? "bg-orange-100 text-orange-600" : "bg-muted text-muted-foreground"} text-sm font-bold`,
414
+ className: `flex h-8 w-8 items-center justify-center rounded-full ${t === 0 ? "bg-yellow-100 text-yellow-700" : t === 1 ? "bg-gray-100 text-gray-600" : t === 2 ? "bg-orange-100 text-orange-600" : "bg-bg-sunken text-text-secondary"} text-sm font-bold`,
415
415
  children: t + 1
416
416
  }), /* @__PURE__ */ m("span", {
417
417
  className: "font-medium text-sm",
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/AnalyticsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport {\n TrendingUp,\n TrendingDown,\n Minus,\n DollarSign,\n Users,\n BarChart3,\n Activity,\n Globe,\n Calendar,\n ArrowUpRight,\n ArrowDownRight,\n Download,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype AnalyticsTab = 'overview' | 'revenue' | 'clients' | 'services' | 'performance';\n\nexport function AnalyticsPage() {\n const { analyticsMetrics, revenueData, clientData, servicePerformance, geographicData } =\n useProServiceWorldStore();\n const [activeTab, setActiveTab] = useState<AnalyticsTab>('overview');\n const [timeRange, setTimeRange] = useState('6m');\n\n const tabs: { key: AnalyticsTab; label: string; icon: typeof BarChart3 }[] = [\n { key: 'overview', label: 'Overview', icon: BarChart3 },\n { key: 'revenue', label: 'Revenue', icon: DollarSign },\n { key: 'clients', label: 'Clients', icon: Users },\n { key: 'services', label: 'Services', icon: Activity },\n { key: 'performance', label: 'Performance', icon: TrendingUp },\n ];\n\n const changeIcon = (type: string) => {\n if (type === 'positive') return <TrendingUp className=\"h-4 w-4 text-green-500\" />;\n if (type === 'negative') return <TrendingDown className=\"h-4 w-4 text-red-500\" />;\n return <Minus className=\"h-4 w-4 text-gray-400\" />;\n };\n\n const maxRevenue = Math.max(...revenueData.map((d) => d.value));\n const maxClients = Math.max(...clientData.map((d) => d.value));\n const maxServiceBookings = Math.max(...servicePerformance.map((d) => d.value));\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Analytics</h1>\n <p className=\"text-sm text-muted-foreground\">\n Insights and performance metrics for your professional services.\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex rounded border\">\n {['1m', '3m', '6m', '1y'].map((range) => (\n <button\n key={range}\n onClick={() => setTimeRange(range)}\n className={`px-3 py-1 text-xs font-medium ${\n timeRange === range\n ? 'bg-primary text-primary-foreground'\n : 'text-muted-foreground hover:bg-muted/50'\n }`}\n >\n {range.toUpperCase()}\n </button>\n ))}\n </div>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-2 h-4 w-4\" /> Export\n </Button>\n </div>\n </div>\n\n {/* Tabs */}\n <div className=\"flex gap-1 border-b\">\n {tabs.map(({ key, label, icon: Icon }) => (\n <button\n key={key}\n onClick={() => setActiveTab(key)}\n className={`flex items-center gap-2 border-b-2 px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === key\n ? 'border-primary text-primary'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n <Icon className=\"h-4 w-4\" />\n {label}\n </button>\n ))}\n </div>\n\n {/* Metric Cards (shown on all tabs) */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-5\">\n {analyticsMetrics.map((metric, i) => (\n <Card key={i}>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs font-medium text-muted-foreground\">{metric.label}</p>\n {changeIcon(metric.changeType)}\n </div>\n <p className=\"mt-1 text-2xl font-bold\">{metric.value}</p>\n <p\n className={`mt-0.5 text-xs ${\n metric.changeType === 'positive'\n ? 'text-green-600'\n : metric.changeType === 'negative'\n ? 'text-red-600'\n : 'text-gray-500'\n }`}\n >\n {metric.change} from last period\n </p>\n </CardContent>\n </Card>\n ))}\n </div>\n\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"grid gap-6 lg:grid-cols-2\">\n {/* Revenue chart */}\n <Card>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">Revenue Trend</CardTitle>\n <Badge variant=\"secondary\">Last 6 months</Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {revenueData.map((point) => (\n <div key={point.name} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-xs text-muted-foreground\">{point.name}</span>\n <div className=\"relative flex-1 h-6 bg-muted rounded overflow-hidden\">\n {point.prev !== undefined && (\n <div\n className=\"absolute h-6 bg-muted-foreground/10 rounded\"\n style={{ width: `${(point.prev / maxRevenue) * 100}%` }}\n />\n )}\n <div\n className=\"relative h-6 bg-primary rounded\"\n style={{ width: `${(point.value / maxRevenue) * 100}%` }}\n />\n </div>\n <span className=\"w-20 text-right text-xs font-medium\">\n ${(point.value / 1000).toFixed(1)}k\n </span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n {/* Client growth */}\n <Card>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">Client Growth</CardTitle>\n <Badge variant=\"secondary\">Monthly</Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {clientData.map((point) => (\n <div key={point.name} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-xs text-muted-foreground\">{point.name}</span>\n <div className=\"flex-1 h-6 bg-muted rounded overflow-hidden\">\n <div\n className=\"h-6 bg-blue-500 rounded\"\n style={{ width: `${(point.value / maxClients) * 100}%` }}\n />\n </div>\n <span className=\"w-12 text-right text-xs font-medium\">{point.value}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Revenue Tab */}\n {activeTab === 'revenue' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Revenue Breakdown</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {revenueData.map((point) => {\n const growth = point.prev\n ? (((point.value - point.prev) / point.prev) * 100).toFixed(1)\n : '0';\n const isPositive = point.prev ? point.value >= point.prev : true;\n return (\n <div\n key={point.name}\n className=\"flex items-center justify-between rounded-lg border p-4\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10\">\n <Calendar className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <p className=\"font-medium\">{point.name} 2025</p>\n <p className=\"text-sm text-muted-foreground\">\n Previous: ${((point.prev ?? 0) / 1000).toFixed(1)}k\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <p className=\"text-lg font-bold\">${(point.value / 1000).toFixed(1)}k</p>\n <p\n className={`flex items-center gap-1 text-xs ${isPositive ? 'text-green-600' : 'text-red-600'}`}\n >\n {isPositive ? (\n <ArrowUpRight className=\"h-3 w-3\" />\n ) : (\n <ArrowDownRight className=\"h-3 w-3\" />\n )}\n {growth}%\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Clients Tab */}\n {activeTab === 'clients' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Client Acquisition</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {clientData.map((point, idx) => {\n const prev = idx > 0 ? (clientData[idx - 1]?.value ?? 0) : 0;\n const growth = prev > 0 ? (((point.value - prev) / prev) * 100).toFixed(0) : 'N/A';\n return (\n <div key={point.name} className=\"flex items-center gap-4 rounded-lg border p-3\">\n <div className=\"flex-1\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium\">{point.name}</span>\n <span className=\"text-lg font-bold\">{point.value} clients</span>\n </div>\n <div className=\"mt-2 h-2 overflow-hidden rounded-full bg-muted\">\n <div\n className=\"h-2 rounded-full bg-blue-500\"\n style={{ width: `${(point.value / maxClients) * 100}%` }}\n />\n </div>\n </div>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {typeof growth === 'string' ? growth : `+${growth}%`}\n </Badge>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n {/* Geographic data */}\n <Card>\n <CardHeader>\n <div className=\"flex items-center gap-2\">\n <Globe className=\"h-5 w-5 text-muted-foreground\" />\n <CardTitle className=\"text-base\">Geographic Distribution</CardTitle>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-muted-foreground\">\n <th className=\"p-3\">Country</th>\n <th className=\"p-3 text-right\">Clients</th>\n <th className=\"p-3 text-right\">Revenue</th>\n <th className=\"p-3\">Distribution</th>\n </tr>\n </thead>\n <tbody>\n {geographicData.map((geo) => {\n const totalClients = geographicData.reduce((s, g) => s + g.clients, 0);\n const pct = Math.round((geo.clients / totalClients) * 100);\n return (\n <tr key={geo.country} className=\"border-b hover:bg-muted/50\">\n <td className=\"p-3 font-medium\">{geo.country}</td>\n <td className=\"p-3 text-right\">{geo.clients}</td>\n <td className=\"p-3 text-right\">${(geo.revenue / 1000).toFixed(0)}k</td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"h-2 flex-1 overflow-hidden rounded-full bg-muted\">\n <div\n className=\"h-2 rounded-full bg-primary\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-xs text-muted-foreground\">\n {pct}%\n </span>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Services Tab */}\n {activeTab === 'services' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Service Performance (Total Bookings)</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {[...servicePerformance]\n .sort((a, b) => b.value - a.value)\n .map((service, idx) => (\n <div key={service.name} className=\"flex items-center gap-4\">\n <span className=\"w-6 text-sm font-medium text-muted-foreground\">#{idx + 1}</span>\n <div className=\"flex-1\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium\">{service.name}</span>\n <span className=\"text-sm font-bold\">{service.value}</span>\n </div>\n <div className=\"mt-1 h-3 overflow-hidden rounded-full bg-muted\">\n <div\n className=\"h-3 rounded-full bg-primary transition-all\"\n style={{ width: `${(service.value / maxServiceBookings) * 100}%` }}\n />\n </div>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n )}\n\n {/* Performance Tab */}\n {activeTab === 'performance' && (\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Monthly Revenue vs Previous</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {revenueData.map((point) => (\n <div key={point.name} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium\">{point.name}</span>\n <span className=\"text-muted-foreground\">\n ${(point.value / 1000).toFixed(1)}k vs $\n {((point.prev ?? 0) / 1000).toFixed(1)}k\n </span>\n </div>\n <div className=\"flex gap-1\">\n <div\n className=\"h-4 rounded bg-primary/30\"\n style={{ width: `${((point.prev ?? 0) / maxRevenue) * 100}%` }}\n />\n <div\n className=\"h-4 rounded bg-primary\"\n style={{\n width: `${(point.value / maxRevenue) * 100 - ((point.prev ?? 0) / maxRevenue) * 100}%`,\n }}\n />\n </div>\n </div>\n ))}\n <div className=\"mt-4 flex items-center gap-4 text-xs\">\n <span className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 rounded bg-primary/30\" /> Previous\n </span>\n <span className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 rounded bg-primary\" /> Current\n </span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Top Performing Services</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {[...servicePerformance]\n .sort((a, b) => b.value - a.value)\n .slice(0, 5)\n .map((service, idx) => (\n <div\n key={service.name}\n className=\"flex items-center justify-between rounded-lg border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <div\n className={`flex h-8 w-8 items-center justify-center rounded-full ${\n idx === 0\n ? 'bg-yellow-100 text-yellow-700'\n : idx === 1\n ? 'bg-gray-100 text-gray-600'\n : idx === 2\n ? 'bg-orange-100 text-orange-600'\n : 'bg-muted text-muted-foreground'\n } text-sm font-bold`}\n >\n {idx + 1}\n </div>\n <span className=\"font-medium text-sm\">{service.name}</span>\n </div>\n <Badge variant=\"secondary\">{service.value} bookings</Badge>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/AnalyticsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport {\n TrendingUp,\n TrendingDown,\n Minus,\n DollarSign,\n Users,\n BarChart3,\n Activity,\n Globe,\n Calendar,\n ArrowUpRight,\n ArrowDownRight,\n Download,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype AnalyticsTab = 'overview' | 'revenue' | 'clients' | 'services' | 'performance';\n\nexport function AnalyticsPage() {\n const { analyticsMetrics, revenueData, clientData, servicePerformance, geographicData } =\n useProServiceWorldStore();\n const [activeTab, setActiveTab] = useState<AnalyticsTab>('overview');\n const [timeRange, setTimeRange] = useState('6m');\n\n const tabs: { key: AnalyticsTab; label: string; icon: typeof BarChart3 }[] = [\n { key: 'overview', label: 'Overview', icon: BarChart3 },\n { key: 'revenue', label: 'Revenue', icon: DollarSign },\n { key: 'clients', label: 'Clients', icon: Users },\n { key: 'services', label: 'Services', icon: Activity },\n { key: 'performance', label: 'Performance', icon: TrendingUp },\n ];\n\n const changeIcon = (type: string) => {\n if (type === 'positive') return <TrendingUp className=\"h-4 w-4 text-green-500\" />;\n if (type === 'negative') return <TrendingDown className=\"h-4 w-4 text-red-500\" />;\n return <Minus className=\"h-4 w-4 text-gray-400\" />;\n };\n\n const maxRevenue = Math.max(...revenueData.map((d) => d.value));\n const maxClients = Math.max(...clientData.map((d) => d.value));\n const maxServiceBookings = Math.max(...servicePerformance.map((d) => d.value));\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Analytics</h1>\n <p className=\"text-sm text-text-secondary\">\n Insights and performance metrics for your professional services.\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex rounded border\">\n {['1m', '3m', '6m', '1y'].map((range) => (\n <button\n key={range}\n onClick={() => setTimeRange(range)}\n className={`px-3 py-1 text-xs font-medium ${\n timeRange === range\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-secondary hover:bg-bg-sunken/50'\n }`}\n >\n {range.toUpperCase()}\n </button>\n ))}\n </div>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-2 h-4 w-4\" /> Export\n </Button>\n </div>\n </div>\n\n {/* Tabs */}\n <div className=\"flex gap-1 border-b\">\n {tabs.map(({ key, label, icon: Icon }) => (\n <button\n key={key}\n onClick={() => setActiveTab(key)}\n className={`flex items-center gap-2 border-b-2 px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === key\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n }`}\n >\n <Icon className=\"h-4 w-4\" />\n {label}\n </button>\n ))}\n </div>\n\n {/* Metric Cards (shown on all tabs) */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-5\">\n {analyticsMetrics.map((metric, i) => (\n <Card key={i}>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs font-medium text-text-secondary\">{metric.label}</p>\n {changeIcon(metric.changeType)}\n </div>\n <p className=\"mt-1 text-2xl font-bold\">{metric.value}</p>\n <p\n className={`mt-0.5 text-xs ${\n metric.changeType === 'positive'\n ? 'text-green-600'\n : metric.changeType === 'negative'\n ? 'text-red-600'\n : 'text-gray-500'\n }`}\n >\n {metric.change} from last period\n </p>\n </CardContent>\n </Card>\n ))}\n </div>\n\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"grid gap-6 lg:grid-cols-2\">\n {/* Revenue chart */}\n <Card>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">Revenue Trend</CardTitle>\n <Badge variant=\"secondary\">Last 6 months</Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {revenueData.map((point) => (\n <div key={point.name} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-xs text-text-secondary\">{point.name}</span>\n <div className=\"relative flex-1 h-6 bg-bg-sunken rounded overflow-hidden\">\n {point.prev !== undefined && (\n <div\n className=\"absolute h-6 bg-muted-foreground/10 rounded\"\n style={{ width: `${(point.prev / maxRevenue) * 100}%` }}\n />\n )}\n <div\n className=\"relative h-6 bg-action-primary-bg rounded\"\n style={{ width: `${(point.value / maxRevenue) * 100}%` }}\n />\n </div>\n <span className=\"w-20 text-right text-xs font-medium\">\n ${(point.value / 1000).toFixed(1)}k\n </span>\n </div>\n ))}\n </CardContent>\n </Card>\n\n {/* Client growth */}\n <Card>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">Client Growth</CardTitle>\n <Badge variant=\"secondary\">Monthly</Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {clientData.map((point) => (\n <div key={point.name} className=\"flex items-center gap-3\">\n <span className=\"w-10 text-xs text-text-secondary\">{point.name}</span>\n <div className=\"flex-1 h-6 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-6 bg-blue-500 rounded\"\n style={{ width: `${(point.value / maxClients) * 100}%` }}\n />\n </div>\n <span className=\"w-12 text-right text-xs font-medium\">{point.value}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Revenue Tab */}\n {activeTab === 'revenue' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Revenue Breakdown</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {revenueData.map((point) => {\n const growth = point.prev\n ? (((point.value - point.prev) / point.prev) * 100).toFixed(1)\n : '0';\n const isPositive = point.prev ? point.value >= point.prev : true;\n return (\n <div\n key={point.name}\n className=\"flex items-center justify-between rounded-lg border p-4\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-action-primary-bg/10\">\n <Calendar className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <p className=\"font-medium\">{point.name} 2025</p>\n <p className=\"text-sm text-text-secondary\">\n Previous: ${((point.prev ?? 0) / 1000).toFixed(1)}k\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <p className=\"text-lg font-bold\">${(point.value / 1000).toFixed(1)}k</p>\n <p\n className={`flex items-center gap-1 text-xs ${isPositive ? 'text-green-600' : 'text-red-600'}`}\n >\n {isPositive ? (\n <ArrowUpRight className=\"h-3 w-3\" />\n ) : (\n <ArrowDownRight className=\"h-3 w-3\" />\n )}\n {growth}%\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Clients Tab */}\n {activeTab === 'clients' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Client Acquisition</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {clientData.map((point, idx) => {\n const prev = idx > 0 ? (clientData[idx - 1]?.value ?? 0) : 0;\n const growth = prev > 0 ? (((point.value - prev) / prev) * 100).toFixed(0) : 'N/A';\n return (\n <div key={point.name} className=\"flex items-center gap-4 rounded-lg border p-3\">\n <div className=\"flex-1\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium\">{point.name}</span>\n <span className=\"text-lg font-bold\">{point.value} clients</span>\n </div>\n <div className=\"mt-2 h-2 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-2 rounded-full bg-blue-500\"\n style={{ width: `${(point.value / maxClients) * 100}%` }}\n />\n </div>\n </div>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {typeof growth === 'string' ? growth : `+${growth}%`}\n </Badge>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n {/* Geographic data */}\n <Card>\n <CardHeader>\n <div className=\"flex items-center gap-2\">\n <Globe className=\"h-5 w-5 text-text-secondary\" />\n <CardTitle className=\"text-base\">Geographic Distribution</CardTitle>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-text-secondary\">\n <th className=\"p-3\">Country</th>\n <th className=\"p-3 text-right\">Clients</th>\n <th className=\"p-3 text-right\">Revenue</th>\n <th className=\"p-3\">Distribution</th>\n </tr>\n </thead>\n <tbody>\n {geographicData.map((geo) => {\n const totalClients = geographicData.reduce((s, g) => s + g.clients, 0);\n const pct = Math.round((geo.clients / totalClients) * 100);\n return (\n <tr key={geo.country} className=\"border-b hover:bg-bg-sunken/50\">\n <td className=\"p-3 font-medium\">{geo.country}</td>\n <td className=\"p-3 text-right\">{geo.clients}</td>\n <td className=\"p-3 text-right\">${(geo.revenue / 1000).toFixed(0)}k</td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"h-2 flex-1 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-2 rounded-full bg-action-primary-bg\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"w-10 text-right text-xs text-text-secondary\">\n {pct}%\n </span>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Services Tab */}\n {activeTab === 'services' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Service Performance (Total Bookings)</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {[...servicePerformance]\n .sort((a, b) => b.value - a.value)\n .map((service, idx) => (\n <div key={service.name} className=\"flex items-center gap-4\">\n <span className=\"w-6 text-sm font-medium text-text-secondary\">#{idx + 1}</span>\n <div className=\"flex-1\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium\">{service.name}</span>\n <span className=\"text-sm font-bold\">{service.value}</span>\n </div>\n <div className=\"mt-1 h-3 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-3 rounded-full bg-action-primary-bg transition-all\"\n style={{ width: `${(service.value / maxServiceBookings) * 100}%` }}\n />\n </div>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n )}\n\n {/* Performance Tab */}\n {activeTab === 'performance' && (\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Monthly Revenue vs Previous</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {revenueData.map((point) => (\n <div key={point.name} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium\">{point.name}</span>\n <span className=\"text-text-secondary\">\n ${(point.value / 1000).toFixed(1)}k vs $\n {((point.prev ?? 0) / 1000).toFixed(1)}k\n </span>\n </div>\n <div className=\"flex gap-1\">\n <div\n className=\"h-4 rounded bg-action-primary-bg/30\"\n style={{ width: `${((point.prev ?? 0) / maxRevenue) * 100}%` }}\n />\n <div\n className=\"h-4 rounded bg-action-primary-bg\"\n style={{\n width: `${(point.value / maxRevenue) * 100 - ((point.prev ?? 0) / maxRevenue) * 100}%`,\n }}\n />\n </div>\n </div>\n ))}\n <div className=\"mt-4 flex items-center gap-4 text-xs\">\n <span className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 rounded bg-action-primary-bg/30\" /> Previous\n </span>\n <span className=\"flex items-center gap-1\">\n <div className=\"h-3 w-3 rounded bg-action-primary-bg\" /> Current\n </span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Top Performing Services</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {[...servicePerformance]\n .sort((a, b) => b.value - a.value)\n .slice(0, 5)\n .map((service, idx) => (\n <div\n key={service.name}\n className=\"flex items-center justify-between rounded-lg border p-3\"\n >\n <div className=\"flex items-center gap-3\">\n <div\n className={`flex h-8 w-8 items-center justify-center rounded-full ${\n idx === 0\n ? 'bg-yellow-100 text-yellow-700'\n : idx === 1\n ? 'bg-gray-100 text-gray-600'\n : idx === 2\n ? 'bg-orange-100 text-orange-600'\n : 'bg-bg-sunken text-text-secondary'\n } text-sm font-bold`}\n >\n {idx + 1}\n </div>\n <span className=\"font-medium text-sm\">{service.name}</span>\n </div>\n <Badge variant=\"secondary\">{service.value} bookings</Badge>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}