2026-01-09 11:58:08 +08:00
|
|
|
|
"use client"
|
|
|
|
|
|
|
|
|
|
|
|
import { useState } from "react"
|
2026-01-14 05:41:44 +00:00
|
|
|
|
import { X, Phone, Lock, User, Gift } from "lucide-react"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
import { Button } from "@/components/ui/button"
|
|
|
|
|
|
import { Input } from "@/components/ui/input"
|
|
|
|
|
|
import { useStore } from "@/lib/store"
|
|
|
|
|
|
|
|
|
|
|
|
interface AuthModalProps {
|
|
|
|
|
|
isOpen: boolean
|
|
|
|
|
|
onClose: () => void
|
|
|
|
|
|
defaultTab?: "login" | "register"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function AuthModal({ isOpen, onClose, defaultTab = "login" }: AuthModalProps) {
|
|
|
|
|
|
const [tab, setTab] = useState<"login" | "register">(defaultTab)
|
|
|
|
|
|
const [phone, setPhone] = useState("")
|
2026-01-14 05:41:44 +00:00
|
|
|
|
const [password, setPassword] = useState("")
|
2026-01-09 11:58:08 +08:00
|
|
|
|
const [nickname, setNickname] = useState("")
|
|
|
|
|
|
const [referralCode, setReferralCode] = useState("")
|
|
|
|
|
|
const [error, setError] = useState("")
|
2026-01-14 05:41:44 +00:00
|
|
|
|
const [isLoading, setIsLoading] = useState(false)
|
2026-01-09 11:58:08 +08:00
|
|
|
|
|
|
|
|
|
|
const { login, register } = useStore()
|
|
|
|
|
|
|
2026-01-14 05:41:44 +00:00
|
|
|
|
const handleLogin = async () => {
|
|
|
|
|
|
setError("")
|
2026-01-09 11:58:08 +08:00
|
|
|
|
if (phone.length !== 11) {
|
|
|
|
|
|
setError("请输入正确的手机号")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-01-14 05:41:44 +00:00
|
|
|
|
if (!password) {
|
|
|
|
|
|
setError("请输入密码")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setIsLoading(true)
|
|
|
|
|
|
// 使用密码替代验证码进行登录
|
|
|
|
|
|
const success = await login(phone, password)
|
|
|
|
|
|
setIsLoading(false)
|
2026-01-09 11:58:08 +08:00
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
|
onClose()
|
|
|
|
|
|
} else {
|
2026-01-14 05:41:44 +00:00
|
|
|
|
setError("手机号或密码错误,请先注册")
|
2026-01-09 11:58:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleRegister = async () => {
|
|
|
|
|
|
setError("")
|
2026-01-14 05:41:44 +00:00
|
|
|
|
if (phone.length !== 11) {
|
|
|
|
|
|
setError("请输入正确的手机号")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!password || password.length < 6) {
|
|
|
|
|
|
setError("密码至少6位")
|
2026-01-09 11:58:08 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-01-14 05:41:44 +00:00
|
|
|
|
|
|
|
|
|
|
setIsLoading(true)
|
|
|
|
|
|
// 昵称可选,默认使用手机号后四位
|
|
|
|
|
|
const name = nickname.trim() || `用户${phone.slice(-4)}`
|
|
|
|
|
|
const success = await register(phone, name, referralCode || undefined)
|
|
|
|
|
|
setIsLoading(false)
|
|
|
|
|
|
|
2026-01-09 11:58:08 +08:00
|
|
|
|
if (success) {
|
|
|
|
|
|
onClose()
|
|
|
|
|
|
} else {
|
2026-01-14 05:41:44 +00:00
|
|
|
|
setError("该手机号已注册,请直接登录")
|
2026-01-09 11:58:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!isOpen) return null
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
|
|
|
|
{/* Backdrop */}
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<div className="absolute inset-0 bg-black/80 backdrop-blur-sm" onClick={onClose} />
|
2026-01-09 11:58:08 +08:00
|
|
|
|
|
|
|
|
|
|
{/* Modal */}
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<div className="relative w-full max-w-sm bg-[#1c1c1e] rounded-2xl border border-white/10 overflow-hidden">
|
2026-01-09 11:58:08 +08:00
|
|
|
|
{/* Close button */}
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={onClose}
|
2026-01-14 05:41:44 +00:00
|
|
|
|
className="absolute top-4 right-4 p-2 text-white/40 hover:text-white transition-colors"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
>
|
|
|
|
|
|
<X className="w-5 h-5" />
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Tabs */}
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<div className="flex border-b border-white/10">
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<button
|
2026-01-14 05:41:44 +00:00
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setTab("login")
|
|
|
|
|
|
setError("")
|
|
|
|
|
|
}}
|
2026-01-09 11:58:08 +08:00
|
|
|
|
className={`flex-1 py-4 text-center transition-colors ${
|
2026-01-14 05:41:44 +00:00
|
|
|
|
tab === "login" ? "text-white border-b-2 border-[#ff3b5c]" : "text-white/40 hover:text-white"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
登录
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button
|
2026-01-14 05:41:44 +00:00
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setTab("register")
|
|
|
|
|
|
setError("")
|
|
|
|
|
|
}}
|
2026-01-09 11:58:08 +08:00
|
|
|
|
className={`flex-1 py-4 text-center transition-colors ${
|
2026-01-14 05:41:44 +00:00
|
|
|
|
tab === "register" ? "text-white border-b-2 border-[#ff3b5c]" : "text-white/40 hover:text-white"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
注册
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Content */}
|
|
|
|
|
|
<div className="p-6">
|
|
|
|
|
|
{tab === "login" ? (
|
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
|
<div>
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<label className="block text-white/60 text-sm mb-2">手机号</label>
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<div className="relative">
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<Phone className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-white/30" />
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<Input
|
|
|
|
|
|
type="tel"
|
|
|
|
|
|
value={phone}
|
|
|
|
|
|
onChange={(e) => setPhone(e.target.value)}
|
|
|
|
|
|
placeholder="请输入手机号"
|
2026-01-14 05:41:44 +00:00
|
|
|
|
className="pl-10 bg-[#2c2c2e] border-white/10 text-white placeholder:text-white/30 h-12 rounded-xl"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
maxLength={11}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<label className="block text-white/60 text-sm mb-2">密码</label>
|
|
|
|
|
|
<div className="relative">
|
|
|
|
|
|
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-white/30" />
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<Input
|
2026-01-14 05:41:44 +00:00
|
|
|
|
type="password"
|
|
|
|
|
|
value={password}
|
|
|
|
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
|
|
|
|
placeholder="请输入密码"
|
|
|
|
|
|
className="pl-10 bg-[#2c2c2e] border-white/10 text-white placeholder:text-white/30 h-12 rounded-xl"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-14 05:41:44 +00:00
|
|
|
|
{error && <p className="text-[#ff3b5c] text-sm">{error}</p>}
|
2026-01-09 11:58:08 +08:00
|
|
|
|
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<Button
|
|
|
|
|
|
onClick={handleLogin}
|
|
|
|
|
|
disabled={isLoading}
|
|
|
|
|
|
className="w-full bg-[#ff3b5c] hover:bg-[#ff5c7a] text-white h-12 rounded-xl font-medium"
|
|
|
|
|
|
>
|
|
|
|
|
|
{isLoading ? "登录中..." : "登录"}
|
2026-01-09 11:58:08 +08:00
|
|
|
|
</Button>
|
2026-01-14 05:41:44 +00:00
|
|
|
|
|
|
|
|
|
|
<p className="text-center text-white/40 text-xs">测试账号:任意11位手机号,密码:123456</p>
|
2026-01-09 11:58:08 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
|
<div>
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<label className="block text-white/60 text-sm mb-2">手机号</label>
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<div className="relative">
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<Phone className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-white/30" />
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<Input
|
|
|
|
|
|
type="tel"
|
|
|
|
|
|
value={phone}
|
|
|
|
|
|
onChange={(e) => setPhone(e.target.value)}
|
|
|
|
|
|
placeholder="请输入手机号"
|
2026-01-14 05:41:44 +00:00
|
|
|
|
className="pl-10 bg-[#2c2c2e] border-white/10 text-white placeholder:text-white/30 h-12 rounded-xl"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
maxLength={11}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<label className="block text-white/60 text-sm mb-2">密码</label>
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<div className="relative">
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-white/30" />
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<Input
|
2026-01-14 05:41:44 +00:00
|
|
|
|
type="password"
|
|
|
|
|
|
value={password}
|
|
|
|
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
|
|
|
|
placeholder="设置密码(至少6位)"
|
|
|
|
|
|
className="pl-10 bg-[#2c2c2e] border-white/10 text-white placeholder:text-white/30 h-12 rounded-xl"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<label className="block text-white/60 text-sm mb-2">昵称(选填)</label>
|
|
|
|
|
|
<div className="relative">
|
|
|
|
|
|
<User className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-white/30" />
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<Input
|
|
|
|
|
|
type="text"
|
2026-01-14 05:41:44 +00:00
|
|
|
|
value={nickname}
|
|
|
|
|
|
onChange={(e) => setNickname(e.target.value)}
|
|
|
|
|
|
placeholder="不填则使用默认昵称"
|
|
|
|
|
|
className="pl-10 bg-[#2c2c2e] border-white/10 text-white placeholder:text-white/30 h-12 rounded-xl"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<label className="block text-white/60 text-sm mb-2">邀请码(选填)</label>
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<div className="relative">
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<Gift className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-white/30" />
|
2026-01-09 11:58:08 +08:00
|
|
|
|
<Input
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
value={referralCode}
|
|
|
|
|
|
onChange={(e) => setReferralCode(e.target.value)}
|
2026-01-14 05:41:44 +00:00
|
|
|
|
placeholder="填写可获得优惠"
|
|
|
|
|
|
className="pl-10 bg-[#2c2c2e] border-white/10 text-white placeholder:text-white/30 h-12 rounded-xl"
|
2026-01-09 11:58:08 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-14 05:41:44 +00:00
|
|
|
|
{error && <p className="text-[#ff3b5c] text-sm">{error}</p>}
|
2026-01-09 11:58:08 +08:00
|
|
|
|
|
2026-01-14 05:41:44 +00:00
|
|
|
|
<Button
|
|
|
|
|
|
onClick={handleRegister}
|
|
|
|
|
|
disabled={isLoading}
|
|
|
|
|
|
className="w-full bg-[#ff3b5c] hover:bg-[#ff5c7a] text-white h-12 rounded-xl font-medium"
|
|
|
|
|
|
>
|
|
|
|
|
|
{isLoading ? "注册中..." : "立即注册"}
|
2026-01-09 11:58:08 +08:00
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|