Files
goldenChart/frontend/src/components/tradeNotification/TradeNotificationSignalSummary.tsx
T
2026-06-08 01:23:49 +09:00

105 lines
3.1 KiB
TypeScript

/**
* 매매 시그널 알림 목록 — 가상매매 종목 카드(요약·신호)와 동일 UI · 실시간 신호 갱신
*/
import React, { useMemo, useState } from 'react';
import type { TickerData } from '../../hooks/useMarketTicker';
import type { VirtualIndicatorSnapshot } from '../../hooks/useVirtualIndicatorSnapshots';
import { useTradeNotificationSignalSnapshot } from '../../hooks/useTradeNotificationSignalSnapshot';
import type { StrategyDto } from '../../utils/backendApi';
import type { Theme } from '../../types';
import VirtualTargetCard, { type VirtualCardDisplayMode } from '../virtual/VirtualTargetCard';
interface Props {
market: string;
strategyId: number | null | undefined;
strategy?: StrategyDto;
strategies?: StrategyDto[];
globalStrategyId?: number | null;
candleType?: string;
theme?: Theme;
ticker?: TickerData;
enabled?: boolean;
/** tnl-chart-card 본문에 삽입 */
embedded?: boolean;
/** 부모에서 스냅샷 공유 시(행 테두리 플래시와 중복 폴링 방지) */
snapshot?: VirtualIndicatorSnapshot;
signalLoading?: boolean;
/** 차트 영역 펼쳐보기 (헤더 확대 버튼) */
onExpandCharts?: () => void;
/** 푸터 전략명 (읽기 전용) */
strategyLabel?: string;
}
const TradeNotificationSignalSummary: React.FC<Props> = ({
market,
strategyId,
strategy,
strategies = [],
globalStrategyId = null,
theme = 'dark',
ticker,
enabled = true,
embedded = false,
snapshot: snapshotProp,
signalLoading: signalLoadingProp,
onExpandCharts,
strategyLabel,
}) => {
const active = enabled && strategyId != null;
const [displayMode, setDisplayMode] = useState<VirtualCardDisplayMode>('signal');
const internal = useTradeNotificationSignalSnapshot(
market,
strategyId,
strategy,
strategyLabel,
active && snapshotProp === undefined,
strategies,
);
const snapshot = snapshotProp ?? internal.snapshot;
const loading = signalLoadingProp ?? internal.loading;
const strategiesList = useMemo(() => {
if (strategies.length > 0) return strategies;
return strategy ? [strategy] : [];
}, [strategies, strategy]);
const card = (
<VirtualTargetCard
market={market}
strategy={strategy}
strategies={strategiesList}
strategyId={strategyId ?? null}
globalStrategyId={globalStrategyId}
snapshot={snapshot}
signalLoading={loading}
running={active}
liveStatus="live"
viewMode="summary"
displayMode={displayMode}
onDisplayModeChange={embedded ? undefined : setDisplayMode}
onEnterFocus={embedded ? undefined : onExpandCharts}
headVariant={embedded ? 'inline-quote' : 'default'}
theme={theme}
ticker={ticker}
chartLiveReceiveHighlight={!embedded}
readOnlyStrategyLabel={strategyLabel}
/>
);
if (embedded) {
return (
<div
className={`tnl-signal-summary--embedded-wrap se-page se-page--${theme}`}
onClick={e => e.stopPropagation()}
>
{card}
</div>
);
}
return card;
};
export default TradeNotificationSignalSummary;