| import { createContext, useContext, useMemo, useState } from "react"; |
| import { api } from "../lib/api"; |
| import { buildCardTree } from "../lib/tree"; |
| const DataContext = createContext(null); |
| export function DataProvider({ children }) { |
| const [cards, setCards] = useState([]); |
| const [entriesByCard, setEntriesByCard] = useState({}); |
| const [loadingCards, setLoadingCards] = useState(false); |
| const [loadingEntries, setLoadingEntries] = useState({}); |
| async function refreshCards() { |
| setLoadingCards(true); |
| try { |
| const { data } = await api.get("/cards"); |
| setCards(data.cards); |
| const entryResponses = await Promise.all( |
| data.cards.map(async (card) => { |
| const result = await api.get(`/cards/${card._id}/entries`); |
| return [card._id, result.data.entries]; |
| }) |
| ); |
| setEntriesByCard(Object.fromEntries(entryResponses)); |
| return data.cards; |
| } finally { |
| setLoadingCards(false); |
| } |
| } |
| async function loadEntries(cardId, silent = false) { |
| if (!cardId) { |
| return []; |
| } |
| if (!silent) { |
| setLoadingEntries((current) => ({ ...current, [cardId]: true })); |
| } |
| try { |
| const { data } = await api.get(`/cards/${cardId}/entries`); |
| setEntriesByCard((current) => ({ ...current, [cardId]: data.entries })); |
| return data.entries; |
| } finally { |
| if (!silent) { |
| setLoadingEntries((current) => ({ ...current, [cardId]: false })); |
| } |
| } |
| } |
| const tree = useMemo(() => buildCardTree(cards), [cards]); |
| const value = useMemo( |
| () => ({ |
| cards, |
| tree, |
| entriesByCard, |
| loadingCards, |
| loadingEntries, |
| refreshCards, |
| loadEntries, |
| setEntriesByCard |
| }), |
| [cards, entriesByCard, loadingCards, loadingEntries, tree] |
| ); |
| return <DataContext.Provider value={value}>{children}</DataContext.Provider>; |
| } |
| export function useData() { |
| return useContext(DataContext); |
| } |
|
|