알림 목록 정렬 기능 추가

This commit is contained in:
Macbook
2026-05-29 20:55:21 +09:00
parent 775f83e1b3
commit 6556741f83
3 changed files with 74 additions and 2 deletions
@@ -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<Props> = ({
theme,
onGoToChart,
@@ -96,6 +117,9 @@ export const TradeNotificationListPage: React.FC<Props> = ({
} = useTradeNotification();
const [filter, setFilter] = useState<'all' | 'unread'>('all');
const [listSort, setListSort] = useState<TradeNotificationListSort>(
() => loadTradeNotificationListSort(),
);
const [listLayout, setListLayout] = useState<TradeNotificationListLayout>(
() => loadTradeNotificationListLayout(),
);
@@ -226,6 +250,16 @@ export const TradeNotificationListPage: React.FC<Props> = ({
? 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<Props> = ({
</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>
<div className="tnl-toolbar-end">
<div className="tnl-layout-toggle vtd-view-toggle" role="group" aria-label="목록 표시 방식">
<button
@@ -361,7 +418,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
</div>
<div className={['tnl-list-wrap', !isListView ? 'tnl-list-wrap--grid' : ''].filter(Boolean).join(' ')}>
{filtered.length === 0 ? (
{sorted.length === 0 ? (
<div className="tnl-empty"> .</div>
) : (
<ul
@@ -372,7 +429,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
].filter(Boolean).join(' ')}
style={!isListView ? { gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))` } : undefined}
>
{filtered.map(item => (
{sorted.map(item => (
<TradeNotificationListRow
key={item.id}
item={item}