1. 라우팅 최적화

2. API 호출 병렬 처리
3. UI개선 - 로딩 경험 개선
4. 반응형 디자인
5. API 통신 특이사항 - URL 구성 로직의 잠재적 위험 해결
This commit is contained in:
2026-02-09 00:13:40 +09:00
parent d7e7ccdb16
commit bdb055cb32
8 changed files with 173 additions and 55 deletions

View File

@@ -1,6 +1,8 @@
.stock {
display: grid;
gap: 28px;
/* Prevent overflow on small screens */
width: 100%;
}
.stock-header {
@@ -66,7 +68,7 @@
font-size: 13px;
}
.stock-status > div {
.stock-status>div {
display: flex;
justify-content: space-between;
gap: 12px;
@@ -536,15 +538,39 @@
}
@media (max-width: 768px) {
.stock {
gap: 20px;
}
.stock-panel {
padding: 16px;
gap: 12px;
}
.stock-filter-row {
gap: 12px;
grid-template-columns: 1fr;
}
.stock-header h1 {
font-size: 28px;
}
.stock-actions {
width: 100%;
}
.stock-actions .button {
flex: 1;
text-align: center;
justify-content: center;
}
.stock-card {
padding: 16px;
}
.stock-status > div {
.stock-status>div {
gap: 8px;
}
@@ -568,13 +594,19 @@
}
.stock-holdings__metric {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
grid-template-columns: repeat(2, 1fr);
align-items: center;
justify-items: start;
gap: 8px 16px;
}
/* Make the last item span full width if it's odd */
.stock-holdings__metric>*:last-child:nth-child(odd) {
grid-column: 1 / -1;
}
.stock-holdings__metric span {
font-size: 12px;
font-size: 11px;
}
.stock-holdings__metric strong {
@@ -591,4 +623,4 @@
.stock-holdings__metric strong {
font-size: 14px;
}
}
}

View File

@@ -1,6 +1,7 @@
import React, { useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { getStockIndices, getStockNews } from '../../api';
import Loading from '../../components/Loading';
import './Stock.css';
const formatDate = (value) => {
@@ -206,7 +207,7 @@ const Stock = () => {
</div>
<div className="stock-panel__actions">
{indicesLoading ? (
<span className="stock-chip">불러오는 </span>
<Loading type="spinner" message="" />
) : null}
<button
className="button ghost small"
@@ -237,22 +238,20 @@ const Stock = () => {
return (
<div
key={item.name}
className={`stock-snapshot__card ${
highlighted.has(item.name)
? 'is-highlight'
: ''
}`}
className={`stock-snapshot__card ${highlighted.has(item.name)
? 'is-highlight'
: ''
}`}
>
<p>{item.name}</p>
<strong>{item.value ?? '--'}</strong>
<span
className={`stock-snapshot__change ${
direction === 'up'
? 'is-up'
: direction === 'down'
? 'is-down'
: ''
}`}
className={`stock-snapshot__change ${direction === 'up'
? 'is-up'
: direction === 'down'
? 'is-down'
: ''
}`}
>
{changeText || '--'}
</span>
@@ -332,9 +331,7 @@ const Stock = () => {
</p>
</div>
<div className="stock-panel__actions">
{loading ? (
<span className="stock-chip">불러오는 </span>
) : null}
{loading && <span className="stock-chip">Updating...</span>}
<span className="stock-chip">
국내 {newsDomestic.length} / 해외{' '}
{newsOverseas.length}
@@ -342,8 +339,8 @@ const Stock = () => {
</div>
</div>
{loading ? (
<p className="stock-empty">뉴스를 불러오는 ...</p>
{loading && combinedNews.length === 0 ? (
<Loading type="skeleton" />
) : newsError ? (
<p className="stock-empty">{newsError}</p>
) : combinedNews.length === 0 ? (
@@ -353,22 +350,20 @@ const Stock = () => {
<div className="stock-tabs">
<button
type="button"
className={`stock-tab ${
newsCategory === 'domestic'
? 'is-active'
: ''
}`}
className={`stock-tab ${newsCategory === 'domestic'
? 'is-active'
: ''
}`}
onClick={() => setNewsCategory('domestic')}
>
국내
</button>
<button
type="button"
className={`stock-tab ${
newsCategory === 'overseas'
? 'is-active'
: ''
}`}
className={`stock-tab ${newsCategory === 'overseas'
? 'is-active'
: ''
}`}
onClick={() => setNewsCategory('overseas')}
>
해외