102 lines
2.9 KiB
React
102 lines
2.9 KiB
React
// ChatLayout.jsx
|
|
import React, { useState, useEffect } from "react";
|
|
import ChatHeader from "./ChatHeader";
|
|
import ChatWindow from "./ChatWindow";
|
|
import ChatInput from "./ChatInput";
|
|
import SessionTable from "./SessionTable";
|
|
|
|
export default function ChatLayout({
|
|
theme,
|
|
messages,
|
|
loading,
|
|
onSend,
|
|
onStop,
|
|
onToggleTheme,
|
|
onReloadHistory,
|
|
onFreshStart,
|
|
onCreateSession,
|
|
onEditSession,
|
|
onSelectSession,
|
|
userId
|
|
}) {
|
|
const [showSessionsPanel, setShowSessionsPanel] = useState(false);
|
|
|
|
// 1️⃣ helper at the top (inside the component is fine)
|
|
function getScrollbarWidth() {
|
|
return window.innerWidth - document.documentElement.clientWidth;
|
|
}
|
|
|
|
// update body class when panel state changes
|
|
useEffect(() => {
|
|
document.body.classList.toggle("sessions-open", showSessionsPanel);
|
|
}, [showSessionsPanel]);
|
|
|
|
// 2️⃣ revised toggles
|
|
const openSessionManager = () => {
|
|
const scrollBarWidth = getScrollbarWidth();
|
|
document.body.style.overflow = "hidden";
|
|
document.body.style.paddingRight = `${scrollBarWidth}px`;
|
|
setShowSessionsPanel(true);
|
|
};
|
|
|
|
const closeSessionManager = () => {
|
|
document.body.style.overflow = "";
|
|
document.body.style.paddingRight = "";
|
|
setShowSessionsPanel(false);
|
|
document.body.classList.remove("sessions-open"); // extra sicurezza
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className={`sessions-wrapper d-flex flex-column vh-100 ${theme.bodyBg}`}>
|
|
<ChatHeader
|
|
theme={theme}
|
|
onToggleTheme={onToggleTheme}
|
|
onReloadHistory={onReloadHistory}
|
|
onFreshStart={onFreshStart}
|
|
onCreateSession={onCreateSession}
|
|
onEditSession={onEditSession}
|
|
onManageSession={openSessionManager} // opens panel
|
|
/>
|
|
|
|
<div className="flex-grow-1 overflow-auto">
|
|
<ChatWindow messages={messages} loading={loading} theme={theme} />
|
|
</div>
|
|
|
|
{loading && (
|
|
<div className="p-2 text-center">
|
|
<button className="btn btn-warning btn-sm" onClick={onStop}>
|
|
⏹ Stop Generating
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
<ChatInput onSend={onSend} loading={loading} />
|
|
</div>
|
|
|
|
<div
|
|
className={`offcanvas offcanvas-start ${showSessionsPanel ? "show" : ""}`}
|
|
tabIndex="-1"
|
|
style={{ visibility: showSessionsPanel ? "visible" : "hidden" }}
|
|
>
|
|
<div className="offcanvas-header">
|
|
<h5 className="offcanvas-title">Manage Sessions</h5>
|
|
<button
|
|
type="button"
|
|
className="btn-close text-reset"
|
|
onClick={closeSessionManager} // closes panel
|
|
></button>
|
|
</div>
|
|
<div className="offcanvas-body">
|
|
<SessionTable
|
|
userId={userId}
|
|
onSelectSession={onSelectSession}
|
|
onClosePanel={closeSessionManager}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|