From dca1be73d72558ce2172c21f362914294f8ccfcb Mon Sep 17 00:00:00 2001 From: d-kimsuon Date: Wed, 3 Sep 2025 20:58:47 +0900 Subject: [PATCH] feat: adjust response design --- .../components/SessionPageContent.tsx | 2 +- .../sessionSidebar/MobileSidebar.tsx | 188 ++++++++++++++++++ .../sessionSidebar/SessionSidebar.tsx | 20 +- 3 files changed, 197 insertions(+), 13 deletions(-) create mode 100644 src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx index 7d8f3f7..027f260 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx @@ -172,7 +172,7 @@ export const SessionPageContent: FC<{ ref={scrollContainerRef} className="flex-1 overflow-y-auto min-h-0" > -
+
void; +} + +export const MobileSidebar: FC = ({ + currentSessionId, + projectId, + isOpen, + onClose, +}) => { + const { + data: { sessions }, + } = useProject(projectId); + const [activeTab, setActiveTab] = useState<"sessions" | "mcp" | "settings">( + "sessions", + ); + const [mounted, setMounted] = useState(false); + + // Handle portal mounting + useEffect(() => { + setMounted(true); + }, []); + + // Handle escape key + useEffect(() => { + const handleEscape = (e: KeyboardEvent) => { + if (e.key === "Escape") { + onClose(); + } + }; + + if (isOpen) { + document.addEventListener("keydown", handleEscape); + // Prevent body scroll when sidebar is open + document.body.style.overflow = "hidden"; + } + + return () => { + document.removeEventListener("keydown", handleEscape); + document.body.style.overflow = ""; + }; + }, [isOpen, onClose]); + + const handleTabClick = (tab: "sessions" | "mcp" | "settings") => { + setActiveTab(tab); + }; + + const handleBackdropClick = (e: React.MouseEvent) => { + if (e.target === e.currentTarget) { + onClose(); + } + }; + + const renderContent = () => { + switch (activeTab) { + case "sessions": + return ( + + ); + case "mcp": + return ; + case "settings": + return ; + default: + return null; + } + }; + + if (!mounted) return null; + + return createPortal( +
+ {/* Backdrop */} + + + + + +
+ + + {/* Content Area */} +
+ {/* Header with close button */} +
+

{activeTab}

+ +
+ + {/* Tab Content */} +
{renderContent()}
+
+ + , + document.body, + ); +}; diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx index e2deae4..47f191f 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx @@ -2,10 +2,10 @@ import { MessageSquareIcon, PlugIcon, SettingsIcon } from "lucide-react"; import { type FC, useState } from "react"; -import { Dialog, DialogContent } from "@/components/ui/dialog"; import { cn } from "@/lib/utils"; import { useProject } from "../../../../hooks/useProject"; import { McpTab } from "./McpTab"; +import { MobileSidebar } from "./MobileSidebar"; import { SessionsTab } from "./SessionsTab"; import { SettingsTab } from "./SettingsTab"; @@ -133,17 +133,13 @@ export const SessionSidebar: FC<{ {sidebarContent} - {/* Mobile sidebar - rendered in dialog */} -
- - -
{sidebarContent}
-
-
-
+ {/* Mobile sidebar */} + onMobileOpenChange?.(false)} + /> ); };