🔄 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
|
// Initial load
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPagination(prev => ({ ...prev, page: 1 }));
|
setPagination(prev => ({ ...prev, page: 1 }));
|
||||||
|
|
@ -112,6 +134,7 @@ export default function Cards() {
|
||||||
setHasMore(true);
|
setHasMore(true);
|
||||||
hasMoreRef.current = true;
|
hasMoreRef.current = true;
|
||||||
fetchCards(false);
|
fetchCards(false);
|
||||||
|
loadFavoritedCards(); // Load user's favorites
|
||||||
}, [selectedTCG, selectedRarity, selectedSet, selectedValueRange]);
|
}, [selectedTCG, selectedRarity, selectedSet, selectedValueRange]);
|
||||||
|
|
||||||
// Handle search with debounce
|
// Handle search with debounce
|
||||||
|
|
@ -369,14 +392,88 @@ export default function Cards() {
|
||||||
alert(`Adding ${cards.length} cards to deck (functionality coming soon)`);
|
alert(`Adding ${cards.length} cards to deck (functionality coming soon)`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBulkMarkAsOwned = (cards) => {
|
const handleBulkMarkAsOwned = async (cards) => {
|
||||||
console.log('Marking as owned:', cards);
|
try {
|
||||||
alert(`Marking ${cards.length} cards as owned (functionality coming soon)`);
|
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) => {
|
const handleBulkRemoveFromOwned = async (cards) => {
|
||||||
console.log('Removing from owned:', cards);
|
try {
|
||||||
alert(`Removing ${cards.length} cards from owned (functionality coming soon)`);
|
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) => {
|
const handleBulkFavorite = async (cards) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue