fix: dropdown menu
This commit is contained in:
parent
615e8e6384
commit
7ce8ae0867
8 changed files with 230 additions and 119 deletions
|
|
@ -43,10 +43,10 @@ export default function RootLayout({ children }: RootLayoutProps) {
|
||||||
>
|
>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<Providers attribute="class" defaultTheme="system" enableSystem>
|
<Providers attribute="class" defaultTheme="system" enableSystem>
|
||||||
<div className="flex flex-col min-h-screen">
|
<div className="flex min-h-screen flex-col">
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<Header />
|
<Header />
|
||||||
<main className="flex flex-col flex-1 bg-muted/50">{children}</main>
|
<main className="flex flex-1 flex-col bg-muted/50">{children}</main>
|
||||||
</div>
|
</div>
|
||||||
<TailwindIndicator />
|
<TailwindIndicator />
|
||||||
</Providers>
|
</Providers>
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,13 @@ import { ClearHistory } from '@/components/clear-history'
|
||||||
import { clearChats } from '@/app/actions'
|
import { clearChats } from '@/app/actions'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { auth } from '@/auth'
|
import { auth } from '@/auth'
|
||||||
import { UserMenu } from './ui/user-menu'
|
import { UserMenu } from './user-menu'
|
||||||
import { LoginButton } from './login-button'
|
import { LoginButton } from './login-button'
|
||||||
|
|
||||||
export async function Header() {
|
export async function Header() {
|
||||||
const session = await auth()
|
const session = await auth()
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 flex items-center justify-between w-full h-16 px-4 border-b shrink-0 bg-gradient-to-b from-background/10 via-background/50 to-background/80 backdrop-blur-xl">
|
<header className="sticky top-0 z-50 flex h-16 w-full shrink-0 items-center justify-between border-b bg-gradient-to-b from-background/10 via-background/50 to-background/80 px-4 backdrop-blur-xl">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
{session?.user ? (
|
{session?.user ? (
|
||||||
<Sidebar>
|
<Sidebar>
|
||||||
|
|
@ -33,12 +33,16 @@ export async function Header() {
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
) : (
|
) : (
|
||||||
<Link href="https://vercel.com" target="_blank" rel="nofollow">
|
<Link href="https://vercel.com" target="_blank" rel="nofollow">
|
||||||
<IconVercel className="w-6 h-6 mr-2" />
|
<IconVercel className="mr-2 h-6 w-6" />
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<IconSeparator className="w-6 h-6 text-muted-foreground/50" />
|
<IconSeparator className="h-6 w-6 text-muted-foreground/50" />
|
||||||
{session?.user ? <UserMenu session={session} /> : <LoginButton />}
|
{session?.user ? (
|
||||||
|
<UserMenu user={session.user} />
|
||||||
|
) : (
|
||||||
|
<LoginButton className="-ml-2" />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-end space-x-2">
|
<div className="flex items-center justify-end space-x-2">
|
||||||
|
|
@ -49,7 +53,7 @@ export async function Header() {
|
||||||
className={cn(buttonVariants({ variant: 'outline' }))}
|
className={cn(buttonVariants({ variant: 'outline' }))}
|
||||||
>
|
>
|
||||||
<IconGitHub />
|
<IconGitHub />
|
||||||
<span className="hidden ml-2 md:flex">GitHub</span>
|
<span className="ml-2 hidden md:flex">GitHub</span>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="https://github.com/vercel/nextjs-ai-chatbot/"
|
href="https://github.com/vercel/nextjs-ai-chatbot/"
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,22 @@
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
import { signIn } from 'next-auth/react'
|
||||||
|
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { Button, type ButtonProps } from '@/components/ui/button'
|
import { Button, type ButtonProps } from '@/components/ui/button'
|
||||||
import { IconGitHub, IconSpinner } from '@/components/ui/icons'
|
import { IconSpinner } from '@/components/ui/icons'
|
||||||
import { signIn } from 'next-auth/react'
|
|
||||||
|
|
||||||
interface LoginButtonProps extends ButtonProps {
|
interface LoginButtonProps extends ButtonProps {
|
||||||
text?: string
|
text?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LoginButton({
|
export function LoginButton({ className, ...props }: LoginButtonProps) {
|
||||||
className,
|
|
||||||
text = 'Login with GitHub',
|
|
||||||
...props
|
|
||||||
}: LoginButtonProps) {
|
|
||||||
const [isLoading, setIsLoading] = React.useState(false)
|
const [isLoading, setIsLoading] = React.useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="link"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
signIn('github')
|
signIn('github')
|
||||||
|
|
@ -29,12 +25,8 @@ export function LoginButton({
|
||||||
className={cn(className)}
|
className={cn(className)}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading && <IconSpinner className="mr-2 animate-spin" />}
|
||||||
<IconSpinner className="mr-2 animate-spin" />
|
Login
|
||||||
) : (
|
|
||||||
<IconGitHub className="mr-2" />
|
|
||||||
)}
|
|
||||||
{text}
|
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ export interface SidebarListProps {
|
||||||
export async function SidebarList({ userId }: SidebarListProps) {
|
export async function SidebarList({ userId }: SidebarListProps) {
|
||||||
const chats = await getChats(userId)
|
const chats = await getChats(userId)
|
||||||
|
|
||||||
console.log(chats)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 overflow-auto">
|
<div className="flex-1 overflow-auto">
|
||||||
{chats?.length ? (
|
{chats?.length ? (
|
||||||
|
|
|
||||||
128
components/ui/dropdown-menu.tsx
Normal file
128
components/ui/dropdown-menu.tsx
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import * as React from 'react'
|
||||||
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
|
||||||
|
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const DropdownMenu = DropdownMenuPrimitive.Root
|
||||||
|
|
||||||
|
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
||||||
|
|
||||||
|
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
||||||
|
|
||||||
|
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
||||||
|
|
||||||
|
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
||||||
|
|
||||||
|
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
||||||
|
|
||||||
|
const DropdownMenuSubContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.SubContent
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuSubContent.displayName =
|
||||||
|
DropdownMenuPrimitive.SubContent.displayName
|
||||||
|
|
||||||
|
const DropdownMenuContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
||||||
|
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Portal>
|
||||||
|
<DropdownMenuPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</DropdownMenuPrimitive.Portal>
|
||||||
|
))
|
||||||
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const DropdownMenuItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||||
|
inset && 'pl-8',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
||||||
|
|
||||||
|
const DropdownMenuLabel = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Label
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'px-2 py-1.5 text-sm font-semibold',
|
||||||
|
inset && 'pl-8',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
||||||
|
|
||||||
|
const DropdownMenuSeparator = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Separator
|
||||||
|
ref={ref}
|
||||||
|
className={cn('-mx-1 my-1 h-px bg-muted', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
||||||
|
|
||||||
|
const DropdownMenuShortcut = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={cn('ml-auto text-xs tracking-widest opacity-60', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DropdownMenuShortcut.displayName = 'DropdownMenuShortcut'
|
||||||
|
|
||||||
|
export {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuShortcut,
|
||||||
|
DropdownMenuGroup,
|
||||||
|
DropdownMenuPortal,
|
||||||
|
DropdownMenuSub,
|
||||||
|
DropdownMenuSubContent,
|
||||||
|
DropdownMenuRadioGroup
|
||||||
|
}
|
||||||
|
|
@ -442,6 +442,23 @@ function IconUsers({ className, ...props }: React.ComponentProps<'svg'>) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function IconExternalLink({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<'svg'>) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor"
|
||||||
|
className={cn('h-4 w-4', className)}
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path d="M224 104a8 8 0 0 1-16 0V59.32l-66.33 66.34a8 8 0 0 1-11.32-11.32L196.68 48H152a8 8 0 0 1 0-16h64a8 8 0 0 1 8 8Zm-40 24a8 8 0 0 0-8 8v72H48V80h72a8 8 0 0 0 0-16H48a16 16 0 0 0-16 16v128a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-72a8 8 0 0 0-8-8Z" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
IconEdit,
|
IconEdit,
|
||||||
IconNextChat,
|
IconNextChat,
|
||||||
|
|
@ -467,5 +484,6 @@ export {
|
||||||
IconDownload,
|
IconDownload,
|
||||||
IconClose,
|
IconClose,
|
||||||
IconShare,
|
IconShare,
|
||||||
IconUsers
|
IconUsers,
|
||||||
|
IconExternalLink
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
'use client'
|
|
||||||
|
|
||||||
// import { type Session } from 'next-auth'
|
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
|
||||||
import { signOut } from 'next-auth/react'
|
|
||||||
|
|
||||||
import Image from 'next/image'
|
|
||||||
|
|
||||||
export interface UserMenuProps {
|
|
||||||
session: any // Session
|
|
||||||
}
|
|
||||||
|
|
||||||
export function UserMenu({ session }: UserMenuProps) {
|
|
||||||
return (
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<DropdownMenu.Root>
|
|
||||||
<DropdownMenu.Trigger asChild>
|
|
||||||
<button className="focus:outline-none">
|
|
||||||
{session.user?.image ? (
|
|
||||||
<Image
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
className="w-6 h-6 transition-opacity duration-300 rounded-full select-none ring-zinc-100/10 ring-1 hover:opacity-80"
|
|
||||||
src={session.user?.image ? `${session.user.image}&s=60` : ''}
|
|
||||||
alt={session.user.name ?? 'Avatar'}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div className="flex items-center justify-center w-8 h-8 p-2 rounded-full select-none shrink-0 bg-gradient-to-r from-cyan-500 to-blue-500">
|
|
||||||
<div
|
|
||||||
className="font-medium uppercase text-zinc-100"
|
|
||||||
style={{ fontSize: 12 }}
|
|
||||||
>
|
|
||||||
{session.user?.name ? session.user?.name.slice(0, 2) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</DropdownMenu.Trigger>
|
|
||||||
|
|
||||||
<DropdownMenu.Portal>
|
|
||||||
<DropdownMenu.Content
|
|
||||||
className="min-w-[200px] bg-white dark:bg-zinc-950 rounded-lg shadow-lg text-zinc-900 dark:text-zinc-400 overflow-hidden border border-transparent dark:border-zinc-700 focus:outline-none relative z-20 py-2"
|
|
||||||
sideOffset={8}
|
|
||||||
align="end"
|
|
||||||
>
|
|
||||||
<DropdownMenu.Item className="px-3 py-2 focus:outline-none">
|
|
||||||
<div className="text-xs font-medium">{session.user?.name}</div>
|
|
||||||
<div className="text-xs text-zinc-500">{session.user?.email}</div>
|
|
||||||
</DropdownMenu.Item>
|
|
||||||
|
|
||||||
<DropdownMenu.Separator className="my-1 h-[1px] bg-zinc-100 dark:bg-zinc-800" />
|
|
||||||
<DropdownMenu.Item className="px-3 py-2 text-xs transition-colors duration-200 cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800 focus:outline-none ">
|
|
||||||
<a
|
|
||||||
href="https://vercel.com"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="inline-flex items-center justify-between w-full"
|
|
||||||
>
|
|
||||||
<span>Vercel Homepage</span>
|
|
||||||
<span>
|
|
||||||
<svg
|
|
||||||
fill="none"
|
|
||||||
height={16}
|
|
||||||
shapeRendering="geometricPrecision"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width={16}
|
|
||||||
aria-hidden="true"
|
|
||||||
className="mr-1"
|
|
||||||
>
|
|
||||||
<path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6" />
|
|
||||||
<path d="M15 3h6v6" />
|
|
||||||
<path d="M10 14L21 3" />
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</DropdownMenu.Item>
|
|
||||||
<DropdownMenu.Item
|
|
||||||
className="px-3 py-2 text-xs transition-colors duration-200 cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800 focus:outline-none"
|
|
||||||
onClick={() => signOut()}
|
|
||||||
>
|
|
||||||
Log Out
|
|
||||||
</DropdownMenu.Item>
|
|
||||||
</DropdownMenu.Content>
|
|
||||||
</DropdownMenu.Portal>
|
|
||||||
</DropdownMenu.Root>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
UserMenu.displayName = 'UserMenu'
|
|
||||||
65
components/user-menu.tsx
Normal file
65
components/user-menu.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import Image from 'next/image'
|
||||||
|
import { type Session } from 'next-auth'
|
||||||
|
import { signOut } from 'next-auth/react'
|
||||||
|
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuTrigger
|
||||||
|
} from '@/components/ui/dropdown-menu'
|
||||||
|
import { IconExternalLink } from '@/components/ui/icons'
|
||||||
|
|
||||||
|
export interface UserMenuProps {
|
||||||
|
user: Session['user']
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UserMenu({ user }: UserMenuProps) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button variant="ghost" className="pl-0">
|
||||||
|
{user?.image ? (
|
||||||
|
<Image
|
||||||
|
className="h-6 w-6 select-none rounded-full ring-1 ring-zinc-100/10 transition-opacity duration-300 hover:opacity-80"
|
||||||
|
src={user?.image ? `${user.image}&s=60` : ''}
|
||||||
|
alt={user.name ?? 'Avatar'}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="flex h-7 w-7 shrink-0 select-none items-center justify-center rounded-full bg-muted/50 text-xs font-medium uppercase text-muted-foreground">
|
||||||
|
{user?.name ? user?.name.slice(0, 2) : null}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<span className="ml-2">{user?.name}</span>
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent sideOffset={8} align="start" className="w-[180px]">
|
||||||
|
<DropdownMenuItem className="flex-col items-start">
|
||||||
|
<div className="text-xs font-medium">{user?.name}</div>
|
||||||
|
<div className="text-xs text-zinc-500">{user?.email}</div>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem asChild>
|
||||||
|
<a
|
||||||
|
href="https://vercel.com"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="inline-flex w-full items-center justify-between text-xs"
|
||||||
|
>
|
||||||
|
Vercel Homepage
|
||||||
|
<IconExternalLink className="ml-auto h-3 w-3" />
|
||||||
|
</a>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onClick={() => signOut()} className="text-xs">
|
||||||
|
Log Out
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue