feat(Component): Add UserCard.

mack-mac
mackt 8 months ago
parent a3def0adc4
commit 4441fe1132

@ -5,7 +5,7 @@ import { useShallow } from 'zustand/react/shallow';
import { Avatar } from '@/components'; import { Avatar } from '@/components';
import useUserStore from '@/store/user'; import useUserStore from '@/store/user';
export default function HeaderAvatar({ className }: { className: string }) { export default function HeaderAvatar({ className }: { className?: string }) {
const { userInfo, setShowLogin } = useUserStore( const { userInfo, setShowLogin } = useUserStore(
useShallow((state) => ({ useShallow((state) => ({
userInfo: state.userInfo, userInfo: state.userInfo,
@ -17,7 +17,6 @@ export default function HeaderAvatar({ className }: { className: string }) {
<div className={`${className}`}> <div className={`${className}`}>
{/* 已登录 展示头像 */} {/* 已登录 展示头像 */}
{!!userInfo.id && <Avatar size={36} src={userInfo.avatar} className="cursor-pointer" />} {!!userInfo.id && <Avatar size={36} src={userInfo.avatar} className="cursor-pointer" />}
{/* 未登录 展示按钮 */} {/* 未登录 展示按钮 */}
{!userInfo.id && ( {!userInfo.id && (
<button <button

@ -0,0 +1,77 @@
import { useState, useEffect } from 'react';
import Image from 'next/image';
import { useShallow } from 'zustand/react/shallow';
import { Avatar } from '@/components';
import useUserStore from '@/store/user';
interface Props {
className?: string;
}
interface TDataList {
label: string;
value: number;
}
export default function UserCard({ className }: Props) {
const { userInfo } = useUserStore(
useShallow((state) => ({
userInfo: state.userInfo,
setShowLogin: state.setShowLogin,
})),
);
const [userDataList, setUserDataList] = useState<TDataList[]>([
{ label: '关注', value: userInfo.followCount },
{ label: '粉丝', value: userInfo.fansCount },
{ label: '评论', value: userInfo.commentReplyCount },
{ label: '获赞', value: userInfo.thumbUpCount },
]);
useEffect(() => {
setUserDataList([
{ label: '关注', value: userInfo.followCount },
{ label: '粉丝', value: userInfo.fansCount },
{ label: '评论', value: userInfo.commentReplyCount },
{ label: '获赞', value: userInfo.thumbUpCount },
]);
}, [userInfo]);
return (
<div className={`py-[24px] rounded-[12px] border-[1px] border-[#c3c3c3] shadow-md ${className}`}>
{/* 头像 & 昵称 & 个签 */}
<div className="flex flex-row items-center px-[27px]">
<Avatar size={48} src={userInfo.avatar} />
<div className="ml-[17px]">
<p className="w-[100px] mt-[1px] text-base text-[15px] leading-[21px] text-overflow">{userInfo.nickName}</p>
<p className="w-[100px] mt-[3px] text-[rgba(0,0,0,0.4)] text-[12px] leading-[16.8px] text-overflow">
{userInfo.signature}
</p>
</div>
</div>
{/* 用户数据 */}
<ul className="flex flex-row items-center justify-between mt-[12px] px-[19px]">
{userDataList.map((item, index) => (
<li key={index} className="flex flex-col justify-around w-[53px] h-[60px] text-center">
<div className="text-base text-[15px] leading-[16.3px]">{item.value}</div>
<div className="text-[rgba(0,0,0,0.7)] text-[12px] leading-[16.8px]">{item.label}</div>
</li>
))}
</ul>
{/* 按钮 */}
<ul className="px-[15px] mt-[6px]">
<li className="flex flex-row justify-between items-center w-[238px] h-[49px] px-[15px] rounded-[3px] text-[15px] leading-[21px] hover:bg-[#f2f3f7] cursor-pointer">
<span></span>
<Image width={24} height={24} src="/img/icon/love.svg" alt="我的收藏" />
</li>
<li className="flex flex-row items-center w-[238px] h-[49px] px-[15px] rounded-[3px] text-[15px] leading-[21px] hover:bg-[#f2f3f7] cursor-pointer">
<span>退</span>
</li>
</ul>
</div>
);
}

@ -1,23 +1,28 @@
'use client'; 'use client';
import React from 'react'; import React, { useState, useRef } from 'react';
import Link from 'next/link'; import Link from 'next/link';
import { usePathname } from 'next/navigation'; import { usePathname } from 'next/navigation';
import { useShallow } from 'zustand/react/shallow'; import { useShallow } from 'zustand/react/shallow';
import HeaderAvatar from './HeaderAvatar'; import HeaderAvatar from './HeaderAvatar';
import UserCard from './UserCard';
import { Logo, LoginModal } from '@/components'; import { Logo, LoginModal } from '@/components';
import useUserStore from '@/store/user'; import useUserStore from '@/store/user';
export default function Header() { export default function Header() {
const { showLogin } = useUserStore( const { userInfo, showLogin } = useUserStore(
useShallow((state) => ({ useShallow((state) => ({
userInfo: state.userInfo,
showLogin: state.showLogin, showLogin: state.showLogin,
})), })),
); );
const [showUserCard, setShowUserCard] = useState<boolean>(false);
let timer: number | null | NodeJS.Timeout = null;
const pathName = usePathname(); const pathName = usePathname();
const menuList = [ const menuList = [
{ {
@ -34,11 +39,22 @@ export default function Header() {
}, },
]; ];
const handleShowUserCard = () => {
if (!userInfo.id) return;
timer && clearTimeout(timer);
setShowUserCard(true);
};
const handleHideUserCard = () => {
timer = setTimeout(() => {
setShowUserCard(false);
}, 200);
};
return ( return (
<header className="absolute top-0 w-full h-[80px] z-2"> <header className="absolute top-0 w-full h-[80px] z-2">
<div className="w-[1200px] h-full mx-auto flex items-center justify-between"> <div className="relative w-[1200px] h-full mx-auto flex items-center justify-between">
<Logo /> <Logo />
<div className="h-full flex flex-row items-center"> <div className="h-full flex flex-row items-center">
<ul className="flex flex-row items-center space-x-[40px]"> <ul className="flex flex-row items-center space-x-[40px]">
{menuList.map(({ name, path }) => ( {menuList.map(({ name, path }) => (
@ -50,13 +66,23 @@ export default function Header() {
</li> </li>
))} ))}
</ul> </ul>
{/* 登录按钮/头像 */} {/* 登录按钮/头像 */}
<HeaderAvatar className="ml-[40px]" /> <div className="ml-[40px]" onMouseEnter={handleShowUserCard} onMouseLeave={handleHideUserCard}>
<HeaderAvatar />
</div>
</div> </div>
{/* 登录框 */} {/* 登录框 */}
{showLogin && <LoginModal />} {showLogin && <LoginModal />}
{/* 用户信息卡片 */}
{showUserCard && (
<div
className="absolute top-[70px] right-0"
onMouseEnter={handleShowUserCard}
onMouseLeave={handleHideUserCard}
>
<UserCard />
</div>
)}
</div> </div>
</header> </header>
); );

@ -37,8 +37,8 @@ const useUserStore = create<UserState>()(
birthDay: '', birthDay: '',
commentReplyCount: 0, commentReplyCount: 0,
contributorRole: '', contributorRole: '',
fansCount: '', fansCount: 0,
followCount: '', followCount: 0,
haveNewMessage: false, haveNewMessage: false,
id: '', id: '',
ipLocation: '', ipLocation: '',

@ -123,9 +123,9 @@ declare interface UserInfo {
/** 贡献者角色 */ /** 贡献者角色 */
contributorRole: string; contributorRole: string;
/** 粉丝数 */ /** 粉丝数 */
fansCount: string; fansCount: number;
/** 关注数 */ /** 关注数 */
followCount: string; followCount: number;
/** 是否有新的未读消息 */ /** 是否有新的未读消息 */
haveNewMessage: boolean; haveNewMessage: boolean;
/** ID */ /** ID */

Loading…
Cancel
Save