165 lines
4.4 KiB
TypeScript
165 lines
4.4 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect } from 'react'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Label } from '@/components/ui/label'
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@/components/ui/dialog'
|
|
import { Spinner } from '@/components/ui/spinner'
|
|
import { User, UserFormData } from '@/types'
|
|
|
|
interface UserDialogProps {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
user?: User | null
|
|
onSubmit: (data: UserFormData) => Promise<void>
|
|
}
|
|
|
|
const defaultFormData: UserFormData = {
|
|
email: '',
|
|
password: '',
|
|
name: '',
|
|
}
|
|
|
|
export function UserDialog({ open, onOpenChange, user, onSubmit }: UserDialogProps) {
|
|
const [formData, setFormData] = useState<UserFormData>(defaultFormData)
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
const [error, setError] = useState('')
|
|
|
|
// Reset form when dialog opens/closes or user changes
|
|
useEffect(() => {
|
|
if (open) {
|
|
if (user) {
|
|
setFormData({
|
|
email: user.email,
|
|
password: '',
|
|
name: user.name || '',
|
|
})
|
|
} else {
|
|
setFormData(defaultFormData)
|
|
}
|
|
setError('')
|
|
}
|
|
}, [open, user])
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
setError('')
|
|
|
|
if (!formData.email.trim()) {
|
|
setError('请输入邮箱')
|
|
return
|
|
}
|
|
|
|
if (!user && !formData.password) {
|
|
setError('请输入密码')
|
|
return
|
|
}
|
|
|
|
if (formData.password && formData.password.length < 6) {
|
|
setError('密码至少需要6个字符')
|
|
return
|
|
}
|
|
|
|
setIsLoading(true)
|
|
try {
|
|
await onSubmit(formData)
|
|
onOpenChange(false)
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : '操作失败,请稍后重试')
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-[400px]">
|
|
<DialogHeader>
|
|
<DialogTitle>{user ? '编辑用户' : '添加用户'}</DialogTitle>
|
|
<DialogDescription>
|
|
{user ? '修改用户信息,密码留空则不修改' : '创建新的平台用户'}
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
{error && (
|
|
<div className="p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-md">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="email">邮箱 *</Label>
|
|
<Input
|
|
id="email"
|
|
type="email"
|
|
value={formData.email}
|
|
onChange={(e) =>
|
|
setFormData((prev) => ({ ...prev, email: e.target.value }))
|
|
}
|
|
placeholder="请输入邮箱"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="password">
|
|
{user ? '密码 (留空则不修改)' : '密码 *'}
|
|
</Label>
|
|
<Input
|
|
id="password"
|
|
type="password"
|
|
value={formData.password}
|
|
onChange={(e) =>
|
|
setFormData((prev) => ({ ...prev, password: e.target.value }))
|
|
}
|
|
placeholder={user ? '留空则不修改密码' : '请输入密码'}
|
|
required={!user}
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="name">姓名 (可选)</Label>
|
|
<Input
|
|
id="name"
|
|
value={formData.name}
|
|
onChange={(e) =>
|
|
setFormData((prev) => ({ ...prev, name: e.target.value }))
|
|
}
|
|
placeholder="请输入姓名"
|
|
/>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
onClick={() => onOpenChange(false)}
|
|
disabled={isLoading}
|
|
>
|
|
取消
|
|
</Button>
|
|
<Button type="submit" disabled={isLoading}>
|
|
{isLoading ? (
|
|
<>
|
|
<Spinner size="sm" className="mr-2" />
|
|
保存中...
|
|
</>
|
|
) : (
|
|
'保存'
|
|
)}
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|