종목목록 전일대비 정렬문제
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user