/* eslint-disable @next/next/no-img-element -- External card image URLs; next/image migration is out of scope. */ import { useState, useEffect } from 'react'; import { VOCAB } from '../lib/collection-vocabulary.js'; export default function CollectionSelectionModal({ isOpen, onClose, cards, // Array of cards to add onAddToCollections }) { const [collections, setCollections] = useState([]); const [selectedCollections, setSelectedCollections] = useState([]); const [loading, setLoading] = useState(false); const [submitting, setSubmitting] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [prevIsOpen, setPrevIsOpen] = useState(isOpen); if (isOpen && !prevIsOpen) { setPrevIsOpen(true); setSelectedCollections([]); setSearchQuery(''); } else if (!isOpen && prevIsOpen) { setPrevIsOpen(false); } useEffect(() => { if (!isOpen) return; const fetchCollections = async () => { setLoading(true); try { const response = await fetch('/api/collections?excludeSystem=true'); if (response.ok) { const data = await response.json(); // The API returns an array directly, not wrapped in collections property setCollections(Array.isArray(data) ? data : data.collections || []); } else { console.error('Failed to fetch collections:', response.status, response.statusText); setCollections([]); } } catch (error) { console.error('Error fetching collections:', error); setCollections([]); } finally { setLoading(false); } }; fetchCollections(); }, [isOpen]); const handleCollectionToggle = (collectionId) => { setSelectedCollections(prev => { if (prev.includes(collectionId)) { return prev.filter(id => id !== collectionId); } else { return [...prev, collectionId]; } }); }; const handleSelectAll = () => { const filteredCollections = getFilteredCollections(); const allSelected = filteredCollections.every(collection => selectedCollections.includes(collection.id) ); if (allSelected) { // Deselect all filtered collections setSelectedCollections(prev => prev.filter(id => !filteredCollections.some(c => c.id === id)) ); } else { // Select all filtered collections const newSelections = filteredCollections .filter(collection => !selectedCollections.includes(collection.id)) .map(collection => collection.id); setSelectedCollections(prev => [...prev, ...newSelections]); } }; const getFilteredCollections = () => { if (!searchQuery.trim()) return collections; return collections.filter(collection => collection.name.toLowerCase().includes(searchQuery.toLowerCase()) || collection.description?.toLowerCase().includes(searchQuery.toLowerCase()) ); }; const handleSubmit = async () => { if (selectedCollections.length === 0) return; setSubmitting(true); try { const results = []; // Add cards to each selected collection for (const collectionId of selectedCollections) { for (const card of cards) { const response = await fetch(`/api/collections/${collectionId}/cards`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ cardId: card.id, quantity: 1 }) }); if (response.ok) { results.push({ collectionId, cardId: card.id, success: true }); } else { results.push({ collectionId, cardId: card.id, success: false }); } } } // Call callback with results onAddToCollections(results, selectedCollections, cards); onClose(); } catch (error) { console.error('Error adding cards to collections:', error); } finally { setSubmitting(false); } }; const filteredCollections = getFilteredCollections(); const allFilteredSelected = filteredCollections.length > 0 && filteredCollections.every(collection => selectedCollections.includes(collection.id)); if (!isOpen) return null; return (
{cards.length} card{cards.length !== 1 ? 's' : ''} selected
Choose lists to add {cards.length === 1 ? 'this card' : 'these cards'} to
Loading lists...
{searchQuery ? 'No lists match your search' : 'No lists found'}
{searchQuery ? 'Try a different search term' : 'Create your first list to get started'}
{collection.description}
)}