likes
comments
collection
share

「7」next-shopping:登录注册页完善、弹窗改动

作者站长头像
站长
· 阅读数 13

我们先来看看当前存在的问题:

  1. 登录注册页面成功后只清空了表单,并没有跳转
  2. 登录注册的提示太小了,能不能换一个大一点的

「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>
  )
}

效果如下:

「7」next-shopping:登录注册页完善、弹窗改动

「7」next-shopping:登录注册页完善、弹窗改动

同理我们把登录页面也改造一下: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>
  )
}

效果如下:

「7」next-shopping:登录注册页完善、弹窗改动

今天周五,就少更点,下周见!!

代码地址:feat: 登录提示toast改为alert · liyunfu1998/next-shopping@ba69b5a (github.com)

转载自:https://juejin.cn/post/7356506122356686860
评论
请登录