@burdenoff/microfe-kadaikodi 2026.802.1 → 2026.830.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/kadaikodi/KadaikodiRoot.d.ts.map +1 -1
- package/dist/kadaikodi/KadaikodiRoot.js +69 -72
- package/dist/kadaikodi/KadaikodiRoot.js.map +1 -1
- package/dist/kadaikodi/components/InvestmentCard.d.ts.map +1 -1
- package/dist/kadaikodi/components/InvestmentCard.js +58 -54
- package/dist/kadaikodi/components/InvestmentCard.js.map +1 -1
- package/dist/kadaikodi/components/OrderCard.d.ts.map +1 -1
- package/dist/kadaikodi/components/StatusBadge.d.ts.map +1 -1
- package/dist/kadaikodi/components/StatusBadge.js +25 -14
- package/dist/kadaikodi/components/StatusBadge.js.map +1 -1
- package/dist/kadaikodi/hooks/useKadaikodiApi.d.ts +24 -0
- package/dist/kadaikodi/hooks/useKadaikodiApi.d.ts.map +1 -1
- package/dist/kadaikodi/hooks/useKadaikodiApi.js +177 -132
- package/dist/kadaikodi/hooks/useKadaikodiApi.js.map +1 -1
- package/dist/kadaikodi/pages/HomePage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/HomePage.js +284 -282
- package/dist/kadaikodi/pages/HomePage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.d.ts +7 -2
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js +319 -228
- package/dist/kadaikodi/pages/admin/AdminAnalyticsPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js +1 -1
- package/dist/kadaikodi/pages/admin/AdminOrdersPage.js.map +1 -1
- package/dist/kadaikodi/pages/admin/CartManagementPage.d.ts +10 -4
- package/dist/kadaikodi/pages/admin/CartManagementPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/admin/CartManagementPage.js +320 -279
- package/dist/kadaikodi/pages/admin/CartManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js +365 -292
- package/dist/kadaikodi/pages/cart-owner/MerchantOnboardingPage.js.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.d.ts +7 -2
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js +300 -158
- package/dist/kadaikodi/pages/cart-owner/StaffManagementPage.js.map +1 -1
- package/dist/kadaikodi/pages/common/SettingsPage.js +286 -286
- package/dist/kadaikodi/pages/common/SettingsPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDetailPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDetailPage.js +3 -3
- package/dist/kadaikodi/pages/customer/CartDetailPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.d.ts +13 -3
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js +270 -220
- package/dist/kadaikodi/pages/customer/CartDiscoveryPage.js.map +1 -1
- package/dist/kadaikodi/pages/customer/CustomerDashboard.js +97 -97
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js +1 -1
- package/dist/kadaikodi/pages/customer/OrderTrackingPage.js.map +1 -1
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.d.ts +5 -3
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.d.ts.map +1 -1
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js +286 -199
- package/dist/kadaikodi/pages/worker/TaskDetailsPage.js.map +1 -1
- package/dist/kadaikodi/types/index.d.ts +46 -2
- package/dist/kadaikodi/types/index.d.ts.map +1 -1
- package/dist/shared/hooks/useTr.d.ts +2 -0
- package/dist/shared/hooks/useTr.d.ts.map +1 -0
- package/dist/shared/hooks/useTr.js +14 -0
- package/dist/shared/hooks/useTr.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartManagementPage.js","names":[],"sources":["../../../../src/kadaikodi/pages/admin/CartManagementPage.tsx"],"sourcesContent":["/**\n * Merchant (Cart) Management Page\n * @module kadaikodi/pages/admin\n *\n * Merchant management wired to the live backend (useProviders +\n * useUpdateProvider). Status tabs, the merchant table, expandable detail rows\n * and the approve / verify / suspend / reject actions all operate on real\n * provider records. Approve→VERIFIED, Suspend→SUSPENDED and Reject→ARCHIVED\n * persist via useUpdateProvider. Fields with no backend source (verification\n * documents, monthly revenue) are omitted rather than fabricated.\n */\n\nimport { Fragment, useState, useMemo } from 'react';\nimport {\n Search,\n Store,\n CheckCircle2,\n Star,\n Loader2,\n X,\n AlertCircle,\n ChevronDown,\n MapPin,\n Calendar,\n IndianRupee,\n FileText,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { StatCard, SegmentedTabs } from '../../components/viz';\nimport { useProviders, useUpdateProvider } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\nimport type { MockCart } from '../../types';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\ntype MerchantStatus = 'verified' | 'pending' | 'inactive';\ntype StatusTab = 'all' | MerchantStatus;\ntype CartActionType = 'approve' | 'reject' | 'suspend';\n\ninterface MerchantVM {\n id: string;\n name: string;\n category: string;\n ownerId: string;\n address: string;\n rating: number;\n reviewCount: number;\n avgOrderValue: number;\n serviceTypes: string[];\n isOpen: boolean;\n isVerified: boolean;\n status: MerchantStatus;\n createdAt: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Provider → merchant view-model (real data only) */\n/* ------------------------------------------------------------------ */\n\nconst titleCase = (s: string) =>\n s\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n\nfunction toMerchant(p: MockCart): MerchantVM {\n const status: MerchantStatus = p.isVerified ? 'verified' : p.isOpen ? 'pending' : 'inactive';\n return {\n id: p.id,\n name: p.name,\n category: p.category,\n ownerId: p.ownerId ?? '',\n address: p.location?.address ?? '',\n rating: p.rating,\n reviewCount: p.totalRatings,\n avgOrderValue: p.averageOrderValue ?? 0,\n serviceTypes: p.serviceTypes ?? [],\n isOpen: p.isOpen,\n isVerified: p.isVerified ?? false,\n status,\n createdAt: p.createdAt ?? new Date().toISOString(),\n };\n}\n\nconst STATUS_META: Record<MerchantStatus, { label: string; cls: string }> = {\n verified: { label: 'Verified', cls: 'bg-status-success-bg-subtle text-status-success-text' },\n pending: { label: 'Pending', cls: 'bg-status-warning-bg-subtle text-status-warning-text' },\n inactive: { label: 'Inactive', cls: 'bg-bg-sunken text-text-secondary' },\n};\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function CartManagementPage() {\n const { data: providers = [], isLoading: loading } = useProviders();\n const updateProvider = useUpdateProvider();\n\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\n const [statusTab, setStatusTab] = useState<StatusTab>('all');\n const [searchQuery, setSearchQuery] = useState('');\n const [category, setCategory] = useState('');\n const [sortBy, setSortBy] = useState('recent');\n const [expandedId, setExpandedId] = useState<string | null>(null);\n\n const [selected, setSelected] = useState<MerchantVM | null>(null);\n const [actionType, setActionType] = useState<CartActionType>('approve');\n const [showModal, setShowModal] = useState(false);\n const [rejectionReason, setRejectionReason] = useState('');\n\n const merchants = useMemo(() => providers.map(toMerchant), [providers]);\n\n const counts = useMemo(\n () => ({\n all: merchants.length,\n verified: merchants.filter((m) => m.status === 'verified').length,\n pending: merchants.filter((m) => m.status === 'pending').length,\n inactive: merchants.filter((m) => m.status === 'inactive').length,\n }),\n [merchants]\n );\n\n const avgRating = useMemo(() => {\n const rated = merchants.filter((m) => m.rating > 0);\n if (rated.length === 0) return 0;\n return rated.reduce((s, m) => s + m.rating, 0) / rated.length;\n }, [merchants]);\n\n const categories = useMemo(\n () => Array.from(new Set(merchants.map((m) => m.category))).sort(),\n [merchants]\n );\n\n const rows = useMemo(() => {\n let list = [...merchants];\n if (statusTab !== 'all') list = list.filter((m) => m.status === statusTab);\n if (category) list = list.filter((m) => m.category === category);\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n list = list.filter(\n (m) =>\n m.name.toLowerCase().includes(q) ||\n m.category.toLowerCase().includes(q) ||\n m.address.toLowerCase().includes(q)\n );\n }\n switch (sortBy) {\n case 'name':\n list.sort((a, b) => a.name.localeCompare(b.name));\n break;\n case 'rating':\n list.sort((a, b) => b.rating - a.rating);\n break;\n case 'value':\n list.sort((a, b) => b.avgOrderValue - a.avgOrderValue);\n break;\n default:\n list.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n }\n return list;\n }, [merchants, statusTab, category, searchQuery, sortBy]);\n\n const fmtCur = (n: number) => formatCurrency(n, { minimumFractionDigits: 0 });\n const formatDate = (d: string) =>\n new Date(d).toLocaleDateString('en-IN', { year: 'numeric', month: 'short', day: 'numeric' });\n\n const openAction = (merchant: MerchantVM, action: CartActionType) => {\n setSelected(merchant);\n setActionType(action);\n setRejectionReason('');\n setShowModal(true);\n };\n\n const executeAction = () => {\n if (!selected) return;\n if (actionType === 'reject' && !rejectionReason.trim()) {\n showStatus('Please provide a rejection reason', 'error');\n return;\n }\n const status =\n actionType === 'approve' ? 'VERIFIED' : actionType === 'reject' ? 'ARCHIVED' : 'SUSPENDED';\n updateProvider.mutate(\n { id: selected.id, input: { status } },\n {\n onSuccess: () => {\n const verb =\n actionType === 'approve'\n ? 'approved & verified'\n : actionType === 'reject'\n ? 'rejected'\n : 'suspended';\n showStatus(`\"${selected.name}\" ${verb}.`, 'success');\n setShowModal(false);\n setRejectionReason('');\n },\n onError: () =>\n showStatus(`Could not ${actionType} \"${selected.name}\". Please try again.`, 'error'),\n }\n );\n };\n\n const StatusPill = ({ status }: { status: MerchantStatus }) => (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n STATUS_META[status].cls\n )}\n >\n {STATUS_META[status].label}\n </span>\n );\n\n const RowActions = ({ m, compact }: { m: MerchantVM; compact?: boolean }) => (\n <div className={cn('flex gap-2', compact ? 'flex-wrap' : 'items-center justify-end')}>\n {!m.isVerified && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'approve')}\n className=\"rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n Approve\n </button>\n )}\n {m.status !== 'inactive' && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'suspend')}\n className=\"rounded-lg border border-border-default px-3 py-1.5 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle\"\n >\n Suspend\n </button>\n )}\n </div>\n );\n\n const MerchantDetail = ({ m }: { m: MerchantVM }) => (\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-4\">\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2\">\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Business Details</h4>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Merchant</dt>\n <dd className=\"font-medium text-text-primary\">{m.name}</dd>\n </div>\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Category</dt>\n <dd className=\"text-text-primary\">{titleCase(m.category)}</dd>\n </div>\n {m.address && (\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Address</dt>\n <dd className=\"flex items-start gap-1 text-text-primary\">\n <MapPin className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-text-secondary\" />\n {m.address}\n </dd>\n </div>\n )}\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Applied</dt>\n <dd className=\"flex items-center gap-1 text-text-primary\">\n <Calendar className=\"h-3.5 w-3.5 text-text-secondary\" />\n {formatDate(m.createdAt)}\n </dd>\n </div>\n {m.ownerId && (\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Owner ID</dt>\n <dd className=\"truncate font-mono text-xs text-text-primary\">{m.ownerId}</dd>\n </div>\n )}\n </dl>\n </div>\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Performance</h4>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Rating</p>\n <p className=\"flex items-center gap-1 text-lg font-bold text-text-primary\">\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n {m.rating > 0 ? m.rating.toFixed(1) : '—'}\n </p>\n <p className=\"text-xs text-text-secondary\">{m.reviewCount} reviews</p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Avg Order Value</p>\n <p className=\"flex items-center gap-0.5 text-lg font-bold text-text-primary\">\n <IndianRupee className=\"h-3.5 w-3.5\" />\n {m.avgOrderValue > 0 ? m.avgOrderValue.toLocaleString('en-IN') : '—'}\n </p>\n </div>\n </div>\n {m.serviceTypes.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {m.serviceTypes.map((s) => (\n <span\n key={s}\n className=\"rounded-full bg-bg-surface px-2 py-0.5 text-xs text-text-secondary\"\n >\n {titleCase(s)}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"mt-4 flex flex-col items-start justify-between gap-3 border-t border-border-subtle pt-4 sm:flex-row sm:items-center\">\n <p className=\"flex items-center gap-1.5 text-xs text-text-muted\">\n <FileText className=\"h-3.5 w-3.5\" />\n Verification documents are not stored on the platform yet.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n {!m.isVerified && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'reject')}\n className=\"rounded-lg border border-status-error-text/40 px-3 py-1.5 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle\"\n >\n Reject\n </button>\n )}\n {!m.isVerified && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'approve')}\n className=\"rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n Approve Merchant\n </button>\n )}\n {m.status !== 'inactive' && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'suspend')}\n className=\"rounded-lg border border-border-default px-3 py-1.5 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle\"\n >\n Suspend\n </button>\n )}\n </div>\n </div>\n </div>\n );\n\n if (loading) {\n return (\n <PageLayout title=\"Merchants\" description=\"Loading merchants...\">\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 className=\"mb-4 h-10 w-10 animate-spin text-text-secondary\" />\n <p className=\"text-text-secondary\">Loading merchants...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Merchants\"\n description={`${counts.all} merchants on the platform · ${counts.pending} awaiting review`}\n >\n <PagePurpose className=\"mb-6\">\n Onboard and oversee every merchant (cart) on Kadaikodi. Approve and verify legitimate\n businesses, suspend ones that break the rules, and keep an eye on ratings and performance —\n so customers only ever see trustworthy, active merchants.\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 {/* KPI row */}\n <div className=\"mb-6 grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <StatCard\n label=\"Total Merchants\"\n value={counts.all.toLocaleString('en-IN')}\n icon={<Store className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Pending Review\"\n value={counts.pending.toLocaleString('en-IN')}\n icon={<AlertCircle className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Verified\"\n value={counts.verified.toLocaleString('en-IN')}\n icon={<CheckCircle2 className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Avg Rating\"\n value={avgRating > 0 ? avgRating.toFixed(1) : '—'}\n icon={<Star className=\"h-4 w-4\" />}\n />\n </div>\n\n {/* Tabs + search */}\n <div className=\"mb-6 flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"overflow-x-auto\">\n <SegmentedTabs\n aria-label=\"Filter merchants by status\"\n value={statusTab}\n onChange={(id) => setStatusTab(id as StatusTab)}\n tabs={[\n { id: 'all', label: 'All', count: counts.all },\n { id: 'pending', label: 'Pending', count: counts.pending },\n { id: 'verified', label: 'Verified', count: counts.verified },\n { id: 'inactive', label: 'Inactive', count: counts.inactive },\n ]}\n />\n </div>\n <div className=\"flex flex-col gap-3 sm:flex-row\">\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 merchants...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(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)] sm:w-64\"\n />\n </div>\n <select\n value={category}\n onChange={(e) => setCategory(e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Categories</option>\n {categories.map((c) => (\n <option key={c} value={c}>\n {titleCase(c)}\n </option>\n ))}\n </select>\n <select\n value={sortBy}\n onChange={(e) => setSortBy(e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 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=\"rating\">Highest Rated</option>\n <option value=\"value\">Highest Avg Order</option>\n </select>\n </div>\n </div>\n\n {/* Merchant table / cards */}\n {rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-search\"\n title=\"No merchants found\"\n description=\"No merchants match your current filters. Try clearing the search or switching tabs.\"\n action={\n <button\n type=\"button\"\n onClick={() => {\n setSearchQuery('');\n setCategory('');\n setStatusTab('all');\n }}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n Clear filters\n </button>\n }\n />\n ) : (\n <GlassCard treatment=\"plain\" className=\"overflow-hidden\">\n {/* Desktop table */}\n <div className=\"hidden overflow-x-auto md:block\">\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 uppercase tracking-wider text-text-secondary\">\n Merchant\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Category\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Status\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Rating\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Avg Order\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {rows.map((m) => {\n const expanded = expandedId === m.id;\n return (\n <Fragment key={m.id}>\n <tr className=\"transition-colors hover:bg-accent/50\">\n <td className=\"px-4 py-3\">\n <button\n type=\"button\"\n onClick={() => setExpandedId(expanded ? null : m.id)}\n className=\"flex items-center gap-3 text-left\"\n >\n <ChevronDown\n className={cn(\n 'h-4 w-4 shrink-0 text-text-secondary transition-transform',\n expanded && 'rotate-180'\n )}\n />\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Store className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {m.name}\n </p>\n {m.address && (\n <p className=\"truncate text-xs text-text-secondary\">{m.address}</p>\n )}\n </div>\n </button>\n </td>\n <td className=\"px-4 py-3 text-sm text-text-secondary\">\n {titleCase(m.category)}\n </td>\n <td className=\"px-4 py-3\">\n <StatusPill status={m.status} />\n </td>\n <td className=\"px-4 py-3 text-sm\">\n {m.rating > 0 ? (\n <span className=\"flex items-center gap-1 text-text-primary\">\n <Star className=\"h-3.5 w-3.5 fill-status-warning-text text-status-warning-text\" />\n {m.rating.toFixed(1)}\n <span className=\"text-text-secondary\">({m.reviewCount})</span>\n </span>\n ) : (\n <span className=\"text-text-secondary\">—</span>\n )}\n </td>\n <td className=\"px-4 py-3 text-sm text-text-primary\">\n {m.avgOrderValue > 0 ? fmtCur(m.avgOrderValue) : '—'}\n </td>\n <td className=\"px-4 py-3\">\n <RowActions m={m} />\n </td>\n </tr>\n {expanded && (\n <tr className=\"bg-bg-sunken/20\">\n <td colSpan={6} className=\"px-4 py-4\">\n <MerchantDetail m={m} />\n </td>\n </tr>\n )}\n </Fragment>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {/* Mobile cards */}\n <div className=\"space-y-4 p-4 md:hidden\">\n {rows.map((m) => {\n const expanded = expandedId === m.id;\n return (\n <div\n key={m.id}\n className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-4\"\n >\n <div className=\"mb-3 flex items-start gap-3\">\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Store className=\"h-6 w-6\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate font-medium text-text-primary\">{m.name}</h3>\n <p className=\"truncate text-sm text-text-secondary\">\n {titleCase(m.category)}\n </p>\n {m.address && (\n <p className=\"truncate text-xs text-text-secondary\">{m.address}</p>\n )}\n </div>\n </div>\n <div className=\"mb-3 flex flex-wrap items-center gap-2\">\n <StatusPill status={m.status} />\n {m.rating > 0 && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2.5 py-0.5 text-xs font-medium text-status-warning-text\">\n <Star className=\"h-3 w-3 fill-current\" />\n {m.rating.toFixed(1)} ({m.reviewCount})\n </span>\n )}\n {m.avgOrderValue > 0 && (\n <span className=\"text-xs text-text-secondary\">\n Avg {fmtCur(m.avgOrderValue)}\n </span>\n )}\n </div>\n <div className=\"mb-3\">\n <RowActions m={m} compact />\n </div>\n <button\n type=\"button\"\n onClick={() => setExpandedId(expanded ? null : m.id)}\n className=\"flex w-full items-center justify-center gap-1 rounded-lg border border-border-subtle py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n {expanded ? 'Hide details' : 'View details'}\n <ChevronDown\n className={cn('h-4 w-4 transition-transform', expanded && 'rotate-180')}\n />\n </button>\n {expanded && (\n <div className=\"mt-3\">\n <MerchantDetail m={m} />\n </div>\n )}\n </div>\n );\n })}\n </div>\n </GlassCard>\n )}\n\n {/* Confirmation modal */}\n {showModal && selected && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div className=\"max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-lg border border-border-subtle bg-bg-surface shadow-lg\">\n <div className=\"flex items-center justify-between border-b border-border-subtle p-4\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {actionType === 'approve'\n ? 'Approve Merchant'\n : actionType === 'reject'\n ? 'Reject Merchant'\n : 'Suspend Merchant'}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShowModal(false)}\n className=\"rounded p-1.5 text-text-secondary transition-colors hover:bg-accent hover:text-text-primary\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <div className=\"space-y-4 p-4\">\n <div className=\"flex items-center gap-3 rounded-lg bg-bg-sunken/50 p-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Store className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{selected.name}</p>\n <p className=\"truncate text-sm text-text-secondary\">\n {titleCase(selected.category)}\n </p>\n </div>\n </div>\n\n {actionType === 'approve' && (\n <div className=\"rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-3\">\n <p className=\"text-sm text-status-success-text\">\n This marks the merchant as verified and active, so customers can start ordering\n from it.\n </p>\n </div>\n )}\n {actionType === 'suspend' && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle p-3\">\n <p className=\"text-sm text-status-error-text\">\n This suspends the merchant. It will be hidden from customers until reinstated.\n </p>\n </div>\n )}\n {actionType === 'reject' && (\n <div>\n <label className=\"mb-2 block text-sm font-medium text-text-primary\">\n Rejection Reason *\n </label>\n <textarea\n className=\"min-h-[100px] w-full rounded-lg border border-border-subtle bg-bg-surface p-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n rows={4}\n value={rejectionReason}\n onChange={(e) => setRejectionReason(e.target.value)}\n placeholder=\"Explain why this application is being rejected...\"\n />\n </div>\n )}\n\n <div className=\"flex gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={() => setShowModal(false)}\n className=\"flex-1 rounded-lg border border-border-subtle py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={executeAction}\n disabled={\n updateProvider.isPending || (actionType === 'reject' && !rejectionReason.trim())\n }\n className=\"flex-1 rounded-lg bg-action-primary-bg py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {updateProvider.isPending\n ? 'Working…'\n : actionType === 'approve'\n ? 'Approve Merchant'\n : actionType === 'reject'\n ? 'Reject Merchant'\n : 'Suspend Merchant'}\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CartManagementPage.js","names":[],"sources":["../../../../src/kadaikodi/pages/admin/CartManagementPage.tsx"],"sourcesContent":["/**\n * Merchant (Cart) Management Page\n * @module kadaikodi/pages/admin\n *\n * Merchant management wired to the live backend (useProviders +\n * useUpdateProvider). Status tabs, the merchant table, expandable detail rows\n * and the approve / verify / suspend / reject / reinstate actions all operate on\n * real provider records.\n *\n * Statuses are the provider's own `KadaikodiProviderStatus` value (DRAFT,\n * ACTIVE, VERIFIED, PAUSED, SUSPENDED, ARCHIVED), not a boolean derivation —\n * an operator has to be able to tell a suspended cart from an archived or\n * merely paused one. Approve→VERIFIED, Suspend→SUSPENDED, Reject→ARCHIVED and\n * Reinstate→ACTIVE persist via useUpdateProvider. Fields with no backend source\n * (verification documents, monthly revenue, per-merchant order counts) are\n * omitted rather than fabricated.\n */\n\nimport { Fragment, useState, useMemo } from 'react';\nimport {\n Search,\n Store,\n CheckCircle2,\n Star,\n Loader2,\n X,\n AlertCircle,\n ChevronDown,\n MapPin,\n Calendar,\n IndianRupee,\n FileText,\n Ban,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { StatCard, SegmentedTabs } from '../../components/viz';\nimport { useProviders, useUpdateProvider } from '../../hooks/useKadaikodiApi';\nimport { cn } from '../../utils/cn';\nimport { formatCurrency } from '../../utils/formatters';\nimport type { MockCart, ProviderLifecycleStatus } from '../../types';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\ntype StatusTab = 'all' | ProviderLifecycleStatus;\ntype CartActionType = 'approve' | 'reject' | 'suspend' | 'reinstate';\n\ninterface MerchantVM {\n id: string;\n name: string;\n category: string;\n ownerId: string;\n address: string;\n rating: number;\n reviewCount: number;\n avgOrderValue: number;\n serviceTypes: string[];\n isOpen: boolean;\n isVerified: boolean;\n /** The provider's real lifecycle status. DRAFT is the fallback for a row the\n * service returned with a status this build does not know. */\n status: ProviderLifecycleStatus;\n createdAt: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Provider → merchant view-model (real data only) */\n/* ------------------------------------------------------------------ */\n\nconst titleCase = (s: string) =>\n s\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n\nfunction toMerchant(p: MockCart): MerchantVM {\n const status: ProviderLifecycleStatus = p.status ?? 'DRAFT';\n return {\n id: p.id,\n name: p.name,\n category: p.category,\n ownerId: p.ownerId ?? '',\n address: p.location?.address ?? '',\n rating: p.rating,\n reviewCount: p.totalRatings,\n avgOrderValue: p.averageOrderValue ?? 0,\n serviceTypes: p.serviceTypes ?? [],\n isOpen: p.isOpen,\n isVerified: p.isVerified ?? false,\n status,\n createdAt: p.createdAt ?? new Date().toISOString(),\n };\n}\n\nconst STATUS_META: Record<ProviderLifecycleStatus, { label: string; cls: string }> = {\n VERIFIED: { label: 'Verified', cls: 'bg-status-success-bg-subtle text-status-success-text' },\n ACTIVE: { label: 'Active', cls: 'bg-status-success-bg-subtle text-status-success-text' },\n DRAFT: { label: 'Pending', cls: 'bg-status-warning-bg-subtle text-status-warning-text' },\n PAUSED: { label: 'Paused', cls: 'bg-status-warning-bg-subtle text-status-warning-text' },\n SUSPENDED: { label: 'Suspended', cls: 'bg-status-error-bg-subtle text-status-error-text' },\n ARCHIVED: { label: 'Archived', cls: 'bg-bg-sunken text-text-secondary' },\n};\n\n/** Tab order for the status filter — the review queue leads. */\nconst STATUS_TABS: ProviderLifecycleStatus[] = [\n 'DRAFT',\n 'VERIFIED',\n 'ACTIVE',\n 'PAUSED',\n 'SUSPENDED',\n 'ARCHIVED',\n];\n\n/** A cart still trading — Suspend is meaningful, Reinstate is not. */\nconst isLive = (s: ProviderLifecycleStatus) =>\n s === 'ACTIVE' || s === 'VERIFIED' || s === 'PAUSED' || s === 'DRAFT';\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function CartManagementPage() {\n const { data: providers = [], isLoading: loading } = useProviders();\n const updateProvider = useUpdateProvider();\n\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\n const [statusTab, setStatusTab] = useState<StatusTab>('all');\n const [searchQuery, setSearchQuery] = useState('');\n const [category, setCategory] = useState('');\n const [sortBy, setSortBy] = useState('recent');\n const [expandedId, setExpandedId] = useState<string | null>(null);\n\n const [selected, setSelected] = useState<MerchantVM | null>(null);\n const [actionType, setActionType] = useState<CartActionType>('approve');\n const [showModal, setShowModal] = useState(false);\n const [rejectionReason, setRejectionReason] = useState('');\n\n const merchants = useMemo(() => providers.map(toMerchant), [providers]);\n\n const counts = useMemo(() => {\n const byStatus = STATUS_TABS.reduce<Record<ProviderLifecycleStatus, number>>(\n (acc, s) => {\n acc[s] = merchants.filter((m) => m.status === s).length;\n return acc;\n },\n { DRAFT: 0, ACTIVE: 0, VERIFIED: 0, PAUSED: 0, SUSPENDED: 0, ARCHIVED: 0 }\n );\n return { all: merchants.length, byStatus };\n }, [merchants]);\n\n const avgRating = useMemo(() => {\n const rated = merchants.filter((m) => m.rating > 0);\n if (rated.length === 0) return 0;\n return rated.reduce((s, m) => s + m.rating, 0) / rated.length;\n }, [merchants]);\n\n const categories = useMemo(\n () => Array.from(new Set(merchants.map((m) => m.category))).sort(),\n [merchants]\n );\n\n const rows = useMemo(() => {\n let list = [...merchants];\n if (statusTab !== 'all') list = list.filter((m) => m.status === statusTab);\n if (category) list = list.filter((m) => m.category === category);\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n list = list.filter(\n (m) =>\n m.name.toLowerCase().includes(q) ||\n m.category.toLowerCase().includes(q) ||\n m.address.toLowerCase().includes(q)\n );\n }\n switch (sortBy) {\n case 'name':\n list.sort((a, b) => a.name.localeCompare(b.name));\n break;\n case 'rating':\n list.sort((a, b) => b.rating - a.rating);\n break;\n case 'value':\n list.sort((a, b) => b.avgOrderValue - a.avgOrderValue);\n break;\n default:\n list.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n }\n return list;\n }, [merchants, statusTab, category, searchQuery, sortBy]);\n\n const fmtCur = (n: number) => formatCurrency(n, { minimumFractionDigits: 0 });\n const formatDate = (d: string) =>\n new Date(d).toLocaleDateString('en-IN', { year: 'numeric', month: 'short', day: 'numeric' });\n\n const openAction = (merchant: MerchantVM, action: CartActionType) => {\n setSelected(merchant);\n setActionType(action);\n setRejectionReason('');\n setShowModal(true);\n };\n\n const executeAction = () => {\n if (!selected) return;\n if (actionType === 'reject' && !rejectionReason.trim()) {\n showStatus('Please provide a rejection reason', 'error');\n return;\n }\n const status: ProviderLifecycleStatus =\n actionType === 'approve'\n ? 'VERIFIED'\n : actionType === 'reject'\n ? 'ARCHIVED'\n : actionType === 'reinstate'\n ? 'ACTIVE'\n : 'SUSPENDED';\n updateProvider.mutate(\n { id: selected.id, input: { status } },\n {\n onSuccess: () => {\n const verb =\n actionType === 'approve'\n ? 'approved & verified'\n : actionType === 'reject'\n ? 'rejected'\n : actionType === 'reinstate'\n ? 'reinstated'\n : 'suspended';\n showStatus(`\"${selected.name}\" ${verb}.`, 'success');\n setShowModal(false);\n setRejectionReason('');\n },\n onError: () =>\n showStatus(`Could not ${actionType} \"${selected.name}\". Please try again.`, 'error'),\n }\n );\n };\n\n const StatusPill = ({ status }: { status: ProviderLifecycleStatus }) => (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n STATUS_META[status].cls\n )}\n >\n {STATUS_META[status].label}\n </span>\n );\n\n const RowActions = ({ m, compact }: { m: MerchantVM; compact?: boolean }) => (\n <div className={cn('flex gap-2', compact ? 'flex-wrap' : 'items-center justify-end')}>\n {m.status !== 'VERIFIED' && m.status !== 'ARCHIVED' && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'approve')}\n className=\"rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n Approve\n </button>\n )}\n {isLive(m.status) && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'suspend')}\n className=\"rounded-lg border border-border-default px-3 py-1.5 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle\"\n >\n Suspend\n </button>\n )}\n {m.status === 'SUSPENDED' && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'reinstate')}\n className=\"rounded-lg border border-status-success-text/40 px-3 py-1.5 text-sm font-medium text-status-success-text transition-colors hover:bg-status-success-bg-subtle\"\n >\n Reinstate\n </button>\n )}\n </div>\n );\n\n const MerchantDetail = ({ m }: { m: MerchantVM }) => (\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-4\">\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2\">\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Business Details</h4>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Merchant</dt>\n <dd className=\"font-medium text-text-primary\">{m.name}</dd>\n </div>\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Category</dt>\n <dd className=\"text-text-primary\">{titleCase(m.category)}</dd>\n </div>\n {m.address && (\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Address</dt>\n <dd className=\"flex items-start gap-1 text-text-primary\">\n <MapPin className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-text-secondary\" />\n {m.address}\n </dd>\n </div>\n )}\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Applied</dt>\n <dd className=\"flex items-center gap-1 text-text-primary\">\n <Calendar className=\"h-3.5 w-3.5 text-text-secondary\" />\n {formatDate(m.createdAt)}\n </dd>\n </div>\n {m.ownerId && (\n <div className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-text-secondary\">Owner ID</dt>\n <dd className=\"truncate font-mono text-xs text-text-primary\">{m.ownerId}</dd>\n </div>\n )}\n </dl>\n </div>\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Performance</h4>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Rating</p>\n <p className=\"flex items-center gap-1 text-lg font-bold text-text-primary\">\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n {m.rating > 0 ? m.rating.toFixed(1) : '—'}\n </p>\n <p className=\"text-xs text-text-secondary\">{m.reviewCount} reviews</p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Avg Order Value</p>\n <p className=\"flex items-center gap-0.5 text-lg font-bold text-text-primary\">\n <IndianRupee className=\"h-3.5 w-3.5\" />\n {m.avgOrderValue > 0 ? m.avgOrderValue.toLocaleString('en-IN') : '—'}\n </p>\n </div>\n </div>\n {m.serviceTypes.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {m.serviceTypes.map((s) => (\n <span\n key={s}\n className=\"rounded-full bg-bg-surface px-2 py-0.5 text-xs text-text-secondary\"\n >\n {titleCase(s)}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"mt-4 flex flex-col items-start justify-between gap-3 border-t border-border-subtle pt-4 sm:flex-row sm:items-center\">\n <p className=\"flex items-center gap-1.5 text-xs text-text-muted\">\n <FileText className=\"h-3.5 w-3.5\" />\n Verification documents are not stored on the platform yet.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n {m.status !== 'VERIFIED' && m.status !== 'ARCHIVED' && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'reject')}\n className=\"rounded-lg border border-status-error-text/40 px-3 py-1.5 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle\"\n >\n Reject\n </button>\n )}\n {m.status !== 'VERIFIED' && m.status !== 'ARCHIVED' && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'approve')}\n className=\"rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n Approve Merchant\n </button>\n )}\n {m.status === 'SUSPENDED' && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'reinstate')}\n className=\"rounded-lg border border-status-success-text/40 px-3 py-1.5 text-sm font-medium text-status-success-text transition-colors hover:bg-status-success-bg-subtle\"\n >\n Reinstate Merchant\n </button>\n )}\n {isLive(m.status) && (\n <button\n type=\"button\"\n onClick={() => openAction(m, 'suspend')}\n className=\"rounded-lg border border-border-default px-3 py-1.5 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle\"\n >\n Suspend\n </button>\n )}\n </div>\n </div>\n </div>\n );\n\n if (loading) {\n return (\n <PageLayout title=\"Merchants\" description=\"Loading merchants...\">\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 className=\"mb-4 h-10 w-10 animate-spin text-text-secondary\" />\n <p className=\"text-text-secondary\">Loading merchants...</p>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Merchants\"\n description={`${counts.all} merchants on the platform · ${counts.byStatus.DRAFT} awaiting review`}\n >\n <PagePurpose className=\"mb-6\">\n Onboard and oversee every merchant (cart) on Kadaikodi. Approve and verify legitimate\n businesses, suspend ones that break the rules, and keep an eye on ratings and performance —\n so customers only ever see trustworthy, active merchants.\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 {/* KPI row */}\n <div className=\"mb-6 grid grid-cols-2 gap-4 lg:grid-cols-5\">\n <StatCard\n label=\"Total Merchants\"\n value={counts.all.toLocaleString('en-IN')}\n icon={<Store className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Pending Review\"\n value={counts.byStatus.DRAFT.toLocaleString('en-IN')}\n icon={<AlertCircle className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Verified\"\n value={counts.byStatus.VERIFIED.toLocaleString('en-IN')}\n icon={<CheckCircle2 className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Suspended\"\n value={counts.byStatus.SUSPENDED.toLocaleString('en-IN')}\n icon={<Ban className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Avg Rating\"\n value={avgRating > 0 ? avgRating.toFixed(1) : '—'}\n icon={<Star className=\"h-4 w-4\" />}\n />\n </div>\n\n {/* Tabs + search */}\n <div className=\"mb-6 flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"overflow-x-auto\">\n <SegmentedTabs\n aria-label=\"Filter merchants by status\"\n value={statusTab}\n onChange={(id) => setStatusTab(id as StatusTab)}\n tabs={[\n { id: 'all', label: 'All', count: counts.all },\n ...STATUS_TABS.map((s) => ({\n id: s,\n label: STATUS_META[s].label,\n count: counts.byStatus[s],\n })),\n ]}\n />\n </div>\n <div className=\"flex flex-col gap-3 sm:flex-row\">\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 merchants...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(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)] sm:w-64\"\n />\n </div>\n <select\n value={category}\n onChange={(e) => setCategory(e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">All Categories</option>\n {categories.map((c) => (\n <option key={c} value={c}>\n {titleCase(c)}\n </option>\n ))}\n </select>\n <select\n value={sortBy}\n onChange={(e) => setSortBy(e.target.value)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 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=\"rating\">Highest Rated</option>\n <option value=\"value\">Highest Avg Order</option>\n </select>\n </div>\n </div>\n\n {/* Merchant table / cards */}\n {rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-search\"\n title=\"No merchants found\"\n description=\"No merchants match your current filters. Try clearing the search or switching tabs.\"\n action={\n <button\n type=\"button\"\n onClick={() => {\n setSearchQuery('');\n setCategory('');\n setStatusTab('all');\n }}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n Clear filters\n </button>\n }\n />\n ) : (\n <GlassCard treatment=\"plain\" className=\"overflow-hidden\">\n {/* Desktop table */}\n <div className=\"hidden overflow-x-auto md:block\">\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 uppercase tracking-wider text-text-secondary\">\n Merchant\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Category\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Status\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Rating\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Avg Order\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wider text-text-secondary\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {rows.map((m) => {\n const expanded = expandedId === m.id;\n return (\n <Fragment key={m.id}>\n <tr className=\"transition-colors hover:bg-accent/50\">\n <td className=\"px-4 py-3\">\n <button\n type=\"button\"\n onClick={() => setExpandedId(expanded ? null : m.id)}\n className=\"flex items-center gap-3 text-left\"\n >\n <ChevronDown\n className={cn(\n 'h-4 w-4 shrink-0 text-text-secondary transition-transform',\n expanded && 'rotate-180'\n )}\n />\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Store className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {m.name}\n </p>\n {m.address && (\n <p className=\"truncate text-xs text-text-secondary\">{m.address}</p>\n )}\n </div>\n </button>\n </td>\n <td className=\"px-4 py-3 text-sm text-text-secondary\">\n {titleCase(m.category)}\n </td>\n <td className=\"px-4 py-3\">\n <StatusPill status={m.status} />\n </td>\n <td className=\"px-4 py-3 text-sm\">\n {m.rating > 0 ? (\n <span className=\"flex items-center gap-1 text-text-primary\">\n <Star className=\"h-3.5 w-3.5 fill-status-warning-text text-status-warning-text\" />\n {m.rating.toFixed(1)}\n <span className=\"text-text-secondary\">({m.reviewCount})</span>\n </span>\n ) : (\n <span className=\"text-text-secondary\">—</span>\n )}\n </td>\n <td className=\"px-4 py-3 text-sm text-text-primary\">\n {m.avgOrderValue > 0 ? fmtCur(m.avgOrderValue) : '—'}\n </td>\n <td className=\"px-4 py-3\">\n <RowActions m={m} />\n </td>\n </tr>\n {expanded && (\n <tr className=\"bg-bg-sunken/20\">\n <td colSpan={6} className=\"px-4 py-4\">\n <MerchantDetail m={m} />\n </td>\n </tr>\n )}\n </Fragment>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {/* Mobile cards */}\n <div className=\"space-y-4 p-4 md:hidden\">\n {rows.map((m) => {\n const expanded = expandedId === m.id;\n return (\n <div\n key={m.id}\n className=\"rounded-lg border border-border-subtle bg-bg-sunken/30 p-4\"\n >\n <div className=\"mb-3 flex items-start gap-3\">\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Store className=\"h-6 w-6\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate font-medium text-text-primary\">{m.name}</h3>\n <p className=\"truncate text-sm text-text-secondary\">\n {titleCase(m.category)}\n </p>\n {m.address && (\n <p className=\"truncate text-xs text-text-secondary\">{m.address}</p>\n )}\n </div>\n </div>\n <div className=\"mb-3 flex flex-wrap items-center gap-2\">\n <StatusPill status={m.status} />\n {m.rating > 0 && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2.5 py-0.5 text-xs font-medium text-status-warning-text\">\n <Star className=\"h-3 w-3 fill-current\" />\n {m.rating.toFixed(1)} ({m.reviewCount})\n </span>\n )}\n {m.avgOrderValue > 0 && (\n <span className=\"text-xs text-text-secondary\">\n Avg {fmtCur(m.avgOrderValue)}\n </span>\n )}\n </div>\n <div className=\"mb-3\">\n <RowActions m={m} compact />\n </div>\n <button\n type=\"button\"\n onClick={() => setExpandedId(expanded ? null : m.id)}\n className=\"flex w-full items-center justify-center gap-1 rounded-lg border border-border-subtle py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n {expanded ? 'Hide details' : 'View details'}\n <ChevronDown\n className={cn('h-4 w-4 transition-transform', expanded && 'rotate-180')}\n />\n </button>\n {expanded && (\n <div className=\"mt-3\">\n <MerchantDetail m={m} />\n </div>\n )}\n </div>\n );\n })}\n </div>\n </GlassCard>\n )}\n\n {/* Confirmation modal */}\n {showModal && selected && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div className=\"max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-lg border border-border-subtle bg-bg-surface shadow-lg\">\n <div className=\"flex items-center justify-between border-b border-border-subtle p-4\">\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {actionType === 'approve'\n ? 'Approve Merchant'\n : actionType === 'reject'\n ? 'Reject Merchant'\n : actionType === 'reinstate'\n ? 'Reinstate Merchant'\n : 'Suspend Merchant'}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShowModal(false)}\n className=\"rounded p-1.5 text-text-secondary transition-colors hover:bg-accent hover:text-text-primary\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <div className=\"space-y-4 p-4\">\n <div className=\"flex items-center gap-3 rounded-lg bg-bg-sunken/50 p-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Store className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{selected.name}</p>\n <p className=\"truncate text-sm text-text-secondary\">\n {titleCase(selected.category)}\n </p>\n </div>\n </div>\n\n {actionType === 'approve' && (\n <div className=\"rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-3\">\n <p className=\"text-sm text-status-success-text\">\n This marks the merchant as verified and active, so customers can start ordering\n from it.\n </p>\n </div>\n )}\n {actionType === 'suspend' && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle p-3\">\n <p className=\"text-sm text-status-error-text\">\n This suspends the merchant. It will be hidden from customers until reinstated.\n </p>\n </div>\n )}\n {actionType === 'reinstate' && (\n <div className=\"rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle p-3\">\n <p className=\"text-sm text-status-success-text\">\n This returns the merchant to active trading. Re-approve it afterwards if it\n should also carry the verified badge.\n </p>\n </div>\n )}\n {actionType === 'reject' && (\n <div>\n <label className=\"mb-2 block text-sm font-medium text-text-primary\">\n Rejection Reason *\n </label>\n <textarea\n className=\"min-h-[100px] w-full rounded-lg border border-border-subtle bg-bg-surface p-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n rows={4}\n value={rejectionReason}\n onChange={(e) => setRejectionReason(e.target.value)}\n placeholder=\"Explain why this application is being rejected...\"\n />\n </div>\n )}\n\n <div className=\"flex gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={() => setShowModal(false)}\n className=\"flex-1 rounded-lg border border-border-subtle py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={executeAction}\n disabled={\n updateProvider.isPending || (actionType === 'reject' && !rejectionReason.trim())\n }\n className=\"flex-1 rounded-lg bg-action-primary-bg py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {updateProvider.isPending\n ? 'Working…'\n : actionType === 'approve'\n ? 'Approve Merchant'\n : actionType === 'reject'\n ? 'Reject Merchant'\n : actionType === 'reinstate'\n ? 'Reinstate Merchant'\n : 'Suspend Merchant'}\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MerchantOnboardingPage.d.ts","sourceRoot":"","sources":["../../../../src/kadaikodi/pages/cart-owner/MerchantOnboardingPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MerchantOnboardingPage.d.ts","sourceRoot":"","sources":["../../../../src/kadaikodi/pages/cart-owner/MerchantOnboardingPage.tsx"],"names":[],"mappings":"AA2EA,wBAAgB,sBAAsB,gCAkZrC"}
|