diff --git a/lib/collection-cards-csv.js b/lib/collection-cards-csv.js new file mode 100644 index 0000000..42aeb5e --- /dev/null +++ b/lib/collection-cards-csv.js @@ -0,0 +1,66 @@ +/** + * Build and trigger a browser download of collection cards as CSV. + */ +export function downloadCollectionCardsCsv(cards, collectionName) { + if (cards.length === 0) { + alert('No cards to download'); + return; + } + + const headers = [ + 'Name', + 'Set Name', + 'Set Code', + 'Card Number', + 'Rarity', + 'Game', + 'Mana Cost', + 'CMC', + 'Type', + 'Colors', + 'Oracle Text', + 'Power', + 'Toughness', + 'Market Price', + 'Quantity', + 'Added Date', + ]; + + const csvRows = [ + headers.join(','), + ...cards.map((card) => + [ + `"${(card.name || '').replace(/"/g, '""')}"`, + `"${(card.set_name || '').replace(/"/g, '""')}"`, + `"${card.set_code || ''}"`, + `"${card.card_number || ''}"`, + `"${card.rarity || ''}"`, + `"${card.game || ''}"`, + `"${card.mana_cost || ''}"`, + `"${card.cmc || ''}"`, + `"${card.card_type || ''}"`, + `"${Array.isArray(card.colors) ? card.colors.join(', ') : card.colors || ''}"`, + `"${(card.oracle_text || '').replace(/"/g, '""')}"`, + `"${card.power || ''}"`, + `"${card.toughness || ''}"`, + `"${card.market_price || ''}"`, + `"${card.quantity || 1}"`, + `"${card.created_at ? new Date(card.created_at).toLocaleDateString() : ''}"`, + ].join(',') + ), + ]; + + const csvContent = csvRows.join('\n'); + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const link = document.createElement('a'); + + if (link.download !== undefined) { + const url = URL.createObjectURL(blob); + link.setAttribute('href', url); + link.setAttribute('download', `${collectionName || 'collection'}_cards.csv`); + link.style.visibility = 'hidden'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } +} diff --git a/pages/collection/[identifier].js b/pages/collection/[identifier].js index af9d411..58c3301 100644 --- a/pages/collection/[identifier].js +++ b/pages/collection/[identifier].js @@ -12,6 +12,7 @@ import { ManaCost, ColorFilterSymbol } from '../../components/ManaSymbols'; import ManaSymbolSettings from '../../components/ManaSymbolSettings'; import { useAuth } from '../../lib/use-auth'; import { VOCAB, collectionDisplayName } from '../../lib/collection-vocabulary.js'; +import { downloadCollectionCardsCsv } from '../../lib/collection-cards-csv.js'; export default function CollectionView() { const router = useRouter(); @@ -424,68 +425,7 @@ export default function CollectionView() { }; const handleDownloadCSV = () => { - if (cards.length === 0) { - alert('No cards to download'); - return; - } - - // Create CSV headers - const headers = [ - 'Name', - 'Set Name', - 'Set Code', - 'Card Number', - 'Rarity', - 'Game', - 'Mana Cost', - 'CMC', - 'Type', - 'Colors', - 'Oracle Text', - 'Power', - 'Toughness', - 'Market Price', - 'Quantity', - 'Added Date' - ]; - - // Create CSV rows - const csvRows = [ - headers.join(','), // Header row - ...cards.map(card => [ - `"${(card.name || '').replace(/"/g, '""')}"`, - `"${(card.set_name || '').replace(/"/g, '""')}"`, - `"${card.set_code || ''}"`, - `"${card.card_number || ''}"`, - `"${card.rarity || ''}"`, - `"${card.game || ''}"`, - `"${card.mana_cost || ''}"`, - `"${card.cmc || ''}"`, - `"${card.card_type || ''}"`, - `"${Array.isArray(card.colors) ? card.colors.join(', ') : (card.colors || '')}"`, - `"${(card.oracle_text || '').replace(/"/g, '""')}"`, - `"${card.power || ''}"`, - `"${card.toughness || ''}"`, - `"${card.market_price || ''}"`, - `"${card.quantity || 1}"`, - `"${card.created_at ? new Date(card.created_at).toLocaleDateString() : ''}"` - ].join(',')) - ]; - - // Create and download the CSV file - const csvContent = csvRows.join('\n'); - const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); - const link = document.createElement('a'); - - if (link.download !== undefined) { - const url = URL.createObjectURL(blob); - link.setAttribute('href', url); - link.setAttribute('download', `${collection.name || 'collection'}_cards.csv`); - link.style.visibility = 'hidden'; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - } + downloadCollectionCardsCsv(cards, collection?.name); }; // Group cards by game