all
This commit is contained in:
@ -0,0 +1,25 @@
|
||||
import { ReactNode } from 'react'
|
||||
import { Circle } from '@chakra-ui/react'
|
||||
import { variables } from '@/lib'
|
||||
import { useAppSelector } from '@/store/hook'
|
||||
import { NavType } from '@/store/ui/nav'
|
||||
|
||||
export type AccountMenuActiveCircleProps = {
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
const AccountMenuActiveCircle = ({
|
||||
children,
|
||||
}: AccountMenuActiveCircleProps) => {
|
||||
const activeNav = useAppSelector((state) => state.ui.nav.active)
|
||||
return (
|
||||
<Circle
|
||||
size="50px"
|
||||
bg={activeNav === NavType.Account ? variables.gradiant : 'transparent'}
|
||||
>
|
||||
{children}
|
||||
</Circle>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccountMenuActiveCircle
|
@ -0,0 +1,36 @@
|
||||
import { Avatar } from '@chakra-ui/react'
|
||||
import { forwardRef } from '@chakra-ui/system'
|
||||
import cx from 'classnames'
|
||||
import { User } from '@/client/idp/user'
|
||||
import { useAppSelector } from '@/store/hook'
|
||||
import { NavType } from '@/store/ui/nav'
|
||||
import AccountMenuActiveCircle from './account-menu-active-circle'
|
||||
|
||||
export type AccountMenuAvatarButtonProps = {
|
||||
user: User
|
||||
}
|
||||
|
||||
const AccountMenuAvatarButton = forwardRef<AccountMenuAvatarButtonProps, 'div'>(
|
||||
({ user, ...props }, ref) => {
|
||||
const activeNav = useAppSelector((state) => state.ui.nav.active)
|
||||
const isActive = activeNav === NavType.Account
|
||||
return (
|
||||
<div ref={ref} {...props} className={cx('cursor-pointer')}>
|
||||
<AccountMenuActiveCircle>
|
||||
<Avatar
|
||||
name={user.fullName}
|
||||
src={user.picture}
|
||||
size="sm"
|
||||
className={cx('w-[40px]', 'h-[40px]', {
|
||||
'border': isActive,
|
||||
'border-gray-300': isActive,
|
||||
'dark:border-gray-700': isActive,
|
||||
})}
|
||||
/>
|
||||
</AccountMenuActiveCircle>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
export default AccountMenuAvatarButton
|
@ -0,0 +1,24 @@
|
||||
import { Avatar } from '@chakra-ui/react'
|
||||
import cx from 'classnames'
|
||||
import { User } from '@/client/idp/user'
|
||||
|
||||
export type AccountMenuAvatarImageProps = {
|
||||
user: User
|
||||
}
|
||||
|
||||
const AccountMenuAvatarImage = ({ user }: AccountMenuAvatarImageProps) => (
|
||||
<Avatar
|
||||
name={user.fullName}
|
||||
src={user.picture}
|
||||
size="sm"
|
||||
className={cx(
|
||||
'w-[40px]',
|
||||
'h-[40px]',
|
||||
'border',
|
||||
'border-gray-300',
|
||||
'dark:border-gray-700',
|
||||
)}
|
||||
/>
|
||||
)
|
||||
|
||||
export default AccountMenuAvatarImage
|
@ -0,0 +1,71 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
import {
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuDivider,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Portal,
|
||||
SkeletonCircle,
|
||||
} from '@chakra-ui/react'
|
||||
import cx from 'classnames'
|
||||
import UserAPI from '@/client/idp/user'
|
||||
import { swrConfig } from '@/client/options'
|
||||
import AccountMenuActiveCircle from './account-menu-active-circle'
|
||||
import AccountMenuAvatarButton from './account-menu-avatar-button'
|
||||
import AccountMenuAvatarImage from './account-menu-avatar-image'
|
||||
|
||||
const TopBarAccountMenu = () => {
|
||||
const { data: user } = UserAPI.useGet(swrConfig())
|
||||
if (user) {
|
||||
return (
|
||||
<Menu>
|
||||
<MenuButton as={AccountMenuAvatarButton} user={user} />
|
||||
<Portal>
|
||||
<MenuList>
|
||||
<div
|
||||
className={cx(
|
||||
'flex',
|
||||
'flex-row',
|
||||
'items-center',
|
||||
'gap-0.5',
|
||||
'px-1',
|
||||
)}
|
||||
>
|
||||
<AccountMenuAvatarImage user={user} />
|
||||
<div className={cx('flex', 'flex-col', 'gap-0')}>
|
||||
<span
|
||||
className={cx(
|
||||
'font-semibold',
|
||||
'grow',
|
||||
'text-ellipsis',
|
||||
'overflow-hidden',
|
||||
'whitespace-nowrap',
|
||||
)}
|
||||
>
|
||||
{user.fullName}
|
||||
</span>
|
||||
<span className={cx('text-gray-500')}>{user.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
<MenuDivider />
|
||||
<MenuItem as={Link} to="/account/settings">
|
||||
Account
|
||||
</MenuItem>
|
||||
<MenuItem as={Link} to="/sign-out" className={cx('text-red-500')}>
|
||||
Sign Out
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Portal>
|
||||
</Menu>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<AccountMenuActiveCircle>
|
||||
<SkeletonCircle size="40px" />
|
||||
</AccountMenuActiveCircle>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default TopBarAccountMenu
|
Reference in New Issue
Block a user