"use client"; import React, { useState, useEffect, useCallback } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Search, MoreHorizontal, UserCheck, UserX, Mail, Loader2 } from "lucide-react"; import { fetchClient } from "@/lib/api-client"; import { useToast } from "@/hooks/use-toast"; interface Vendor { _id: string; username: string; storeId?: string; createdAt?: string; lastLogin?: string; isAdmin?: boolean; isActive: boolean; } interface PaginationResponse { success: boolean; vendors: Vendor[]; pagination: { page: number; limit: number; total: number; totalPages: number; hasNextPage: boolean; hasPrevPage: boolean; }; } export default function AdminVendorsPage() { const { toast } = useToast(); const [loading, setLoading] = useState(true); const [vendors, setVendors] = useState([]); const [page, setPage] = useState(1); const [pagination, setPagination] = useState(null); const [searchQuery, setSearchQuery] = useState(""); const fetchVendors = useCallback(async () => { try { setLoading(true); const params = new URLSearchParams({ page: page.toString(), limit: '25' }); const data = await fetchClient(`/admin/vendors?${params.toString()}`); setVendors(data.vendors); setPagination(data.pagination); } catch (error: any) { console.error("Failed to fetch vendors:", error); toast({ title: "Error", description: error.message || "Failed to load vendors", variant: "destructive", }); } finally { setLoading(false); } }, [page, toast]); useEffect(() => { fetchVendors(); }, [fetchVendors]); const filteredVendors = searchQuery.trim() ? vendors.filter(v => v.username.toLowerCase().includes(searchQuery.toLowerCase()) || (v.storeId && v.storeId.toString().toLowerCase().includes(searchQuery.toLowerCase())) ) : vendors; const activeVendors = vendors.filter(v => v.isActive); const suspendedVendors = vendors.filter(v => !v.isActive); const adminVendors = vendors.filter(v => v.isAdmin); const totalVendors = pagination?.total || vendors.length; return (

All Vendors

Manage vendor accounts and permissions

{/* Stats Cards */}
Total Vendors
{totalVendors}

Registered vendors

Active Vendors
{activeVendors.length}

{vendors.length > 0 ? Math.round((activeVendors.length / vendors.length) * 100) : 0}% active rate

Suspended
{suspendedVendors.length}

{vendors.length > 0 ? Math.round((suspendedVendors.length / vendors.length) * 100) : 0}% suspension rate

Admin Users
{adminVendors.length}

Administrative access

{/* Search and Filters */}
Vendor Management View and manage all vendor accounts
setSearchQuery(e.target.value)} />
{loading ? (
) : filteredVendors.length === 0 ? (
{searchQuery.trim() ? "No vendors found matching your search" : "No vendors found"}
) : ( <> Vendor Store Status Join Date Last Login Actions {filteredVendors.map((vendor) => (
{vendor.username}
{vendor.storeId || 'No store'}
{vendor.isActive ? "active" : "suspended"} {vendor.isAdmin && ( Admin )}
{vendor.createdAt ? new Date(vendor.createdAt).toLocaleDateString() : 'N/A'} {vendor.lastLogin ? new Date(vendor.lastLogin).toLocaleDateString() : 'Never'}
))}
{pagination && pagination.totalPages > 1 && (
Page {pagination.page} of {pagination.totalPages} ({pagination.total} total)
)} )}
); }