/**
* EXAMPLE FILE - Collection Integration Examples
*
* This file demonstrates how to integrate the collection service
* into your components. These are complete, working examples that
* can be used as templates for implementing the collection features.
*
* DO NOT DELETE - Reference for frontend integration
*/
import React, { useState, useEffect } from 'react';
import { useCollection } from '../hooks/useCollection';
import { CardOwnershipInfo, MissingCardInfo } from '../services/collectionService';
import { Card } from '../types';
import { Plus, CheckCircle, AlertCircle } from 'lucide-react';
/**
* Example 1: Display Missing Cards Badge
* Shows a badge indicating how many cards are missing from collection
*/
export function MissingCardsBadge({ deckId }: { deckId: string }) {
const { getMissingCards, loading } = useCollection();
const [missingCount, setMissingCount] = useState(0);
useEffect(() => {
const fetchMissing = async () => {
const missing = await getMissingCards(deckId);
if (missing) {
setMissingCount(missing.length);
}
};
fetchMissing();
}, [deckId, getMissingCards]);
if (loading) return ...;
return missingCount > 0 ? (
{missingCount} cards missing
) : (
Complete
);
}
/**
* Example 2: Card Ownership Indicator
* Shows whether a specific card is owned and in what quantity
*/
interface CardOwnershipIndicatorProps {
cardId: string;
quantityNeeded: number;
}
export function CardOwnershipIndicator({ cardId, quantityNeeded }: CardOwnershipIndicatorProps) {
const { checkCardOwnership } = useCollection();
const [owned, setOwned] = useState(0);
useEffect(() => {
const check = async () => {
const card = await checkCardOwnership(cardId);
setOwned(card?.quantity || 0);
};
check();
}, [cardId, checkCardOwnership]);
const hasEnough = owned >= quantityNeeded;
return (
{hasEnough ?
:
}
{owned} / {quantityNeeded} owned
);
}
/**
* Example 3: Add Single Card Button
* Button to add a specific card to collection
*/
interface AddCardButtonProps {
cardId: string;
cardName: string;
quantity?: number;
onSuccess?: () => void;
}
export function AddCardButton({ cardId, cardName, quantity = 1, onSuccess }: AddCardButtonProps) {
const { addCard, loading, error, clearError } = useCollection();
const handleAdd = async () => {
clearError();
const success = await addCard(cardId, quantity);
if (success) {
alert(`Added ${quantity}x ${cardName} to collection!`);
onSuccess?.();
}
};
return (
{error &&
{error}
}
);
}
/**
* Example 4: Add All Missing Cards Button
* Button to add all missing cards from a deck to collection
*/
export function AddAllMissingCardsButton({ deckId, onSuccess }: { deckId: string; onSuccess?: () => void }) {
const { addMissingDeckCards, loading, error, clearError } = useCollection();
const [lastResult, setLastResult] = useState(null);
const handleAddAll = async () => {
clearError();
setLastResult(null);
const results = await addMissingDeckCards(deckId);
if (results) {
const successCount = results.filter(r => r.success).length;
const failCount = results.filter(r => !r.success).length;
let message = `Added ${successCount} cards to collection`;
if (failCount > 0) {
message += `, ${failCount} failed`;
}
setLastResult(message);
if (successCount > 0) {
onSuccess?.();
}
}
};
return (
{lastResult &&
{lastResult}
}
{error &&
{error}
}
);
}
/**
* Example 5: Deck Card List with Collection Status
* Shows all cards in a deck with their collection status
*/
interface DeckCardWithStatusProps {
deckId: string;
cards: Array<{ card: Card; quantity: number }>;
}
export function DeckCardListWithStatus({ deckId, cards }: DeckCardWithStatusProps) {
const { getDeckOwnership, loading } = useCollection();
const [ownership, setOwnership] = useState([]);
useEffect(() => {
const fetchOwnership = async () => {
const data = await getDeckOwnership(deckId);
if (data) setOwnership(data);
};
fetchOwnership();
}, [deckId, getDeckOwnership]);
if (loading) {
return Loading collection status...
;
}
const ownershipMap = new Map(ownership.map(o => [o.card_id, o]));
return (
{cards.map(({ card, quantity }) => {
const status = ownershipMap.get(card.id);
const isOwned = status?.owned || false;
const quantityOwned = status?.quantity_in_collection || 0;
const quantityNeeded = status?.quantity_needed || 0;
return (
{card.name}
Need: {quantity} | Owned: {quantityOwned}
{isOwned ? (
Complete
) : (
<>
Need {quantityNeeded} more
>
)}
);
})}
);
}
/**
* Example 6: Bulk Add with Preview
* Shows missing cards and allows bulk add with preview
*/
export function BulkAddWithPreview({ deckId }: { deckId: string }) {
const { getMissingCards, addCardsBulk, loading, error } = useCollection();
const [missingCards, setMissingCards] = useState([]);
const [showPreview, setShowPreview] = useState(false);
useEffect(() => {
const fetchMissing = async () => {
const missing = await getMissingCards(deckId);
if (missing) setMissingCards(missing);
};
fetchMissing();
}, [deckId, getMissingCards]);
const handleBulkAdd = async () => {
const cardsToAdd = missingCards.map(card => ({
card_id: card.card_id,
quantity: card.quantity_needed,
}));
const results = await addCardsBulk(cardsToAdd);
if (results) {
const successCount = results.filter(r => r.success).length;
alert(`Successfully added ${successCount} cards to collection!`);
setMissingCards([]);
setShowPreview(false);
}
};
if (missingCards.length === 0) {
return (
All cards from this deck are in your collection!
);
}
return (
Missing Cards: {missingCards.length}
{showPreview && (
{missingCards.map(card => (
{card.card_id}
Need {card.quantity_needed} (have {card.quantity_in_collection})
))}
)}
{error && (
{error}
)}
);
}
/**
* Example 7: Complete Deck Editor Integration
* Full example of a deck editor with collection integration
*/
interface CompleteDeckEditorExampleProps {
deckId: string;
deckName: string;
cards: Array<{ card: Card; quantity: number }>;
}
export function CompleteDeckEditorExample({ deckId, deckName, cards }: CompleteDeckEditorExampleProps) {
const { getDeckOwnership, addMissingDeckCards, loading } = useCollection();
const [ownership, setOwnership] = useState([]);
const [refreshKey, setRefreshKey] = useState(0);
useEffect(() => {
const fetchOwnership = async () => {
const data = await getDeckOwnership(deckId);
if (data) setOwnership(data);
};
fetchOwnership();
}, [deckId, getDeckOwnership, refreshKey]);
const handleRefresh = () => setRefreshKey(prev => prev + 1);
const missingCount = ownership.filter(o => !o.owned).length;
const totalCards = cards.length;
const ownedCount = totalCards - missingCount;
const completionPercent = totalCards > 0 ? Math.round((ownedCount / totalCards) * 100) : 0;
return (
{/* Header with stats */}
{deckName}
{/* Progress bar */}
{/* Action buttons */}
{missingCount > 0 && (
)}
{/* Card list */}
);
}