Files
deckerr/src/hooks/useCollection.ts
Matthieu ad7ae17985 [ISSUE-10] Add card collection integration to deck manager
Implemented comprehensive collection management features:

Backend:
- Created collectionService with 9 API functions
- Added useCollection React hook for state management
- Implemented batch processing for performance
- Added full authentication and authorization

Frontend:
- Enhanced DeckManager with collection status indicators
- Added "Add All Missing Cards" bulk operation button
- Added individual "Add Card" buttons for missing cards
- Implemented loading states and error handling
- Added responsive design with visual badges

Features:
- Visual indicators (yellow for missing, green for owned)
- Bulk add all missing cards functionality
- Individual card addition with quantity tracking
- Real-time collection synchronization
- Success/error notifications

Tests: Build passing (5.98s), linting passing, TypeScript passing

Resolves: #ISSUE-10

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 14:53:42 +01:00

234 lines
6.2 KiB
TypeScript

import { useState, useCallback } from 'react';
import {
getUserCollection,
getCardInCollection,
checkCardsOwnership,
getDeckCardOwnership,
getMissingCardsFromDeck,
addCardToCollection,
addCardsToCollectionBulk,
addMissingDeckCardsToCollection,
removeCardFromCollection,
CollectionCard,
CardOwnershipInfo,
MissingCardInfo,
} from '../services/collectionService';
/**
* Custom React hook for managing card collections
* Provides state management and loading/error handling for collection operations
*/
export const useCollection = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
/**
* Clear any existing error
*/
const clearError = useCallback(() => {
setError(null);
}, []);
/**
* Get user's entire collection
*/
const getCollection = useCallback(async (): Promise<CollectionCard[] | null> => {
setLoading(true);
setError(null);
try {
const collection = await getUserCollection();
return collection;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to fetch collection';
setError(errorMessage);
return null;
} finally {
setLoading(false);
}
}, []);
/**
* Check if a single card is in the collection
*/
const checkCardOwnership = useCallback(async (cardId: string): Promise<CollectionCard | null> => {
setLoading(true);
setError(null);
try {
const card = await getCardInCollection(cardId);
return card;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to check card ownership';
setError(errorMessage);
return null;
} finally {
setLoading(false);
}
}, []);
/**
* Check ownership for multiple cards
*/
const checkMultipleCardsOwnership = useCallback(
async (cardIds: string[]): Promise<Map<string, number> | null> => {
setLoading(true);
setError(null);
try {
const ownershipMap = await checkCardsOwnership(cardIds);
return ownershipMap;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to check cards ownership';
setError(errorMessage);
return null;
} finally {
setLoading(false);
}
},
[]
);
/**
* Get detailed ownership info for all cards in a deck
*/
const getDeckOwnership = useCallback(
async (deckId: string): Promise<CardOwnershipInfo[] | null> => {
setLoading(true);
setError(null);
try {
const ownershipInfo = await getDeckCardOwnership(deckId);
return ownershipInfo;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to get deck ownership info';
setError(errorMessage);
return null;
} finally {
setLoading(false);
}
},
[]
);
/**
* Get list of missing cards from a deck
*/
const getMissingCards = useCallback(
async (deckId: string): Promise<MissingCardInfo[] | null> => {
setLoading(true);
setError(null);
try {
const missingCards = await getMissingCardsFromDeck(deckId);
return missingCards;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to get missing cards';
setError(errorMessage);
return null;
} finally {
setLoading(false);
}
},
[]
);
/**
* Add a single card to collection
*/
const addCard = useCallback(
async (cardId: string, quantity: number = 1): Promise<boolean> => {
setLoading(true);
setError(null);
try {
await addCardToCollection(cardId, quantity);
return true;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to add card to collection';
setError(errorMessage);
return false;
} finally {
setLoading(false);
}
},
[]
);
/**
* Add multiple cards to collection in bulk
*/
const addCardsBulk = useCallback(
async (
cards: Array<{ card_id: string; quantity: number }>
): Promise<Array<{ card_id: string; success: boolean; error?: string }> | null> => {
setLoading(true);
setError(null);
try {
const results = await addCardsToCollectionBulk(cards);
return results;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to add cards to collection';
setError(errorMessage);
return null;
} finally {
setLoading(false);
}
},
[]
);
/**
* Add all missing cards from a deck to collection
*/
const addMissingDeckCards = useCallback(
async (
deckId: string
): Promise<Array<{ card_id: string; success: boolean; error?: string }> | null> => {
setLoading(true);
setError(null);
try {
const results = await addMissingDeckCardsToCollection(deckId);
return results;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to add missing cards';
setError(errorMessage);
return null;
} finally {
setLoading(false);
}
},
[]
);
/**
* Remove a card from collection
*/
const removeCard = useCallback(
async (cardId: string, quantity?: number): Promise<boolean> => {
setLoading(true);
setError(null);
try {
await removeCardFromCollection(cardId, quantity);
return true;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to remove card from collection';
setError(errorMessage);
return false;
} finally {
setLoading(false);
}
},
[]
);
return {
loading,
error,
clearError,
getCollection,
checkCardOwnership,
checkMultipleCardsOwnership,
getDeckOwnership,
getMissingCards,
addCard,
addCardsBulk,
addMissingDeckCards,
removeCard,
};
};