「10」next-shopping:admin页面布局、用户组件调整

我们先来调整一下C端页面,把app/(normal-layout) 改名叫app/(client-layout),虽然对实际没有影响,但是对开发者更好识别

我们现在可以把layout抽成通用的:

新建components/Layouts/ClientLayout.jsx

jsx 复制代码
import { Navbar } from '@/components'

export default function Layout({ children }) {
  return (
    <>
      <Navbar />
      {children}
    </>
  )
}

这是客户端的页面通用布局,header部分需要nav

新建components/Layouts/DashboardLayout.jsx

jsx 复制代码
export default function Layout({ children }) {
  return <div>{children} </div>
}

目前仅最简单的包一层,后面会添加NavFooter

新建components/Layouts/ProfileLayout.jsx

jsx 复制代码
export default function Layout({ children }) {
  return <div>{children}</div>
}

这个个人中心也是组简单的布局

components/index.js中导出

jsx 复制代码
export { default as Icons } from './share/Icons'
export { default as Loading } from './share/Loading'
export { default as DisplayError } from './share/DisplayError'
export { default as Navbar } from './Navbar'
export { default as User } from './User'
export { default as Cart } from './Cart'
export { default as Search } from './Search'
export { default as ClientLayout } from './Layouts/ClientLayout'
export { default as DashboardLayout } from './Layouts/DashboardLayout'
export { default as ProfileLayout } from './Layouts/ProfileLayout'

然后我们用ClientLayout来代替app/(main)/(client-layout)/layout.js的布局

jsx 复制代码
'use client'

import { ClientLayout } from '@/components'
import { useRefreshToken } from '@/hooks'

export default function Layout({ children }) {
  useRefreshToken()
  return (
    <>
      <ClientLayout>{children}</ClientLayout>
    </>
  )
}

效果如下:

然后我们新建app/(dashboard-layout)/layout.js

jsx 复制代码
'use client'

import { DashboardLayout } from '@/components'

export default function Layout({ children }) {
  return (
    <>
      <DashboardLayout>{children}</DashboardLayout>
    </>
  )
}

新建app/(dashboard-layout)/dashboard/page.jsx

jsx 复制代码
export default function Page() {
  return <div>这是管理页面</div>
}

效果如下:

注销页面

我们先来实现两个通用组件BoxLinkArrowLink

新建components/share/BoxLink.jsx

jsx 复制代码
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { Icons } from '@/components'

export default function BoxLink({ children, path, name }) {
  const router = useRouter()

  return (
    <div
      className={`transition-colors hover:bg-gray-200 px-3 ${
        router.asPath === path ? 'border-r-4 border-red-600' : 'border-r-4 border-white'
      }`}
    >
      <Link href={path}>
        <span className="flex justify-between mx-4 py-4 gap-x-2 border-t border-gray-300">
          {children}
          <span className="ml-auto mr-3">{name}</span>
          <Icons.ArrowLeft className="icon" />
        </span>
      </Link>
    </div>
  )
}

新建components/share/ArrowLink.jsx

jsx 复制代码
import Link from 'next/link'
import { Icons } from '@/components'

export default function ArrowLink({ children, path }) {
  return (
    <Link href={path}>
      <span className="inline-flex items-center text-blue-400 text-sm max-w-max">
        <span className="uppercase">{children}</span>
        <Icons.ArrowLeft className="icon text-blue-400" />
      </span>
    </Link>
  )
}

然后我们来写退出登录组件:

新建components/Logout.jsx

jsx 复制代码
import { useRouter } from 'next/navigation'
import { useDispatch } from 'react-redux'
import { userLogout } from '@/store/slices/authSlice'
import { Icons } from '@/components'
import alert from '@/utils/alert'

export default function Logout() {
  const dispatch = useDispatch()
  const router = useRouter()

  const handleLogout = () => {
    router.push('/')
    dispatch(userLogout())
    alert('success', '退出成功')
  }

  return (
    <div className="transition-colors hover:bg-gray-200 px-3">
      <div
        role="button"
        className="flex justify-between cursor-pointer py-4 gap-x-2 mx-4  border-t border-gray-300"
        onClick={() => handleLogout()}
      >
        <Icons.Logout className="icon text-black" />
        <span className="ml-auto mr-3">其他组织者</span>
      </div>
    </div>
  )
}

