diff --git a/src/pages/stock/Stock.css b/src/pages/stock/Stock.css index 6db4d54..96761df 100644 --- a/src/pages/stock/Stock.css +++ b/src/pages/stock/Stock.css @@ -105,6 +105,15 @@ background: rgba(249, 182, 177, 0.1); } +.stock-success { + margin: 0; + color: #b5f0dd; + border: 1px solid rgba(106, 220, 187, 0.4); + border-radius: 14px; + padding: 12px; + background: rgba(106, 220, 187, 0.12); +} + .stock-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); diff --git a/src/pages/stock/Stock.jsx b/src/pages/stock/Stock.jsx index 7f830a7..4f56584 100644 --- a/src/pages/stock/Stock.jsx +++ b/src/pages/stock/Stock.jsx @@ -31,6 +31,9 @@ const Stock = () => { const [loading, setLoading] = useState(false); const [scraping, setScraping] = useState(false); const [error, setError] = useState(''); + const [newsError, setNewsError] = useState(''); + const [indicesError, setIndicesError] = useState(''); + const [scrapMessage, setScrapMessage] = useState(''); const [health, setHealth] = useState({ status: 'unknown', message: '', @@ -51,12 +54,12 @@ const Stock = () => { const loadNews = async () => { setLoading(true); - setError(''); + setNewsError(''); try { const data = await getStockNews(limit); setNews(Array.isArray(data) ? data : []); } catch (err) { - setError(err?.message ?? String(err)); + setNewsError(err?.message ?? String(err)); } finally { setLoading(false); } @@ -70,22 +73,26 @@ const Stock = () => { message: data?.message ?? '', }); } catch (err) { + const rawMessage = err?.message ?? String(err); + const message = rawMessage.includes('404') + ? '헬스 체크 엔드포인트가 아직 준비되지 않았습니다.' + : rawMessage; setHealth({ status: 'unknown', - message: err?.message ?? '', + message, }); } }; const loadIndices = async () => { setIndicesLoading(true); - setError(''); + setIndicesError(''); try { const data = await getStockIndices(); setIndices(Array.isArray(data?.indices) ? data.indices : []); setIndicesAt(data?.crawled_at ?? ''); } catch (err) { - setError(err?.message ?? String(err)); + setIndicesError(err?.message ?? String(err)); } finally { setIndicesLoading(false); } @@ -94,11 +101,13 @@ const Stock = () => { const onScrap = async () => { setScraping(true); setError(''); + setScrapMessage(''); try { const result = await triggerStockScrap(); if (!result?.ok) { throw new Error('스크랩 요청이 실패했습니다.'); } + setScrapMessage('스크랩 요청 완료'); await loadNews(); } catch (err) { setError(err?.message ?? String(err)); @@ -176,6 +185,9 @@ const Stock = () => { {error ?
{error}
: null} + {scrapMessage ? ( +{scrapMessage}
+ ) : null}{indicesError}
+ ) : indices.length === 0 ? (지표 데이터를 불러오지 못했습니다.
) : ( [...indices] @@ -218,36 +232,36 @@ const Stock = () => { return aIdx - bIdx; }) .map((item) => ( -{item.name}
- {item.value ?? '--'} - - {item.direction === 'red' - ? '▲' - : item.direction === 'blue' - ? '▼' - : '■'}{' '} - {item.change_value ?? '--'}{' '} - {item.change_percent ?? ''} - -{item.name}
+ {item.value ?? '--'} + + {item.direction === 'red' + ? '▲' + : item.direction === 'blue' + ? '▼' + : '■'}{' '} + {item.change_value ?? '--'}{' '} + {item.change_percent ?? ''} + +뉴스를 불러오는 중...
+ ) : newsError ? ( +{newsError}
) : news.length === 0 ? (표시할 뉴스가 없습니다.
) : (