매매 시그널 알림 수정
This commit is contained in:
@@ -207,33 +207,44 @@ export const TopMenuBar = memo(function TopMenuBar({
|
||||
|
||||
{/* 내비게이션 메뉴 */}
|
||||
<nav className="tmb-nav">
|
||||
{visibleItems.map(({ page, label, icon }) => (
|
||||
<button
|
||||
key={page}
|
||||
className={`tmb-nav-btn ${activePage === page ? 'tmb-nav-btn--active' : ''}`}
|
||||
onClick={() => onPage(page)}
|
||||
>
|
||||
<span className="tmb-nav-icon">{icon}</span>
|
||||
<span className="tmb-nav-label">{label}</span>
|
||||
</button>
|
||||
{visibleItems.map(({ page, label, icon }, index) => (
|
||||
<React.Fragment key={page}>
|
||||
{index > 0 && <span className="tmb-divider tmb-divider--nav" aria-hidden="true" />}
|
||||
<button
|
||||
type="button"
|
||||
className={`tmb-nav-btn ${activePage === page ? 'tmb-nav-btn--active' : ''}`}
|
||||
onClick={() => onPage(page)}
|
||||
>
|
||||
<span className="tmb-nav-icon">{icon}</span>
|
||||
<span className="tmb-nav-label">{label}</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<span className="tmb-divider" aria-hidden="true" />
|
||||
|
||||
{/* 우측 영역 */}
|
||||
<div className="tmb-right">
|
||||
{onOpenAppDownload && (
|
||||
<button
|
||||
type="button"
|
||||
className="tmb-app-download-btn"
|
||||
onClick={onOpenAppDownload}
|
||||
title="GoldenChart 모바일 앱 다운로드"
|
||||
aria-label="앱 다운로드"
|
||||
>
|
||||
<IcAppDownload />
|
||||
</button>
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
className="tmb-app-download-btn"
|
||||
onClick={onOpenAppDownload}
|
||||
title="GoldenChart 모바일 앱 다운로드"
|
||||
aria-label="앱 다운로드"
|
||||
>
|
||||
<IcAppDownload />
|
||||
</button>
|
||||
{onOpenNotifications && showNotifications && (
|
||||
<span className="tmb-divider" aria-hidden="true" />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{onOpenNotifications && showNotifications && (
|
||||
<div className="tmb-notify-group">
|
||||
<>
|
||||
<div className="tmb-notify-group">
|
||||
<button
|
||||
type="button"
|
||||
className={`tmb-notify-btn ${activePage === 'notifications' ? 'tmb-nav-btn--active' : ''}`}
|
||||
@@ -272,11 +283,14 @@ export const TopMenuBar = memo(function TopMenuBar({
|
||||
<IcDismissPopups />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<span className="tmb-divider" aria-hidden="true" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 테마 토글 버튼 */}
|
||||
<button
|
||||
type="button"
|
||||
className={`tmb-theme-btn tmb-theme-btn--${theme}`}
|
||||
onClick={onTheme}
|
||||
title={`테마 전환 (현재: ${tc.label}) → ${THEME_CONFIG[tc.next].label}`}
|
||||
@@ -285,7 +299,7 @@ export const TopMenuBar = memo(function TopMenuBar({
|
||||
<span className="tmb-theme-label">{tc.label}</span>
|
||||
</button>
|
||||
|
||||
<div className="tmb-sep" />
|
||||
<span className="tmb-divider" aria-hidden="true" />
|
||||
|
||||
{authUser ? (
|
||||
<>
|
||||
|
||||
@@ -30,9 +30,12 @@ import {
|
||||
saveTradeNotificationListLayout,
|
||||
saveTradeNotificationListSort,
|
||||
TRADE_NOTIFICATION_CANDLE_FILTER_OPTIONS,
|
||||
TRADE_NOTIFICATION_READ_FILTER_OPTIONS,
|
||||
TRADE_NOTIFICATION_SORT_OPTIONS,
|
||||
type TradeNotificationCandleFilter,
|
||||
type TradeNotificationListLayout,
|
||||
type TradeNotificationListSort,
|
||||
type TradeNotificationReadFilter,
|
||||
} from '../utils/tradeNotificationListLayout';
|
||||
import { normalizeStartCandleType } from '../utils/strategyStartNodes';
|
||||
import {
|
||||
@@ -121,7 +124,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
|
||||
refreshHistory,
|
||||
} = useTradeNotification();
|
||||
|
||||
const [filter, setFilter] = useState<'all' | 'unread'>('all');
|
||||
const [filter, setFilter] = useState<TradeNotificationReadFilter>('all');
|
||||
const [listSort, setListSort] = useState<TradeNotificationListSort>(
|
||||
() => loadTradeNotificationListSort(),
|
||||
);
|
||||
@@ -337,61 +340,46 @@ export const TradeNotificationListPage: React.FC<Props> = ({
|
||||
{selectedCount > 0 && (
|
||||
<span className="tnl-chip tnl-chip--selected">선택 {selectedCount}건</span>
|
||||
)}
|
||||
<div className="tnl-filter">
|
||||
<button
|
||||
type="button"
|
||||
className={filter === 'all' ? 'tnl-filter-btn--active' : ''}
|
||||
onClick={() => setFilter('all')}
|
||||
<div className="tnl-toolbar-selects">
|
||||
<select
|
||||
className="tnl-toolbar-select"
|
||||
value={filter}
|
||||
aria-label="표시 범위"
|
||||
onChange={e => setFilter(e.target.value as TradeNotificationReadFilter)}
|
||||
>
|
||||
전체
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={filter === 'unread' ? 'tnl-filter-btn--active' : ''}
|
||||
onClick={() => setFilter('unread')}
|
||||
{TRADE_NOTIFICATION_READ_FILTER_OPTIONS.map(o => (
|
||||
<option key={o.value} value={o.value}>{o.label}</option>
|
||||
))}
|
||||
</select>
|
||||
<span className="header-toolbar-divider" aria-hidden="true" />
|
||||
<select
|
||||
className="tnl-toolbar-select"
|
||||
value={listSort}
|
||||
aria-label="목록 정렬"
|
||||
onChange={e => handleListSortChange(e.target.value as TradeNotificationListSort)}
|
||||
>
|
||||
미확인
|
||||
</button>
|
||||
{TRADE_NOTIFICATION_SORT_OPTIONS.map(o => (
|
||||
<option key={o.value} value={o.value}>{o.label}</option>
|
||||
))}
|
||||
</select>
|
||||
<span className="header-toolbar-divider" aria-hidden="true" />
|
||||
<select
|
||||
className="tnl-toolbar-select"
|
||||
value={candleFilter}
|
||||
aria-label="시간봉 필터"
|
||||
onChange={e => handleCandleFilterChange(e.target.value as TradeNotificationCandleFilter)}
|
||||
>
|
||||
<option value="">전체</option>
|
||||
{TRADE_NOTIFICATION_CANDLE_FILTER_OPTIONS.map(o => (
|
||||
<option key={o.value} value={o.value}>{o.label}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{unreadCount > 0 && (
|
||||
<button type="button" className="tnl-btn tnl-btn--primary" onClick={markAllAsRead}>
|
||||
모두 읽음
|
||||
</button>
|
||||
)}
|
||||
<div className="tnl-filter tnl-sort-toggle" role="group" aria-label="목록 정렬">
|
||||
<button
|
||||
type="button"
|
||||
className={listSort === 'market' ? 'tnl-filter-btn--active' : ''}
|
||||
onClick={() => handleListSortChange('market')}
|
||||
>
|
||||
종목순
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={listSort === 'newest' ? 'tnl-filter-btn--active' : ''}
|
||||
onClick={() => handleListSortChange('newest')}
|
||||
>
|
||||
최신시간순
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={listSort === 'oldest' ? 'tnl-filter-btn--active' : ''}
|
||||
onClick={() => handleListSortChange('oldest')}
|
||||
>
|
||||
이전시간순
|
||||
</button>
|
||||
</div>
|
||||
<select
|
||||
className="tnl-candle-filter-select"
|
||||
value={candleFilter}
|
||||
aria-label="시간봉 필터"
|
||||
onChange={e => handleCandleFilterChange(e.target.value as TradeNotificationCandleFilter)}
|
||||
>
|
||||
<option value="">전체</option>
|
||||
{TRADE_NOTIFICATION_CANDLE_FILTER_OPTIONS.map(o => (
|
||||
<option key={o.value} value={o.value}>{o.label}</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="tnl-layout-toggle vtd-view-toggle" role="group" aria-label="목록 표시 방식">
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user