Also removes the legacy home mode selector from the settings form because the affected JSX lives inside the same settings client refactor.
122 lines
2.8 KiB
TypeScript
122 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { ArrowDown, ArrowUp } from "lucide-react";
|
|
import type { ReactNode } from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
import { cn } from "@/lib/utils";
|
|
import type { SettingStatusTone } from "../_lib/types";
|
|
import { SettingStatusBadge } from "./setting-status-badge";
|
|
|
|
export function LocalAiGroupHeading({
|
|
eyebrow,
|
|
title,
|
|
description,
|
|
}: {
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
}) {
|
|
return (
|
|
<div className="rounded-lg border bg-muted/20 px-4 py-3">
|
|
<div className="font-semibold text-[11px] text-muted-foreground uppercase tracking-[0.16em]">
|
|
{eyebrow}
|
|
</div>
|
|
<div className="mt-1 flex flex-col gap-1 md:flex-row md:items-end md:justify-between">
|
|
<h3 className="font-semibold text-base text-foreground">{title}</h3>
|
|
<p className="max-w-3xl text-muted-foreground text-sm">{description}</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function LocalAiSectionSummary({
|
|
items,
|
|
}: {
|
|
items: Array<{
|
|
label: string;
|
|
tone?: SettingStatusTone;
|
|
}>;
|
|
}) {
|
|
return (
|
|
<div className="flex flex-wrap gap-2 pt-1">
|
|
{items.map((item) => (
|
|
<SettingStatusBadge key={item.label} tone={item.tone || "neutral"}>
|
|
{item.label}
|
|
</SettingStatusBadge>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function LocalAiSectionToggleButton({
|
|
expanded,
|
|
onClick,
|
|
}: {
|
|
expanded: boolean;
|
|
onClick: () => void;
|
|
}) {
|
|
return (
|
|
<Button
|
|
aria-expanded={expanded}
|
|
className="h-8 shrink-0 gap-1.5 rounded-md px-2.5 text-xs"
|
|
onClick={onClick}
|
|
size="sm"
|
|
type="button"
|
|
variant="outline"
|
|
>
|
|
{expanded ? (
|
|
<ArrowUp className="h-3.5 w-3.5" />
|
|
) : (
|
|
<ArrowDown className="h-3.5 w-3.5" />
|
|
)}
|
|
{expanded ? "收起配置" : "展开配置"}
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
export function LocalAiSectionShell({
|
|
id,
|
|
title,
|
|
description,
|
|
summary,
|
|
expanded,
|
|
onToggle,
|
|
children,
|
|
}: {
|
|
id: string;
|
|
title: ReactNode;
|
|
description: ReactNode;
|
|
summary?: ReactNode;
|
|
expanded: boolean;
|
|
onToggle: () => void;
|
|
children: ReactNode;
|
|
}) {
|
|
return (
|
|
<Card id={id}>
|
|
<CardHeader className="flex flex-col gap-4 space-y-0 md:flex-row md:items-start md:justify-between">
|
|
<div className="space-y-1.5">
|
|
<CardTitle className="text-xl">{title}</CardTitle>
|
|
<CardDescription>{description}</CardDescription>
|
|
{summary}
|
|
</div>
|
|
<LocalAiSectionToggleButton expanded={expanded} onClick={onToggle} />
|
|
</CardHeader>
|
|
<CardContent
|
|
className={cn(
|
|
"local-ai-config-card-content space-y-6 pt-6",
|
|
!expanded && "hidden"
|
|
)}
|
|
>
|
|
{children}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|