diff --git a/web/app/dashboard/conversations/_components/chat-panel.tsx b/web/app/dashboard/conversations/_components/chat-panel.tsx index 91a03b6..6054d23 100644 --- a/web/app/dashboard/conversations/_components/chat-panel.tsx +++ b/web/app/dashboard/conversations/_components/chat-panel.tsx @@ -1,6 +1,15 @@ "use client"; -import { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from "react"; +import { + memo, + type ReactNode, + useCallback, + useEffect, + useLayoutEffect, + useRef, + useState, +} from "react"; +import { BotIcon, LockKeyholeIcon, UserCheckIcon } from "lucide-react"; import { toast } from "sonner"; import { ConversationTransferDialog } from "@/components/conversation-actions/transfer-dialog"; @@ -39,6 +48,63 @@ import { AgentMessageEditor } from "./agent-message-editor"; const EMPTY_AGENT_MESSAGES: AgentMessage[] = []; +type ComposerNoticeTone = "muted" | "ai" | "action"; + +type ComposerNoticeProps = { + icon: ReactNode; + message: string; + tone?: ComposerNoticeTone; + action?: ReactNode; +}; + +function getComposerNoticeClassName(tone: ComposerNoticeTone) { + if (tone === "ai") { + return { + wrap: "border-primary/15 bg-primary/5", + icon: "bg-primary/10 text-primary", + }; + } + + if (tone === "action") { + return { + wrap: "border-border bg-muted/35", + icon: "bg-background text-foreground shadow-sm", + }; + } + + return { + wrap: "border-border bg-muted/30", + icon: "bg-muted text-muted-foreground", + }; +} + +function ComposerNotice({ + icon, + message, + tone = "muted", + action, +}: ComposerNoticeProps) { + const className = getComposerNoticeClassName(tone); + + return ( +
+
+
+ {icon} +
+
+ {message} +
+ {action ?
{action}
: null} +
+
+ ); +} + export function ChatPanel() { const t = useI18n(); const conversation = useAgentConversationsStore( @@ -395,16 +461,22 @@ export function ChatPanel() { const bottomPanel = (
{isClosedConversation ? ( -
- {t("conversation.closedNotice")} -
+ } + message={t("conversation.closedNotice")} + /> ) : conversation?.status === 1 ? ( -
- {t("conversation.aiServingNotice")} -
+ } + message={t("conversation.aiServingNotice")} + tone="ai" + /> ) : isPendingConversation ? ( -
-
+ } + message={t("conversation.claimCurrent")} + tone="action" + action={ -
-
+ } + /> ) : (