Commit 67fc813e by HoMeTown

feat: login tip处理

parent a42cb84d
...@@ -6,6 +6,7 @@ import { useLocalStorageState } from 'ahooks' ...@@ -6,6 +6,7 @@ import { useLocalStorageState } from 'ahooks'
interface AuthContextType { interface AuthContextType {
isLoggedIn: boolean isLoggedIn: boolean
showLoginModal: boolean showLoginModal: boolean
showLoginTip: boolean
login: () => void login: () => void
logout: () => void logout: () => void
toggleLoginModal: () => void toggleLoginModal: () => void
...@@ -24,8 +25,9 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => { ...@@ -24,8 +25,9 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
defaultValue: '', defaultValue: '',
}, },
) )
const [isLoggedIn, setIsLoggedIn] = useState(Boolean(token)) const [isLoggedIn, setIsLoggedIn] = useState(!!token)
const [showLoginModal, setShowLoginModal] = useState(false) const [showLoginModal, setShowLoginModal] = useState(false)
const [showLoginTip, setShowLoginTip] = useState(!token)
const login = () => { const login = () => {
setIsLoggedIn(true) setIsLoggedIn(true)
...@@ -38,11 +40,12 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => { ...@@ -38,11 +40,12 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
const toggleLoginModal = () => { const toggleLoginModal = () => {
setShowLoginModal(!showLoginModal) setShowLoginModal(!showLoginModal)
setShowLoginTip(showLoginModal)
} }
return ( return (
// eslint-disable-next-line react/no-unstable-context-value // eslint-disable-next-line react/no-unstable-context-value
<AuthContext.Provider value={{ isLoggedIn, showLoginModal, login, logout, toggleLoginModal }}> <AuthContext.Provider value={{ isLoggedIn, showLoginTip, showLoginModal, login, logout, toggleLoginModal }}>
{children} {children}
</AuthContext.Provider> </AuthContext.Provider>
) )
......
...@@ -4,13 +4,14 @@ import { useAuth } from './AuthContext' ...@@ -4,13 +4,14 @@ import { useAuth } from './AuthContext'
export interface WithAuthProps { export interface WithAuthProps {
checkAuth: () => boolean checkAuth: () => boolean
showLoginTip: boolean
} }
export function withAuth<T extends WithAuthProps = WithAuthProps>( export function withAuth<T extends WithAuthProps = WithAuthProps>(
WrappedComponent: React.ComponentType<T>, WrappedComponent: React.ComponentType<T>,
) { ) {
return (props: Omit<T, keyof WithAuthProps>) => { return (props: Omit<T, keyof WithAuthProps>) => {
const { isLoggedIn, toggleLoginModal } = useAuth() const { isLoggedIn, toggleLoginModal, showLoginTip } = useAuth()
const checkAuth = () => { const checkAuth = () => {
if (!isLoggedIn) { if (!isLoggedIn) {
...@@ -20,6 +21,6 @@ export function withAuth<T extends WithAuthProps = WithAuthProps>( ...@@ -20,6 +21,6 @@ export function withAuth<T extends WithAuthProps = WithAuthProps>(
return true return true
} }
return <WrappedComponent {...(props as T)} checkAuth={checkAuth} /> return <WrappedComponent {...(props as T)} showLoginTip={showLoginTip} checkAuth={checkAuth} />
} }
} }
import Tools from '@/assets/svg/tools.svg?react'
import Logo from '@/assets/svg/logo.svg?react'
import AddNewChat from '@/assets/svg/addNewChat.svg?react'
import HistoryChat from '@/assets/svg/historyChat.svg?react'
import Collect from '@/assets/svg/collect.svg?react'
export const NAV_BAR_ITEMS = [
{ icon: Logo, label: '', key: 'logo' },
{ icon: '', label: '', key: 'line1' },
{ icon: AddNewChat, label: '新建对话', key: 'add' },
{ icon: HistoryChat, label: '历史对话', key: 'history' },
{ icon: Collect, label: '收藏', key: 'collect' },
{ icon: '', label: '', key: 'line2' },
{ icon: Tools, label: '工具', key: 'tools' },
{ icon: '', label: '', key: 'line3' },
]
import type React from 'react' import type React from 'react'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { Button, Tooltip } from '@nextui-org/react' import { Button, Tooltip } from '@nextui-org/react'
import { useLocalStorageState, useToggle } from 'ahooks'
import { useEffect, useRef } from 'react'
import styles from './Navbar.module.less' import styles from './Navbar.module.less'
import { NavBarItem } from './components/NavBarItem' import { NavBarItem } from './components/NavBarItem'
import Logo from '@/assets/svg/logo.svg?react'
import AddNewChat from '@/assets/svg/addNewChat.svg?react'
import HistoryChat from '@/assets/svg/historyChat.svg?react'
import Collect from '@/assets/svg/collect.svg?react'
import Tools from '@/assets/svg/tools.svg?react'
import UserIcon from '@/assets/svg/user.svg?react' import UserIcon from '@/assets/svg/user.svg?react'
import { LoginModal } from '@/components/LoginModal'
import type { WithAuthProps } from '@/auth/withAuth' import type { WithAuthProps } from '@/auth/withAuth'
import { withAuth } from '@/auth/withAuth' import { withAuth } from '@/auth/withAuth'
import { NAV_BAR_ITEMS } from '@/config/nav'
const NAV_BAR_ITEMS = [
{ icon: Logo, label: '', key: 'logo' },
{ icon: '', label: '', key: 'line1' },
{ icon: AddNewChat, label: '新建对话', key: 'add' },
{ icon: HistoryChat, label: '历史对话', key: 'history' },
{ icon: Collect, label: '收藏', key: 'collect' },
{ icon: '', label: '', key: 'line2' },
{ icon: Tools, label: '工具', key: 'tools' },
{ icon: '', label: '', key: 'line3' },
]
interface NavbarProps { interface NavbarProps {
isCollapsed: boolean isCollapsed: boolean
onToggle: () => void onToggle: () => void
} }
const NavbarBase: React.FC<NavbarProps & WithAuthProps> = ({ checkAuth, onToggle }) => { const NavbarBase: React.FC<NavbarProps & WithAuthProps> = ({ showLoginTip, checkAuth, onToggle }) => {
const [token] = useLocalStorageState<string | undefined>('__TOKEN__', {
defaultValue: '',
listenStorageChange: true,
})
const [isOpenLogTip, isOpenLogTipActions] = useToggle()
const [isOpenLoginModal, isOpenLoginModalActions] = useToggle()
const intervalRef = useRef<NodeJS.Timeout | null>(null)
const handleShowLoginTip = () => {
intervalRef.current = setTimeout(() => {
if (!token) {
isOpenLogTipActions.setRight()
}
if (intervalRef.current) {
clearInterval(intervalRef.current)
intervalRef.current = null
}
}, 1000)
}
const handleCloseLoginModal = () => {
isOpenLoginModalActions.setLeft()
handleShowLoginTip()
}
const handleClick = (type: string | undefined) => { const handleClick = (type: string | undefined) => {
if (!checkAuth()) if (!checkAuth())
return return
...@@ -67,28 +23,21 @@ const NavbarBase: React.FC<NavbarProps & WithAuthProps> = ({ checkAuth, onToggle ...@@ -67,28 +23,21 @@ const NavbarBase: React.FC<NavbarProps & WithAuthProps> = ({ checkAuth, onToggle
} }
} }
useEffect(() => {
handleShowLoginTip()
}, [])
return ( return (
<> <motion.nav className="h-full flex-shrink-0 flex flex-col items-center justify-center">
<motion.nav className="h-full flex-shrink-0 flex flex-col items-center justify-center"> <motion.div className={`${styles.layoutNavBarAgent} sm:flex hidden w-[64px] bg-white gap-[24px]`}>
<motion.div className={`${styles.layoutNavBarAgent} sm:flex hidden w-[64px] bg-white gap-[24px]`}> {NAV_BAR_ITEMS.map((item) => {
{NAV_BAR_ITEMS.map((item) => { return (
return ( <NavBarItem onClick={handleClick} icon={item.icon} label={item.label} key={item.key} type={item.key} />
<NavBarItem onClick={handleClick} icon={item.icon} label={item.label} key={item.key} type={item.key} /> )
) })}
})} <Tooltip isOpen={showLoginTip} color="foreground" content="登录体验更多功能" placement="right">
<Tooltip isOpen={isOpenLogTip} color="foreground" content="登录体验更多功能" placement="right"> <Button onClick={checkAuth} variant="light" isIconOnly aria-label="Like">
<Button onClick={checkAuth} variant="light" isIconOnly aria-label="Like"> <UserIcon />
<UserIcon /> </Button>
</Button> </Tooltip>
</Tooltip> </motion.div>
</motion.div> </motion.nav>
</motion.nav>
<LoginModal onClose={handleCloseLoginModal} isOpen={isOpenLoginModal} />
</>
) )
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment