diff --git a/src/pages/lotto/hooks/useBriefing.js b/src/pages/lotto/hooks/useBriefing.js new file mode 100644 index 0000000..a405623 --- /dev/null +++ b/src/pages/lotto/hooks/useBriefing.js @@ -0,0 +1,56 @@ +import { useState, useEffect, useCallback, useRef } from 'react'; +import { getLatestBriefing, triggerLottoCurate } from '../../../api'; + +export default function useBriefing() { + const [briefing, setBriefing] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(''); + const [regenerating, setRegenerating] = useState(false); + const pollingRef = useRef(null); + + const load = useCallback(async () => { + setLoading(true); setError(''); + try { + const data = await getLatestBriefing(); + setBriefing(data); + } catch (e) { + setError(e.message); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { load(); }, [load]); + + const regenerate = useCallback(async () => { + setRegenerating(true); setError(''); + try { + const prevGen = briefing?.generated_at; + await triggerLottoCurate(); + let attempts = 0; + pollingRef.current = setInterval(async () => { + attempts += 1; + try { + const data = await getLatestBriefing(); + if (data && data.generated_at !== prevGen) { + setBriefing(data); + setRegenerating(false); + clearInterval(pollingRef.current); + } + } catch {} + if (attempts >= 40) { + clearInterval(pollingRef.current); + setRegenerating(false); + setError('재생성 타임아웃 (2분)'); + } + }, 3000); + } catch (e) { + setError(e.message); + setRegenerating(false); + } + }, [briefing?.generated_at]); + + useEffect(() => () => { if (pollingRef.current) clearInterval(pollingRef.current); }, []); + + return { briefing, loading, error, regenerating, reload: load, regenerate }; +} diff --git a/src/pages/lotto/hooks/useCuratorUsage.js b/src/pages/lotto/hooks/useCuratorUsage.js new file mode 100644 index 0000000..14616e5 --- /dev/null +++ b/src/pages/lotto/hooks/useCuratorUsage.js @@ -0,0 +1,17 @@ +import { useState, useEffect } from 'react'; +import { getCuratorUsage } from '../../../api'; + +export default function useCuratorUsage(days = 30) { + const [usage, setUsage] = useState(null); + const [error, setError] = useState(''); + + useEffect(() => { + let alive = true; + getCuratorUsage(days) + .then(d => { if (alive) setUsage(d); }) + .catch(e => { if (alive) setError(e.message); }); + return () => { alive = false; }; + }, [days]); + + return { usage, error }; +}