@burdenoff/microfe-subscriberbot 2026.624.1 → 2026.625.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.
- package/dist/subscriberbot/components/EmptyState.js +17 -10
- package/dist/subscriberbot/components/EmptyState.js.map +1 -1
- package/dist/subscriberbot/components/InvestmentCard.js +23 -22
- package/dist/subscriberbot/components/InvestmentCard.js.map +1 -1
- package/dist/subscriberbot/components/MetricsCard.js +15 -12
- package/dist/subscriberbot/components/MetricsCard.js.map +1 -1
- package/dist/subscriberbot/components/PageLayout.js +27 -15
- package/dist/subscriberbot/components/PageLayout.js.map +1 -1
- package/dist/subscriberbot/components/RatingDisplay.js +3 -3
- package/dist/subscriberbot/components/RatingDisplay.js.map +1 -1
- package/dist/subscriberbot/components/StatusBadge.js +25 -13
- package/dist/subscriberbot/components/StatusBadge.js.map +1 -1
- package/dist/subscriberbot/context/SubscriberBotContext.js.map +1 -1
- package/dist/subscriberbot/pages/HomePage.js +67 -63
- package/dist/subscriberbot/pages/HomePage.js.map +1 -1
- package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js +42 -42
- package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/subscriberbot/pages/admin/AdminDashboard.js +42 -41
- package/dist/subscriberbot/pages/admin/AdminDashboard.js.map +1 -1
- package/dist/subscriberbot/pages/admin/AdminFinancialPage.js +14 -14
- package/dist/subscriberbot/pages/admin/AdminFinancialPage.js.map +1 -1
- package/dist/subscriberbot/pages/admin/AdminOrdersPage.js +24 -24
- package/dist/subscriberbot/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/subscriberbot/pages/admin/AdminProfilePage.js +11 -11
- package/dist/subscriberbot/pages/admin/AdminProfilePage.js.map +1 -1
- package/dist/subscriberbot/pages/admin/AdminSettingsPage.js +14 -14
- package/dist/subscriberbot/pages/admin/AdminSettingsPage.js.map +1 -1
- package/dist/subscriberbot/pages/admin/CartManagementPage.js +41 -41
- package/dist/subscriberbot/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/subscriberbot/pages/admin/UserManagementPage.js +47 -47
- package/dist/subscriberbot/pages/admin/UserManagementPage.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js +44 -44
- package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js +17 -17
- package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js +94 -89
- package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js +58 -58
- package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js +51 -51
- package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js +54 -54
- package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js +54 -53
- package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js.map +1 -1
- package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js +51 -51
- package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/subscriberbot/pages/common/HelpSupportPage.js +65 -65
- package/dist/subscriberbot/pages/common/HelpSupportPage.js.map +1 -1
- package/dist/subscriberbot/pages/common/NotificationCenterPage.js +46 -45
- package/dist/subscriberbot/pages/common/NotificationCenterPage.js.map +1 -1
- package/dist/subscriberbot/pages/common/SettingsPage.js +46 -46
- package/dist/subscriberbot/pages/common/SettingsPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/BookingDetailsPage.js +24 -23
- package/dist/subscriberbot/pages/customer/BookingDetailsPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/CartDetailPage.js +31 -30
- package/dist/subscriberbot/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js +25 -23
- package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/CheckoutPage.js +26 -26
- package/dist/subscriberbot/pages/customer/CheckoutPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/CustomerDashboard.js +39 -38
- package/dist/subscriberbot/pages/customer/CustomerDashboard.js.map +1 -1
- package/dist/subscriberbot/pages/customer/CustomerProfilePage.js +36 -36
- package/dist/subscriberbot/pages/customer/CustomerProfilePage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js +37 -36
- package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/FavoritesPage.js +16 -15
- package/dist/subscriberbot/pages/customer/FavoritesPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/OrderHistoryPage.js +19 -17
- package/dist/subscriberbot/pages/customer/OrderHistoryPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/OrderTrackingPage.js +21 -20
- package/dist/subscriberbot/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js +22 -21
- package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/ReviewsPage.js +29 -28
- package/dist/subscriberbot/pages/customer/ReviewsPage.js.map +1 -1
- package/dist/subscriberbot/pages/customer/SavedAddressesPage.js +26 -25
- package/dist/subscriberbot/pages/customer/SavedAddressesPage.js.map +1 -1
- package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js +46 -46
- package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js.map +1 -1
- package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js +34 -32
- package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
- package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js +38 -38
- package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js.map +1 -1
- package/dist/subscriberbot/pages/investor/InvestorDashboard.js +26 -25
- package/dist/subscriberbot/pages/investor/InvestorDashboard.js.map +1 -1
- package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js +12 -11
- package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js.map +1 -1
- package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js +25 -25
- package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js.map +1 -1
- package/dist/subscriberbot/pages/investor/InvestorProfilePage.js +58 -58
- package/dist/subscriberbot/pages/investor/InvestorProfilePage.js.map +1 -1
- package/dist/subscriberbot/pages/worker/TaskDetailsPage.js +26 -25
- package/dist/subscriberbot/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/subscriberbot/pages/worker/WorkerDashboard.js +48 -47
- package/dist/subscriberbot/pages/worker/WorkerDashboard.js.map +1 -1
- package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js +41 -40
- package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js.map +1 -1
- package/dist/subscriberbot/pages/worker/WorkerProfilePage.js +44 -44
- package/dist/subscriberbot/pages/worker/WorkerProfilePage.js.map +1 -1
- package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js +32 -30
- package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserManagementPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/admin/UserManagementPage.tsx"],"sourcesContent":["/**\n * User Management Page\n * @module subscriberbot/pages/admin\n *\n * Full-featured user management with 8 stats cards, 5 filter controls,\n * dual layout (mobile cards + desktop table), user action modal\n * (edit form + delete confirmation), pagination, and loading state.\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport {\n Search,\n Users,\n UserCheck,\n UserX,\n Shield,\n Eye,\n Edit3,\n Trash2,\n CheckCircle2,\n XCircle,\n Loader2,\n ChevronLeft,\n ChevronRight,\n Smartphone,\n Mail,\n Phone,\n X,\n} from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { cn } from '../../utils/cn';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\ninterface ExtendedUser {\n id: string;\n email: string;\n phone: string;\n firstName: string;\n lastName: string;\n role: 'customer' | 'cart_owner' | 'worker' | 'investor' | 'admin';\n isEmailVerified: boolean;\n isPhoneVerified: boolean;\n profilePicture: string;\n status: 'active' | 'inactive' | 'suspended' | 'pending';\n lastLoginTime?: string;\n totalOrders?: number;\n totalSpent?: number;\n totalEarnings?: number;\n kycStatus?: 'pending' | 'verified' | 'rejected';\n riskScore?: number;\n registrationDate: string;\n deviceInfo?: string;\n}\n\ninterface UserFilters {\n role: string;\n status: string;\n searchQuery: string;\n sortBy: string;\n registrationDate: string;\n}\n\ninterface UserStats {\n totalUsers: number;\n activeUsers: number;\n newUsers: number;\n verifiedUsers: number;\n customers: number;\n cartOwners: number;\n workers: number;\n investors: number;\n}\n\n/* ------------------------------------------------------------------ */\n/* Mock data */\n/* ------------------------------------------------------------------ */\n\nconst mockUsers: ExtendedUser[] = [\n {\n id: 'user-001',\n email: 'rahul.sharma@gmail.com',\n phone: '+91 98765 43210',\n firstName: 'Rahul',\n lastName: 'Sharma',\n role: 'customer',\n isEmailVerified: true,\n isPhoneVerified: true,\n profilePicture: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n status: 'active',\n lastLoginTime: '2024-06-23T16:45:00Z',\n totalOrders: 45,\n totalSpent: 12350,\n registrationDate: '2024-01-15T08:30:00Z',\n deviceInfo: 'iPhone 14 Pro',\n },\n {\n id: 'user-002',\n email: 'priya.patel@gmail.com',\n phone: '+91 98765 43211',\n firstName: 'Priya',\n lastName: 'Patel',\n role: 'cart_owner',\n isEmailVerified: true,\n isPhoneVerified: true,\n profilePicture: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100',\n status: 'active',\n lastLoginTime: '2024-06-24T09:15:00Z',\n totalEarnings: 285000,\n kycStatus: 'verified',\n registrationDate: '2023-08-20T10:15:00Z',\n deviceInfo: 'Android Samsung',\n },\n {\n id: 'user-003',\n email: 'amit.kumar@gmail.com',\n phone: '+91 98765 43212',\n firstName: 'Amit',\n lastName: 'Kumar',\n role: 'worker',\n isEmailVerified: true,\n isPhoneVerified: false,\n profilePicture: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100',\n status: 'suspended',\n lastLoginTime: '2024-06-15T14:30:00Z',\n totalEarnings: 45000,\n kycStatus: 'pending',\n registrationDate: '2024-02-10T12:45:00Z',\n deviceInfo: 'Web Browser',\n },\n {\n id: 'user-004',\n email: 'sneha.investor@gmail.com',\n phone: '+91 98765 43213',\n firstName: 'Sneha',\n lastName: 'Reddy',\n role: 'investor',\n isEmailVerified: true,\n isPhoneVerified: true,\n profilePicture: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100',\n status: 'active',\n lastLoginTime: '2024-06-24T10:30:00Z',\n kycStatus: 'verified',\n riskScore: 2.1,\n registrationDate: '2023-12-01T15:20:00Z',\n deviceInfo: 'MacBook Pro',\n },\n {\n id: 'user-005',\n email: 'new.user@gmail.com',\n phone: '+91 98765 43214',\n firstName: 'New',\n lastName: 'User',\n role: 'customer',\n isEmailVerified: false,\n isPhoneVerified: false,\n profilePicture: '',\n status: 'pending',\n registrationDate: '2024-06-24T09:00:00Z',\n deviceInfo: 'iPhone 15',\n },\n];\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function UserManagementPage() {\n const { navigateTo } = useSubscriberBot();\n\n const [users, setUsers] = useState<ExtendedUser[]>([]);\n const [loading, setLoading] = useState(true);\n const [selectedUser, setSelectedUser] = useState<ExtendedUser | null>(null);\n const [showUserModal, setShowUserModal] = useState(false);\n const [actionType, setActionType] = useState<'edit' | 'delete'>('edit');\n const [editForm, setEditForm] = useState({\n firstName: '',\n lastName: '',\n email: '',\n phone: '',\n role: '',\n });\n const [currentPage, setCurrentPage] = useState(1);\n const itemsPerPage = 10;\n\n const [filters, setFilters] = useState<UserFilters>({\n role: '',\n status: '',\n searchQuery: '',\n sortBy: 'recent',\n registrationDate: '',\n });\n\n const [stats] = useState<UserStats>({\n totalUsers: 2456,\n activeUsers: 2134,\n newUsers: 89,\n verifiedUsers: 2021,\n customers: 1845,\n cartOwners: 342,\n workers: 156,\n investors: 113,\n });\n\n const loadUsers = useCallback(() => {\n setLoading(true);\n setTimeout(() => {\n let filtered = [...mockUsers];\n\n if (filters.searchQuery) {\n const q = filters.searchQuery.toLowerCase();\n filtered = filtered.filter(\n (u) =>\n u.firstName.toLowerCase().includes(q) ||\n u.lastName.toLowerCase().includes(q) ||\n u.email.toLowerCase().includes(q) ||\n u.phone.includes(q)\n );\n }\n if (filters.role) filtered = filtered.filter((u) => u.role === filters.role);\n if (filters.status) filtered = filtered.filter((u) => u.status === filters.status);\n if (filters.registrationDate) {\n const days = parseInt(filters.registrationDate);\n const cutoff = new Date(Date.now() - days * 86400000);\n filtered = filtered.filter((u) => new Date(u.registrationDate) >= cutoff);\n }\n\n switch (filters.sortBy) {\n case 'name':\n filtered.sort((a, b) => a.firstName.localeCompare(b.firstName));\n break;\n case 'activity':\n filtered.sort((a, b) => {\n const aT = a.lastLoginTime ? new Date(a.lastLoginTime).getTime() : 0;\n const bT = b.lastLoginTime ? new Date(b.lastLoginTime).getTime() : 0;\n return bT - aT;\n });\n break;\n default:\n filtered.sort(\n (a, b) =>\n new Date(b.registrationDate).getTime() - new Date(a.registrationDate).getTime()\n );\n }\n\n setUsers(filtered);\n setLoading(false);\n }, 800);\n }, [filters]);\n\n useEffect(() => {\n loadUsers();\n }, [loadUsers]);\n\n const handleFilterChange = (key: keyof UserFilters, value: string) => {\n setFilters((prev) => ({ ...prev, [key]: value }));\n setCurrentPage(1);\n };\n\n const handleUserAction = (\n user: ExtendedUser,\n action: 'edit' | 'suspend' | 'activate' | 'delete' | 'verify'\n ) => {\n if (action === 'suspend' || action === 'activate' || action === 'verify') {\n const msg =\n action === 'suspend'\n ? `User ${user.firstName} ${user.lastName} suspended`\n : action === 'activate'\n ? `User ${user.firstName} ${user.lastName} activated`\n : `User ${user.firstName} ${user.lastName} verified`;\n alert(msg);\n loadUsers();\n return;\n }\n setSelectedUser(user);\n setActionType(action);\n setEditForm({\n firstName: user.firstName,\n lastName: user.lastName,\n email: user.email,\n phone: user.phone,\n role: user.role,\n });\n setShowUserModal(true);\n };\n\n const handleDeleteConfirm = () => {\n if (selectedUser) {\n alert(`User ${selectedUser.firstName} ${selectedUser.lastName} deleted`);\n setShowUserModal(false);\n loadUsers();\n }\n };\n\n const handleSaveEdit = () => {\n alert('User updated successfully');\n setShowUserModal(false);\n loadUsers();\n };\n\n const formatDate = (d: string) =>\n new Date(d).toLocaleDateString('en-IN', { year: 'numeric', month: 'short', day: 'numeric' });\n\n const formatCurrency = (amount: number) => `₹${amount.toLocaleString('en-IN')}`;\n\n const pagedUsers = useMemo(() => {\n const start = (currentPage - 1) * itemsPerPage;\n return users.slice(start, start + itemsPerPage);\n }, [users, currentPage]);\n\n const roleBadge = (role: string) => {\n const c: Record<string, string> = {\n customer: 'bg-blue-500/20 text-blue-600 dark:text-blue-400',\n cart_owner: 'bg-green-500/20 text-green-600 dark:text-green-400',\n worker: 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400',\n investor: 'bg-purple-500/20 text-purple-600 dark:text-purple-400',\n admin: 'bg-red-500/20 text-red-600 dark:text-red-400',\n };\n const l: Record<string, string> = {\n customer: 'Customer',\n cart_owner: 'Cart Owner',\n worker: 'Worker',\n investor: 'Investor',\n admin: 'Admin',\n };\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n c[role]\n )}\n >\n {l[role] ?? role}\n </span>\n );\n };\n\n const statusBadge = (status: string) => {\n const c: Record<string, string> = {\n active: 'bg-green-500/20 text-green-600 dark:text-green-400',\n inactive: 'bg-secondary text-secondary-foreground',\n suspended: 'bg-red-500/20 text-red-600 dark:text-red-400',\n pending: 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400',\n };\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium capitalize',\n c[status]\n )}\n >\n {status}\n </span>\n );\n };\n\n /* ---- Loading ---- */\n if (loading) {\n return (\n <PageLayout title=\"User Management\" description=\"Loading users...\">\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 className=\"h-10 w-10 animate-spin text-text-secondary mb-4\" />\n <p className=\"text-text-secondary\">Loading users...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"User Management\"\n description={`${stats.totalUsers.toLocaleString('en-IN')} registered users on the platform`}\n >\n {/* 8 Stats Cards */}\n <div className=\"grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-3 mb-6\">\n {[\n { label: 'Total Users', value: stats.totalUsers.toLocaleString('en-IN'), cls: '' },\n {\n label: 'Active',\n value: stats.activeUsers.toLocaleString('en-IN'),\n cls: 'bg-green-500/10 border-green-500/30',\n },\n {\n label: 'New (30d)',\n value: stats.newUsers.toString(),\n cls: 'bg-blue-500/10 border-blue-500/30',\n },\n {\n label: 'Verified',\n value: stats.verifiedUsers.toLocaleString('en-IN'),\n cls: 'bg-purple-500/10 border-purple-500/30',\n },\n { label: 'Customers', value: stats.customers.toLocaleString('en-IN'), cls: '' },\n { label: 'Cart Owners', value: stats.cartOwners.toString(), cls: '' },\n { label: 'Workers', value: stats.workers.toString(), cls: '' },\n { label: 'Investors', value: stats.investors.toString(), cls: '' },\n ].map((s) => (\n <div key={s.label} className={cn('rounded-lg border border-border-subtle bg-bg-surface p-3', s.cls)}>\n <p className=\"text-xs text-text-secondary\">{s.label}</p>\n <p className=\"text-lg font-bold text-text-primary\">{s.value}</p>\n </div>\n ))}\n </div>\n\n {/* 5 Filter Controls */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 mb-6\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n placeholder=\"Search users...\"\n value={filters.searchQuery}\n onChange={(e) => handleFilterChange('searchQuery', e.target.value)}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 pl-10 pr-4 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <select\n value={filters.role}\n onChange={(e) => handleFilterChange('role', e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Roles</option>\n <option value=\"customer\">Customers</option>\n <option value=\"cart_owner\">Cart Owners</option>\n <option value=\"worker\">Workers</option>\n <option value=\"investor\">Investors</option>\n </select>\n <select\n value={filters.status}\n onChange={(e) => handleFilterChange('status', e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n <option value=\"suspended\">Suspended</option>\n <option value=\"pending\">Pending</option>\n </select>\n <select\n value={filters.registrationDate}\n onChange={(e) => handleFilterChange('registrationDate', e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Time</option>\n <option value=\"1\">Last 24 hours</option>\n <option value=\"7\">Last 7 days</option>\n <option value=\"30\">Last 30 days</option>\n <option value=\"90\">Last 90 days</option>\n </select>\n <select\n value={filters.sortBy}\n onChange={(e) => handleFilterChange('sortBy', e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"recent\">Most Recent</option>\n <option value=\"name\">Name A-Z</option>\n <option value=\"activity\">Last Activity</option>\n </select>\n </div>\n </div>\n\n {/* Dual Layout */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface overflow-hidden\">\n {/* Mobile Card View */}\n <div className=\"block md:hidden space-y-4 p-4\">\n {pagedUsers.map((user) => (\n <div key={user.id} className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-4\">\n <div className=\"flex items-center mb-3\">\n {user.profilePicture ? (\n <img\n src={user.profilePicture}\n alt={`${user.firstName} ${user.lastName}`}\n className=\"w-12 h-12 rounded-full object-cover mr-3\"\n />\n ) : (\n <div className=\"w-12 h-12 rounded-full bg-bg-sunken flex items-center justify-center mr-3\">\n <Users className=\"h-6 w-6 text-text-secondary\" />\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"font-medium text-text-primary\">\n {user.firstName} {user.lastName}\n </h3>\n <p className=\"text-sm text-text-secondary truncate\">{user.email}</p>\n <p className=\"text-sm text-text-secondary\">{user.phone}</p>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-2 mb-3\">\n {roleBadge(user.role)}\n {statusBadge(user.status)}\n </div>\n <div className=\"grid grid-cols-2 gap-4 text-sm mb-3\">\n <div>\n <p className=\"text-text-secondary\">Registered</p>\n <p className=\"text-text-primary\">{formatDate(user.registrationDate)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Last Login</p>\n <p className=\"text-text-primary\">\n {user.lastLoginTime ? formatDate(user.lastLoginTime) : 'Never'}\n </p>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-3 mb-3\">\n <div className=\"flex items-center\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full mr-2',\n user.isEmailVerified ? 'bg-green-500' : 'bg-red-500'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Email</span>\n </div>\n <div className=\"flex items-center\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full mr-2',\n user.isPhoneVerified ? 'bg-green-500' : 'bg-red-500'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Phone</span>\n </div>\n {user.kycStatus && (\n <div className=\"flex items-center\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full mr-2',\n user.kycStatus === 'verified'\n ? 'bg-green-500'\n : user.kycStatus === 'pending'\n ? 'bg-yellow-500'\n : 'bg-red-500'\n )}\n />\n <span className=\"text-sm text-text-secondary\">KYC</span>\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'edit')}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Edit\n </button>\n {user.status === 'active' ? (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'suspend')}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-sm font-medium text-red-600 hover:bg-red-500/10 transition-colors\"\n >\n Suspend\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'activate')}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-sm font-medium text-green-600 hover:bg-green-500/10 transition-colors\"\n >\n Activate\n </button>\n )}\n {user.kycStatus === 'pending' && (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'verify')}\n className=\"rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Verify\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n\n {/* Desktop Table View */}\n <div className=\"hidden md:block overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-subtle bg-bg-sunken/50\">\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n User\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Role & Status\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Activity\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Performance\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Verification\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {pagedUsers.map((user) => (\n <tr key={user.id} className=\"hover:bg-accent/50 transition-colors\">\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n {user.profilePicture ? (\n <img\n src={user.profilePicture}\n alt={`${user.firstName}`}\n className=\"w-10 h-10 rounded-full object-cover\"\n />\n ) : (\n <div className=\"w-10 h-10 rounded-full bg-bg-sunken flex items-center justify-center\">\n <Users className=\"h-5 w-5 text-text-secondary\" />\n </div>\n )}\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {user.firstName} {user.lastName}\n </p>\n <p className=\"text-xs text-text-secondary\">{user.email}</p>\n <p className=\"text-xs text-text-secondary\">{user.phone}</p>\n </div>\n </div>\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"space-y-1\">\n {roleBadge(user.role)}\n <br />\n {statusBadge(user.status)}\n </div>\n </td>\n <td className=\"px-4 py-3 text-sm\">\n <p className=\"text-text-primary\">\n Registered: {formatDate(user.registrationDate)}\n </p>\n {user.lastLoginTime && (\n <p className=\"text-text-secondary\">\n Last login: {formatDate(user.lastLoginTime)}\n </p>\n )}\n {user.deviceInfo && (\n <p className=\"text-text-secondary flex items-center gap-1\">\n <Smartphone className=\"h-3 w-3\" />\n {user.deviceInfo}\n </p>\n )}\n </td>\n <td className=\"px-4 py-3 text-sm\">\n {user.role === 'customer' && user.totalOrders != null && (\n <>\n <p className=\"text-text-primary\">{user.totalOrders} orders</p>\n <p className=\"text-text-secondary\">\n {formatCurrency(user.totalSpent ?? 0)} spent\n </p>\n </>\n )}\n {(user.role === 'cart_owner' || user.role === 'worker') &&\n user.totalEarnings != null && (\n <p className=\"text-text-primary\">\n {formatCurrency(user.totalEarnings)} earned\n </p>\n )}\n {user.role === 'investor' && user.riskScore != null && (\n <p className=\"text-text-primary\">Risk: {user.riskScore}/5</p>\n )}\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full',\n user.isEmailVerified ? 'bg-green-500' : 'bg-red-500'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Email</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full',\n user.isPhoneVerified ? 'bg-green-500' : 'bg-red-500'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Phone</span>\n </div>\n {user.kycStatus && (\n <div className=\"flex items-center gap-2\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full',\n user.kycStatus === 'verified'\n ? 'bg-green-500'\n : user.kycStatus === 'pending'\n ? 'bg-yellow-500'\n : 'bg-red-500'\n )}\n />\n <span className=\"text-sm text-text-secondary\">KYC</span>\n </div>\n )}\n </div>\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'edit')}\n title=\"Edit\"\n className=\"rounded p-1.5 text-text-secondary hover:text-text-primary hover:bg-accent transition-colors\"\n >\n <Edit3 className=\"h-4 w-4\" />\n </button>\n {user.status === 'active' ? (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'suspend')}\n title=\"Suspend\"\n className=\"rounded p-1.5 text-text-secondary hover:text-red-600 hover:bg-red-500/10 transition-colors\"\n >\n <UserX className=\"h-4 w-4\" />\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'activate')}\n title=\"Activate\"\n className=\"rounded p-1.5 text-text-secondary hover:text-green-600 hover:bg-green-500/10 transition-colors\"\n >\n <UserCheck className=\"h-4 w-4\" />\n </button>\n )}\n {user.kycStatus === 'pending' && (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'verify')}\n title=\"Verify\"\n className=\"rounded p-1.5 text-text-secondary hover:text-blue-600 hover:bg-blue-500/10 transition-colors\"\n >\n <Shield className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {users.length === 0 && (\n <div className=\"flex flex-col items-center justify-center py-12 px-4\">\n <Users className=\"h-10 w-10 text-text-secondary/50 mb-3\" />\n <p className=\"text-sm text-text-secondary\">No users found matching your criteria</p>\n </div>\n )}\n </div>\n\n {/* Pagination */}\n <div className=\"mt-6 flex flex-col sm:flex-row sm:items-center justify-between gap-4\">\n <p className=\"text-sm text-text-secondary text-center sm:text-left\">\n Showing{' '}\n <span className=\"font-medium\">\n {Math.min((currentPage - 1) * itemsPerPage + 1, users.length)}\n </span>{' '}\n to{' '}\n <span className=\"font-medium\">{Math.min(currentPage * itemsPerPage, users.length)}</span>{' '}\n of <span className=\"font-medium\">{users.length}</span> results\n </p>\n <div className=\"flex justify-center sm:justify-end gap-2\">\n <button\n type=\"button\"\n disabled={currentPage === 1}\n onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n Previous\n </button>\n <button\n type=\"button\"\n disabled={currentPage * itemsPerPage >= users.length}\n onClick={() => setCurrentPage((p) => p + 1)}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Next\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n\n {/* User Action Modal */}\n {showUserModal && selectedUser && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div className=\"w-full max-w-md rounded-lg border border-border-subtle bg-bg-surface shadow-lg max-h-[90vh] overflow-y-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-border-subtle\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {actionType === 'edit' ? 'Edit User' : 'Delete User'}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShowUserModal(false)}\n className=\"rounded p-1.5 text-text-secondary hover:text-text-primary hover:bg-accent transition-colors\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <div className=\"p-4\">\n {actionType === 'delete' ? (\n <div>\n <p className=\"text-text-secondary mb-4\">\n Are you sure you want to delete user "{selectedUser.firstName}{' '}\n {selectedUser.lastName}"? This action cannot be undone.\n </p>\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={() => setShowUserModal(false)}\n className=\"flex-1 rounded-lg border border-border-subtle py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleDeleteConfirm}\n className=\"flex-1 rounded-lg bg-red-600 hover:bg-red-700 py-2 text-sm font-medium text-white transition-colors\"\n >\n Delete User\n </button>\n </div>\n </div>\n ) : (\n <div>\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n First Name\n </label>\n <input\n type=\"text\"\n value={editForm.firstName}\n onChange={(e) =>\n setEditForm((f) => ({ ...f, firstName: e.target.value }))\n }\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={editForm.lastName}\n onChange={(e) => setEditForm((f) => ({ ...f, lastName: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Email\n </label>\n <input\n type=\"email\"\n value={editForm.email}\n onChange={(e) => setEditForm((f) => ({ ...f, email: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Phone\n </label>\n <input\n type=\"tel\"\n value={editForm.phone}\n onChange={(e) => setEditForm((f) => ({ ...f, phone: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Role\n </label>\n <select\n value={editForm.role}\n onChange={(e) => setEditForm((f) => ({ ...f, role: e.target.value }))}\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"customer\">Customer</option>\n <option value=\"cart_owner\">Cart Owner</option>\n <option value=\"worker\">Worker</option>\n <option value=\"investor\">Investor</option>\n </select>\n </div>\n </div>\n <div className=\"flex gap-3 mt-6\">\n <button\n type=\"button\"\n onClick={() => setShowUserModal(false)}\n className=\"flex-1 rounded-lg border border-border-subtle py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSaveEdit}\n className=\"flex-1 rounded-lg bg-action-primary-bg py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Save Changes\n </button>\n <button\n type=\"button\"\n onClick={() => setActionType('delete')}\n className=\"rounded-lg border border-border-subtle py-2 px-3 text-sm font-medium text-red-600 hover:bg-red-500/10 transition-colors\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UserManagementPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/admin/UserManagementPage.tsx"],"sourcesContent":["/**\n * User Management Page\n * @module subscriberbot/pages/admin\n *\n * Full-featured user management with 8 stats cards, 5 filter controls,\n * dual layout (mobile cards + desktop table), user action modal\n * (edit form + delete confirmation), pagination, and loading state.\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport {\n Search,\n Users,\n UserCheck,\n UserX,\n Shield,\n Eye,\n Edit3,\n Trash2,\n CheckCircle2,\n XCircle,\n Loader2,\n ChevronLeft,\n ChevronRight,\n Smartphone,\n Mail,\n Phone,\n X,\n} from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { cn } from '../../utils/cn';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\ninterface ExtendedUser {\n id: string;\n email: string;\n phone: string;\n firstName: string;\n lastName: string;\n role: 'customer' | 'cart_owner' | 'worker' | 'investor' | 'admin';\n isEmailVerified: boolean;\n isPhoneVerified: boolean;\n profilePicture: string;\n status: 'active' | 'inactive' | 'suspended' | 'pending';\n lastLoginTime?: string;\n totalOrders?: number;\n totalSpent?: number;\n totalEarnings?: number;\n kycStatus?: 'pending' | 'verified' | 'rejected';\n riskScore?: number;\n registrationDate: string;\n deviceInfo?: string;\n}\n\ninterface UserFilters {\n role: string;\n status: string;\n searchQuery: string;\n sortBy: string;\n registrationDate: string;\n}\n\ninterface UserStats {\n totalUsers: number;\n activeUsers: number;\n newUsers: number;\n verifiedUsers: number;\n customers: number;\n cartOwners: number;\n workers: number;\n investors: number;\n}\n\n/* ------------------------------------------------------------------ */\n/* Mock data */\n/* ------------------------------------------------------------------ */\n\nconst mockUsers: ExtendedUser[] = [\n {\n id: 'user-001',\n email: 'rahul.sharma@gmail.com',\n phone: '+91 98765 43210',\n firstName: 'Rahul',\n lastName: 'Sharma',\n role: 'customer',\n isEmailVerified: true,\n isPhoneVerified: true,\n profilePicture: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100',\n status: 'active',\n lastLoginTime: '2024-06-23T16:45:00Z',\n totalOrders: 45,\n totalSpent: 12350,\n registrationDate: '2024-01-15T08:30:00Z',\n deviceInfo: 'iPhone 14 Pro',\n },\n {\n id: 'user-002',\n email: 'priya.patel@gmail.com',\n phone: '+91 98765 43211',\n firstName: 'Priya',\n lastName: 'Patel',\n role: 'cart_owner',\n isEmailVerified: true,\n isPhoneVerified: true,\n profilePicture: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100',\n status: 'active',\n lastLoginTime: '2024-06-24T09:15:00Z',\n totalEarnings: 285000,\n kycStatus: 'verified',\n registrationDate: '2023-08-20T10:15:00Z',\n deviceInfo: 'Android Samsung',\n },\n {\n id: 'user-003',\n email: 'amit.kumar@gmail.com',\n phone: '+91 98765 43212',\n firstName: 'Amit',\n lastName: 'Kumar',\n role: 'worker',\n isEmailVerified: true,\n isPhoneVerified: false,\n profilePicture: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100',\n status: 'suspended',\n lastLoginTime: '2024-06-15T14:30:00Z',\n totalEarnings: 45000,\n kycStatus: 'pending',\n registrationDate: '2024-02-10T12:45:00Z',\n deviceInfo: 'Web Browser',\n },\n {\n id: 'user-004',\n email: 'sneha.investor@gmail.com',\n phone: '+91 98765 43213',\n firstName: 'Sneha',\n lastName: 'Reddy',\n role: 'investor',\n isEmailVerified: true,\n isPhoneVerified: true,\n profilePicture: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100',\n status: 'active',\n lastLoginTime: '2024-06-24T10:30:00Z',\n kycStatus: 'verified',\n riskScore: 2.1,\n registrationDate: '2023-12-01T15:20:00Z',\n deviceInfo: 'MacBook Pro',\n },\n {\n id: 'user-005',\n email: 'new.user@gmail.com',\n phone: '+91 98765 43214',\n firstName: 'New',\n lastName: 'User',\n role: 'customer',\n isEmailVerified: false,\n isPhoneVerified: false,\n profilePicture: '',\n status: 'pending',\n registrationDate: '2024-06-24T09:00:00Z',\n deviceInfo: 'iPhone 15',\n },\n];\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function UserManagementPage() {\n const { navigateTo } = useSubscriberBot();\n\n const [users, setUsers] = useState<ExtendedUser[]>([]);\n const [loading, setLoading] = useState(true);\n const [selectedUser, setSelectedUser] = useState<ExtendedUser | null>(null);\n const [showUserModal, setShowUserModal] = useState(false);\n const [actionType, setActionType] = useState<'edit' | 'delete'>('edit');\n const [editForm, setEditForm] = useState({\n firstName: '',\n lastName: '',\n email: '',\n phone: '',\n role: '',\n });\n const [currentPage, setCurrentPage] = useState(1);\n const itemsPerPage = 10;\n\n const [filters, setFilters] = useState<UserFilters>({\n role: '',\n status: '',\n searchQuery: '',\n sortBy: 'recent',\n registrationDate: '',\n });\n\n const [stats] = useState<UserStats>({\n totalUsers: 2456,\n activeUsers: 2134,\n newUsers: 89,\n verifiedUsers: 2021,\n customers: 1845,\n cartOwners: 342,\n workers: 156,\n investors: 113,\n });\n\n const loadUsers = useCallback(() => {\n setLoading(true);\n setTimeout(() => {\n let filtered = [...mockUsers];\n\n if (filters.searchQuery) {\n const q = filters.searchQuery.toLowerCase();\n filtered = filtered.filter(\n (u) =>\n u.firstName.toLowerCase().includes(q) ||\n u.lastName.toLowerCase().includes(q) ||\n u.email.toLowerCase().includes(q) ||\n u.phone.includes(q)\n );\n }\n if (filters.role) filtered = filtered.filter((u) => u.role === filters.role);\n if (filters.status) filtered = filtered.filter((u) => u.status === filters.status);\n if (filters.registrationDate) {\n const days = parseInt(filters.registrationDate);\n const cutoff = new Date(Date.now() - days * 86400000);\n filtered = filtered.filter((u) => new Date(u.registrationDate) >= cutoff);\n }\n\n switch (filters.sortBy) {\n case 'name':\n filtered.sort((a, b) => a.firstName.localeCompare(b.firstName));\n break;\n case 'activity':\n filtered.sort((a, b) => {\n const aT = a.lastLoginTime ? new Date(a.lastLoginTime).getTime() : 0;\n const bT = b.lastLoginTime ? new Date(b.lastLoginTime).getTime() : 0;\n return bT - aT;\n });\n break;\n default:\n filtered.sort(\n (a, b) =>\n new Date(b.registrationDate).getTime() - new Date(a.registrationDate).getTime()\n );\n }\n\n setUsers(filtered);\n setLoading(false);\n }, 800);\n }, [filters]);\n\n useEffect(() => {\n loadUsers();\n }, [loadUsers]);\n\n const handleFilterChange = (key: keyof UserFilters, value: string) => {\n setFilters((prev) => ({ ...prev, [key]: value }));\n setCurrentPage(1);\n };\n\n const handleUserAction = (\n user: ExtendedUser,\n action: 'edit' | 'suspend' | 'activate' | 'delete' | 'verify'\n ) => {\n if (action === 'suspend' || action === 'activate' || action === 'verify') {\n const msg =\n action === 'suspend'\n ? `User ${user.firstName} ${user.lastName} suspended`\n : action === 'activate'\n ? `User ${user.firstName} ${user.lastName} activated`\n : `User ${user.firstName} ${user.lastName} verified`;\n alert(msg);\n loadUsers();\n return;\n }\n setSelectedUser(user);\n setActionType(action);\n setEditForm({\n firstName: user.firstName,\n lastName: user.lastName,\n email: user.email,\n phone: user.phone,\n role: user.role,\n });\n setShowUserModal(true);\n };\n\n const handleDeleteConfirm = () => {\n if (selectedUser) {\n alert(`User ${selectedUser.firstName} ${selectedUser.lastName} deleted`);\n setShowUserModal(false);\n loadUsers();\n }\n };\n\n const handleSaveEdit = () => {\n alert('User updated successfully');\n setShowUserModal(false);\n loadUsers();\n };\n\n const formatDate = (d: string) =>\n new Date(d).toLocaleDateString('en-IN', { year: 'numeric', month: 'short', day: 'numeric' });\n\n const formatCurrency = (amount: number) => `₹${amount.toLocaleString('en-IN')}`;\n\n const pagedUsers = useMemo(() => {\n const start = (currentPage - 1) * itemsPerPage;\n return users.slice(start, start + itemsPerPage);\n }, [users, currentPage]);\n\n const roleBadge = (role: string) => {\n const c: Record<string, string> = {\n customer: 'bg-status-info-bg/20 text-status-info-text',\n cart_owner: 'bg-status-success-bg/20 text-status-success-text',\n worker: 'bg-status-warning-bg/20 text-status-warning-text',\n investor: 'bg-accent-purple-subtle text-accent-purple',\n admin: 'bg-status-error-bg/20 text-status-error-text',\n };\n const l: Record<string, string> = {\n customer: 'Customer',\n cart_owner: 'Cart Owner',\n worker: 'Worker',\n investor: 'Investor',\n admin: 'Admin',\n };\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n c[role]\n )}\n >\n {l[role] ?? role}\n </span>\n );\n };\n\n const statusBadge = (status: string) => {\n const c: Record<string, string> = {\n active: 'bg-status-success-bg/20 text-status-success-text',\n inactive: 'bg-secondary text-secondary-foreground',\n suspended: 'bg-status-error-bg/20 text-status-error-text',\n pending: 'bg-status-warning-bg/20 text-status-warning-text',\n };\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium capitalize',\n c[status]\n )}\n >\n {status}\n </span>\n );\n };\n\n /* ---- Loading ---- */\n if (loading) {\n return (\n <PageLayout title=\"User Management\" description=\"Loading users...\">\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 className=\"h-10 w-10 animate-spin text-text-secondary mb-4\" />\n <p className=\"text-text-secondary\">Loading users...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"User Management\"\n description={`${stats.totalUsers.toLocaleString('en-IN')} registered users on the platform`}\n >\n {/* 8 Stats Cards */}\n <div className=\"grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-3 mb-6\">\n {[\n { label: 'Total Users', value: stats.totalUsers.toLocaleString('en-IN'), cls: '' },\n {\n label: 'Active',\n value: stats.activeUsers.toLocaleString('en-IN'),\n cls: 'bg-status-success-bg/10 border-status-success-border/30',\n },\n {\n label: 'New (30d)',\n value: stats.newUsers.toString(),\n cls: 'bg-status-info-bg/10 border-status-info-border/30',\n },\n {\n label: 'Verified',\n value: stats.verifiedUsers.toLocaleString('en-IN'),\n cls: 'bg-accent-purple-subtle border-accent-purple/30',\n },\n { label: 'Customers', value: stats.customers.toLocaleString('en-IN'), cls: '' },\n { label: 'Cart Owners', value: stats.cartOwners.toString(), cls: '' },\n { label: 'Workers', value: stats.workers.toString(), cls: '' },\n { label: 'Investors', value: stats.investors.toString(), cls: '' },\n ].map((s) => (\n <div\n key={s.label}\n className={cn('rounded-lg border border-border-seam bg-bg-surface p-3', s.cls)}\n >\n <p className=\"text-xs text-text-secondary\">{s.label}</p>\n <p className=\"text-lg font-bold text-text-primary\">{s.value}</p>\n </div>\n ))}\n </div>\n\n {/* 5 Filter Controls */}\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 mb-6\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n placeholder=\"Search users...\"\n value={filters.searchQuery}\n onChange={(e) => handleFilterChange('searchQuery', e.target.value)}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface py-2 pl-10 pr-4 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <select\n value={filters.role}\n onChange={(e) => handleFilterChange('role', e.target.value)}\n className=\"rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Roles</option>\n <option value=\"customer\">Customers</option>\n <option value=\"cart_owner\">Cart Owners</option>\n <option value=\"worker\">Workers</option>\n <option value=\"investor\">Investors</option>\n </select>\n <select\n value={filters.status}\n onChange={(e) => handleFilterChange('status', e.target.value)}\n className=\"rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n <option value=\"suspended\">Suspended</option>\n <option value=\"pending\">Pending</option>\n </select>\n <select\n value={filters.registrationDate}\n onChange={(e) => handleFilterChange('registrationDate', e.target.value)}\n className=\"rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Time</option>\n <option value=\"1\">Last 24 hours</option>\n <option value=\"7\">Last 7 days</option>\n <option value=\"30\">Last 30 days</option>\n <option value=\"90\">Last 90 days</option>\n </select>\n <select\n value={filters.sortBy}\n onChange={(e) => handleFilterChange('sortBy', e.target.value)}\n className=\"rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"recent\">Most Recent</option>\n <option value=\"name\">Name A-Z</option>\n <option value=\"activity\">Last Activity</option>\n </select>\n </div>\n </div>\n\n {/* Dual Layout */}\n <div className=\"rounded-lg border border-border-seam bg-bg-surface overflow-hidden\">\n {/* Mobile Card View */}\n <div className=\"block md:hidden space-y-4 p-4\">\n {pagedUsers.map((user) => (\n <div key={user.id} className=\"rounded-lg border border-border-seam bg-bg-sunken/30 p-4\">\n <div className=\"flex items-center mb-3\">\n {user.profilePicture ? (\n <img\n src={user.profilePicture}\n alt={`${user.firstName} ${user.lastName}`}\n className=\"w-12 h-12 rounded-full object-cover mr-3\"\n />\n ) : (\n <div className=\"w-12 h-12 rounded-full bg-bg-sunken flex items-center justify-center mr-3\">\n <Users className=\"h-6 w-6 text-text-secondary\" />\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"font-medium text-text-primary\">\n {user.firstName} {user.lastName}\n </h3>\n <p className=\"text-sm text-text-secondary truncate\">{user.email}</p>\n <p className=\"text-sm text-text-secondary\">{user.phone}</p>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-2 mb-3\">\n {roleBadge(user.role)}\n {statusBadge(user.status)}\n </div>\n <div className=\"grid grid-cols-2 gap-4 text-sm mb-3\">\n <div>\n <p className=\"text-text-secondary\">Registered</p>\n <p className=\"text-text-primary\">{formatDate(user.registrationDate)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Last Login</p>\n <p className=\"text-text-primary\">\n {user.lastLoginTime ? formatDate(user.lastLoginTime) : 'Never'}\n </p>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-3 mb-3\">\n <div className=\"flex items-center\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full mr-2',\n user.isEmailVerified ? 'bg-status-success-text' : 'bg-status-error-text'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Email</span>\n </div>\n <div className=\"flex items-center\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full mr-2',\n user.isPhoneVerified ? 'bg-status-success-text' : 'bg-status-error-text'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Phone</span>\n </div>\n {user.kycStatus && (\n <div className=\"flex items-center\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full mr-2',\n user.kycStatus === 'verified'\n ? 'bg-status-success-text'\n : user.kycStatus === 'pending'\n ? 'bg-status-warning-text'\n : 'bg-status-error-text'\n )}\n />\n <span className=\"text-sm text-text-secondary\">KYC</span>\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'edit')}\n className=\"rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Edit\n </button>\n {user.status === 'active' ? (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'suspend')}\n className=\"rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n >\n Suspend\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'activate')}\n className=\"rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-status-success-text hover:bg-status-success-bg/10 transition-colors\"\n >\n Activate\n </button>\n )}\n {user.kycStatus === 'pending' && (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'verify')}\n className=\"rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Verify\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n\n {/* Desktop Table View */}\n <div className=\"hidden md:block overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-seam bg-bg-sunken/50\">\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n User\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Role & Status\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Activity\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Performance\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Verification\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {pagedUsers.map((user) => (\n <tr key={user.id} className=\"hover:bg-accent/50 transition-colors\">\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n {user.profilePicture ? (\n <img\n src={user.profilePicture}\n alt={`${user.firstName}`}\n className=\"w-10 h-10 rounded-full object-cover\"\n />\n ) : (\n <div className=\"w-10 h-10 rounded-full bg-bg-sunken flex items-center justify-center\">\n <Users className=\"h-5 w-5 text-text-secondary\" />\n </div>\n )}\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {user.firstName} {user.lastName}\n </p>\n <p className=\"text-xs text-text-secondary\">{user.email}</p>\n <p className=\"text-xs text-text-secondary\">{user.phone}</p>\n </div>\n </div>\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"space-y-1\">\n {roleBadge(user.role)}\n <br />\n {statusBadge(user.status)}\n </div>\n </td>\n <td className=\"px-4 py-3 text-sm\">\n <p className=\"text-text-primary\">\n Registered: {formatDate(user.registrationDate)}\n </p>\n {user.lastLoginTime && (\n <p className=\"text-text-secondary\">\n Last login: {formatDate(user.lastLoginTime)}\n </p>\n )}\n {user.deviceInfo && (\n <p className=\"text-text-secondary flex items-center gap-1\">\n <Smartphone className=\"h-3 w-3\" />\n {user.deviceInfo}\n </p>\n )}\n </td>\n <td className=\"px-4 py-3 text-sm\">\n {user.role === 'customer' && user.totalOrders != null && (\n <>\n <p className=\"text-text-primary\">{user.totalOrders} orders</p>\n <p className=\"text-text-secondary\">\n {formatCurrency(user.totalSpent ?? 0)} spent\n </p>\n </>\n )}\n {(user.role === 'cart_owner' || user.role === 'worker') &&\n user.totalEarnings != null && (\n <p className=\"text-text-primary\">\n {formatCurrency(user.totalEarnings)} earned\n </p>\n )}\n {user.role === 'investor' && user.riskScore != null && (\n <p className=\"text-text-primary\">Risk: {user.riskScore}/5</p>\n )}\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full',\n user.isEmailVerified ? 'bg-status-success-text' : 'bg-status-error-text'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Email</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full',\n user.isPhoneVerified ? 'bg-status-success-text' : 'bg-status-error-text'\n )}\n />\n <span className=\"text-sm text-text-secondary\">Phone</span>\n </div>\n {user.kycStatus && (\n <div className=\"flex items-center gap-2\">\n <span\n className={cn(\n 'w-2 h-2 rounded-full',\n user.kycStatus === 'verified'\n ? 'bg-status-success-text'\n : user.kycStatus === 'pending'\n ? 'bg-status-warning-text'\n : 'bg-status-error-text'\n )}\n />\n <span className=\"text-sm text-text-secondary\">KYC</span>\n </div>\n )}\n </div>\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'edit')}\n title=\"Edit\"\n className=\"rounded p-1.5 text-text-secondary hover:text-text-primary hover:bg-accent transition-colors\"\n >\n <Edit3 className=\"h-4 w-4\" />\n </button>\n {user.status === 'active' ? (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'suspend')}\n title=\"Suspend\"\n className=\"rounded p-1.5 text-text-secondary hover:text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n >\n <UserX className=\"h-4 w-4\" />\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'activate')}\n title=\"Activate\"\n className=\"rounded p-1.5 text-text-secondary hover:text-status-success-text hover:bg-status-success-bg/10 transition-colors\"\n >\n <UserCheck className=\"h-4 w-4\" />\n </button>\n )}\n {user.kycStatus === 'pending' && (\n <button\n type=\"button\"\n onClick={() => handleUserAction(user, 'verify')}\n title=\"Verify\"\n className=\"rounded p-1.5 text-text-secondary hover:text-status-info-text hover:bg-status-info-bg/10 transition-colors\"\n >\n <Shield className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {users.length === 0 && (\n <div className=\"flex flex-col items-center justify-center py-12 px-4\">\n <Users className=\"h-10 w-10 text-text-secondary/50 mb-3\" />\n <p className=\"text-sm text-text-secondary\">No users found matching your criteria</p>\n </div>\n )}\n </div>\n\n {/* Pagination */}\n <div className=\"mt-6 flex flex-col sm:flex-row sm:items-center justify-between gap-4\">\n <p className=\"text-sm text-text-secondary text-center sm:text-left\">\n Showing{' '}\n <span className=\"font-medium\">\n {Math.min((currentPage - 1) * itemsPerPage + 1, users.length)}\n </span>{' '}\n to{' '}\n <span className=\"font-medium\">{Math.min(currentPage * itemsPerPage, users.length)}</span>{' '}\n of <span className=\"font-medium\">{users.length}</span> results\n </p>\n <div className=\"flex justify-center sm:justify-end gap-2\">\n <button\n type=\"button\"\n disabled={currentPage === 1}\n onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n Previous\n </button>\n <button\n type=\"button\"\n disabled={currentPage * itemsPerPage >= users.length}\n onClick={() => setCurrentPage((p) => p + 1)}\n className=\"flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Next\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n\n {/* User Action Modal */}\n {showUserModal && selectedUser && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-canvas/50 p-4\">\n <div className=\"w-full max-w-md rounded-lg border border-border-seam bg-bg-surface shadow-lg max-h-[90vh] overflow-y-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-border-seam\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {actionType === 'edit' ? 'Edit User' : 'Delete User'}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShowUserModal(false)}\n className=\"rounded p-1.5 text-text-secondary hover:text-text-primary hover:bg-accent transition-colors\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <div className=\"p-4\">\n {actionType === 'delete' ? (\n <div>\n <p className=\"text-text-secondary mb-4\">\n Are you sure you want to delete user "{selectedUser.firstName}{' '}\n {selectedUser.lastName}"? This action cannot be undone.\n </p>\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={() => setShowUserModal(false)}\n className=\"flex-1 rounded-lg border border-border-seam py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleDeleteConfirm}\n className=\"flex-1 rounded-lg bg-status-error-text hover:bg-status-error-text py-2 text-sm font-medium text-text-inverse transition-colors\"\n >\n Delete User\n </button>\n </div>\n </div>\n ) : (\n <div>\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n First Name\n </label>\n <input\n type=\"text\"\n value={editForm.firstName}\n onChange={(e) =>\n setEditForm((f) => ({ ...f, firstName: e.target.value }))\n }\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={editForm.lastName}\n onChange={(e) => setEditForm((f) => ({ ...f, lastName: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Email\n </label>\n <input\n type=\"email\"\n value={editForm.email}\n onChange={(e) => setEditForm((f) => ({ ...f, email: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Phone\n </label>\n <input\n type=\"tel\"\n value={editForm.phone}\n onChange={(e) => setEditForm((f) => ({ ...f, phone: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-secondary mb-1\">\n Role\n </label>\n <select\n value={editForm.role}\n onChange={(e) => setEditForm((f) => ({ ...f, role: e.target.value }))}\n className=\"w-full rounded-lg border border-border-seam bg-bg-surface py-2 px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"customer\">Customer</option>\n <option value=\"cart_owner\">Cart Owner</option>\n <option value=\"worker\">Worker</option>\n <option value=\"investor\">Investor</option>\n </select>\n </div>\n </div>\n <div className=\"flex gap-3 mt-6\">\n <button\n type=\"button\"\n onClick={() => setShowUserModal(false)}\n className=\"flex-1 rounded-lg border border-border-seam py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSaveEdit}\n className=\"flex-1 rounded-lg bg-action-primary-bg py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n Save Changes\n </button>\n <button\n type=\"button\"\n onClick={() => setActionType('delete')}\n className=\"rounded-lg border border-border-seam py-2 px-3 text-sm font-medium text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -259,7 +259,7 @@ var C = {
|
|
|
259
259
|
children: [/* @__PURE__ */ S("select", {
|
|
260
260
|
value: T,
|
|
261
261
|
onChange: (e) => E(e.target.value),
|
|
262
|
-
className: "rounded-md border border-border-
|
|
262
|
+
className: "rounded-md border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary",
|
|
263
263
|
children: [
|
|
264
264
|
/* @__PURE__ */ x("option", {
|
|
265
265
|
value: "today",
|
|
@@ -281,7 +281,7 @@ var C = {
|
|
|
281
281
|
}), /* @__PURE__ */ S("button", {
|
|
282
282
|
type: "button",
|
|
283
283
|
onClick: () => alert("Export feature coming soon!"),
|
|
284
|
-
className: "inline-flex items-center gap-1.5 rounded-md border border-border-
|
|
284
|
+
className: "inline-flex items-center gap-1.5 rounded-md border border-border-seam px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken transition-colors",
|
|
285
285
|
children: [/* @__PURE__ */ x(d, { className: "h-4 w-4" }), "Export"]
|
|
286
286
|
})]
|
|
287
287
|
}),
|
|
@@ -315,7 +315,7 @@ var C = {
|
|
|
315
315
|
growth: null
|
|
316
316
|
}
|
|
317
317
|
].map((e) => /* @__PURE__ */ S("div", {
|
|
318
|
-
className: "rounded-lg border border-border-
|
|
318
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-5 shadow-sm",
|
|
319
319
|
children: [
|
|
320
320
|
/* @__PURE__ */ S("div", {
|
|
321
321
|
className: "flex items-center justify-between",
|
|
@@ -323,7 +323,7 @@ var C = {
|
|
|
323
323
|
className: "rounded-md bg-accent p-2",
|
|
324
324
|
children: /* @__PURE__ */ x(f, { className: "h-5 w-5 text-text-secondary" })
|
|
325
325
|
}), e.growth !== null && /* @__PURE__ */ S("div", {
|
|
326
|
-
className: t("flex items-center gap-1 text-xs font-medium", e.growth >= 0 ? "text-
|
|
326
|
+
className: t("flex items-center gap-1 text-xs font-medium", e.growth >= 0 ? "text-status-success-text" : "text-status-error-text"),
|
|
327
327
|
children: [e.growth >= 0 ? /* @__PURE__ */ x(s, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ x(o, { className: "h-3.5 w-3.5" }), j(e.growth)]
|
|
328
328
|
})]
|
|
329
329
|
}),
|
|
@@ -341,9 +341,9 @@ var C = {
|
|
|
341
341
|
/* @__PURE__ */ S("div", {
|
|
342
342
|
className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
|
|
343
343
|
children: [/* @__PURE__ */ S("div", {
|
|
344
|
-
className: "rounded-lg border border-border-
|
|
344
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
345
345
|
children: [/* @__PURE__ */ x("div", {
|
|
346
|
-
className: "border-b border-border-
|
|
346
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
347
347
|
children: /* @__PURE__ */ S("h2", {
|
|
348
348
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
349
349
|
children: [/* @__PURE__ */ x(m, { className: "h-4 w-4 text-text-secondary" }), "Order Statistics"]
|
|
@@ -371,14 +371,14 @@ var C = {
|
|
|
371
371
|
className: "text-xs text-text-secondary",
|
|
372
372
|
children: "Completed"
|
|
373
373
|
}), /* @__PURE__ */ x("p", {
|
|
374
|
-
className: "text-xl font-bold text-
|
|
374
|
+
className: "text-xl font-bold text-status-success-text",
|
|
375
375
|
children: C.orders.completed
|
|
376
376
|
})] }),
|
|
377
377
|
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("p", {
|
|
378
378
|
className: "text-xs text-text-secondary",
|
|
379
379
|
children: "Cancelled"
|
|
380
380
|
}), /* @__PURE__ */ x("p", {
|
|
381
|
-
className: "text-xl font-bold text-
|
|
381
|
+
className: "text-xl font-bold text-status-error-text",
|
|
382
382
|
children: C.orders.cancelled
|
|
383
383
|
})] })
|
|
384
384
|
]
|
|
@@ -391,9 +391,9 @@ var C = {
|
|
|
391
391
|
})] })]
|
|
392
392
|
})]
|
|
393
393
|
}), /* @__PURE__ */ S("div", {
|
|
394
|
-
className: "rounded-lg border border-border-
|
|
394
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
395
395
|
children: [/* @__PURE__ */ x("div", {
|
|
396
|
-
className: "border-b border-border-
|
|
396
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
397
397
|
children: /* @__PURE__ */ S("h2", {
|
|
398
398
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
399
399
|
children: [/* @__PURE__ */ x(u, { className: "h-4 w-4 text-text-secondary" }), "Popular Times"]
|
|
@@ -414,7 +414,7 @@ var C = {
|
|
|
414
414
|
}), /* @__PURE__ */ x("div", {
|
|
415
415
|
className: "h-2 rounded-full bg-bg-sunken overflow-hidden",
|
|
416
416
|
children: /* @__PURE__ */ x("div", {
|
|
417
|
-
className: t("h-full rounded-full transition-all", e.orders > 25 ? "bg-
|
|
417
|
+
className: t("h-full rounded-full transition-all", e.orders > 25 ? "bg-status-error-bg/60" : e.orders > 18 ? "bg-status-warning-bg/60" : "bg-status-success-bg/60"),
|
|
418
418
|
style: { width: `${n}%` }
|
|
419
419
|
})
|
|
420
420
|
})] }, e.hour);
|
|
@@ -432,30 +432,30 @@ var C = {
|
|
|
432
432
|
label: "Acceptance Rate",
|
|
433
433
|
value: `${C.performance.acceptanceRate}%`,
|
|
434
434
|
icon: g,
|
|
435
|
-
color: "text-
|
|
435
|
+
color: "text-status-success-text"
|
|
436
436
|
},
|
|
437
437
|
{
|
|
438
438
|
label: "Cancellation Rate",
|
|
439
439
|
value: `${C.performance.cancellationRate}%`,
|
|
440
440
|
icon: p,
|
|
441
|
-
color: "text-
|
|
441
|
+
color: "text-status-error-text"
|
|
442
442
|
},
|
|
443
443
|
{
|
|
444
444
|
label: "On-Time Delivery",
|
|
445
445
|
value: `${C.performance.onTimeDeliveryRate}%`,
|
|
446
446
|
icon: u,
|
|
447
|
-
color: "text-
|
|
447
|
+
color: "text-status-info-text"
|
|
448
448
|
},
|
|
449
449
|
{
|
|
450
450
|
label: "Average Rating",
|
|
451
451
|
value: `${C.performance.averageRating}`,
|
|
452
452
|
icon: h,
|
|
453
|
-
color: "text-
|
|
453
|
+
color: "text-status-warning-text"
|
|
454
454
|
}
|
|
455
455
|
].map((e) => {
|
|
456
456
|
let n = e.icon;
|
|
457
457
|
return /* @__PURE__ */ S("div", {
|
|
458
|
-
className: "rounded-lg border border-border-
|
|
458
|
+
className: "rounded-lg border border-border-seam bg-bg-surface p-5 shadow-sm",
|
|
459
459
|
children: [/* @__PURE__ */ S("div", {
|
|
460
460
|
className: "flex items-center gap-2 mb-2",
|
|
461
461
|
children: [/* @__PURE__ */ x(n, { className: t("h-5 w-5", e.color) }), /* @__PURE__ */ x("span", {
|
|
@@ -472,10 +472,10 @@ var C = {
|
|
|
472
472
|
/* @__PURE__ */ S("div", {
|
|
473
473
|
className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
|
|
474
474
|
children: [/* @__PURE__ */ S("div", {
|
|
475
|
-
className: "rounded-lg border border-border-
|
|
475
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
476
476
|
children: [
|
|
477
477
|
/* @__PURE__ */ x("div", {
|
|
478
|
-
className: "border-b border-border-
|
|
478
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
479
479
|
children: /* @__PURE__ */ S("h2", {
|
|
480
480
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
481
481
|
children: [/* @__PURE__ */ x(v, { className: "h-4 w-4 text-text-secondary" }), "Top Selling Offerings"]
|
|
@@ -509,7 +509,7 @@ var C = {
|
|
|
509
509
|
}, e.id))
|
|
510
510
|
}),
|
|
511
511
|
/* @__PURE__ */ S("div", {
|
|
512
|
-
className: "border-t border-border-
|
|
512
|
+
className: "border-t border-border-seam px-5 py-3",
|
|
513
513
|
children: [/* @__PURE__ */ x("p", {
|
|
514
514
|
className: "text-xs font-medium text-text-secondary mb-2",
|
|
515
515
|
children: "Least Selling"
|
|
@@ -531,9 +531,9 @@ var C = {
|
|
|
531
531
|
})
|
|
532
532
|
]
|
|
533
533
|
}), /* @__PURE__ */ S("div", {
|
|
534
|
-
className: "rounded-lg border border-border-
|
|
534
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
535
535
|
children: [/* @__PURE__ */ x("div", {
|
|
536
|
-
className: "border-b border-border-
|
|
536
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
537
537
|
children: /* @__PURE__ */ S("h2", {
|
|
538
538
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
539
539
|
children: [/* @__PURE__ */ x(c, { className: "h-4 w-4 text-text-secondary" }), "Category Performance"]
|
|
@@ -560,7 +560,7 @@ var C = {
|
|
|
560
560
|
}), /* @__PURE__ */ x("div", {
|
|
561
561
|
className: "h-2.5 rounded-full bg-bg-sunken overflow-hidden",
|
|
562
562
|
children: /* @__PURE__ */ x("div", {
|
|
563
|
-
className: "h-full rounded-full bg-
|
|
563
|
+
className: "h-full rounded-full bg-status-info-bg/60",
|
|
564
564
|
style: { width: `${t}%` }
|
|
565
565
|
})
|
|
566
566
|
})] }, e.category);
|
|
@@ -571,9 +571,9 @@ var C = {
|
|
|
571
571
|
/* @__PURE__ */ S("div", {
|
|
572
572
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
573
573
|
children: [/* @__PURE__ */ S("div", {
|
|
574
|
-
className: "lg:col-span-2 rounded-lg border border-border-
|
|
574
|
+
className: "lg:col-span-2 rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
575
575
|
children: [/* @__PURE__ */ x("div", {
|
|
576
|
-
className: "border-b border-border-
|
|
576
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
577
577
|
children: /* @__PURE__ */ S("h2", {
|
|
578
578
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
579
579
|
children: [/* @__PURE__ */ x(y, { className: "h-4 w-4 text-text-secondary" }), "Customer Overview"]
|
|
@@ -595,22 +595,22 @@ var C = {
|
|
|
595
595
|
className: "text-xs text-text-secondary",
|
|
596
596
|
children: "New This Month"
|
|
597
597
|
}), /* @__PURE__ */ x("p", {
|
|
598
|
-
className: "text-xl font-bold text-
|
|
598
|
+
className: "text-xl font-bold text-status-info-text",
|
|
599
599
|
children: C.customers.new
|
|
600
600
|
})] }),
|
|
601
601
|
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("p", {
|
|
602
602
|
className: "text-xs text-text-secondary",
|
|
603
603
|
children: "Returning"
|
|
604
604
|
}), /* @__PURE__ */ x("p", {
|
|
605
|
-
className: "text-xl font-bold text-
|
|
605
|
+
className: "text-xl font-bold text-status-success-text",
|
|
606
606
|
children: C.customers.returning
|
|
607
607
|
})] }),
|
|
608
608
|
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("p", {
|
|
609
609
|
className: "text-xs text-text-secondary",
|
|
610
610
|
children: "Satisfaction"
|
|
611
611
|
}), /* @__PURE__ */ S("p", {
|
|
612
|
-
className: "text-xl font-bold text-
|
|
613
|
-
children: [/* @__PURE__ */ x(h, { className: "h-4 w-4 fill-
|
|
612
|
+
className: "text-xl font-bold text-status-warning-text flex items-center gap-1",
|
|
613
|
+
children: [/* @__PURE__ */ x(h, { className: "h-4 w-4 fill-status-warning-text text-status-warning-text" }), C.customers.satisfaction.rating]
|
|
614
614
|
})] })
|
|
615
615
|
]
|
|
616
616
|
}),
|
|
@@ -623,7 +623,7 @@ var C = {
|
|
|
623
623
|
children: /* @__PURE__ */ S("table", {
|
|
624
624
|
className: "w-full text-sm",
|
|
625
625
|
children: [/* @__PURE__ */ x("thead", { children: /* @__PURE__ */ S("tr", {
|
|
626
|
-
className: "border-b border-border-
|
|
626
|
+
className: "border-b border-border-seam",
|
|
627
627
|
children: [
|
|
628
628
|
/* @__PURE__ */ x("th", {
|
|
629
629
|
className: "py-2 text-left font-medium text-text-secondary",
|
|
@@ -643,7 +643,7 @@ var C = {
|
|
|
643
643
|
})
|
|
644
644
|
]
|
|
645
645
|
}) }), /* @__PURE__ */ x("tbody", { children: C.customers.topCustomers.map((e, t) => /* @__PURE__ */ S("tr", {
|
|
646
|
-
className: "border-b border-border-
|
|
646
|
+
className: "border-b border-border-seam last:border-0",
|
|
647
647
|
children: [
|
|
648
648
|
/* @__PURE__ */ x("td", {
|
|
649
649
|
className: "py-2.5 text-text-secondary",
|
|
@@ -669,7 +669,7 @@ var C = {
|
|
|
669
669
|
className: "mt-4 flex items-center gap-4 text-sm",
|
|
670
670
|
children: /* @__PURE__ */ S("div", {
|
|
671
671
|
className: "flex items-center gap-1.5",
|
|
672
|
-
children: [/* @__PURE__ */ x(_, { className: "h-4 w-4 text-
|
|
672
|
+
children: [/* @__PURE__ */ x(_, { className: "h-4 w-4 text-status-success-text" }), /* @__PURE__ */ S("span", {
|
|
673
673
|
className: "text-text-secondary",
|
|
674
674
|
children: [
|
|
675
675
|
C.customers.satisfaction.positiveReviews,
|
|
@@ -685,9 +685,9 @@ var C = {
|
|
|
685
685
|
}), /* @__PURE__ */ S("div", {
|
|
686
686
|
className: "space-y-6",
|
|
687
687
|
children: [/* @__PURE__ */ S("div", {
|
|
688
|
-
className: "rounded-lg border border-border-
|
|
688
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
689
689
|
children: [/* @__PURE__ */ x("div", {
|
|
690
|
-
className: "border-b border-border-
|
|
690
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
691
691
|
children: /* @__PURE__ */ S("h2", {
|
|
692
692
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
693
693
|
children: [/* @__PURE__ */ x(u, { className: "h-4 w-4 text-text-secondary" }), "Peak Hours"]
|
|
@@ -708,16 +708,16 @@ var C = {
|
|
|
708
708
|
}), /* @__PURE__ */ x("div", {
|
|
709
709
|
className: "h-2 rounded-full bg-bg-sunken overflow-hidden",
|
|
710
710
|
children: /* @__PURE__ */ x("div", {
|
|
711
|
-
className: t("h-full rounded-full", e.orders > 28 ? "bg-
|
|
711
|
+
className: t("h-full rounded-full", e.orders > 28 ? "bg-status-error-bg/60" : e.orders > 22 ? "bg-status-warning-bg/60" : "bg-status-success-bg/60"),
|
|
712
712
|
style: { width: `${n}%` }
|
|
713
713
|
})
|
|
714
714
|
})] }, e.hour);
|
|
715
715
|
})
|
|
716
716
|
})]
|
|
717
717
|
}), /* @__PURE__ */ S("div", {
|
|
718
|
-
className: "rounded-lg border border-border-
|
|
718
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
719
719
|
children: [/* @__PURE__ */ x("div", {
|
|
720
|
-
className: "border-b border-border-
|
|
720
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
721
721
|
children: /* @__PURE__ */ S("h2", {
|
|
722
722
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
723
723
|
children: [/* @__PURE__ */ x(l, { className: "h-4 w-4 text-text-secondary" }), "Peak Days"]
|
|
@@ -738,7 +738,7 @@ var C = {
|
|
|
738
738
|
}), /* @__PURE__ */ x("div", {
|
|
739
739
|
className: "h-2 rounded-full bg-bg-sunken overflow-hidden",
|
|
740
740
|
children: /* @__PURE__ */ x("div", {
|
|
741
|
-
className: "h-full rounded-full bg-
|
|
741
|
+
className: "h-full rounded-full bg-status-info-bg/60",
|
|
742
742
|
style: { width: `${t}%` }
|
|
743
743
|
})
|
|
744
744
|
})] }, e.day);
|
|
@@ -748,9 +748,9 @@ var C = {
|
|
|
748
748
|
})]
|
|
749
749
|
}),
|
|
750
750
|
/* @__PURE__ */ S("div", {
|
|
751
|
-
className: "rounded-lg border border-border-
|
|
751
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
752
752
|
children: [/* @__PURE__ */ x("div", {
|
|
753
|
-
className: "border-b border-border-
|
|
753
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
754
754
|
children: /* @__PURE__ */ S("h2", {
|
|
755
755
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
756
756
|
children: [/* @__PURE__ */ x(v, { className: "h-4 w-4 text-text-secondary" }), "Daily Order Trends"]
|
|
@@ -760,7 +760,7 @@ var C = {
|
|
|
760
760
|
children: /* @__PURE__ */ S("table", {
|
|
761
761
|
className: "w-full text-sm",
|
|
762
762
|
children: [/* @__PURE__ */ x("thead", { children: /* @__PURE__ */ S("tr", {
|
|
763
|
-
className: "border-b border-border-
|
|
763
|
+
className: "border-b border-border-seam",
|
|
764
764
|
children: [
|
|
765
765
|
/* @__PURE__ */ x("th", {
|
|
766
766
|
className: "px-5 py-2.5 text-left font-medium text-text-secondary",
|
|
@@ -776,7 +776,7 @@ var C = {
|
|
|
776
776
|
})
|
|
777
777
|
]
|
|
778
778
|
}) }), /* @__PURE__ */ x("tbody", { children: i.orderTrends.map((e) => /* @__PURE__ */ S("tr", {
|
|
779
|
-
className: "border-b border-border-
|
|
779
|
+
className: "border-b border-border-seam last:border-0",
|
|
780
780
|
children: [
|
|
781
781
|
/* @__PURE__ */ x("td", {
|
|
782
782
|
className: "px-5 py-2.5 text-text-primary",
|
|
@@ -799,9 +799,9 @@ var C = {
|
|
|
799
799
|
})]
|
|
800
800
|
}),
|
|
801
801
|
/* @__PURE__ */ S("div", {
|
|
802
|
-
className: "rounded-lg border border-border-
|
|
802
|
+
className: "rounded-lg border border-border-seam bg-bg-surface shadow-sm",
|
|
803
803
|
children: [/* @__PURE__ */ x("div", {
|
|
804
|
-
className: "border-b border-border-
|
|
804
|
+
className: "border-b border-border-seam px-5 py-4",
|
|
805
805
|
children: /* @__PURE__ */ S("h2", {
|
|
806
806
|
className: "text-base font-semibold text-text-primary flex items-center gap-2",
|
|
807
807
|
children: [/* @__PURE__ */ x(y, { className: "h-4 w-4 text-text-secondary" }), "Monthly Customer Growth"]
|
|
@@ -813,7 +813,7 @@ var C = {
|
|
|
813
813
|
children: i.customerGrowth.map((e) => {
|
|
814
814
|
let t = Math.max(...i.customerGrowth.map((e) => e.newCustomers));
|
|
815
815
|
return /* @__PURE__ */ x("div", {
|
|
816
|
-
className: "flex-1 rounded-t bg-
|
|
816
|
+
className: "flex-1 rounded-t bg-status-info-bg/40 hover:bg-status-info-bg/60 transition-colors cursor-default",
|
|
817
817
|
style: { height: `${e.newCustomers / t * 100}%` },
|
|
818
818
|
title: `${e.month}: ${e.newCustomers} new customers`
|
|
819
819
|
}, e.month);
|