Files
admin/src/app/(root)/admin/create.tsx

238 lines
6.9 KiB
TypeScript

import { zodResolver } from "@hookform/resolvers/zod"
import { useState } from "react"
import { Controller, useForm } from "react-hook-form"
import { toast } from "sonner"
import z from "zod"
import { createAdmin } from "@/actions/admin"
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import {
Field,
FieldError,
FieldGroup,
FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { AdminStatus } from "@/models/admin"
const schema = z.object({
username: z.string().min(1, "请输入用户名"),
password: z.string().min(6, "密码至少 6 位"),
name: z.string().optional(),
phone: z.string().optional(),
email: z.string().email("请输入有效的邮箱地址").optional().or(z.literal("")),
status: z.nativeEnum(AdminStatus),
})
type FormValues = z.infer<typeof schema>
export function CreateAdmin(props: { onSuccess?: () => void }) {
const [open, setOpen] = useState(false)
const form = useForm<FormValues>({
resolver: zodResolver(schema),
defaultValues: {
username: "",
password: "",
name: "",
phone: "",
email: "",
status: AdminStatus.Enabled,
},
})
const onSubmit = async (data: FormValues) => {
try {
const resp = await createAdmin({
username: data.username,
password: data.password,
name: data.name || undefined,
phone: data.phone || undefined,
email: data.email || undefined,
status: data.status,
})
if (resp.success) {
form.reset()
toast.success("管理员创建成功")
props.onSuccess?.()
setOpen(false)
} else {
toast.error(resp.message)
}
} catch (error) {
const message = error instanceof Error ? error.message : error
toast.error(`接口请求错误: ${message}`)
}
}
const handleOpenChange = (value: boolean) => {
if (!value) {
form.reset()
}
setOpen(value)
}
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
<Button></Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
<form id="admin-create" onSubmit={form.handleSubmit(onSubmit)}>
<FieldGroup>
<Controller
control={form.control}
name="username"
render={({ field, fieldState }) => (
<Field>
<FieldLabel htmlFor="admin-create-username">
</FieldLabel>
<Input
id="admin-create-username"
autoComplete="off"
{...field}
aria-invalid={fieldState.invalid}
/>
{fieldState.invalid && (
<FieldError errors={[fieldState.error]} />
)}
</Field>
)}
/>
<Controller
control={form.control}
name="password"
render={({ field, fieldState }) => (
<Field>
<FieldLabel htmlFor="admin-create-password"></FieldLabel>
<Input
id="admin-create-password"
type="password"
autoComplete="new-password"
{...field}
aria-invalid={fieldState.invalid}
/>
{fieldState.invalid && (
<FieldError errors={[fieldState.error]} />
)}
</Field>
)}
/>
<Controller
control={form.control}
name="name"
render={({ field, fieldState }) => (
<Field>
<FieldLabel htmlFor="admin-create-name"></FieldLabel>
<Input
id="admin-create-name"
{...field}
aria-invalid={fieldState.invalid}
/>
{fieldState.invalid && (
<FieldError errors={[fieldState.error]} />
)}
</Field>
)}
/>
<Controller
control={form.control}
name="phone"
render={({ field, fieldState }) => (
<Field>
<FieldLabel htmlFor="admin-create-phone"></FieldLabel>
<Input
id="admin-create-phone"
{...field}
aria-invalid={fieldState.invalid}
/>
{fieldState.invalid && (
<FieldError errors={[fieldState.error]} />
)}
</Field>
)}
/>
<Controller
control={form.control}
name="email"
render={({ field, fieldState }) => (
<Field>
<FieldLabel htmlFor="admin-create-email"></FieldLabel>
<Input
id="admin-create-email"
{...field}
aria-invalid={fieldState.invalid}
/>
{fieldState.invalid && (
<FieldError errors={[fieldState.error]} />
)}
</Field>
)}
/>
<Controller
control={form.control}
name="status"
render={({ field }) => (
<Field>
<FieldLabel></FieldLabel>
<Select
value={String(field.value)}
onValueChange={value => field.onChange(Number(value))}
>
<SelectTrigger className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value={String(AdminStatus.Enabled)}>
</SelectItem>
<SelectItem value={String(AdminStatus.Disabled)}>
</SelectItem>
</SelectContent>
</Select>
</Field>
)}
/>
</FieldGroup>
</form>
<DialogFooter>
<DialogClose asChild>
<Button variant="ghost"></Button>
</DialogClose>
<Button type="submit" form="admin-create">
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}