「7」next-shopping:登录注册页完善、弹窗改动
我们先来看看当前存在的问题:
- 登录注册页面成功后只清空了表单,并没有跳转
- 登录注册的提示太小了,能不能换一个大一点的
换一个大一点的状态提示
我们希望换一个大一点的提示,目前用的是react-hot-toast
,现在需要换成SweetAlert2 + React example 可以点进去看看效果,很不错,下面我们开始:
安装依赖:
pnpm i sweetalert2 sweetalert2-react-content
新建utils/alert.js
import Swal from 'sweetalert2'
import withReactContent from 'sweetalert2-react-content'
const MySwal = withReactContent(Swal)
const alert = (icon, msg) =>
MySwal.fire({
position: 'center',
icon,
title: msg,
showConfirmButton: false,
timer: 2000,
})
export const confirmAlert = ({ title, text, icon, confirmButtonText }) =>
Swal.fire({
title,
text,
icon,
showCancelButton: false,
confirmButtonColor: '#3085d6',
confirmButtonText,
})
export default alert
可以看到我们定义了默认提示
和确认框
然后我们在app/(main)/(empty-layout)/register/page.js
里面引入,替换掉toast
并且,引入router
在我们成功注册的时候跳转到首页
'use client'
import Image from 'next/image'
import Link from 'next/link'
import * as z from 'zod'
import { toast } from 'react-hot-toast'
import { useEffect } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useDispatch } from 'react-redux'
import { useRouter } from 'next/navigation'
import { usePostDataMutation } from '@/store/slices/fetchApiSlice'
import { userLogin } from '@/store/slices/authSlice'
import { DisplayError, Loading } from '@/components'
import alert, { confirmAlert } from '@/utils/alert'
const schema = z
.object({
name: z
.string({
required_error: '用户名必填',
})
.min(3, { message: '用户名最少三个字符' }),
email: z
.string({
required_error: '电子邮件地址必填',
})
.email('输入的电子邮件地址无效'),
password: z
.string({
required_error: '密码必填',
})
.min(6, { message: '密码必须大于6个字符' }),
confirmPassword: z
.string({
required_error: '确认密码必填',
})
.min(6, { message: '密码必须大于6个字符' }),
})
.refine(data => data.password === data.confirmPassword, {
message: '确认密码必须与密码一致',
path: ['confirmPassword'],
})
export default function RegisterPage() {
const dispatch = useDispatch()
const router = useRouter()
const [postData, { data, isSuccess, isError, isLoading, error }] = usePostDataMutation()
const {
register,
handleSubmit,
formState: { errors: formErrors },
reset,
} = useForm({
resolver: zodResolver(schema),
})
useEffect(() => {
if (isSuccess) {
// toast.success('注册成功')
alert('success', data.msg)
dispatch(userLogin(data.data))
reset()
router.push('/')
}
if (isError) {
confirmAlert({
title: '您的注册有问题',
text: error?.data?.err,
icon: 'warning',
confirmButtonText: '去登录',
}).then(result => {
if (result.isConfirmed) router.push('/login')
})
// toast.error(error?.data?.err)
}
}, [isSuccess, isError])
const submitHandler = async ({ name, email, password, confirmPassword }) => {
if (name && email && password && confirmPassword) {
postData({ url: '/api/auth/register', body: { name, email, password }, token: '' })
}
}
return (
<div className=" grid items-center min-h-screen ">
<div className="container max-w-xl px-12 py-6 space-y-6 lg:border lg:border-gray-100 lg:rounded-lg lg:shadow">
<div className="relative w-44 h-24 mx-auto">
<Link passHref href="/">
<Image src="/images/logo.svg" layout="fill" alt="logo" />
</Link>
</div>
<h2>需要注册</h2>
<form className="space-y-5" onSubmit={handleSubmit(submitHandler)}>
<div>
<input
type="text"
className="input"
name="name"
placeholder="名称"
{...register('name')}
/>
<DisplayError errors={formErrors.name} />
</div>
<div>
<input
className="input"
type="text"
placeholder="电子邮件地址"
{...register('email')}
/>
<DisplayError errors={formErrors.email} />
</div>
<div>
<input className="input" type="password" placeholder="密码" {...register('password')} />
<DisplayError errors={formErrors.password} />
</div>
<div>
<input
className="input"
type="password"
placeholder="重复密码"
{...register('confirmPassword')}
/>
<DisplayError errors={formErrors.confirmPassword} />
</div>
<button className="btn mx-auto w-60" type="submit" disabled={isLoading}>
{isLoading ? <Loading /> : '注册'}
</button>
</form>
<div>
<p className="inline ml-2">已经拥有账户</p>
<Link href="/login">
<span className="text-blue-400 text-lg ">登录</span>
</Link>
</div>
</div>
</div>
)
}
效果如下:
同理我们把登录页面也改造一下:app/(main)/(empty-layout)/login/page.js
'use client'
import { useEffect } from 'react'
import Link from 'next/link'
import Image from 'next/image'
import * as z from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { toast } from 'react-hot-toast'
import { useDispatch } from 'react-redux'
import { useRouter } from 'next/navigation'
import { usePostDataMutation } from '@/store/slices/fetchApiSlice'
import { DisplayError, Loading } from '@/components'
import { userLogin } from '@/store/slices/authSlice'
import alert, { confirmAlert } from '@/utils/alert'
const schema = z.object({
email: z
.string({
required_error: '邮件地址必填',
})
.email('输入的电子邮件地址无效'),
password: z
.string({
required_error: '密码必填',
})
.min(6, { message: '密码最少6个字符' }),
})
export default function LoginPage() {
const dispatch = useDispatch()
const router = useRouter()
const [postData, { data, isSuccess, isError, isLoading, error }] = usePostDataMutation()
const {
handleSubmit,
register,
formState: { errors: formErrors },
reset,
} = useForm({
resolver: zodResolver(schema),
})
useEffect(() => {
if (isSuccess) {
// toast.success(data.msg)
alert('success', data.msg)
dispatch(userLogin(data.data))
reset()
router.push('/')
}
if (isError) {
// toast.error(error?.data.err)
confirmAlert({
title: '您的登录有问题',
text: error?.data?.err,
icon: 'warning',
confirmButtonText: '去注册',
}).then(result => {
if (result.isConfirmed) router.push('/register')
})
}
}, [isSuccess, isError])
const submitHandler = async ({ email, password }) => {
if (email && password) {
await postData({
url: '/api/auth/login',
body: { email, password },
token: '',
})
}
}
return (
<div className="grid items-center min-h-screen ">
<div className="container max-w-xl px-12 py-6 space-y-6 lg:border lg:border-gray-100 lg:rounded-lg lg:shadow">
<div className="relative w-44 h-24 mx-auto">
<Link passHref href="/">
<Image src="/images/logo.svg" layout="fill" alt="logo" />
</Link>
</div>
<h2>登录</h2>
<form className="space-y-5" onSubmit={handleSubmit(submitHandler)}>
<div>
<input
className="input"
type="text"
placeholder="电子邮件地址"
{...register('email')}
/>
<DisplayError errors={formErrors.email} />
</div>
<div>
<input className="input" type="password" placeholder="密码" {...register('password')} />
<DisplayError errors={formErrors.password} />
</div>
<button className="btn mx-auto w-60" type="submit" disabled={isLoading}>
{isLoading ? <Loading /> : '登录'}
</button>
</form>
<div>
<p className="inline ml-2">你还没有注册</p>
<Link href="/register">
<span className="text-blue-400 text-lg ">注册</span>
</Link>
</div>
</div>
</div>
)
}
效果如下:
今天周五,就少更点,下周见!!
代码地址:feat: 登录提示toast改为alert · liyunfu1998/next-shopping@ba69b5a (github.com)
转载自:https://juejin.cn/post/7356506122356686860