From 6556741f83e5abc26f987de89c5e4afb79ba9a43 Mon Sep 17 00:00:00 2001 From: Macbook Date: Fri, 29 May 2026 20:55:21 +0900 Subject: [PATCH] =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/TradeNotificationListPage.tsx | 61 ++++++++++++++++++- frontend/src/types/uiPreferences.ts | 2 + .../src/utils/tradeNotificationListLayout.ts | 13 ++++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/TradeNotificationListPage.tsx b/frontend/src/components/TradeNotificationListPage.tsx index 8278fe5..8d17361 100644 --- a/frontend/src/components/TradeNotificationListPage.tsx +++ b/frontend/src/components/TradeNotificationListPage.tsx @@ -23,9 +23,12 @@ import TradeNotificationGridLayoutPicker from './tradeNotification/TradeNotifica import { loadTradeNotificationGridPreset, loadTradeNotificationListLayout, + loadTradeNotificationListSort, saveTradeNotificationGridPreset, saveTradeNotificationListLayout, + saveTradeNotificationListSort, type TradeNotificationListLayout, + type TradeNotificationListSort, } from '../utils/tradeNotificationListLayout'; import { getTradeNotificationGridPreset, @@ -74,6 +77,24 @@ function fillBothSides( setFillSell({ market, price, side: 'sell', seq: seq + 1 }); } +function sortNotifications( + items: TradeNotificationItem[], + sort: TradeNotificationListSort, +): TradeNotificationItem[] { + const arr = [...items]; + if (sort === 'market') { + return arr.sort((a, b) => { + const byMarket = a.market.localeCompare(b.market, 'ko'); + if (byMarket !== 0) return byMarket; + return b.receivedAt - a.receivedAt; + }); + } + if (sort === 'oldest') { + return arr.sort((a, b) => a.receivedAt - b.receivedAt); + } + return arr.sort((a, b) => b.receivedAt - a.receivedAt); +} + export const TradeNotificationListPage: React.FC = ({ theme, onGoToChart, @@ -96,6 +117,9 @@ export const TradeNotificationListPage: React.FC = ({ } = useTradeNotification(); const [filter, setFilter] = useState<'all' | 'unread'>('all'); + const [listSort, setListSort] = useState( + () => loadTradeNotificationListSort(), + ); const [listLayout, setListLayout] = useState( () => loadTradeNotificationListLayout(), ); @@ -226,6 +250,16 @@ export const TradeNotificationListPage: React.FC = ({ ? allNotifications.filter(n => !n.isRead) : allNotifications; + const sorted = useMemo( + () => sortNotifications(filtered, listSort), + [filtered, listSort], + ); + + const handleListSortChange = useCallback((sort: TradeNotificationListSort) => { + setListSort(sort); + saveTradeNotificationListSort(sort); + }, []); + const handleListLayoutChange = useCallback((layout: TradeNotificationListLayout) => { setListLayout(layout); saveTradeNotificationListLayout(layout); @@ -303,6 +337,29 @@ export const TradeNotificationListPage: React.FC = ({ 모두 읽음 )} +
+ + + +
- {filtered.length === 0 ? ( + {sorted.length === 0 ? (
표시할 알림이 없습니다.
) : (
    = ({ ].filter(Boolean).join(' ')} style={!isListView ? { gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))` } : undefined} > - {filtered.map(item => ( + {sorted.map(item => (