先在components/index.js中导出组件:

jsx 复制代码
export { default as Icons } from './share/Icons'
export { default as Loading } from './share/Loading'
export { default as DisplayError } from './share/DisplayError'
export { default as Navbar } from './Navbar'
export { default as User } from './User'
export { default as Cart } from './Cart'
export { default as Search } from './Search'
export { default as ClientLayout } from './Layouts/ClientLayout'
export { default as DashboardLayout } from './Layouts/DashboardLayout'
export { default as ProfileLayout } from './Layouts/ProfileLayout'
export { default as ArrowLink } from './share/ArrowLink'
export { default as BoxLink } from './share/BoxLink'
export { default as Logout } from './Lagout'

现在来修改User组件,我们先看看当前的效果:

修改components/User.jsx

jsx 复制代码
import Image from 'next/image'
import Link from 'next/link'
import { useState } from 'react'

import { useSelector } from 'react-redux'
import { BoxLink, Icons, Logout } from './index'

export default function User() {
  const { user } = useSelector(state => state.auth)

  const [isOpen, setIsOpen] = useState(false)

  if (!user) {
    return (
      <div className="flex items-center gap-x-2 lg:border lg:border-gray-300 lg:rounded-md lg:py-2 lg:px-3 text-sm">
        <Link href="/login">
          <span className="flex items-center gap-x-1">
            <Icons.Login className="icon" />
            登录
          </span>
        </Link>
        <span className="hidden lg:block lg:border lg:border-gray-300 lg:h-6"></span>
        <Link href="/register">
          <span className="hidden lg:block px-2">注册</span>
        </Link>
      </div>
    )
  }

  return (
    <>
      <div className="lg:hidden">
        <Link href="/profile">
          <span>
            <Icons.User className="icon" />
          </span>
        </Link>
      </div>
      <div
        className={`hidden lg:cursor-pointer lg:relative lg:flex lg:rounded lg:p-1.5 lg:transition ${isOpen && 'bg-red-100'}`}
        onClick={() => setIsOpen(!isOpen)}
      >
        <Icons.User className="icon" />
        <Icons.ArrowDown className="icon" />
        <div
          className={` bg-white shadow-md rounded overflow-hidden absolute top-full left-0 w-60
                   border border-gray-100 ${isOpen ? 'block' : 'hidden'}`}
        >
          <BoxLink path="/profile" name={user.name} className="border-t-0">
            <div className="realative w-6 h-6">
              <Image src={'/avatar.png'} alt="user" width={200} height={200} />
            </div>
          </BoxLink>
          <Logout />
        </div>
      </div>
    </>
  )
}

主要是用BoxLink套了一层,省略很多代码,然后把退出登录的逻辑单独抽出来的Logout.jsx

代码地址:github.com/liyunfu1998...

相关推荐
m0_7482517213 分钟前
DataOps驱动数据集成创新:Apache DolphinScheduler & SeaTunnel on Amazon Web Services
前端·apache
珊珊来吃14 分钟前
EXCEL中给某一列数据加上双引号
java·前端·excel
胡西风_foxww42 分钟前
【ES6复习笔记】Spread 扩展运算符(8)
前端·笔记·es6·扩展·运算符·spread
小林爱1 小时前
【Compose multiplatform教程08】【组件】Text组件
android·java·前端·ui·前端框架·kotlin·android studio
跨境商城搭建开发1 小时前
一个服务器可以搭建几个网站?搭建一个网站的流程介绍
运维·服务器·前端·vue.js·mysql·npm·php
hhzz1 小时前
vue前端项目中实现电子签名功能(附完整源码)
前端·javascript·vue.js
秋雨凉人心1 小时前
上传npm包加强
开发语言·前端·javascript·webpack·npm·node.js
时清云2 小时前
【算法】 课程表
前端·算法·面试
JoeChen.2 小时前
PostCSS插件——postcss-pxtorem结合动态调整rem实现字体自适应
javascript·ecmascript·postcss
NoneCoder2 小时前
CSS系列(37)-- Overscroll Behavior详解
前端·css