위젯 기능 추가
This commit is contained in:
@@ -10,7 +10,7 @@ import type { AuthSession } from '../utils/auth';
|
||||
import type { TradeAlertPopupLayout, TradeAlertPopupPosition } from '../utils/tradeAlertPopupLayout';
|
||||
import { canAccessMenu } from '../utils/permissions';
|
||||
|
||||
export type MenuPage = 'dashboard' | 'chart' | 'paper' | 'virtual' | 'trend-search' | 'verification-board' | 'strategy' | 'strategy-editor' | 'strategy-evaluation' | 'backtest' | 'analysis-report' | 'notifications' | 'settings';
|
||||
export type MenuPage = 'dashboard' | 'chart' | 'paper' | 'virtual' | 'trend-search' | 'verification-board' | 'strategy' | 'strategy-editor' | 'strategy-evaluation' | 'backtest' | 'analysis-report' | 'notifications' | 'settings' | 'widget-dashboard';
|
||||
|
||||
interface TopMenuBarProps {
|
||||
activePage: MenuPage;
|
||||
@@ -42,6 +42,10 @@ interface TopMenuBarProps {
|
||||
onLogout?: () => void;
|
||||
/** 브라우저 전체화면 (모든 화면에서 사용) */
|
||||
onFullscreen?: () => void;
|
||||
/** 플로팅 위젯 레이아웃 선택 열기 */
|
||||
onOpenFloatingWidgets?: () => void;
|
||||
/** 실행 중인 플로팅 위젯 창 수 */
|
||||
floatingWidgetCount?: number;
|
||||
/** 메뉴별 접근 허용 (없으면 전체 표시) */
|
||||
menuPermissions?: Record<string, boolean>;
|
||||
}
|
||||
@@ -196,8 +200,28 @@ const IcVerificationBoard = () => (
|
||||
</svg>
|
||||
);
|
||||
|
||||
const IcWidget = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect x="1" y="1" width="6" height="6" rx="1"/>
|
||||
<rect x="9" y="1" width="6" height="4" rx="1"/>
|
||||
<rect x="1" y="9" width="6" height="6" rx="1"/>
|
||||
<rect x="9" y="7" width="6" height="8" rx="1"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const IcFloatingWidgetAdd = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect x="1" y="1" width="6" height="6" rx="1"/>
|
||||
<rect x="9" y="1" width="6" height="6" rx="1"/>
|
||||
<rect x="1" y="9" width="6" height="6" rx="1"/>
|
||||
<line x1="12" y1="12" x2="12" y2="15"/>
|
||||
<line x1="10.5" y1="13.5" x2="13.5" y2="13.5"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const MENU_ITEMS: { page: MenuPage; label: string; icon: React.ReactNode }[] = [
|
||||
{ page: 'dashboard', label: '대시보드', icon: <IcDashboard /> },
|
||||
{ page: 'widget-dashboard', label: '위젯', icon: <IcWidget /> },
|
||||
{ page: 'chart', label: '실시간차트', icon: <IcChart /> },
|
||||
{ page: 'paper', label: '투자관리', icon: <IcPaper /> },
|
||||
{ page: 'virtual', label: '가상매매', icon: <IcVirtual /> },
|
||||
@@ -228,6 +252,8 @@ export const TopMenuBar = memo(function TopMenuBar({
|
||||
onLoginClick,
|
||||
onLogout,
|
||||
onFullscreen,
|
||||
onOpenFloatingWidgets,
|
||||
floatingWidgetCount = 0,
|
||||
menuPermissions,
|
||||
}: TopMenuBarProps) {
|
||||
const [isFullscreen, setIsFullscreen] = useState(() => !!document.fullscreenElement);
|
||||
@@ -281,6 +307,25 @@ export const TopMenuBar = memo(function TopMenuBar({
|
||||
|
||||
{/* 우측 영역 */}
|
||||
<div className="tmb-right">
|
||||
{onOpenFloatingWidgets && (
|
||||
<div className="tmb-floating-widget-wrap">
|
||||
<button
|
||||
type="button"
|
||||
className="tmb-floating-widget-btn"
|
||||
onClick={onOpenFloatingWidgets}
|
||||
title="플로팅 위젯 추가"
|
||||
aria-label="플로팅 위젯 추가"
|
||||
>
|
||||
<IcFloatingWidgetAdd />
|
||||
</button>
|
||||
{floatingWidgetCount > 0 && (
|
||||
<span className="tmb-floating-widget-count" aria-hidden>
|
||||
{floatingWidgetCount > 9 ? '9+' : floatingWidgetCount}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{onOpenAppDownload && (
|
||||
<>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user