import { useParams, Link, useNavigate } from 'react-router-dom'; import { useBoard } from '../hooks/useBoard'; import { useCardMutations } from '../hooks/useCardMutations'; import { useListMutations } from '../hooks/useListMutations'; import { KanbanColumn } from '../components/kanban/KanbanColumn'; import { CreateListModal } from '../components/kanban/CreateListModal'; import { useModal } from '../context/modals/useModal'; import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, DragOverEvent, PointerSensor, useSensor, useSensors, closestCenter, } from '@dnd-kit/core'; import { Card as CardType } from '../types/kanban'; import { useState } from 'react'; export function BoardDetail() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const { board, fetchBoard } = useBoard(parseInt(id || '0')); const { createCard, moveCard } = useCardMutations(parseInt(id || '0'), fetchBoard); const { createList } = useListMutations(parseInt(id || '0'), fetchBoard); const { openModal } = useModal(); const [activeCard, setActiveCard] = useState(null); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 8, }, }) ); const handleDragStart = (event: DragStartEvent) => { const { active } = event; const activeIdStr = (active.id as string).split('_')[1]; const cardId = parseInt(activeIdStr as string); if (board) { const card = board.lists.flatMap((list) => list.cards).find((c) => c.id === cardId); // console.log('---handleDragStart', event, card) // console.log('---handleDragStart.board', board) if (card) { setActiveCard(card); } } }; const handleDragOver = (event: DragOverEvent) => { const { active, over } = event; console.log('---handleDragOver', event); if (!over) return; // const activeId = parseInt(active.id as string); // const overId = parseInt(over.id as string); const overIdStr = (over.id as string).split('_')[1]; const overId = parseInt(overIdStr, 10); const activeIdStr = (active.id as string).split('_')[1]; const activeId = parseInt(activeIdStr, 10); if (activeId === overId) return; // Find active card and its current list if (!board) return; const activeList = board.lists.find((list) => list.cards.some((card) => card.id === activeId)); // If we're hovering over a card in same list, do nothing if (activeList) { const overCard = activeList.cards.find((card) => card.id === overId); if (overCard) return; } }; const handleDragEnd = async (event: DragEndEvent) => { const { active, over } = event; setActiveCard(null); if (!over || !board) return; // console.log('--------------over', over) // console.log('--------------board', board) const [overType, overIdStr] = (over.id as string).split('_'); const overId = parseInt(overIdStr, 10); const activeIdStr = (active.id as string).split('_')[1]; const activeId = parseInt(activeIdStr, 10); // debugger if (active.id === over.id) return; // Find active card let activeCard: CardType | undefined; let activeList: (typeof board.lists)[0] | undefined; for (const list of board.lists) { const card = list.cards.find((c) => c.id === activeId); if (card) { activeCard = card; activeList = list; break; } } if (!activeCard || !activeList) return; // Check if we're dropping on a list or a card // debugger if (overType.toLocaleLowerCase() === 'list') { const overList = board.lists.find((list) => list.id === overId); // Dropping on a list - append to end if (!overList || overList.id === activeList.id) return; // Same list, do nothing await moveCard(activeCard, activeList.id, overList.id, overList.cards.length); return; } // Dropping on a card - find which list it belongs to let overCard: CardType | undefined; let overListContainingCard: (typeof board.lists)[0] | undefined; for (const list of board.lists) { const card = list.cards.find((c) => c.id === overId); if (card) { overCard = card; overListContainingCard = list; break; } } if (!overCard || !overListContainingCard) return; // Calculate new position const overCardIndex = overListContainingCard.cards.findIndex((c) => c.id === overId); // If dropping on to same list and after of same card, do nothing if ( overListContainingCard.id === activeList.id && overCardIndex === activeList.cards.findIndex((c) => c.id === activeId) + 1 ) { return; } await moveCard(activeCard, activeList.id, overListContainingCard.id, overCardIndex); }; const handleCardClick = (card: CardType) => { navigate(`/boards/${id}/cards/${card.id}`); }; const handleAddList = () => { openModal((props) => ( { await createList(name, board ? board.lists.length : 0); fetchBoard(); // Refresh board data }} /> )); }; const handleAddCard = (listId: number) => async (data: { name: string; description?: string }) => { await createCard(listId, { name: data.name, description: data.description, pos: board ? board.lists.find((list) => list.id === listId)?.cards.length || 0 : 0, }); fetchBoard(); // Refresh board data }; if (!board) { return
Loading...
; } return (
← Back to Boards

{board.name}

{board.description &&

{board.description}

}
Edit Board
{board.lists.map((list) => ( ))}
{activeCard ? (

{activeCard.name}

) : null}
); }