Masters-four-Tab-OpenAI / frontend /src /components /AssistantWorkspace.tsx
Pete Dunn
Finalize UI lock and full validation reruns
38a90cc
Raw
History Blame Contribute Delete
2.86 kB
import React from "react";
import { AssistantShell } from "./PageArchetypes";
import { ButtonSoft, Card } from "./ui";
type AssistantWorkspaceProps = {
title: string;
description: string;
setupTitle?: string;
setupSummary: string;
hasConversation: boolean;
setupContent: React.ReactNode;
toolsContent?: React.ReactNode;
conversationContent: React.ReactNode;
secondaryRail?: React.ReactNode;
supplementalContent?: React.ReactNode;
modalContent?: React.ReactNode;
};
type AssistantSetupPanelProps = {
title?: string;
summary: string;
hasConversation: boolean;
children: React.ReactNode;
};
export function AssistantSetupPanel(props: AssistantSetupPanelProps) {
const {
title = "Assistant setup",
summary,
hasConversation,
children,
} = props;
const [setupOpen, setSetupOpen] = React.useState(!hasConversation);
const conversationSeenRef = React.useRef(hasConversation);
React.useEffect(() => {
if (hasConversation && !conversationSeenRef.current) {
setSetupOpen(false);
}
if (!hasConversation && conversationSeenRef.current) {
setSetupOpen(true);
}
conversationSeenRef.current = hasConversation;
}, [hasConversation]);
return (
<Card className="p-4 sm:p-5">
<div className="flex flex-wrap items-start justify-between gap-3">
<div className="max-w-3xl">
<div className="text-sm font-semibold text-slate-900">{title}</div>
{setupOpen ? <div className="mt-1 text-sm text-slate-600">{summary}</div> : null}
</div>
<ButtonSoft onClick={() => setSetupOpen((value) => !value)}>{setupOpen ? "Hide setup" : "Show setup"}</ButtonSoft>
</div>
{setupOpen ? <div className="mt-4">{children}</div> : null}
</Card>
);
}
export default function AssistantWorkspace(props: AssistantWorkspaceProps) {
const {
title,
description,
setupTitle = "Assistant setup",
setupSummary,
hasConversation,
setupContent,
toolsContent,
conversationContent,
secondaryRail,
supplementalContent,
modalContent,
} = props;
return (
<AssistantShell title={title} description={description}>
<AssistantSetupPanel title={setupTitle} summary={setupSummary} hasConversation={hasConversation}>
<div className={`grid gap-4 ${toolsContent ? "lg:grid-cols-[minmax(0,1fr)_18rem]" : ""}`}>
<div className="space-y-4">{setupContent}</div>
{toolsContent ? <div className="space-y-4">{toolsContent}</div> : null}
</div>
</AssistantSetupPanel>
<div className={`grid gap-4 ${secondaryRail ? "lg:grid-cols-[minmax(0,1fr)_20rem] xl:grid-cols-[minmax(0,1fr)_22rem]" : ""}`}>
{conversationContent}
{secondaryRail ? secondaryRail : null}
</div>
{supplementalContent}
{modalContent}
</AssistantShell>
);
}