import { useState, useEffect } from 'react'; import CloseIcon from './icons/CloseIcon'; import { useApi } from '../hooks/useApi'; import { useLoader } from '../context/loaders/useLoader'; import { useToast } from '../context/toasts/useToast'; import type { Card } from '../types/kanban'; interface LinkExistingCardModalProps { boardId: number; currentCardId: number; onClose: () => void; onLinked: () => void; } export function LinkExistingCardModal({ boardId, currentCardId, onClose, onLinked, }: LinkExistingCardModalProps) { const [search, setSearch] = useState(''); const [cards, setCards] = useState([]); const [selectedCardId, setSelectedCardId] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const { getBoard, createCardLink } = useApi(); const { withLoader } = useLoader(); const { addNotification } = useToast(); useEffect(() => { const fetchCards = async () => { try { const board = await getBoard(boardId); const allCards: Card[] = []; for (const list of board.lists) { allCards.push(...list.cards); } // Filter out the current card setCards(allCards.filter((c) => c.id !== currentCardId)); } catch (err) { console.error(err); addNotification({ type: 'error', title: 'Error', message: 'Failed to load board cards', duration: 5000, }); } }; fetchCards(); }, [getBoard, boardId, currentCardId, addNotification]); const filteredCards = cards.filter( (c) => c.name.toLowerCase().includes(search.toLowerCase()) || String(c.id_short || c.id).includes(search) ); const handleLink = async () => { if (!selectedCardId) return; setIsSubmitting(true); try { await withLoader(() => createCardLink(currentCardId, selectedCardId), 'Linking card...'); addNotification({ type: 'success', title: 'Card Linked', message: 'Card linked successfully.', duration: 3000, }); onLinked(); onClose(); } catch (err) { const msg = err instanceof Error ? err.message : 'Failed to link card'; addNotification({ type: 'error', title: 'Error', message: msg, duration: 5000, }); } finally { setIsSubmitting(false); } }; return (

Link Existing Card

setSearch(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg px-3 py-2 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 mb-3" placeholder="Search cards by name or ID..." autoFocus />
{filteredCards.length === 0 && (

No cards found

)} {filteredCards.map((c) => ( ))}
); }