"use client"; import React, { useState, useRef, useEffect, lazy, Suspense } from "react"; import { createPortal } from "react-dom"; import { LeafNode, PanelId, PANEL_LABELS, PANEL_SECTIONS } from "./types"; import { IconX, IconLayoutColumns, IconLayoutRows, IconRefresh, } from "@tabler/icons-react"; import HelpTooltip from "../HelpTooltip"; const DashboardPanel = lazy(() => import("../panels/DashboardPanel")); const AnalyticsPanel = lazy(() => import("../panels/AnalyticsPanel")); function PanelContent({ panelId, isAuthed }: { panelId: PanelId; isAuthed: boolean }) { return (
}> {panelId === "dashboard" && } {panelId === "analytics-line" && } {panelId === "analytics-bar" && } {panelId === "analytics-candle" && }
); } // ── View picker portal ──────────────────────────────────────────────────────── type SplitDir = "right" | "down"; function ViewPickerPortal({ anchorRef, mode, currentView, onPick, onClose, }: { anchorRef: React.RefObject; mode: "change" | SplitDir; currentView: PanelId; onPick: (panelId: PanelId) => void; onClose: () => void; }) { const menuRef = useRef(null); const [pos, setPos] = useState({ top: 0, left: 0 }); useEffect(() => { const rect = anchorRef.current?.getBoundingClientRect(); if (rect) setPos({ top: rect.bottom + 6, left: rect.left }); }, []); // Clamp to viewport after mount useEffect(() => { if (!menuRef.current) return; const r = menuRef.current.getBoundingClientRect(); const pad = 8; let { left, top } = pos; if (r.right > window.innerWidth - pad) left = window.innerWidth - r.width - pad; if (r.left < pad) left = pad; if (r.bottom > window.innerHeight - pad) top = window.innerHeight - r.height - pad; if (left !== pos.left || top !== pos.top) setPos({ top, left }); }, [pos]); useEffect(() => { const handler = (e: MouseEvent) => { if (!menuRef.current?.contains(e.target as Node) && !anchorRef.current?.contains(e.target as Node)) onClose(); }; document.addEventListener("mousedown", handler); return () => document.removeEventListener("mousedown", handler); }, [onClose]); const title = mode === "change" ? "Change View" : mode === "right" ? "Tile Right" : "Tile Down"; // Dashboard entry + sections const dashboardActive = currentView === "dashboard"; return createPortal(

{title}

{/* Dashboard standalone */} {/* Power Analytics section */} {PANEL_SECTIONS.map((section, si) => (

{section.label}

{section.items.map(({ panelId, label }) => { const active = panelId === currentView; return ( ); })}
))}
, document.body, ); } // ── Window controls pill ────────────────────────────────────────────────────── type MenuMode = "change" | SplitDir; function WindowControls({ paneId, currentView, canClose, onClose, onSplit, onChangeView, }: { paneId: string; currentView: PanelId; canClose: boolean; onClose: (id: string) => void; onSplit: (leafId: string, dir: "h" | "v", newFirst: boolean, panelId: PanelId) => void; onChangeView: (panelId: PanelId) => void; }) { const [menu, setMenu] = useState(null); const [pillHovered, setPillHovered] = useState(false); const changeRef = useRef(null); const rightRef = useRef(null); const downRef = useRef(null); const handlePick = (panelId: PanelId) => { if (menu === "change") onChangeView(panelId); else if (menu === "right") onSplit(paneId, "h", false, panelId); else if (menu === "down") onSplit(paneId, "v", false, panelId); setMenu(null); }; const anchorRef = menu === "change" ? changeRef : menu === "right" ? rightRef : downRef; const BTN = "w-[26px] h-[26px] flex items-center justify-center rounded-full transition-colors cursor-pointer text-foreground-sec hover:text-foreground"; return ( <>
setPillHovered(true)} onMouseLeave={() => setPillHovered(false)} > {canClose && ( )}
{menu && ( setMenu(null)} /> )} ); } // ── WindowPane ──────────────────────────────────────────────────────────────── export default function WindowPane({ node, isFocused, canClose, onSplit, onClose, isAuthed, }: { node: LeafNode; isFocused: boolean; canClose: boolean; onSplit: (leafId: string, dir: "h" | "v", newFirst: boolean, panelId: PanelId) => void; onClose: (leafId: string) => void; isAuthed: boolean; }) { const [hovered, setHovered] = useState(false); const handleChangeView = (panelId: PanelId) => { import("@/stores/windowStore").then(({ requestViewChange }) => requestViewChange(panelId)); }; return (
setHovered(true)} onMouseLeave={() => setHovered(false)} > {/* Title bar */}
{PANEL_LABELS[node.panelId]}
{/* Content */}
{/* Floating controls pill */}
); }