64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
|
|
'use client';
|
||
|
|
|
||
|
|
import { useDroppable } from '@dnd-kit/core';
|
||
|
|
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
||
|
|
|
||
|
|
import { PipelineCard } from '@/components/interests/pipeline-card';
|
||
|
|
import { Badge } from '@/components/ui/badge';
|
||
|
|
|
||
|
|
interface ColumnItem {
|
||
|
|
id: string;
|
||
|
|
clientName: string | null;
|
||
|
|
berthMooringNumber: string | null;
|
||
|
|
leadCategory: string | null;
|
||
|
|
updatedAt: string | Date;
|
||
|
|
}
|
||
|
|
|
||
|
|
interface PipelineColumnProps {
|
||
|
|
stage: string;
|
||
|
|
label: string;
|
||
|
|
items: ColumnItem[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export function PipelineColumn({ stage, label, items }: PipelineColumnProps) {
|
||
|
|
const { setNodeRef, isOver } = useDroppable({ id: stage });
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
ref={setNodeRef}
|
||
|
|
className={`flex flex-col gap-2 min-w-[220px] w-[220px] flex-shrink-0 bg-muted/40 rounded-lg p-3 transition-colors ${
|
||
|
|
isOver ? 'bg-muted/70 ring-2 ring-primary/30' : ''
|
||
|
|
}`}
|
||
|
|
>
|
||
|
|
<div className="flex items-center justify-between mb-1">
|
||
|
|
<span className="text-sm font-semibold capitalize">{label}</span>
|
||
|
|
<Badge variant="outline" className="text-xs">
|
||
|
|
{items.length}
|
||
|
|
</Badge>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="flex flex-col gap-2 overflow-y-auto max-h-[calc(100vh-220px)]">
|
||
|
|
<SortableContext
|
||
|
|
items={items.map((i) => i.id)}
|
||
|
|
strategy={verticalListSortingStrategy}
|
||
|
|
>
|
||
|
|
{items.map((item) => (
|
||
|
|
<PipelineCard
|
||
|
|
key={item.id}
|
||
|
|
id={item.id}
|
||
|
|
clientName={item.clientName}
|
||
|
|
berthMooringNumber={item.berthMooringNumber}
|
||
|
|
leadCategory={item.leadCategory}
|
||
|
|
updatedAt={item.updatedAt}
|
||
|
|
/>
|
||
|
|
))}
|
||
|
|
</SortableContext>
|
||
|
|
|
||
|
|
{items.length === 0 && (
|
||
|
|
<div className="text-center py-6 text-xs text-muted-foreground">Empty</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|