feat: build Lead Workspace page with KPIs, source grid, lead cards, and sidebar widgets

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-16 14:49:59 +05:30
parent d36f9f39b5
commit 1bed4b7d08
7 changed files with 595 additions and 3 deletions

View File

@@ -0,0 +1,93 @@
import { cx } from '@/utils/cx';
import type { Lead } from '@/types/entities';
interface KpiCardsProps {
leads: Lead[];
}
type KpiCard = {
label: string;
value: number;
delta: string;
deltaColor: string;
isHero: boolean;
};
export const KpiCards = ({ leads }: KpiCardsProps) => {
const newCount = leads.filter((l) => l.leadStatus === 'NEW').length;
const assignedCount = leads.filter((l) => l.assignedAgent !== null).length;
const contactedCount = leads.filter((l) => l.leadStatus === 'CONTACTED').length;
const convertedCount = leads.filter((l) => l.leadStatus === 'CONVERTED').length;
const cards: KpiCard[] = [
{
label: 'New Leads Today',
value: newCount,
delta: '+12% vs yesterday',
deltaColor: 'text-success-primary',
isHero: true,
},
{
label: 'Assigned to CC',
value: assignedCount,
delta: '85% assigned',
deltaColor: 'text-brand-secondary',
isHero: false,
},
{
label: 'Contacted',
value: contactedCount,
delta: '+8% vs yesterday',
deltaColor: 'text-success-primary',
isHero: false,
},
{
label: 'Converted',
value: convertedCount,
delta: '+3 this week',
deltaColor: 'text-warning-primary',
isHero: false,
},
];
return (
<div className="flex gap-3">
{cards.map((card) => (
<div
key={card.label}
className={cx(
'rounded-2xl p-5 transition hover:shadow-md',
card.isHero
? 'flex-[1.3] bg-brand-solid text-white'
: 'flex-1 border border-secondary bg-primary',
)}
>
<p
className={cx(
'text-xs font-medium uppercase tracking-wider',
card.isHero ? 'text-white/70' : 'text-quaternary',
)}
>
{card.label}
</p>
<p
className={cx(
'mt-1 text-display-sm font-bold',
card.isHero ? 'text-white' : 'text-primary',
)}
>
{card.value}
</p>
<p
className={cx(
'mt-1 text-xs',
card.isHero ? 'text-white/80' : card.deltaColor,
)}
>
{card.delta}
</p>
</div>
))}
</div>
);
};