---
description: "Shadcn-ui 管理页表单开发指令"
---

## 概述
基于 `src/client/admin-shadcn/pages/Users.tsx` 中用户管理表单的实现，提取可复用的表单开发模式和最佳实践，适用于基于 Shadcn-ui 的管理后台表单开发。

## 核心特性

### 1. 类型安全表单
- **后端Schema复用**：直接使用后端定义的 Zod Schema
- **RPC类型提取**：从 Hono 客户端自动推断类型
- **一致的类型定义**：前后端类型完全同步

### 2. 表单状态管理
- **创建/编辑模式切换**：单一表单处理两种状态
- **智能默认值**：根据模式自动设置表单初始值
- **表单重置**：模式切换时自动重置表单状态

### 3. 统一的UI组件模式
- **Shadcn-ui组件集成**：使用标准的 Shadcn-ui 表单组件
- **响应式布局**：适配不同屏幕尺寸
- **无障碍支持**：完整的 ARIA 属性支持

## 开发模板

### 基础结构模板
```typescript
// 1. 类型定义
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form';
import { Input } from '@/client/components/ui/input';
import { Button } from '@/client/components/ui/button';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog';

// 2. 表单配置
const [isCreateForm, setIsCreateForm] = useState(true);
const [editingData, setEditingData] = useState<any>(null);

const createForm = useForm<CreateType>({
  resolver: zodResolver(createSchema),
  defaultValues: {/* 创建时的默认值 */},
});

const updateForm = useForm<UpdateType>({
  resolver: zodResolver(updateSchema),
  defaultValues: {/* 更新时的默认值 */},
});
```

### 表单字段模板

#### 文本输入框
```typescript
<FormField
  control={form.control}
  name="username"
  render={({ field }) => (
    <FormItem>
      <FormLabel className="flex items-center">
        用户名
        <span className="text-red-500 ml-1">*</span>
      </FormLabel>
      <FormControl>
        <Input placeholder="请输入用户名" {...field} />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>
```

#### 邮箱输入框
```typescript
<FormField
  control={form.control}
  name="email"
  render={({ field }) => (
    <FormItem>
      <FormLabel>邮箱</FormLabel>
      <FormControl>
        <Input type="email" placeholder="请输入邮箱" {...field} />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>
```

#### 密码输入框
```typescript
<FormField
  control={form.control}
  name="password"
  render={({ field }) => (
    <FormItem>
      <FormLabel className="flex items-center">
        密码
        <span className="text-red-500 ml-1">*</span>
      </FormLabel>
      <FormControl>
        <Input type="password" placeholder="请输入密码" {...field} />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>
```

#### 开关控件（布尔值）
```typescript
<FormField
  control={form.control}
  name="isDisabled"
  render={({ field }) => (
    <FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
      <div className="space-y-0.5">
        <FormLabel className="text-base">状态</FormLabel>
        <FormDescription>
          禁用后用户将无法登录系统
        </FormDescription>
      </div>
      <FormControl>
        <Switch
          checked={field.value === 1}
          onCheckedChange={(checked) => field.onChange(checked ? 1 : 0)}
        />
      </FormControl>
    </FormItem>
  )}
/>
```

#### 可选字段处理
```typescript
// 创建时：必须提供值
nickname: z.string().optional()

// 更新时：完全可选
nickname: z.string().optional()
```

### 对话框集成模板
```typescript
<Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
  <DialogContent className="sm:max-w-[500px]">
    <DialogHeader>
      <DialogTitle>{isCreateForm ? '创建' : '编辑'}用户</DialogTitle>
      <DialogDescription>
        {isCreateForm ? '创建新记录' : '编辑现有记录'}
      </DialogDescription>
    </DialogHeader>
    
    <Form {...(isCreateForm ? createForm : updateForm)}>
      <form onSubmit={form.handleSubmit(isCreateForm ? handleCreate : handleUpdate)} className="space-y-4">
        {/* 表单字段 */}
        
        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
            取消
          </Button>
          <Button type="submit">
            {isCreateForm ? '创建' : '更新'}
          </Button>
        </DialogFooter>
      </form>
    </Form>
  </DialogContent>
</Dialog>
```

## 最佳实践

### 1. 表单验证
- 使用 Zod Schema 进行类型验证
- 必填字段标记红色星号
- 提供清晰的错误提示

### 2. 用户体验
- 表单提交时显示加载状态
- 操作成功后显示 toast 通知
- 支持键盘导航和提交

### 3. 数据管理
- 创建后自动刷新数据列表
- 编辑时回填现有数据
- 支持表单重置功能

### 4. 响应式设计
- 对话框最大宽度 `sm:max-w-[500px]`
- 表单间距统一使用 `space-y-4`
- 移动端友好的布局

## 使用示例

### 完整实现参考
```typescript
// 创建用户
const handleCreateSubmit = async (data: CreateUserFormData) => {
  try {
    const res = await apiClient.$post({ json: data });
    if (res.status !== 201) throw new Error('创建失败');
    toast.success('创建成功');
    setIsModalOpen(false);
    refetch();
  } catch (error) {
    toast.error('创建失败，请重试');
  }
};

// 更新用户
const handleUpdateSubmit = async (data: UpdateUserFormData) => {
  try {
    const res = await apiClient[':id']['$put']({
      param: { id: editingData.id },
      json: data
    });
    if (res.status !== 200) throw new Error('更新失败');
    toast.success('更新成功');
    setIsModalOpen(false);
    refetch();
  } catch (error) {
    toast.error('更新失败，请重试');
  }
};
```

## 组件导入清单
```typescript
// 表单相关
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form';
import { Input } from '@/client/components/ui/input';
import { Button } from '@/client/components/ui/button';
import { Switch } from '@/client/components/ui/switch';

// 对话框相关
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog';

// 表单工具
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { toast } from 'sonner';