暂无可用套餐时取消加载中 & 登录页加返回首页 & 加联系专属客服 & 修改白名单上限10个
This commit is contained in:
@@ -6,7 +6,7 @@ import {Card, CardContent} from '@/components/ui/card'
|
||||
import {Form, FormField} from '@/components/ui/form'
|
||||
import {Label} from '@/components/ui/label'
|
||||
import {Tabs, TabsList, TabsTrigger} from '@/components/ui/tabs'
|
||||
import {EyeClosedIcon, EyeIcon} from 'lucide-react'
|
||||
import {EyeClosedIcon, EyeIcon, HomeIcon} from 'lucide-react'
|
||||
import {useState, ReactNode, useEffect, Suspense} from 'react'
|
||||
import zod from 'zod'
|
||||
import {useForm, useFormContext, useWatch} from 'react-hook-form'
|
||||
@@ -16,6 +16,7 @@ import {useRouter} from 'next/navigation'
|
||||
import {login, LoginMode} from '@/actions/auth'
|
||||
import {useProfileStore} from '@/components/stores/profile'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
|
||||
const smsSchema = zod.object({
|
||||
username: zod.string().length(11, '请输入正确的手机号码'),
|
||||
@@ -88,111 +89,122 @@ export default function LoginCard() {
|
||||
const [showPwd, setShowPwd] = useState(false)
|
||||
|
||||
return (
|
||||
<Card className="w-96 mx-4 shadow-lg relative z-20 py-8">
|
||||
<CardContent className="px-8">
|
||||
{/* 登录方式切换 */}
|
||||
<Tabs
|
||||
value={mode}
|
||||
onValueChange={(val) => {
|
||||
setMode(val as LoginMode)
|
||||
form.reset({username: '', password: '', remember: false})
|
||||
form.clearErrors()
|
||||
}}
|
||||
className="mb-6">
|
||||
<TabsList className="w-full p-0 bg-white">
|
||||
<Tab value="password">密码登录</Tab>
|
||||
<Tab value="phone_code">验证码登录/注册</Tab>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<Form<LoginSchema> className="space-y-6" form={form} handler={handler}>
|
||||
<FormField name="username" label={mode === 'phone_code' ? '手机号' : '用户名'}>
|
||||
{({id, field}) => (
|
||||
<Input
|
||||
{...field}
|
||||
id={id}
|
||||
type="tel"
|
||||
placeholder={mode === 'phone_code' ? '请输入手机号' : '请输入用户名/手机号/邮箱'}
|
||||
autoComplete="tel-national"
|
||||
/>
|
||||
)}
|
||||
</FormField>
|
||||
<FormField name="password" label={mode === 'phone_code' ? '验证码' : '密码'}>
|
||||
{({id, field}) =>
|
||||
mode === 'phone_code' ? (
|
||||
<div className="flex space-x-4">
|
||||
<Input
|
||||
{...field}
|
||||
id={id}
|
||||
className="h-10"
|
||||
placeholder="请输入验证码"
|
||||
autoComplete="one-time-code"
|
||||
disabled={submitting}
|
||||
/>
|
||||
<SendMsgByUsername/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="relative">
|
||||
<Input
|
||||
{...field}
|
||||
id={id}
|
||||
type={showPwd ? 'text' : 'password'}
|
||||
className="h-10 pr-10"
|
||||
placeholder="至少6位密码,需包含字母和数字"
|
||||
autoComplete="current-password"
|
||||
minLength={6}
|
||||
disabled={submitting}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 cursor-pointer"
|
||||
onClick={() => setShowPwd(v => !v)}
|
||||
aria-label={showPwd ? '隐藏密码' : '显示密码'}
|
||||
>
|
||||
{showPwd ? (
|
||||
<EyeIcon size={20}/>
|
||||
) : (
|
||||
<EyeClosedIcon size={20}/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</FormField>
|
||||
<FormField name="remember">
|
||||
{({id, field}) => (
|
||||
<div className="flex flex-row items-start space-x-2 space-y-0">
|
||||
<Checkbox
|
||||
<div className="relative flex flex-col items-center">
|
||||
<div className="relative w-96 mx-4">
|
||||
<Link
|
||||
href="/"
|
||||
className="absolute -top-8 right-0 inline-flex items-center text-sm transition-colors"
|
||||
>
|
||||
<HomeIcon size={18} className="mr-1"/>
|
||||
返回首页
|
||||
</Link>
|
||||
</div>
|
||||
<Card className="w-96 mx-4 shadow-lg relative z-20 py-8">
|
||||
<CardContent className="px-8">
|
||||
{/* 登录方式切换 */}
|
||||
<Tabs
|
||||
value={mode}
|
||||
onValueChange={(val) => {
|
||||
setMode(val as LoginMode)
|
||||
form.reset({username: '', password: '', remember: false})
|
||||
form.clearErrors()
|
||||
}}
|
||||
className="mb-6">
|
||||
<TabsList className="w-full p-0 bg-white">
|
||||
<Tab value="password">密码登录</Tab>
|
||||
<Tab value="phone_code">验证码登录/注册</Tab>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<Form<LoginSchema> className="space-y-6" form={form} handler={handler}>
|
||||
<FormField name="username" label={mode === 'phone_code' ? '手机号' : '用户名'}>
|
||||
{({id, field}) => (
|
||||
<Input
|
||||
{...field}
|
||||
id={id}
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={submitting}
|
||||
type="tel"
|
||||
placeholder={mode === 'phone_code' ? '请输入手机号' : '请输入用户名/手机号/邮箱'}
|
||||
autoComplete="tel-national"
|
||||
/>
|
||||
<div className="space-y-1 leading-none">
|
||||
<Label>保持登录</Label>
|
||||
)}
|
||||
</FormField>
|
||||
<FormField name="password" label={mode === 'phone_code' ? '验证码' : '密码'}>
|
||||
{({id, field}) =>
|
||||
mode === 'phone_code' ? (
|
||||
<div className="flex space-x-4">
|
||||
<Input
|
||||
{...field}
|
||||
id={id}
|
||||
className="h-10"
|
||||
placeholder="请输入验证码"
|
||||
autoComplete="one-time-code"
|
||||
disabled={submitting}
|
||||
/>
|
||||
<SendMsgByUsername/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="relative">
|
||||
<Input
|
||||
{...field}
|
||||
id={id}
|
||||
type={showPwd ? 'text' : 'password'}
|
||||
className="h-10 pr-10"
|
||||
placeholder="至少6位密码,需包含字母和数字"
|
||||
autoComplete="current-password"
|
||||
minLength={6}
|
||||
disabled={submitting}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 cursor-pointer"
|
||||
onClick={() => setShowPwd(v => !v)}
|
||||
aria-label={showPwd ? '隐藏密码' : '显示密码'}
|
||||
>
|
||||
{showPwd ? (
|
||||
<EyeIcon size={20}/>
|
||||
) : (
|
||||
<EyeClosedIcon size={20}/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</FormField>
|
||||
<FormField name="remember">
|
||||
{({id, field}) => (
|
||||
<div className="flex flex-row items-start space-x-2 space-y-0">
|
||||
<Checkbox
|
||||
id={id}
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={submitting}
|
||||
/>
|
||||
<div className="space-y-1 leading-none">
|
||||
<Label>保持登录</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</FormField>
|
||||
<div className="flex flex-col gap-3">
|
||||
<Button
|
||||
className="w-full h-12 text-lg"
|
||||
type="submit"
|
||||
theme="gradient"
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? '登录中...' : (mode === 'phone_code' ? '首次登录即注册' : '立即登录')}
|
||||
</Button>
|
||||
<p className="text-xs text-center text-gray-500">
|
||||
登录即表示您同意
|
||||
<a href="/userAgreement" className="text-blue-600 hover:text-blue-500">《用户协议》</a>
|
||||
和
|
||||
<a href="/privacyPolicy" className="text-blue-600 hover:text-blue-500">《隐私政策》</a>
|
||||
</p>
|
||||
</div>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
</FormField>
|
||||
<div className="flex flex-col gap-3">
|
||||
<Button
|
||||
className="w-full h-12 text-lg"
|
||||
type="submit"
|
||||
theme="gradient"
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? '登录中...' : (mode === 'phone_code' ? '首次登录即注册' : '立即登录')}
|
||||
</Button>
|
||||
<p className="text-xs text-center text-gray-500">
|
||||
登录即表示您同意
|
||||
<a href="/userAgreement" className="text-blue-600 hover:text-blue-500">《用户协议》</a>
|
||||
和
|
||||
<a href="/privacyPolicy" className="text-blue-600 hover:text-blue-500">《隐私政策》</a>
|
||||
</p>
|
||||
</div>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user