开启 ppr 优化渲染性能
This commit is contained in:
@@ -1,16 +1,30 @@
|
||||
'use client'
|
||||
import {useEffect, useRef, useState} from 'react'
|
||||
import {useState} from 'react'
|
||||
import {Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger} from '@/components/ui/dialog'
|
||||
import {Button} from '@/components/ui/button'
|
||||
import {Form, FormField} from '@/components/ui/form'
|
||||
import {Input} from '@/components/ui/input'
|
||||
import {useForm} from 'react-hook-form'
|
||||
import {useForm, useFormContext} from 'react-hook-form'
|
||||
import {zodResolver} from '@hookform/resolvers/zod'
|
||||
import * as z from 'zod'
|
||||
import {toast} from 'sonner'
|
||||
import {useRouter} from 'next/navigation'
|
||||
import {sendSMS} from '@/actions/verify'
|
||||
import {updatePassword} from '@/actions/user'
|
||||
import SendMsg from '@/components/send-msg'
|
||||
|
||||
// 表单验证规则
|
||||
const schema = z.object({
|
||||
phone: z.string().regex(/^1\d{10}$/, `请输入正确的手机号`),
|
||||
captcha: z.string().nonempty('请输入验证码'),
|
||||
code: z.string().regex(/^\d{6}$/, `请输入正确的验证码`),
|
||||
password: z.string().min(6, `密码至少6位`),
|
||||
confirm_password: z.string(),
|
||||
}).refine(data => data.password === data.confirm_password, {
|
||||
message: '两次输入的密码不一致',
|
||||
path: ['confirm_password'],
|
||||
})
|
||||
|
||||
type Schema = z.infer<typeof schema>
|
||||
|
||||
interface ChangePasswordDialogProps {
|
||||
triggerClassName?: string
|
||||
@@ -33,20 +47,6 @@ export function ChangePasswordDialog({
|
||||
const actualOpen = open !== undefined ? open : internalOpen
|
||||
const actualOnOpenChange = onOpenChange || setInternalOpen
|
||||
|
||||
// 表单验证规则
|
||||
const schema = z.object({
|
||||
phone: z.string().regex(/^1\d{10}$/, `请输入正确的手机号`),
|
||||
captcha: z.string().nonempty('请输入验证码'),
|
||||
code: z.string().regex(/^\d{6}$/, `请输入正确的验证码`),
|
||||
password: z.string().min(6, `密码至少6位`),
|
||||
confirm_password: z.string(),
|
||||
}).refine(data => data.password === data.confirm_password, {
|
||||
message: '两次输入的密码不一致',
|
||||
path: ['confirm_password'],
|
||||
})
|
||||
|
||||
type Schema = z.infer<typeof schema>
|
||||
|
||||
// 表单初始化
|
||||
const form = useForm<Schema>({
|
||||
resolver: zodResolver(
|
||||
@@ -92,52 +92,6 @@ export function ChangePasswordDialog({
|
||||
}
|
||||
})
|
||||
|
||||
// 验证码相关状态
|
||||
const [captchaUrl, setCaptchaUrl] = useState(`/captcha?t=${new Date().getTime()}`)
|
||||
const [captchaWait, setCaptchaWait] = useState(0)
|
||||
const interval = useRef<NodeJS.Timeout>(null)
|
||||
|
||||
// 刷新验证码
|
||||
const refreshCaptcha = () => {
|
||||
setCaptchaUrl(`/captcha?t=${new Date().getTime()}`)
|
||||
}
|
||||
|
||||
// 发送短信验证码
|
||||
const sendVerifier = async () => {
|
||||
const result = await form.trigger(['phone', 'captcha'])
|
||||
if (!result) return
|
||||
|
||||
const {phone, captcha} = form.getValues()
|
||||
const resp = await sendSMS({phone, captcha})
|
||||
if (!resp.success) {
|
||||
toast.error(resp.message)
|
||||
refreshCaptcha()
|
||||
return
|
||||
}
|
||||
|
||||
setCaptchaWait(60)
|
||||
interval.current = setInterval(() => {
|
||||
setCaptchaWait((wait) => {
|
||||
if (wait <= 1) {
|
||||
clearInterval(interval.current!)
|
||||
return 0
|
||||
}
|
||||
return wait - 1
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
toast.success(`验证码已发送,请注意查收`)
|
||||
}
|
||||
|
||||
// 清理定时器
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (interval.current) {
|
||||
clearInterval(interval.current)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Dialog open={actualOpen} onOpenChange={actualOnOpenChange}>
|
||||
<DialogTrigger asChild>
|
||||
@@ -155,29 +109,15 @@ export function ChangePasswordDialog({
|
||||
)}
|
||||
</FormField>
|
||||
|
||||
{/* 图形验证码 */}
|
||||
<FormField<Schema> name="captcha" label="验证码">
|
||||
{({field}) => (
|
||||
<div className="flex gap-4">
|
||||
<Input {...field} placeholder="请输入验证码" autoComplete="one-time-code"/>
|
||||
<Button className="p-0 bg-transparent" onClick={refreshCaptcha} type="button">
|
||||
<img src={captchaUrl} alt="验证码" className="h-10"/>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</FormField>
|
||||
|
||||
{/* 短信验证码 */}
|
||||
<FormField<Schema> name="code" label="短信令牌" className="flex-auto">
|
||||
{({field}) => (
|
||||
<div className="flex gap-4">
|
||||
<div className="flex gap-4 items-end">
|
||||
<FormField<Schema> name="code" label="验证码" className="flex-auto">
|
||||
{({field}) => (
|
||||
<Input {...field} placeholder="请输入验证码" autoComplete="one-time-code"/>
|
||||
<Button theme="outline" type="button" className="w-36" onClick={() => sendVerifier()}>
|
||||
{captchaWait > 0 ? `重新发送(${captchaWait})` : `获取短信令牌`}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</FormField>
|
||||
)}
|
||||
</FormField>
|
||||
<SendMsgByPhone/>
|
||||
</div>
|
||||
|
||||
{/* 新密码 */}
|
||||
<FormField<Schema> name="password" label="新密码" className="flex-auto">
|
||||
@@ -212,3 +152,9 @@ export function ChangePasswordDialog({
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
function SendMsgByPhone() {
|
||||
const form = useFormContext<Schema>()
|
||||
const phone = form.watch('phone')
|
||||
return <SendMsg phone={phone}/>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user