kanban-app/frontend/src/components/kanban/KanbanColumn.tsx

73 lines
2.4 KiB
TypeScript
Raw Normal View History

import { useDroppable } from '@dnd-kit/core';
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { ListWithCards, Card as CardType } from '../../types/kanban';
import { KanbanCard } from './KanbanCard';
2026-02-27 07:53:36 +00:00
import { CreateCardModal } from './CreateCardModal';
import { useModal } from '../../context/modals/useModal';
interface KanbanColumnProps {
list: ListWithCards;
cards: CardType[];
2026-02-27 19:25:34 +00:00
onOpenCardModal: (card: CardType) => void;
2026-02-27 07:53:36 +00:00
onCardCreate: (data: { name: string; description?: string }) => Promise<void>;
}
2026-02-27 19:25:34 +00:00
export function KanbanColumn({ list, cards, onOpenCardModal, onCardCreate }: KanbanColumnProps) {
const { setNodeRef, isOver } = useDroppable({
2026-02-27 07:53:36 +00:00
id: `LIST_${list.id}`,
});
2026-02-27 07:53:36 +00:00
const { openModal } = useModal();
const handleAddCard = () => {
openModal((props) => <CreateCardModal {...props} onCreate={onCardCreate} />);
};
return (
2026-02-27 07:53:36 +00:00
<div className="bg-gray-800 rounded-lg p-4 min-w-[300px] max-w-[300px] border border-gray-700 flex flex-col">
<h2 className="text-white font-bold text-lg mb-4 flex items-center justify-between">
{list.name}
<span className="bg-gray-600 text-gray-300 text-xs px-2 py-1 rounded-full">
{cards.length}
</span>
</h2>
<SortableContext
id={list.id.toString()}
items={cards.map((card) => card.id.toString())}
strategy={verticalListSortingStrategy}
>
<div
ref={setNodeRef}
2026-02-27 07:53:36 +00:00
className={`min-h-[200px] flex-1 transition-colors ${isOver ? 'bg-gray-750' : ''}`}
>
{cards.map((card) => (
2026-02-27 19:25:34 +00:00
<KanbanCard key={card.id} card={card} onOpenModal={() => onOpenCardModal(card)} />
))}
</div>
</SortableContext>
2026-02-27 07:53:36 +00:00
<button
onClick={handleAddCard}
className="mt-3 w-full py-2 px-4 bg-gray-700 hover:bg-gray-600 text-gray-300 hover:text-white rounded-lg transition-colors flex items-center justify-center gap-2 text-sm font-medium"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<line x1="12" y1="5" x2="12" y2="19"></line>
<line x1="5" y1="12" x2="19" y2="12"></line>
</svg>
Add Card
</button>
</div>
);
}