매매 시그널 알림 화면 수정

This commit is contained in:
Macbook
2026-05-29 00:46:20 +09:00
parent cbad62a5b0
commit e43b5cbd5a
45 changed files with 2186 additions and 415 deletions
@@ -12,6 +12,8 @@ import { OrderbookPanel } from './OrderbookPanel';
import PaperSplitPanel from './paper/PaperSplitPanel';
import { useUpbitOrderbook } from '../hooks/useUpbitOrderbook';
import { useUpbitRecentTrades } from '../hooks/useUpbitRecentTrades';
import { useAppSettings } from '../hooks/useAppSettings';
import '../styles/strategyEditorTheme.css';
import '../styles/virtualTradingDashboard.css';
import '../styles/tradeNotificationList.css';
import TradeNotificationListRow from './tradeNotification/TradeNotificationListRow';
@@ -95,6 +97,8 @@ export const TradeNotificationListPage: React.FC<Props> = ({
const [fillSell, setFillSell] = useState<TradeOrderFillRequest | null>(null);
const [summary, setSummary] = useState<PaperSummaryDto | null>(null);
const orderAnchorRef = useRef<HTMLDivElement>(null);
const { settings: appSettings } = useAppSettings();
const chartLiveReceiveHighlight = appSettings.chartLiveReceiveHighlight ?? true;
const refreshPaperData = useCallback(async () => {
try {
@@ -205,43 +209,16 @@ export const TradeNotificationListPage: React.FC<Props> = ({
const gridCols = getTradeNotificationGridPreset(gridPreset).cols;
return (
<div className={`tnl-page tnl-page--with-right bps-page--vtd app ${theme}`}>
<div className={`tnl-page tnl-page--with-right bps-page--vtd se-page se-page--${theme} app ${theme}`}>
<div className="tnl-body">
<div className="tnl-main" style={{ containerType: 'inline-size', containerName: 'tnl-main' }}>
<div className="tnl-header">
<div className="tnl-header-row">
<div className="tnl-header-intro">
<h1 className="tnl-title"> </h1>
<p className="tnl-sub">
{isListView
? '각 알림 왼쪽은 요약, 오른쪽은 캔들·지표 차트입니다. 차트 영역은 가로 스크롤로 확인할 수 있습니다.'
: `목록형과 동일한 알림 상세 카드를 ${getTradeNotificationGridPreset(gridPreset).label} 그리드로 표시합니다. 우측 아이콘으로 배치를 변경할 수 있습니다.`}
</p>
</div>
<div className="tnl-header-actions">
<div className="tnl-layout-toggle vtd-view-toggle" role="group" aria-label="목록 표시 방식">
<button
type="button"
className={`vtd-view-toggle-btn${isListView ? ' vtd-view-toggle-btn--on' : ''}`}
onClick={() => handleListLayoutChange('list')}
>
</button>
<button
type="button"
className={`vtd-view-toggle-btn${!isListView ? ' vtd-view-toggle-btn--on' : ''}`}
onClick={() => handleListLayoutChange('grid')}
>
</button>
</div>
<TradeNotificationGridLayoutPicker
value={gridPreset}
onChange={handleGridPresetChange}
disabled={isListView}
/>
</div>
</div>
<h1 className="tnl-title"> </h1>
<p className="tnl-sub">
{isListView
? '각 알림 왼쪽은 가상매매와 동일한 신호 상세 카드, 오른쪽은 캔들·지표 차트입니다. 영역 우측 버튼으로 가로 스크롤할 수 있습니다.'
: `목록형과 동일한 알림 상세 카드를 ${getTradeNotificationGridPreset(gridPreset).label} 그리드로 표시합니다. 툴바 우측에서 배치를 변경할 수 있습니다.`}
</p>
<div className="tnl-toolbar">
<span className="tnl-chip tnl-chip--warn"> {unreadCount}</span>
<div className="tnl-filter">
@@ -268,27 +245,50 @@ export const TradeNotificationListPage: React.FC<Props> = ({
</button>
)}
<span className="tnl-toolbar-divider" aria-hidden="true" />
<button
type="button"
className="tnl-icon-btn"
title="미확인 알림 삭제"
aria-label="미확인 알림 삭제"
disabled={unreadCount === 0}
onClick={() => void handleDeleteUnread()}
>
<IcTrash />
</button>
<button
type="button"
className="tnl-icon-btn tnl-icon-btn--danger"
title="모두 삭제"
aria-label="모두 삭제"
disabled={allNotifications.length === 0}
onClick={() => void handleDeleteAll()}
>
<IcTrash />
</button>
<div className="tnl-toolbar-end">
<div className="tnl-layout-toggle vtd-view-toggle" role="group" aria-label="목록 표시 방식">
<button
type="button"
className={`vtd-view-toggle-btn${isListView ? ' vtd-view-toggle-btn--on' : ''}`}
onClick={() => handleListLayoutChange('list')}
>
</button>
<button
type="button"
className={`vtd-view-toggle-btn${!isListView ? ' vtd-view-toggle-btn--on' : ''}`}
onClick={() => handleListLayoutChange('grid')}
>
</button>
</div>
<TradeNotificationGridLayoutPicker
value={gridPreset}
onChange={handleGridPresetChange}
disabled={isListView}
/>
<span className="tnl-toolbar-divider" aria-hidden="true" />
<button
type="button"
className="tnl-icon-btn"
title="미확인 알림 삭제"
aria-label="미확인 알림 삭제"
disabled={unreadCount === 0}
onClick={() => void handleDeleteUnread()}
>
<IcTrash />
</button>
<button
type="button"
className="tnl-icon-btn tnl-icon-btn--danger"
title="모두 삭제"
aria-label="모두 삭제"
disabled={allNotifications.length === 0}
onClick={() => void handleDeleteAll()}
>
<IcTrash />
</button>
</div>
</div>
</div>
@@ -312,6 +312,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
layoutMode={listLayout}
isSelected={selectedNotifyId === item.id}
chartsEnabled={isListView}
chartLiveReceiveHighlight={chartLiveReceiveHighlight}
onSelect={() => handleNotificationSelect(item)}
onDelete={e => void handleDeleteOne(item, e)}
onDetail={() => {
@@ -322,6 +323,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
markAsRead(item.id);
onGoToChart(item.market);
}}
tickers={tickers}
/>
))}
</ul>