알림목록 수정

This commit is contained in:
Macbook
2026-06-06 02:53:39 +09:00
parent 8a81b08d34
commit 650fb354a8
7 changed files with 1146 additions and 112 deletions
@@ -23,6 +23,7 @@ import '../styles/builderPageShell.css';
import '../styles/tradeNotificationList.css';
import TradeNotificationListRow from './tradeNotification/TradeNotificationListRow';
import TradeNotificationGridLayoutPicker from './tradeNotification/TradeNotificationGridLayoutPicker';
import FullscreenChartModal from './tradeNotification/FullscreenChartModal';
import {
loadTradeNotificationGridPreset,
loadTradeNotificationListLayout,
@@ -110,6 +111,9 @@ export const TradeNotificationListPage: React.FC<Props> = ({
refreshHistory,
} = useTradeNotification();
const [query, setQuery] = useState('');
const normalizedQuery = useMemo(() => query.trim().toLowerCase(), [query]);
const [filter, setFilter] = useState<TradeNotificationReadFilter>('all');
const [listSort, setListSort] = useState<TradeNotificationListSort>(
() => loadTradeNotificationListSort(),
@@ -132,6 +136,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
const orderAnchorRef = useRef<HTMLDivElement>(null);
const [refreshing, setRefreshing] = useState(false);
const [rightOpen, setRightOpen] = useState(() => readStoredBool(TNL_RIGHT_OPEN_KEY, true));
const [fullscreenItem, setFullscreenItem] = useState<TradeNotificationItem | null>(null);
const { settings: appSettings } = useAppSettings();
const chartLiveReceiveHighlight = appSettings.chartLiveReceiveHighlight ?? true;
@@ -252,8 +257,22 @@ export const TradeNotificationListPage: React.FC<Props> = ({
n => normalizeStartCandleType(n.candleType) === candleFilter,
);
}
if (normalizedQuery) {
items = items.filter(n => {
const mkt = n.market.toLowerCase();
const sym = n.market.includes('-') ? n.market.split('-')[1].toLowerCase() : mkt;
const strat = (n.strategyName ?? '').toLowerCase();
const sigKo = n.signalType === 'BUY' ? '매수' : '매도';
return (
mkt.includes(normalizedQuery) ||
sym.includes(normalizedQuery) ||
strat.includes(normalizedQuery) ||
sigKo.includes(normalizedQuery)
);
});
}
return items;
}, [allNotifications, filter, candleFilter]);
}, [allNotifications, filter, candleFilter, normalizedQuery]);
const sorted = useMemo(
() => sortTradeNotifications(filtered, listSort),
@@ -305,6 +324,14 @@ export const TradeNotificationListPage: React.FC<Props> = ({
const gridCols = getTradeNotificationGridPreset(gridPreset).cols;
return (
<>
{fullscreenItem && (
<FullscreenChartModal
item={fullscreenItem}
theme={theme}
onClose={() => setFullscreenItem(null)}
/>
)}
<div
className={[
'tnl-page',
@@ -322,6 +349,32 @@ export const TradeNotificationListPage: React.FC<Props> = ({
<div className="tnl-header">
<h1 className="tnl-title"> </h1>
<div className="tnl-toolbar">
{/* 검색란 */}
<div className={`tnl-search-box${query ? ' tnl-search-box--active' : ''}`}>
<svg className="tnl-search-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
</svg>
<input
type="text"
className="tnl-search-input"
placeholder="종목·전략 검색"
value={query}
onChange={e => setQuery(e.target.value)}
aria-label="알림 목록 검색"
/>
{query && (
<button
type="button"
className="tnl-search-clear"
onClick={() => setQuery('')}
aria-label="검색어 초기화"
>
</button>
)}
</div>
<span className="tnl-chip tnl-chip--warn"> {unreadCount}</span>
{selectedCount > 0 && (
<span className="tnl-chip tnl-chip--selected"> {selectedCount}</span>
@@ -425,7 +478,9 @@ export const TradeNotificationListPage: React.FC<Props> = ({
<div className={['tnl-list-wrap', !isListView ? 'tnl-list-wrap--grid' : ''].filter(Boolean).join(' ')}>
{sorted.length === 0 ? (
<div className="tnl-empty"> .</div>
<div className="tnl-empty">
{normalizedQuery ? `"${query}" 에 해당하는 알림이 없습니다.` : '표시할 알림이 없습니다.'}
</div>
) : (
<ul
className={[
@@ -452,7 +507,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
}}
onGoToChart={() => {
markAsRead(item.id);
onGoToChart(item.market);
setFullscreenItem(item);
}}
tickers={tickers}
/>
@@ -540,6 +595,7 @@ export const TradeNotificationListPage: React.FC<Props> = ({
</div>
</div>
</div>
</>
);
};