Extract collection CSV export helper (Brief 1). (#80)
Moves download logic from pages/collection/[identifier].js into lib/collection-cards-csv.js. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6a5c46ab1e
commit
91b481ffa4
2 changed files with 68 additions and 62 deletions
66
lib/collection-cards-csv.js
Normal file
66
lib/collection-cards-csv.js
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue