알림목록 시간봉 필터 추가

This commit is contained in:
Macbook
2026-05-30 16:37:18 +09:00
parent 42a9b6a1fb
commit d5699a827e
6 changed files with 110 additions and 21 deletions
@@ -23,13 +23,18 @@ import TradeNotificationGridLayoutPicker from './tradeNotification/TradeNotifica
import {
loadTradeNotificationGridPreset,
loadTradeNotificationListLayout,
loadTradeNotificationCandleFilter,
loadTradeNotificationListSort,
saveTradeNotificationCandleFilter,
saveTradeNotificationGridPreset,
saveTradeNotificationListLayout,
saveTradeNotificationListSort,
TRADE_NOTIFICATION_CANDLE_FILTER_OPTIONS,
type TradeNotificationCandleFilter,
type TradeNotificationListLayout,
type TradeNotificationListSort,
} from '../utils/tradeNotificationListLayout';
import { normalizeStartCandleType } from '../utils/strategyStartNodes';
import {
getTradeNotificationGridPreset,
type TradeNotificationGridPresetId,
@@ -120,6 +125,9 @@ export const TradeNotificationListPage: React.FC<Props> = ({
const [listSort, setListSort] = useState<TradeNotificationListSort>(
() => loadTradeNotificationListSort(),
);
const [candleFilter, setCandleFilter] = useState<TradeNotificationCandleFilter>(
() => loadTradeNotificationCandleFilter(),
);
const [listLayout, setListLayout] = useState<TradeNotificationListLayout>(
() => loadTradeNotificationListLayout(),
);
@@ -246,9 +254,17 @@ export const TradeNotificationListPage: React.FC<Props> = ({
else setFillSell(req);
}, [selectedMarket]);
const filtered = filter === 'unread'
? allNotifications.filter(n => !n.isRead)
: allNotifications;
const filtered = useMemo(() => {
let items = filter === 'unread'
? allNotifications.filter(n => !n.isRead)
: allNotifications;
if (candleFilter) {
items = items.filter(
n => normalizeStartCandleType(n.candleType) === candleFilter,
);
}
return items;
}, [allNotifications, filter, candleFilter]);
const sorted = useMemo(
() => sortNotifications(filtered, listSort),
@@ -260,6 +276,11 @@ export const TradeNotificationListPage: React.FC<Props> = ({
saveTradeNotificationListSort(sort);
}, []);
const handleCandleFilterChange = useCallback((value: TradeNotificationCandleFilter) => {
setCandleFilter(value);
saveTradeNotificationCandleFilter(value);
}, []);
const handleListLayoutChange = useCallback((layout: TradeNotificationListLayout) => {
setListLayout(layout);
saveTradeNotificationListLayout(layout);
@@ -360,23 +381,35 @@ export const TradeNotificationListPage: React.FC<Props> = ({
</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"
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>
<span className="header-toolbar-divider" aria-hidden="true" />
<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>
<button
type="button"
className={['tnl-icon-btn', refreshing ? 'tnl-icon-btn--refreshing' : ''].filter(Boolean).join(' ')}
@@ -392,7 +425,6 @@ export const TradeNotificationListPage: React.FC<Props> = ({
onChange={handleGridPresetChange}
disabled={isListView}
/>
<span className="tnl-toolbar-divider" aria-hidden="true" />
<button
type="button"
className="tnl-icon-btn"