feat(02-01): /ai-model 页面新增凭据槽位入口 Button + 占位 Dialog

- 文件转为 Client Component(line 1 加 'use client')
- 新增 import:useState/useEffect (react)、Dialog 子组件 5 个、KeyRound (lucide-react)、hasPermission (@/lib/permissions)
- 函数体顶部加 mounted 守卫 + isCredentialDialogOpen 两个 useState(复用 sidebar.tsx 同模式避免 SSR 水合警告)
- DashboardHeader children 改为 flex 容器,包含原「添加新模型」+ 新增「凭据槽位」(variant=outline)
- 凭据槽位 Button 由 mounted && hasPermission('credential-slot') 收敛,未授权角色 DOM 中完全不存在
- </Tabs> 之后插入 controlled mode 占位 Dialog,DialogTitle「通用凭据槽位」+ DialogDescription 提示由 Phase 3 落地
- Tabs / TabsContent / Card 等所有原有内容(line 18-441)逐字未动
This commit is contained in:
pmc 2026-05-08 11:44:07 +08:00
parent d60dd897c7
commit 0bcaa398cc

View File

@ -1,18 +1,47 @@
"use client"
import { useState, useEffect } from "react"
import { DashboardShell } from "@/components/dashboard-shell"
import { DashboardHeader } from "@/components/dashboard-header"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Brain, Mic, Database, Plus, Sparkles, Edit, Play, Sliders, User } from "lucide-react"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
import { Brain, Mic, Database, Plus, Sparkles, Edit, Play, Sliders, User, KeyRound } from "lucide-react"
import { hasPermission } from "@/lib/permissions"
export default function AIModelPage() {
const [mounted, setMounted] = useState(false)
const [isCredentialDialogOpen, setIsCredentialDialogOpen] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
return (
<DashboardShell>
<DashboardHeader heading="大模型管理" text="管理洛天依的AI模型、语音和知识库">
<Button className="bg-gradient-to-r from-pink-500 to-purple-600 hover:from-pink-600 hover:to-purple-700 transition-all duration-300 shadow-md hover:shadow-lg">
<Plus className="mr-2 h-4 w-4" />
</Button>
<div className="flex items-center gap-2">
<Button className="bg-gradient-to-r from-pink-500 to-purple-600 hover:from-pink-600 hover:to-purple-700 transition-all duration-300 shadow-md hover:shadow-lg">
<Plus className="mr-2 h-4 w-4" />
</Button>
{mounted && hasPermission("credential-slot") && (
<Button
variant="outline"
onClick={() => setIsCredentialDialogOpen(true)}
>
<KeyRound className="mr-2 h-4 w-4" />
</Button>
)}
</div>
</DashboardHeader>
<Tabs defaultValue="framework" className="space-y-4">
@ -440,6 +469,20 @@ export default function AIModelPage() {
</Card>
</TabsContent>
</Tabs>
<Dialog
open={isCredentialDialogOpen}
onOpenChange={setIsCredentialDialogOpen}
>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
Phase 3
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
</DashboardShell>
)
}