알림목록 수정
This commit is contained in:
@@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user