feat: login/register pages, login dialog, homepage with game categories and player/shop cards

Use standardSchemaResolver instead of zodResolver to work around
Zod v4 type incompatibility with @hookform/resolvers.
This commit is contained in:
zetaloop
2026-02-20 14:17:26 +08:00
parent f7c76db00f
commit e2b47681a3
7 changed files with 392 additions and 21 deletions
+61 -3
View File
@@ -1,8 +1,66 @@
"use client"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { Gamepad2 } from "lucide-react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { useAuthStore } from "@/store/auth"
const loginSchema = z.object({
phone: z.string().min(11, "请输入正确的手机号"),
password: z.string().min(6, "密码至少6位"),
})
export default function LoginPage() {
const router = useRouter()
const { login } = useAuthStore()
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm({
resolver: standardSchemaResolver(loginSchema),
})
const onSubmit = async (_data: z.infer<typeof loginSchema>) => {
await new Promise((r) => setTimeout(r, 500))
login()
router.push("/")
}
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-sm text-muted-foreground"></p>
<div className="space-y-6">
<div className="flex flex-col items-center gap-2">
<Gamepad2 className="h-8 w-8" />
<h1 className="text-2xl font-bold"></h1>
<p className="text-sm text-muted-foreground"></p>
</div>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="phone"></Label>
<Input id="phone" placeholder="请输入手机号" {...register("phone")} />
{errors.phone && <p className="text-xs text-destructive">{errors.phone.message}</p>}
</div>
<div className="space-y-2">
<Label htmlFor="password"></Label>
<Input id="password" type="password" placeholder="请输入密码" {...register("password")} />
{errors.password && <p className="text-xs text-destructive">{errors.password.message}</p>}
</div>
<Button type="submit" className="w-full" disabled={isSubmitting}>
{isSubmitting ? "登录中..." : "登录"}
</Button>
</form>
<p className="text-center text-sm text-muted-foreground">
{" "}
<Link href="/register" className="text-primary underline-offset-4 hover:underline">
</Link>
</p>
</div>
)
}