🔄 Enhanced Cards Page Authentication & Bulk Actions
✅ User Favorites Integration: - Added loadFavoritedCards() function to fetch user's favorited cards on page load - Favorites now properly display across page refreshes - Authentication headers included for favorites API calls 🔧 Bulk Actions Implementation: - Implemented handleBulkMarkAsOwned() with proper API calls - Implemented handleBulkRemoveFromOwned() with ownership removal - Added authentication checks and error handling - Success/failure feedback with clear user messaging - Auto-clear selection after successful operations 🛡️ Authentication Enhancements: - All user-specific operations now require valid JWT tokens - Graceful handling when user is not authenticated - Proper error messaging for auth failures - Individual card actions properly connected to bulk handlers 🎯 User Experience Improvements: - Real-time favorite state management - Bulk operations provide detailed success feedback - Error handling with user-friendly messages - Selection clearing after successful operations The cards page now properly integrates with the secured API system and provides full user-specific functionality! 🃏✨
This commit is contained in:
parent
f36fea8e58
commit
3aeed51448
1 changed files with 103 additions and 6 deletions
109
pages/cards.js
109
pages/cards.js
|
|
@ -105,6 +105,28 @@ export default function Cards() {
|
|||
}
|
||||
};
|
||||
|
||||
// Load user's favorited cards
|
||||
const loadFavoritedCards = async () => {
|
||||
try {
|
||||
const token = localStorage.getItem('auth_token');
|
||||
if (!token) return;
|
||||
|
||||
const response = await fetch('/api/favorites?type=card', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
const favoriteIds = new Set(data.favorites.map(fav => parseInt(fav.item_id)));
|
||||
setFavoritedCards(favoriteIds);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading favorited cards:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Initial load
|
||||
useEffect(() => {
|
||||
setPagination(prev => ({ ...prev, page: 1 }));
|
||||
|
|
@ -112,6 +134,7 @@ export default function Cards() {
|
|||
setHasMore(true);
|
||||
hasMoreRef.current = true;
|
||||
fetchCards(false);
|
||||
loadFavoritedCards(); // Load user's favorites
|
||||
}, [selectedTCG, selectedRarity, selectedSet, selectedValueRange]);
|
||||
|
||||
// Handle search with debounce
|
||||
|
|
@ -369,14 +392,88 @@ export default function Cards() {
|
|||
alert(`Adding ${cards.length} cards to deck (functionality coming soon)`);
|
||||
};
|
||||
|
||||
const handleBulkMarkAsOwned = (cards) => {
|
||||
console.log('Marking as owned:', cards);
|
||||
alert(`Marking ${cards.length} cards as owned (functionality coming soon)`);
|
||||
const handleBulkMarkAsOwned = async (cards) => {
|
||||
try {
|
||||
const token = localStorage.getItem('auth_token');
|
||||
if (!token) {
|
||||
alert('Please log in to mark cards as owned');
|
||||
return;
|
||||
}
|
||||
|
||||
let successCount = 0;
|
||||
for (const card of cards) {
|
||||
try {
|
||||
const response = await fetch(`/api/cards/${card.id}/ownership`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ quantity: 1 })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
successCount++;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error marking card ${card.id} as owned:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
if (successCount === cards.length) {
|
||||
alert(`Successfully marked ${cards.length} cards as owned!`);
|
||||
} else {
|
||||
alert(`Marked ${successCount} out of ${cards.length} cards as owned. Some operations may have failed.`);
|
||||
}
|
||||
|
||||
// Clear selection after successful operation
|
||||
setSelectedCards([]);
|
||||
} catch (error) {
|
||||
console.error('Error in bulk mark as owned:', error);
|
||||
alert('Failed to mark cards as owned. Please try again.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleBulkRemoveFromOwned = (cards) => {
|
||||
console.log('Removing from owned:', cards);
|
||||
alert(`Removing ${cards.length} cards from owned (functionality coming soon)`);
|
||||
const handleBulkRemoveFromOwned = async (cards) => {
|
||||
try {
|
||||
const token = localStorage.getItem('auth_token');
|
||||
if (!token) {
|
||||
alert('Please log in to remove cards from owned');
|
||||
return;
|
||||
}
|
||||
|
||||
let successCount = 0;
|
||||
for (const card of cards) {
|
||||
try {
|
||||
const response = await fetch(`/api/cards/${card.id}/ownership`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ quantity: 0 })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
successCount++;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error removing card ${card.id} from owned:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
if (successCount === cards.length) {
|
||||
alert(`Successfully removed ${cards.length} cards from owned!`);
|
||||
} else {
|
||||
alert(`Removed ${successCount} out of ${cards.length} cards from owned. Some operations may have failed.`);
|
||||
}
|
||||
|
||||
// Clear selection after successful operation
|
||||
setSelectedCards([]);
|
||||
} catch (error) {
|
||||
console.error('Error in bulk remove from owned:', error);
|
||||
alert('Failed to remove cards from owned. Please try again.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleBulkFavorite = async (cards) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue