import React, { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { adminApi } from '../../api/admin';
import { AppLayout } from '../../components/layout/AppLayout';
import { PageLoader } from '../../components/ui/LoadingSpinner';
import { Search, Filter, TrendingUp, Mail, Phone, Building2, Eye } from 'lucide-react';
import type { Lead } from '../../types';
const STATUS_FILTERS = [
{ value: '', label: 'All Statuses' },
{ value: 'new', label: 'New' },
{ value: 'assigned', label: 'Assigned' },
{ value: 'contacted', label: 'Contacted' },
{ value: 'converted', label: 'Converted' },
{ value: 'lost', label: 'Lost' },
];
const STATUS_COLORS: Record<string, string> = {
new: 'bg-brand-100 text-brand-700',
assigned: 'bg-surface-200 text-surface-700',
contacted: 'bg-warning/10 text-warning',
converted: 'bg-success/10 text-success',
lost: 'bg-red-100 text-red-700',
};
const STATUS_ICONS: Record<string, React.ReactNode> = {
new: <TrendingUp className="mr-1 h-3 w-3" />,
assigned: <Eye className="mr-1 h-3 w-3" />,
contacted: <Mail className="mr-1 h-3 w-3" />,
converted: <TrendingUp className="mr-1 h-3 w-3" />,
lost: <Phone className="mr-1 h-3 w-3" />,
};
export function LeadsPage() {
const [search, setSearch] = useState('');
const [statusFilter, setStatusFilter] = useState<string>('');
const { data, isLoading } = useQuery({
queryKey: ['admin-leads', statusFilter],
queryFn: () => adminApi.getLeads(),
});
const leads = data?.items ?? [];
const filtered = leads.filter((lead) => {
const matchesSearch =
lead.name.toLowerCase().includes(search.toLowerCase()) ||
lead.email.toLowerCase().includes(search.toLowerCase()) ||
lead.company.toLowerCase().includes(search.toLowerCase());
const matchesStatus = !statusFilter || lead.status === statusFilter;
return matchesSearch && matchesStatus;
});
if (isLoading) {
return (
<AppLayout title="Leads">
<PageLoader />
</AppLayout>
);
}
return (
<AppLayout title="Leads">
{/* Header */}
<div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div>
<h1 className="text-xl sm:text-2xl font-bold text-surface-900">Leads</h1>
<p className="mt-1 text-sm text-surface-500">
{leads.length} lead{leads.length !== 1 ? 's' : ''} in the pipeline
</p>
</div>
<div className="flex flex-col gap-3 sm:flex-row">
<div className="relative">
<Filter className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-surface-500" />
<select
value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value)}
className="w-full sm:w-48 rounded-lg border border-surface-300 py-2.5 pl-9 pr-3 text-sm outline-none focus:border-brand-500 appearance-none min-h-[44px]"
>
{STATUS_FILTERS.map((filter) => (
<option key={filter.value} value={filter.value}>
{filter.label}
</option>
))}
</select>
</div>
<div className="relative">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-surface-500" />
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search leads..."
className="w-full rounded-lg border border-surface-300 py-2.5 pl-9 pr-4 text-sm outline-none focus:border-brand-500 sm:w-64 min-h-[44px]"
/>
</div>
</div>
</div>
{/* Leads Table */}
{filtered.length === 0 ? (
<div className="flex flex-col items-center justify-center rounded-xl border border-surface-200 bg-white py-16">
<TrendingUp className="h-12 w-12 text-surface-300" />
<p className="mt-4 text-sm font-medium text-surface-700">
{search || statusFilter ? 'No leads match your filters' : 'No leads yet'}
</p>
<p className="mt-1 text-xs text-surface-500">
Leads will appear here when they come through the system
</p>
</div>
) : (
<div className="rounded-xl border border-surface-200 bg-white">
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-surface-200">
<th className="pb-3 pl-5 text-left font-medium text-surface-500">Lead</th>
<th className="pb-3 text-left font-medium text-surface-500">Company</th>
<th className="pb-3 text-left font-medium text-surface-500">Status</th>
<th className="pb-3 text-left font-medium text-surface-500">Source</th>
<th className="pb-3 text-left font-medium text-surface-500">Assigned To</th>
<th className="pb-3 text-right font-medium text-surface-500 pr-5">Created</th>
</tr>
</thead>
<tbody className="divide-y divide-surface-100">
{filtered.map((lead) => (
<tr key={lead.id} className="hover:bg-surface-50">
<td className="py-3 pl-5">
<div className="flex items-center gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-brand-100 text-xs font-semibold text-brand-700">
{lead.name.charAt(0).toUpperCase()}
</div>
<div className="min-w-0 flex-1">
<p className="font-medium text-surface-900 truncate">{lead.name}</p>
<p className="text-xs text-surface-500 truncate">{lead.email}</p>
{lead.phone && (
<p className="text-xs text-surface-500 flex items-center gap-1 mt-0.5">
<Phone className="h-3 w-3" />
{lead.phone}
</p>
)}
</div>
</div>
</td>
<td className="py-3">
<div className="flex items-center gap-1.5 text-surface-700 min-w-0">
<Building2 className="h-3.5 w-3.5 text-surface-500 shrink-0" />
<span className="truncate">{lead.company || '—'}</span>
</div>
</td>
<td className="py-3">
<span
className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${STATUS_COLORS[lead.status] || 'bg-surface-200 text-surface-600'}`}
>
{STATUS_ICONS[lead.status]}
{lead.status}
</span>
</td>
<td className="py-3 text-surface-600">{lead.source || '—'}</td>
<td className="py-3 text-surface-600 truncate">{lead.assignedTo || 'Unassigned'}</td>
<td className="py-3 text-right text-surface-500 pr-5">
{new Date(lead.createdAt).toLocaleDateString()}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
</AppLayout>
);
}