一、切换注册与登录组件优化
当用户没有登录时访问受保护页面会重定向到http://localhost:3000/login?callbackUrl=http%3A%2F%2Flocalhost%3A3000%2Fdashboard,这时切换到注册时直接跳转到/register ,然后切换回登录页时callbackUrl丢失,所以把NavigationPrompt转为客户端组件,在切换注册和登录页时如果本身存在callbackUrl就需要继续在url里使用,并且需要对URL进行编码。
// src/components/NavigationPrompt.tsx
'use client'
import Link from 'next/link'
import { useSearchParams } from 'next/navigation'
const NavigationPrompt = ({
isLoginToRegister,
}: {
isLoginToRegister?: boolean
}) => {
const searchParams = useSearchParams()
const callbackUrl = searchParams.get('callbackUrl')
return (
<div className="p-6 pt-0 text-center text-sm">
{isLoginToRegister ? (
<>
<span className="text-zinc-600">还没有账号?</span>
<Link
href={
callbackUrl
? `/register?callbackUrl=${encodeURIComponent(callbackUrl)}`
: '/register'
}
className="text-primary"
>
去注册
</Link>
</>
) : (
<>
<span className="text-zinc-600">已经有账号了?</span>
<Link
href={
callbackUrl
? `/login?callbackUrl=${encodeURIComponent(callbackUrl)}`
: '/login'
}
className="text-primary"
>
去登录
</Link>
</>
)}
</div>
)
}
export default NavigationPrompt
修复样式:
在设计文件展示卡片时修改destructive样式影响了Form表单的错误提示,复原然后单独设置卡片样式,或使用统一的颜色。
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 20% 98%;
二、账号注册自动登录
用户注册完成后执行登录的方法如下
// src/app/(page)/(blockAccessAfterLogin)/register/EmailRegister.tsx
const searchParams = useSearchParams()
const callbackUrl = searchParams.get('callbackUrl')
const pwdRef = useRef('')
const [logging, setLogging] = useState<boolean>(false) // 开始登录
const autoLogin = useCallback(
async (email: string) => {
setLogging(true)
try {
const response = await signIn('credentials', {
email,
password,
loginType: 'email',
phoneCode: '',
redirect: false,
})
if (!response?.error) {
router.push(callbackUrl || '/')
router.refresh()
toast({
title: getMessages('10030'),
description: getMessages('10034'),
variant: 'default',
})
} else {
toast({
title: getMessages('10030'),
description: getMessages(response.error as TipsCode),
variant: 'destructive',
})
}
setLogging(false)
} catch (error) {
setLogging(false)
console.log(error)
}
},
[callbackUrl, password, router, toast]
)
注意不要忘记给注册按钮补全加载状态
<Button
className="w-full"
type="submit"
disabled={emailRegisterLoading || logging}
>
{(emailRegisterLoading || logging) && (
<Loader2 className="mr-4 h-4 w-4 animate-spin text-white" />
)}
注册
</Button>
三、手机号注册自动登录
手机号注册完成后执行登录的方法
// src/app/(page)/(blockAccessAfterLogin)/register/PhoneRegister.tsx
const searchParams = useSearchParams()
const callbackUrl = searchParams.get('callbackUrl')
const [logging, setLogging] = useState<boolean>(false) // 开始登录
const autoLogin = useCallback(async () => {
setLogging(true)
try {
const response = await signIn('credentials', {
loginType: 'phone',
phone,
phoneCode,
redirect: false,
})
if (!response?.error) {
router.push(callbackUrl || '/')
router.refresh()
toast({
title: getMessages('10030'),
description: getMessages('10034'),
variant: 'default',
})
} else {
toast({
title: getMessages('10030'),
description: getMessages(response.error as TipsCode),
variant: 'destructive',
})
}
} catch (error) {
console.log(error)
}
setLogging(false)
}, [callbackUrl, phone, phoneCode, router, toast])
注意不要忘记给注册按钮补全加载状态
<Button
className="w-full"
type="submit"
disabled={phoneRegisterLoading || logging}
>
{(phoneRegisterLoading || logging) && (
<Loader2 className="mr-4 h-4 w-4 animate-spin text-white" />
)}
注册
</Button>