docs(03): 据 researcher 实测修正 CONTEXT.md(Sonner Toaster 未挂载关键 bug + kebab-case 命名 + 直接 import sonner toast + 显式 import handleApiError)
This commit is contained in:
parent
c21a16af5c
commit
1068c77075
@ -29,9 +29,9 @@
|
||||
|
||||
### 组件抽离
|
||||
|
||||
- **新建**:`components/ai-model/CredentialSlotDialog.tsx`
|
||||
- 该路径目录 `components/ai-model/` 可能不存在;需 planner 在 read_first 阶段确认(推测目前没有,若没有则 mkdir)
|
||||
- 沿用 shadcn 组件风格(参考现有 `components/songs/` / `components/outfits/` 等已有业务组件目录的写法)
|
||||
- **新建**:`components/ai-model/credential-slot-dialog.tsx`(researcher 修正:仓库 9 个现有业务对话框全部 **kebab-case**,如 `add-song-dialog.tsx` / `user-form-dialog.tsx`,本 phase 跟规约)
|
||||
- 该路径目录 `components/ai-model/` **确认不存在**(researcher 实测 `ls` 退出码 2),需要 mkdir
|
||||
- 沿用 shadcn 组件风格 + RHF + Zod;1:1 模板首选 `components/users/user-form-dialog.tsx` L1-289(最贴近本 phase 形态:单 dialog + 几个字段 + RHF + Zod + Form wrapper + Loader2 spinner + 提交后关闭)
|
||||
- **修改**:`app/ai-model/page.tsx`
|
||||
- 删除 Phase 2 落地的占位 Dialog(约第 473-485 行的内联 Dialog)
|
||||
- 用 `<CredentialSlotDialog open={isCredentialDialogOpen} onOpenChange={setIsCredentialDialogOpen} />` 替换
|
||||
@ -153,12 +153,35 @@ const onSubmit = async (values: { appId: string; accessToken: string }) => {
|
||||
|
||||
**Planner 重要:必须按"强制输入"路线落地,不要尝试实现"留空保留旧值"**(除非 plan-checker 一轮里我明确改主意)。
|
||||
|
||||
### Toast 通知
|
||||
### Toast 通知(researcher 修正:3 个关键纠偏)
|
||||
|
||||
- **Sonner**(项目已用,参考 `components/ui/sonner.tsx` 或 `hooks/use-toast.ts`)
|
||||
- 成功文案:"凭据槽位已更新" / 描述:"配置已生效"
|
||||
- 失败文案:title "保存失败" / description: 经 `handleApiError` 映射后的中文消息
|
||||
- variant:失败用 `destructive`(如 Sonner 支持)
|
||||
**纠偏 1 — Sonner Toaster 全局未挂载(关键 pre-existing bug)**:
|
||||
- `app/layout.tsx` 是 20 行裸 RootLayout,没有 `<Toaster />`
|
||||
- 现有 9 处 `toast(...)` 调用其实**全是 dead code**(toast 不会显示)
|
||||
- **本 phase 必须前置一个任务**:在 `app/layout.tsx` `<body>` 末尾挂载 `<Toaster />` from `@/components/ui/sonner`
|
||||
- 否则 Phase 3 的成功 / 失败反馈完全静默
|
||||
|
||||
**纠偏 2 — 双 `useToast` 实现都是 Radix Toast,与 Sonner 不通**:
|
||||
- `hooks/use-toast.ts` + `components/ui/use-toast.ts` 是两份内容相同的 Radix Toast 实现(295 行 dead code)
|
||||
- 不要走 `useToast` hook
|
||||
- **直接** `import { toast } from "sonner"` 命令式调用:`toast.success(...)` / `toast.error(...)`
|
||||
|
||||
**纠偏 3 — 双 `handleApiError` 函数**:
|
||||
- `lib/api/error-handler.ts:38` `(error: unknown): string` ← 用这个
|
||||
- `lib/api/index.ts:191` `(error: any): string` ← 同名重复定义,**不要**从 barrel import
|
||||
- 显式 import:`import { handleApiError } from '@/lib/api/error-handler'`
|
||||
|
||||
**Toast 调用形态**:
|
||||
```typescript
|
||||
import { toast } from "sonner"
|
||||
import { handleApiError } from "@/lib/api/error-handler"
|
||||
|
||||
// 成功
|
||||
toast.success("凭据槽位已更新", { description: "配置已生效" })
|
||||
|
||||
// 失败
|
||||
toast.error("保存失败", { description: handleApiError(e) })
|
||||
```
|
||||
|
||||
### 错误处理
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user