deckhearth/lib/use-deck-detail.js

75 lines
2 KiB
JavaScript
Raw Normal View History

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,
};
}