@burdenoff/microfe-kadaikodi 2026.704.2 → 2026.704.4
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/kadaikodi/KadaikodiRoutes.js +30 -26
- package/dist/kadaikodi/KadaikodiRoutes.js.map +1 -1
- package/dist/kadaikodi/hooks/useKadaikodiApi.js +76 -6
- package/dist/kadaikodi/hooks/useKadaikodiApi.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js +45 -107
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminDashboard.js +30 -32
- package/dist/kadaikodi/pages/admin/AdminDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminFinancialPage.js +137 -120
- package/dist/kadaikodi/pages/admin/AdminFinancialPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js +2 -2
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminSettingsPage.js +332 -276
- package/dist/kadaikodi/pages/admin/AdminSettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/CartManagementPage.js +278 -283
- package/dist/kadaikodi/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/UserManagementPage.js +310 -366
- package/dist/kadaikodi/pages/admin/UserManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js +105 -111
- package/dist/kadaikodi/pages/cart-owner/AnalyticsDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js +290 -257
- package/dist/kadaikodi/pages/cart-owner/BusinessSettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js +84 -70
- package/dist/kadaikodi/pages/cart-owner/CartOwnerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js +270 -228
- package/dist/kadaikodi/pages/cart-owner/CartOwnerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js +194 -173
- package/dist/kadaikodi/pages/cart-owner/CartServiceConfigPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js +202 -139
- package/dist/kadaikodi/pages/cart-owner/InventoryManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js +232 -0
- package/dist/kadaikodi/pages/cart-owner/InvestmentListingPage.js.map +1 -0
- package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js +84 -79
- package/dist/kadaikodi/pages/cart-owner/OrderManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/HelpSupportPage.js +310 -317
- package/dist/kadaikodi/pages/common/HelpSupportPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/NotificationCenterPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/SettingsPage.js +502 -586
- package/dist/kadaikodi/pages/common/SettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/BookingDetailsPage.js +243 -143
- package/dist/kadaikodi/pages/customer/BookingDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDetailPage.js +4 -4
- package/dist/kadaikodi/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js +2 -2
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CheckoutPage.js +4 -4
- package/dist/kadaikodi/pages/customer/CheckoutPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerDashboard.js +6 -6
- package/dist/kadaikodi/pages/customer/CustomerDashboard.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js +189 -199
- package/dist/kadaikodi/pages/customer/CustomerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js +6 -4
- package/dist/kadaikodi/pages/customer/DirectServiceBookingPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/FavoritesPage.js +6 -6
- package/dist/kadaikodi/pages/customer/FavoritesPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/OrderHistoryPage.js +4 -4
- package/dist/kadaikodi/pages/customer/OrderHistoryPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js +409 -304
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/ReviewsPage.js +209 -162
- package/dist/kadaikodi/pages/customer/ReviewsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/SavedAddressesPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestmentDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorAnalyticsPage.js.map +1 -1
- package/dist/kadaikodi/pages/investor/InvestorProfilePage.js +441 -514
- package/dist/kadaikodi/pages/investor/InvestorProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js +207 -186
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerOrdersPage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerProfilePage.js +340 -272
- package/dist/kadaikodi/pages/worker/WorkerProfilePage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js +122 -75
- package/dist/kadaikodi/pages/worker/WorkerSchedulePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserManagementPage.js","names":[],"sources":["../../../../src/kadaikodi/pages/admin/UserManagementPage.tsx"],"sourcesContent":["/**\n * User Management Page\n * @module kadaikodi/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, 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 { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useProviders } from '../../hooks/useKadaikodiApi';\nimport type { MockCart } from '../../types';\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/* Real data mapping — cart owners are real users (service providers). */\n/* No users endpoint exists, so we never fabricate accounts. */\n/* ------------------------------------------------------------------ */\n\nconst providerToUser = (p: MockCart): ExtendedUser => ({\n id: p.ownerId ?? p.id,\n email: '',\n phone: '',\n firstName: p.name,\n lastName: '',\n role: 'cart_owner',\n isEmailVerified: Boolean(p.isVerified),\n isPhoneVerified: false,\n profilePicture: '',\n status: p.isOpen ? 'active' : 'inactive',\n registrationDate: p.createdAt ?? new Date(0).toISOString(),\n});\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function UserManagementPage() {\n const { navigateTo } = useKadaikodi();\n\n const { data: providers = [], isLoading: loading } = useProviders();\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 // Real user base: cart owners derived from the live service-provider list.\n const allUsers = useMemo<ExtendedUser[]>(() => providers.map(providerToUser), [providers]);\n\n const users = useMemo<ExtendedUser[]>(() => {\n let filtered = [...allUsers];\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) => new Date(b.registrationDate).getTime() - new Date(a.registrationDate).getTime()\n );\n }\n\n return filtered;\n }, [allUsers, filters]);\n\n const stats = useMemo<UserStats>(() => {\n const thirtyDaysAgo = Date.now() - 30 * 86400000;\n return {\n totalUsers: allUsers.length,\n activeUsers: allUsers.filter((u) => u.status === 'active').length,\n newUsers: allUsers.filter((u) => new Date(u.registrationDate).getTime() >= thirtyDaysAgo)\n .length,\n verifiedUsers: allUsers.filter((u) => u.isEmailVerified).length,\n customers: allUsers.filter((u) => u.role === 'customer').length,\n cartOwners: allUsers.filter((u) => u.role === 'cart_owner').length,\n workers: allUsers.filter((u) => u.role === 'worker').length,\n investors: allUsers.filter((u) => u.role === 'investor').length,\n };\n }, [allUsers]);\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 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 }\n };\n\n const handleSaveEdit = () => {\n alert('User updated successfully');\n setShowUserModal(false);\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-[var(--color-accent-soft)] text-text-primary',\n cart_owner: 'bg-status-success-bg-subtle text-status-success-text',\n worker: 'bg-status-warning-bg-subtle text-status-warning-text',\n investor: 'bg-accent-purple-subtle text-text-primary',\n admin: 'bg-status-error-bg-subtle 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-subtle text-status-success-text',\n inactive: 'bg-bg-sunken text-text-secondary',\n suspended: 'bg-status-error-bg-subtle text-status-error-text',\n pending: 'bg-status-warning-bg-subtle 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 <PagePurpose className=\"mb-6\">\n The directory of everyone on Kadaikodi — customers, cart owners, workers and investors. Use\n this page to find an account, verify or activate users, edit roles, and step in when someone\n needs help or needs to be removed. Filter by role or status to manage one group at a time.\n </PagePurpose>\n\n {/* 8 Stats Cards — the one emphasis zone for this page */}\n <EmphasisPanel className=\"mb-6\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">User Base Overview</h2>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-3\">\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-subtle border-status-success-text/30',\n },\n {\n label: 'New (30d)',\n value: stats.newUsers.toString(),\n cls: 'bg-[var(--color-accent-soft)] border-border-focus/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-subtle 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 </EmphasisPanel>\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\n key={user.id}\n className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-4\"\n >\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-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-status-error-text hover:bg-status-error-bg-subtle 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-status-success-text hover:bg-status-success-bg-subtle 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-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-subtle 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-subtle 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-text-primary hover:bg-[var(--color-accent-soft)] 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 <EmptyState\n illustration=\"empty-people\"\n title=\"No users found\"\n description=\"No accounts match your current filters. Try clearing them or searching for a different name or email.\"\n action={\n <button\n type=\"button\"\n onClick={() =>\n setFilters({\n role: '',\n status: '',\n searchQuery: '',\n sortBy: 'recent',\n registrationDate: '',\n })\n }\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Clear filters\n </button>\n }\n />\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-status-error-text hover:bg-status-error-text 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-status-error-text hover:bg-status-error-bg-subtle 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/kadaikodi/pages/admin/UserManagementPage.tsx"],"sourcesContent":["/**\n * User Management Page\n * @module kadaikodi/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, useMemo } from 'react';\nimport {\n Search,\n Users,\n UserCheck,\n UserX,\n Shield,\n Eye,\n CheckCircle2,\n AlertCircle,\n Loader2,\n ChevronLeft,\n ChevronRight,\n Smartphone,\n Mail,\n Phone,\n X,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { useKadaikodi } from '../../context/KadaikodiContext';\nimport { useProviders, useUpdateProvider } from '../../hooks/useKadaikodiApi';\nimport type { MockCart } from '../../types';\nimport { cn } from '../../utils/cn';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\ninterface ExtendedUser {\n id: string;\n providerId: 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/* Real data mapping — cart owners are real users (service providers). */\n/* No users endpoint exists, so we never fabricate accounts. */\n/* ------------------------------------------------------------------ */\n\nconst providerToUser = (p: MockCart): ExtendedUser => ({\n id: p.ownerId ?? p.id,\n providerId: p.id,\n email: '',\n phone: '',\n firstName: p.name,\n lastName: '',\n role: 'cart_owner',\n isEmailVerified: Boolean(p.isVerified),\n isPhoneVerified: false,\n profilePicture: '',\n status: p.isOpen ? 'active' : 'inactive',\n registrationDate: p.createdAt ?? new Date(0).toISOString(),\n});\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function UserManagementPage() {\n const { navigateTo } = useKadaikodi();\n\n const { data: providers = [], isLoading: loading } = useProviders();\n const updateProvider = useUpdateProvider();\n const [selectedUser, setSelectedUser] = useState<ExtendedUser | null>(null);\n const [showUserModal, setShowUserModal] = useState(false);\n const [statusMessage, setStatusMessage] = useState<{\n text: string;\n type: 'success' | 'error';\n } | null>(null);\n const showStatus = (text: string, type: 'success' | 'error') => {\n setStatusMessage({ text, type });\n setTimeout(() => setStatusMessage(null), 3500);\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 // Real user base: cart owners derived from the live service-provider list.\n const allUsers = useMemo<ExtendedUser[]>(() => providers.map(providerToUser), [providers]);\n\n const users = useMemo<ExtendedUser[]>(() => {\n let filtered = [...allUsers];\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) => new Date(b.registrationDate).getTime() - new Date(a.registrationDate).getTime()\n );\n }\n\n return filtered;\n }, [allUsers, filters]);\n\n const stats = useMemo<UserStats>(() => {\n const thirtyDaysAgo = Date.now() - 30 * 86400000;\n return {\n totalUsers: allUsers.length,\n activeUsers: allUsers.filter((u) => u.status === 'active').length,\n newUsers: allUsers.filter((u) => new Date(u.registrationDate).getTime() >= thirtyDaysAgo)\n .length,\n verifiedUsers: allUsers.filter((u) => u.isEmailVerified).length,\n customers: allUsers.filter((u) => u.role === 'customer').length,\n cartOwners: allUsers.filter((u) => u.role === 'cart_owner').length,\n workers: allUsers.filter((u) => u.role === 'worker').length,\n investors: allUsers.filter((u) => u.role === 'investor').length,\n };\n }, [allUsers]);\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: 'view' | 'suspend' | 'activate' | 'verify'\n ) => {\n if (action === 'suspend' || action === 'activate' || action === 'verify') {\n // Every \"user\" here is a cart owner backed by a real service-provider\n // record, so account state persists to the provider status.\n const status =\n action === 'suspend' ? 'SUSPENDED' : action === 'activate' ? 'ACTIVE' : 'VERIFIED';\n const verb = action === 'suspend' ? 'suspended' : action === 'activate' ? 'activated' : 'verified';\n updateProvider.mutate(\n { id: user.providerId, input: { status } },\n {\n onSuccess: () => showStatus(`${user.firstName} ${user.lastName} ${verb}.`, 'success'),\n onError: () =>\n showStatus(`Could not ${action} ${user.firstName}. Please try again.`, 'error'),\n }\n );\n return;\n }\n setSelectedUser(user);\n setShowUserModal(true);\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-[var(--color-accent-soft)] text-text-primary',\n cart_owner: 'bg-status-success-bg-subtle text-status-success-text',\n worker: 'bg-status-warning-bg-subtle text-status-warning-text',\n investor: 'bg-accent-purple-subtle text-text-primary',\n admin: 'bg-status-error-bg-subtle 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-subtle text-status-success-text',\n inactive: 'bg-bg-sunken text-text-secondary',\n suspended: 'bg-status-error-bg-subtle text-status-error-text',\n pending: 'bg-status-warning-bg-subtle 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 ?? 0).toLocaleString('en-IN')} registered users on the platform`}\n >\n <PagePurpose className=\"mb-6\">\n The directory of everyone on Kadaikodi — customers, cart owners, workers and investors. Use\n this page to find an account, verify or activate users, edit roles, and step in when someone\n needs help. Filter by role or status to manage one group at a time.\n </PagePurpose>\n\n {statusMessage && (\n <div\n className={cn(\n 'mb-6 flex items-center gap-2 rounded-lg border p-3',\n statusMessage.type === 'success'\n ? 'border-status-success-text/30 bg-status-success-bg-subtle'\n : 'border-status-error-text/30 bg-status-error-bg-subtle'\n )}\n >\n {statusMessage.type === 'success' ? (\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text\" />\n ) : (\n <AlertCircle className=\"h-4 w-4 text-status-error-text\" />\n )}\n <span\n className={cn(\n 'text-sm font-medium',\n statusMessage.type === 'success'\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n {statusMessage.text}\n </span>\n </div>\n )}\n\n {/* 8 Stats Cards — the one emphasis zone for this page */}\n <EmphasisPanel className=\"mb-6\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">User Base Overview</h2>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-3\">\n {[\n {\n label: 'Total Users',\n value: (stats.totalUsers ?? 0).toLocaleString('en-IN'),\n cls: '',\n },\n {\n label: 'Active',\n value: (stats.activeUsers ?? 0).toLocaleString('en-IN'),\n cls: 'bg-status-success-bg-subtle border-status-success-text/30',\n },\n {\n label: 'New (30d)',\n value: stats.newUsers.toString(),\n cls: 'bg-[var(--color-accent-soft)] border-border-focus/30',\n },\n {\n label: 'Verified',\n value: (stats.verifiedUsers ?? 0).toLocaleString('en-IN'),\n cls: 'bg-accent-purple-subtle border-accent-purple/30',\n },\n { label: 'Customers', value: (stats.customers ?? 0).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-subtle 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 </EmphasisPanel>\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\n key={user.id}\n className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-4\"\n >\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, 'view')}\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 View\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-status-error-text hover:bg-status-error-bg-subtle 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-status-success-text hover:bg-status-success-bg-subtle 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-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, 'view')}\n title=\"View details\"\n className=\"rounded p-1.5 text-text-secondary hover:text-text-primary hover:bg-accent transition-colors\"\n >\n <Eye 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-subtle 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-subtle 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-text-primary hover:bg-[var(--color-accent-soft)] 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 <EmptyState\n illustration=\"empty-people\"\n title=\"No users found\"\n description=\"No accounts match your current filters. Try clearing them or searching for a different name or email.\"\n action={\n <button\n type=\"button\"\n onClick={() =>\n setFilters({\n role: '',\n status: '',\n searchQuery: '',\n sortBy: 'recent',\n registrationDate: '',\n })\n }\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Clear filters\n </button>\n }\n />\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 Details Modal (read-only) */}\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\">User Details</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 space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Name</p>\n <p className=\"font-medium text-text-primary\">\n {selectedUser.firstName} {selectedUser.lastName}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Role</p>\n <div className=\"mt-0.5\">{roleBadge(selectedUser.role)}</div>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Status</p>\n <div className=\"mt-0.5\">{statusBadge(selectedUser.status)}</div>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Registered</p>\n <p className=\"font-medium text-text-primary\">\n {formatDate(selectedUser.registrationDate)}\n </p>\n </div>\n {selectedUser.email && (\n <div>\n <p className=\"text-sm text-text-secondary\">Email</p>\n <p className=\"font-medium text-text-primary flex items-center gap-1\">\n <Mail className=\"h-3.5 w-3.5\" />\n {selectedUser.email}\n </p>\n </div>\n )}\n {selectedUser.phone && (\n <div>\n <p className=\"text-sm text-text-secondary\">Phone</p>\n <p className=\"font-medium text-text-primary flex items-center gap-1\">\n <Phone className=\"h-3.5 w-3.5\" />\n {selectedUser.phone}\n </p>\n </div>\n )}\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-3\">\n <p className=\"text-sm text-text-secondary\">\n Profile details, email and role are managed by the account platform and can't\n be edited here. Use the Suspend / Activate controls in the list to change this\n account's access.\n </p>\n </div>\n\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n onClick={() => setShowUserModal(false)}\n className=\"rounded-lg border border-border-subtle py-2 px-4 text-sm font-medium text-text-primary hover:bg-accent transition-colors\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|