75 lines
2 KiB
JavaScript
75 lines
2 KiB
JavaScript
|
|
import { useState, useEffect, useMemo } from 'react';
|
||
|
|
import { useRouter } from 'next/router';
|
||
|
|
import { computeDeckStats } from './deck-builder-stats.js';
|
||
|
|
import { groupDeckCards } from './deck-detail-grouping.js';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Deck detail page state and derived data (god-component split).
|
||
|
|
*/
|
||
|
|
export function useDeckDetail({ user = null, authLoading = true } = {}) {
|
||
|
|
const router = useRouter();
|
||
|
|
const { id: deckId } = router.query;
|
||
|
|
|
||
|
|
const [deck, setDeck] = useState(null);
|
||
|
|
const [loading, setLoading] = useState(true);
|
||
|
|
const [groupBy, setGroupBy] = useState('type');
|
||
|
|
|
||
|
|
const fetchDeck = async () => {
|
||
|
|
try {
|
||
|
|
const token = localStorage.getItem('auth_token');
|
||
|
|
const headers = token ? { Authorization: `Bearer ${token}` } : {};
|
||
|
|
|
||
|
|
const response = await fetch(`/api/decks/${deckId}`, { headers });
|
||
|
|
|
||
|
|
if (response.ok) {
|
||
|
|
const data = await response.json();
|
||
|
|
setDeck(data);
|
||
|
|
} else {
|
||
|
|
console.error('Failed to fetch deck');
|
||
|
|
router.push('/decks');
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error fetching deck:', error);
|
||
|
|
router.push('/decks');
|
||
|
|
} finally {
|
||
|
|
setLoading(false);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
if (deckId) {
|
||
|
|
// eslint-disable-next-line react-hooks/set-state-in-effect -- load deck when route id changes
|
||
|
|
fetchDeck();
|
||
|
|
}
|
||
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- refetch when route deck id changes
|
||
|
|
}, [deckId]);
|
||
|
|
|
||
|
|
const stats = useMemo(
|
||
|
|
() => (deck ? computeDeckStats(deck.cards || []) : null),
|
||
|
|
[deck]
|
||
|
|
);
|
||
|
|
|
||
|
|
const groupedCards = useMemo(
|
||
|
|
() => (deck ? groupDeckCards(deck.cards, groupBy) : {}),
|
||
|
|
[deck, groupBy]
|
||
|
|
);
|
||
|
|
|
||
|
|
const isOwner = Boolean(user && deck && deck.user_id === user.userId);
|
||
|
|
const showDeckLoading = loading;
|
||
|
|
const showDeckNotFound = !loading && !deck;
|
||
|
|
|
||
|
|
return {
|
||
|
|
authLoading,
|
||
|
|
deck,
|
||
|
|
deckId,
|
||
|
|
groupBy,
|
||
|
|
groupedCards,
|
||
|
|
isOwner,
|
||
|
|
setGroupBy,
|
||
|
|
showDeckLoading,
|
||
|
|
showDeckNotFound,
|
||
|
|
stats,
|
||
|
|
user,
|
||
|
|
};
|
||
|
|
}
|