70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { MessageCircle, X } from "lucide-react";
|
|
import { AssistantPanel } from "./assistant-panel";
|
|
|
|
type Props = {
|
|
configured: boolean;
|
|
userId: string;
|
|
assistantName: string;
|
|
assistantModelRoute: string | null;
|
|
assistantModel: string | null;
|
|
};
|
|
|
|
export function AssistantBubble({
|
|
configured,
|
|
userId,
|
|
assistantName,
|
|
assistantModelRoute,
|
|
assistantModel,
|
|
}: Props) {
|
|
const [open, setOpen] = useState(false);
|
|
|
|
return (
|
|
<div className="assistant-bubble" data-open={open ? "true" : "false"}>
|
|
{open ? (
|
|
<div
|
|
className="assistant-bubble-panel"
|
|
role="dialog"
|
|
aria-label={assistantName}
|
|
aria-modal="false"
|
|
>
|
|
<div className="assistant-bubble-header">
|
|
<div>
|
|
<div className="serif text-[15px] font-medium tracking-tight">{assistantName}</div>
|
|
<div className="muted text-[11px]">Household helper</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
className="assistant-bubble-close"
|
|
aria-label={`Close ${assistantName}`}
|
|
onClick={() => setOpen(false)}
|
|
>
|
|
<X className="size-4" />
|
|
</button>
|
|
</div>
|
|
<AssistantPanel
|
|
key={userId}
|
|
configured={configured}
|
|
userId={userId}
|
|
assistantName={assistantName}
|
|
assistantModelRoute={assistantModelRoute}
|
|
assistantModel={assistantModel}
|
|
/>
|
|
</div>
|
|
) : null}
|
|
|
|
<button
|
|
type="button"
|
|
className="assistant-bubble-trigger"
|
|
aria-label={open ? `Close ${assistantName}` : `Open ${assistantName}`}
|
|
aria-expanded={open}
|
|
onClick={() => setOpen((current) => !current)}
|
|
>
|
|
{open ? <X className="size-5" /> : <MessageCircle className="size-5" />}
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|