앱 수정

This commit is contained in:
Macbook
2026-05-28 15:37:02 +09:00
parent 3503ef33f5
commit f64dc1e983
21 changed files with 1434 additions and 755 deletions
@@ -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>
)}