앱 수정
This commit is contained in:
@@ -1,8 +1,21 @@
|
||||
import React from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useTradeNotification } from '../../contexts/TradeNotificationContext';
|
||||
import { useNavigation } from '../../contexts/NavigationContext';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import { useVirtualTradingCore } from '@frontend/hooks/useVirtualTradingCore';
|
||||
import NotificationListRow from './NotificationListRow';
|
||||
import NotificationDetailScreen from './NotificationDetailScreen';
|
||||
import VirtualTradeScreen from '../virtual/VirtualTradeScreen';
|
||||
|
||||
export default function NotificationsScreen() {
|
||||
const {
|
||||
notifyNav,
|
||||
goNotifyList,
|
||||
goNotifyDetail,
|
||||
goNotifyTrade,
|
||||
goVirtualDetail,
|
||||
} = useNavigation();
|
||||
const { sessionKey } = useAuth();
|
||||
const {
|
||||
allNotifications,
|
||||
unreadCount,
|
||||
@@ -12,8 +25,14 @@ export default function NotificationsScreen() {
|
||||
deleteAllNotifications,
|
||||
refreshHistory,
|
||||
} = useTradeNotification();
|
||||
const { openVirtualFocus } = useNavigation();
|
||||
const [refreshing, setRefreshing] = React.useState(false);
|
||||
const { summary, refreshPaperData } = useVirtualTradingCore({ settingsSessionKey: sessionKey });
|
||||
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const selectedItem = useMemo(
|
||||
() => allNotifications.find(n => n.id === notifyNav.notifyId) ?? null,
|
||||
[allNotifications, notifyNav.notifyId],
|
||||
);
|
||||
|
||||
const onRefresh = async () => {
|
||||
setRefreshing(true);
|
||||
@@ -21,13 +40,42 @@ export default function NotificationsScreen() {
|
||||
setRefreshing(false);
|
||||
};
|
||||
|
||||
if (notifyNav.view === 'detail' && selectedItem) {
|
||||
return (
|
||||
<NotificationDetailScreen
|
||||
item={selectedItem}
|
||||
onBack={() => {
|
||||
markAsRead(selectedItem.id);
|
||||
goNotifyList();
|
||||
}}
|
||||
onTrade={side => goNotifyTrade(selectedItem.market, side)}
|
||||
onGoVirtual={() => {
|
||||
markAsRead(selectedItem.id);
|
||||
goVirtualDetail(selectedItem.market);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (notifyNav.view === 'trade' && notifyNav.market && notifyNav.tradeSide) {
|
||||
return (
|
||||
<VirtualTradeScreen
|
||||
market={notifyNav.market}
|
||||
side={notifyNav.tradeSide}
|
||||
summary={summary}
|
||||
onBack={goNotifyList}
|
||||
onOrderDone={refreshPaperData}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="screen">
|
||||
<header className="screen-header">
|
||||
<h1 className="screen-title">알림 {unreadCount > 0 && `(${unreadCount})`}</h1>
|
||||
<div style={{ display: 'flex', gap: 8 }}>
|
||||
<button type="button" className="chip" onClick={() => void onRefresh()}>{refreshing ? '…' : '새로고침'}</button>
|
||||
<button type="button" className="chip" onClick={markAllAsRead}>모두 읽음</button>
|
||||
<button type="button" className="chip" onClick={() => void onRefresh()}>{refreshing ? '…' : '↻'}</button>
|
||||
<button type="button" className="chip" onClick={markAllAsRead}>읽음</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -37,47 +85,21 @@ export default function NotificationsScreen() {
|
||||
<p>전략 조건 충족 시 알림이 표시됩니다</p>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ padding: '0 16px', display: 'flex', flexDirection: 'column', gap: 8 }}>
|
||||
<div className="stack-list" style={{ padding: '0 16px' }}>
|
||||
{allNotifications.map(item => (
|
||||
<div
|
||||
<NotificationListRow
|
||||
key={item.id}
|
||||
className="card"
|
||||
style={{
|
||||
padding: 14,
|
||||
opacity: item.isRead ? 0.65 : 1,
|
||||
borderLeft: `3px solid ${item.signalType === 'BUY' ? 'var(--gc-green)' : 'var(--gc-red)'}`,
|
||||
}}
|
||||
onClick={() => {
|
||||
item={item}
|
||||
onDetail={() => {
|
||||
markAsRead(item.id);
|
||||
openVirtualFocus(item.market);
|
||||
goNotifyDetail(item.id, item.market);
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
|
||||
<div>
|
||||
<span className={item.signalType === 'BUY' ? 'text-green' : 'text-red'} style={{ fontWeight: 700 }}>
|
||||
{item.signalType === 'BUY' ? '매수' : '매도'}
|
||||
</span>
|
||||
<span style={{ marginLeft: 8, fontWeight: 600 }}>{item.market}</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="chip"
|
||||
style={{ minHeight: 28, padding: '4px 8px', color: 'var(--gc-red)' }}
|
||||
onClick={e => { e.stopPropagation(); void deleteNotification(item.id); }}
|
||||
>
|
||||
삭제
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ fontSize: 14, marginTop: 4 }}>₩{item.price?.toLocaleString()}</div>
|
||||
{item.strategyName && (
|
||||
<div className="text-muted" style={{ fontSize: 11, marginTop: 2 }}>{item.strategyName}</div>
|
||||
)}
|
||||
<div className="text-muted" style={{ fontSize: 10, marginTop: 4 }}>
|
||||
{new Date(item.receivedAt).toLocaleString('ko-KR')}
|
||||
</div>
|
||||
</div>
|
||||
onTrade={side => {
|
||||
markAsRead(item.id);
|
||||
goNotifyTrade(item.market, side);
|
||||
}}
|
||||
onDelete={() => void deleteNotification(item.id)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user