Add debug mode functionality to AssistantPage with text and voice testing options

Introduced a DebugDrawer component to allow users to switch between text and voice testing modes. Enhanced the AssistantPage layout for better organization and added a debug interface for testing AI responses. This update improves usability by providing clear options for debugging and testing the assistant's capabilities.
This commit is contained in:
Xin Wang
2026-06-07 21:05:52 +08:00
parent b6cfba03e0
commit 21aef75fb5

View File

@@ -20,6 +20,8 @@ import {
Save,
Mic,
Volume2,
Send,
MessageCircle,
} from "lucide-react";
import { Button } from "@/components/ui/button";
@@ -190,6 +192,8 @@ const mockAssistants: AssistantListItem[] = [
},
];
type DebugMode = "text" | "voice";
type TypeFilter = "全部" | AssistantType;
const typeFilters: TypeFilter[] = ["全部", ...assistantTypes];
@@ -214,6 +218,8 @@ export function AssistantPage() {
const [searchQuery, setSearchQuery] = useState("");
const [typeFilter, setTypeFilter] = useState<TypeFilter>("全部");
const [currentPage, setCurrentPage] = useState(1);
// 右侧调试 drawer 的当前模式
const [debugMode, setDebugMode] = useState<DebugMode>("text");
// choose 步骤的草稿:名称与已选类型,确认后才决定进入哪个构建页
const [draftName, setDraftName] = useState("");
const [draftType, setDraftType] = useState<AssistantType | null>(null);
@@ -667,21 +673,18 @@ export function AssistantPage() {
}
return (
<div className="mx-auto flex w-full max-w-[1180px] flex-col gap-6">
<div className="flex items-start justify-between gap-6">
<div>
<h1 className="font-display display-lg text-ink">
</h1>
<p className="mt-3 text-[15px] text-muted-foreground">
<div className="-mt-6 flex h-full flex-col gap-4">
<div className="flex shrink-0 items-center justify-between gap-6 border-b border-hairline pb-3 pt-1">
<div className="flex items-baseline gap-3">
<h1 className="font-display display-sm text-ink"></h1>
<p className="hidden text-sm text-muted-foreground lg:block">
AI
</p>
</div>
<div className="flex shrink-0 gap-3">
<div className="flex shrink-0 gap-2">
<Button
variant="outline"
size="lg"
className="gap-2 border-hairline-strong text-muted-foreground hover:text-foreground"
onClick={() => setView("list")}
>
@@ -689,14 +692,15 @@ export function AssistantPage() {
</Button>
<Button size="lg" className="gap-2">
<Button className="gap-2">
<Save size={16} />
</Button>
</div>
</div>
<div className="space-y-5">
<div className="flex min-h-0 flex-1 gap-6">
<div className="min-w-0 flex-1 space-y-5 overflow-y-auto pr-1">
<SectionCard>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<button
@@ -868,6 +872,119 @@ export function AssistantPage() {
onChange={(checked) => updateForm("enableInterrupt", checked)}
/>
</SectionCard>
</div>
<DebugDrawer mode={debugMode} onModeChange={setDebugMode} />
</div>
</div>
);
}
function DebugDrawer({
mode,
onModeChange,
}: {
mode: DebugMode;
onModeChange: (mode: DebugMode) => void;
}) {
const modeTabs: { key: DebugMode; label: string; icon: React.ReactNode }[] = [
{ key: "text", label: "文字测试", icon: <MessageCircle size={15} /> },
{ key: "voice", label: "语音测试", icon: <Mic size={15} /> },
];
return (
<aside className="hidden min-w-0 flex-1 flex-col overflow-hidden rounded-2xl border border-hairline bg-card shadow-sm lg:flex">
<div className="shrink-0 border-b border-hairline p-4">
<div className="mb-3 text-sm font-medium text-foreground"></div>
<div className="flex gap-1 rounded-full bg-surface-strong p-1">
{modeTabs.map((tab) => (
<button
key={tab.key}
type="button"
onClick={() => onModeChange(tab.key)}
className={[
"flex flex-1 items-center justify-center gap-1.5 rounded-full px-3 py-1.5 text-sm transition-colors",
mode === tab.key
? "bg-card text-foreground shadow-sm"
: "text-muted-foreground hover:text-foreground",
].join(" ")}
>
{tab.icon}
{tab.label}
</button>
))}
</div>
</div>
{mode === "text" ? <DebugTextPanel /> : <DebugVoicePanel />}
</aside>
);
}
function DebugTextPanel() {
return (
<div className="flex min-h-0 flex-1 flex-col">
<div className="flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4">
<div className="flex max-w-[85%] flex-col gap-1">
<div className="rounded-2xl rounded-tl-sm bg-surface-strong px-4 py-2.5 text-sm leading-6 text-foreground">
AI
</div>
<span className="px-1 text-xs text-muted-soft"></span>
</div>
<div className="flex max-w-[85%] flex-col items-end gap-1 self-end">
<div className="rounded-2xl rounded-tr-sm bg-primary px-4 py-2.5 text-sm leading-6 text-primary-foreground">
</div>
<span className="px-1 text-xs text-muted-soft"></span>
</div>
<div className="flex max-w-[85%] flex-col gap-1">
<div className="rounded-2xl rounded-tl-sm bg-surface-strong px-4 py-2.5 text-sm leading-6 text-foreground">
线线线 App
线
</div>
<span className="px-1 text-xs text-muted-soft"></span>
</div>
</div>
<div className="shrink-0 border-t border-hairline p-3">
<div className="flex items-end gap-2">
<Textarea
rows={1}
placeholder="输入测试消息…"
className="max-h-28 min-h-10 flex-1 resize-none border-hairline-strong bg-background text-sm text-foreground placeholder:text-muted-soft"
/>
<Button size="icon" className="shrink-0" aria-label="发送">
<Send size={16} />
</Button>
</div>
</div>
</div>
);
}
function DebugVoicePanel() {
return (
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-6 p-6 text-center">
<button
type="button"
className="flex h-24 w-24 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-transform hover:scale-105"
aria-label="开始语音测试"
>
<Mic size={32} />
</button>
<div>
<div className="text-sm font-medium text-foreground"></div>
<p className="mt-1.5 text-sm leading-6 text-muted-foreground">
</p>
</div>
<div className="w-full rounded-xl border border-hairline bg-canvas-soft p-4 text-left">
<div className="caption-label mb-2 text-muted-soft"></div>
<p className="text-sm leading-6 text-muted-soft"></p>
</div>
</div>
);