종목목록 전일대비 정렬문제

This commit is contained in:
Macbook
2026-06-16 08:53:35 +09:00
parent 615e1164a6
commit 518b69cdc6
8 changed files with 232 additions and 142 deletions
+27 -4
View File
@@ -28,6 +28,8 @@ export interface MarketPanelProps {
usdRate: number; // KRW per 1 USD (from KRW-USDT)
activeSymbol: string;
onSymbolSelect: (symbol: string) => void;
/** 정렬 전 전 종목 시세 재조회 (useMarketTicker.refreshAllTickers) */
refreshAllTickers?: () => Promise<void>;
}
// ─── 가격 포맷 헬퍼 ────────────────────────────────────────────────────────
@@ -50,6 +52,17 @@ function fmtPct(rate: number | null | undefined): string {
return `${sign}${(rate * 100).toFixed(2)}%`;
}
function compareNullableNum(
a: number | null | undefined,
b: number | null | undefined,
mul: number,
): number {
if (a == null && b == null) return 0;
if (a == null) return 1;
if (b == null) return -1;
return mul * (a - b);
}
// ─── 방향 지시자 삼각형 ────────────────────────────────────────────────────
const ChangeArrow = memo(function ChangeArrow({ change }: { change: ChangeDir }) {
if (change === 'RISE') return <span className="mp-arrow mp-arrow--rise"></span>;
@@ -155,6 +168,7 @@ const MarketRow = memo(function MarketRow({
// ─── 메인 패널 ─────────────────────────────────────────────────────────────
export const MarketPanel: React.FC<MarketPanelProps> = ({
open, tickers, marketInfos, loading, usdRate, activeSymbol, onSymbolSelect,
refreshAllTickers,
}) => {
const [tab, setTab] = useState<Tab>('krw');
const [search, setSearch] = useState('');
@@ -172,8 +186,8 @@ export const MarketPanel: React.FC<MarketPanelProps> = ({
// 검색 초기화 (탭 전환 시)
const handleTab = useCallback((t: Tab) => { setTab(t); setSearch(''); }, []);
// 컬럼 정렬 토글
const handleSort = useCallback((key: SortKey) => {
// 컬럼 정렬 토글 (시세 기반 정렬 전 전 종목 REST 재조회)
const applySortState = useCallback((key: SortKey) => {
setSortKey(prev => {
if (prev === key) {
setSortDir(d => d === 'asc' ? 'desc' : 'asc');
@@ -184,6 +198,15 @@ export const MarketPanel: React.FC<MarketPanelProps> = ({
});
}, []);
const handleSort = useCallback((key: SortKey) => {
const needsRefresh = key === 'change' || key === 'price';
if (needsRefresh && refreshAllTickers) {
void refreshAllTickers().then(() => applySortState(key));
return;
}
applySortState(key);
}, [refreshAllTickers, applySortState]);
// 즐겨찾기 토글
const handleToggleFav = useCallback(async (market: string, e: React.MouseEvent) => {
e.stopPropagation();
@@ -266,9 +289,9 @@ export const MarketPanel: React.FC<MarketPanelProps> = ({
return mul * na.localeCompare(nb, 'ko');
}
case 'price':
return mul * ((ta?.tradePrice ?? 0) - (tb?.tradePrice ?? 0));
return compareNullableNum(ta?.tradePrice, tb?.tradePrice, mul);
case 'change':
return mul * ((ta?.changeRate ?? 0) - (tb?.changeRate ?? 0));
return compareNullableNum(ta?.changeRate, tb?.changeRate, mul);
default:
return 0;
}