style: refine Pipeline fidelity to Quiet Luxury reference
- Sidebar: revert to white palette (drop emerald pass), remove right border - Table: softer slate-100 borders, remove min-height gap, "Mostrando N di M lead" footer, empty Tag cell = dashed-circle add button - SegmentedToggle: more visible track (slate-200/60), neutral active text - Kanban: roomy fixed-width columns (280px, horizontal scroll), sober column headers (no colored dots), airy cards matching mock (name+badge/email/ company+"Tag +"); 6 stages + @dnd-kit intact Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -22,26 +22,22 @@ type LeadStage = "contacted" | "qualified" | "proposal_sent" | "negotiating" | "
|
||||
const LEAD_COLUMNS: {
|
||||
id: LeadStage;
|
||||
label: string;
|
||||
headerClass: string;
|
||||
dotClass: string;
|
||||
}[] = [
|
||||
{ id: "contacted", label: "Contattato", headerClass: "text-muted-foreground", dotClass: "bg-blue-400 dark:bg-blue-500" },
|
||||
{ id: "qualified", label: "Qualificato", headerClass: "text-purple-700 dark:text-purple-400", dotClass: "bg-purple-400 dark:bg-purple-500" },
|
||||
{ id: "proposal_sent", label: "Offerta inviata", headerClass: "text-amber-700 dark:text-amber-400", dotClass: "bg-amber-400 dark:bg-amber-500" },
|
||||
{ id: "negotiating", label: "Trattativa", headerClass: "text-orange-700 dark:text-orange-400", dotClass: "bg-orange-400 dark:bg-orange-500" },
|
||||
{ id: "won", label: "Vinto", headerClass: "text-emerald-700 dark:text-emerald-400", dotClass: "bg-emerald-500" },
|
||||
{ id: "lost", label: "Perso", headerClass: "text-red-700 dark:text-red-400", dotClass: "bg-red-400 dark:bg-red-500" },
|
||||
{ id: "contacted", label: "Contattato" },
|
||||
{ id: "qualified", label: "Qualificato" },
|
||||
{ id: "proposal_sent", label: "Offerta inviata" },
|
||||
{ id: "negotiating", label: "Trattativa" },
|
||||
{ id: "won", label: "Vinto" },
|
||||
{ id: "lost", label: "Perso" },
|
||||
];
|
||||
|
||||
const VALID_STAGES = LEAD_COLUMNS.map((c) => c.id) as string[];
|
||||
|
||||
function DroppableColumn({
|
||||
id, label, headerClass, dotClass, leads, activeId,
|
||||
id, label, leads, activeId,
|
||||
}: {
|
||||
id: LeadStage;
|
||||
label: string;
|
||||
headerClass: string;
|
||||
dotClass: string;
|
||||
leads: LeadWithTags[];
|
||||
activeId: string | null;
|
||||
}) {
|
||||
@@ -50,21 +46,18 @@ function DroppableColumn({
|
||||
return (
|
||||
<div
|
||||
ref={setNodeRef}
|
||||
className={`flex flex-col rounded-xl border p-4 transition-colors ${
|
||||
isOver ? "border-primary bg-primary/5" : "border-border bg-muted/60"
|
||||
} min-h-[240px]`}
|
||||
className={`w-[280px] shrink-0 flex flex-col gap-4 rounded-xl border p-4 transition-colors min-h-[420px] ${
|
||||
isOver ? "border-primary bg-primary/5" : "border-border-light bg-muted/60"
|
||||
}`}
|
||||
>
|
||||
<div className={`flex items-center justify-between pb-2 mb-2 border-b border-border ${headerClass}`}>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`w-2 h-2 rounded-full ${dotClass}`} />
|
||||
<span className="text-xs font-bold uppercase tracking-wider">{label}</span>
|
||||
</div>
|
||||
<span className="text-xs font-semibold tabular-nums bg-card rounded-full px-2 py-0.5 border border-border text-muted-foreground">
|
||||
<div className="flex items-center justify-between border-b border-border-light pb-2">
|
||||
<span className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">{label}</span>
|
||||
<span className="text-xs font-medium tabular-nums bg-secondary text-muted-foreground px-2 py-0.5 rounded-full">
|
||||
{leads.length}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 space-y-2">
|
||||
<div className="flex-1 flex flex-col gap-2">
|
||||
{leads.map((lead) => (
|
||||
<DraggableLeadCard key={lead.id} lead={lead} status={id} isActive={activeId === lead.id} />
|
||||
))}
|
||||
@@ -99,23 +92,21 @@ function DraggableLeadCard({
|
||||
style={style}
|
||||
{...listeners}
|
||||
{...attributes}
|
||||
className={`bg-card rounded-lg border border-border px-3 py-2.5 cursor-grab active:cursor-grabbing shadow-sm select-none transition-all duration-200 ${
|
||||
className={`bg-card p-4 rounded-lg border border-border shadow-sm cursor-grab active:cursor-grabbing select-none transition-all duration-200 ${
|
||||
isDragging ? "opacity-30" : "hover:border-primary/30 hover:shadow-card-hover"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<p className="text-sm font-medium text-foreground">{lead.name}</p>
|
||||
<div className="flex justify-between items-start gap-2 mb-2">
|
||||
<p className="text-xs font-semibold text-foreground">{lead.name}</p>
|
||||
<StatusBadge status={status} className="rounded px-1.5 py-0.5 text-[9px]" />
|
||||
</div>
|
||||
{lead.email && (
|
||||
<p className="text-xs text-muted-foreground mt-0.5 line-clamp-1">{lead.email}</p>
|
||||
)}
|
||||
{lead.company && (
|
||||
<p className="text-xs text-muted-foreground mt-1">{lead.company}</p>
|
||||
)}
|
||||
{lead.next_action && (
|
||||
<p className="text-xs text-muted-foreground mt-1 line-clamp-1">{lead.next_action}</p>
|
||||
<p className="text-[11px] text-muted-foreground mb-3 line-clamp-1">{lead.email}</p>
|
||||
)}
|
||||
<div className="flex justify-between items-center text-[10px] text-muted-foreground">
|
||||
<span className="font-medium">{lead.company ?? ""}</span>
|
||||
<span>Tag +</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -171,7 +162,7 @@ export function LeadsKanbanBoard({ leads }: { leads: LeadWithTags[] }) {
|
||||
onDragEnd={handleDragEnd}
|
||||
>
|
||||
<div className="overflow-x-auto">
|
||||
<div className="grid grid-cols-6 gap-3 min-w-[1080px]">
|
||||
<div className="flex gap-4">
|
||||
{LEAD_COLUMNS.map((col) => (
|
||||
<DroppableColumn
|
||||
key={col.id}
|
||||
@@ -185,10 +176,10 @@ export function LeadsKanbanBoard({ leads }: { leads: LeadWithTags[] }) {
|
||||
|
||||
<DragOverlay dropAnimation={null}>
|
||||
{activeLead && (
|
||||
<div className="bg-card rounded-lg border-2 border-primary px-3 py-2.5 shadow-xl rotate-1 pointer-events-none">
|
||||
<p className="text-sm font-medium text-foreground">{activeLead.name}</p>
|
||||
<div className="bg-card rounded-lg border-2 border-primary p-4 shadow-xl rotate-1 pointer-events-none">
|
||||
<p className="text-xs font-semibold text-foreground mb-2">{activeLead.name}</p>
|
||||
{activeLead.company && (
|
||||
<p className="text-xs text-muted-foreground">{activeLead.company}</p>
|
||||
<p className="text-[10px] text-muted-foreground font-medium">{activeLead.company}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user