File tree Expand file tree Collapse file tree 6 files changed +57
-51
lines changed
Expand file tree Collapse file tree 6 files changed +57
-51
lines changed Original file line number Diff line number Diff line change @@ -21,23 +21,6 @@ describe("UserMenu", () => {
2121 expect ( initialsElement ) . toBeTruthy ( ) ;
2222 } ) ;
2323
24- it ( "shows sign out option in dropdown menu when clicked" , async ( ) => {
25- const userEvent = ( await import ( "@testing-library/user-event" ) ) . default ;
26- const user = userEvent . setup ( ) ;
27- const { container } = render ( < UserMenu userName = "Test User" /> ) ;
28-
29- // Find and click the trigger (button with user name) within this render
30- const trigger = container . querySelector ( "button" ) ;
31- expect ( trigger ) . toBeTruthy ( ) ;
32- if ( ! trigger ) return ;
33-
34- await user . click ( trigger ) ;
35-
36- // Check that sign out menu item appears
37- const signOutItem = screen . getByText ( "Sign out" ) ;
38- expect ( signOutItem ) . toBeTruthy ( ) ;
39- } ) ;
40-
4124 it ( "calls signOut when sign out menu item is clicked" , async ( ) => {
4225 const userEvent = ( await import ( "@testing-library/user-event" ) ) . default ;
4326 render ( < UserMenu userName = "Jane Smith" /> ) ;
Original file line number Diff line number Diff line change 11import type { Metadata } from "next" ;
22import { Geist , Geist_Mono } from "next/font/google" ;
3- import { headers } from "next/headers" ;
43import { Toaster } from "sonner" ;
5- import { UserMenu } from "@/components/user-menu" ;
6- import { auth } from "@/lib/auth/auth" ;
4+ import { Navbar } from "@/components/navbar" ;
75import "@/lib/api-client" ;
86import "./globals.css" ;
97
@@ -22,25 +20,17 @@ export const metadata: Metadata = {
2220 description : "Generated by create next app" ,
2321} ;
2422
25- export default async function RootLayout ( {
23+ export default function RootLayout ( {
2624 children,
2725} : Readonly < {
2826 children : React . ReactNode ;
2927} > ) {
30- const session = await auth . api . getSession ( {
31- headers : await headers ( ) ,
32- } ) ;
33-
3428 return (
3529 < html lang = "en" >
3630 < body
3731 className = { `${ geistSans . variable } ${ geistMono . variable } antialiased` }
3832 >
39- < header className = "border-b" >
40- < div className = "container mx-auto px-4 py-4" >
41- { session ?. user ?. name && < UserMenu userName = { session . user . name } /> }
42- </ div >
43- </ header >
33+ < Navbar />
4434 { children }
4535 < Toaster
4636 richColors
Original file line number Diff line number Diff line change 1+ import { headers } from "next/headers" ;
2+ import { UserMenu } from "@/components/user-menu" ;
3+ import { auth } from "@/lib/auth/auth" ;
4+
5+ export async function Navbar ( ) {
6+ const session = await auth . api . getSession ( {
7+ headers : await headers ( ) ,
8+ } ) ;
9+
10+ return (
11+ < header className = "border-b" >
12+ < div className = "container mx-auto px-4 py-4" >
13+ { session ?. user ?. name && < UserMenu userName = { session . user . name } /> }
14+ </ div >
15+ </ header >
16+ ) ;
17+ }
Original file line number Diff line number Diff line change 11"use client" ;
22
3- import { Avatar , AvatarFallback } from "@/components/ui/avatar" ;
43import { Button } from "@/components/ui/button" ;
54import {
65 DropdownMenu ,
76 DropdownMenuContent ,
8- DropdownMenuItem ,
97 DropdownMenuTrigger ,
108} from "@/components/ui/dropdown-menu" ;
11- import { signOut } from "@/lib/auth/auth-client" ;
9+ import { SignOutMenuItem } from "./sign-out-menu-item" ;
10+ import { UserAvatar } from "./user-avatar" ;
1211
1312interface UserMenuProps {
1413 userName : string ;
1514}
1615
17- function getInitials ( name : string ) : string {
18- return name
19- . split ( " " )
20- . map ( ( word ) => word [ 0 ] )
21- . join ( "" )
22- . toUpperCase ( ) ;
23- }
24-
2516export function UserMenu ( { userName } : UserMenuProps ) {
26- const initials = getInitials ( userName ) ;
27-
28- const handleSignOut = async ( ) => {
29- await signOut ( ) ;
30- } ;
31-
3217 return (
3318 < DropdownMenu >
3419 < DropdownMenuTrigger asChild >
3520 < Button variant = "ghost" className = "flex items-center gap-2" >
36- < Avatar >
37- < AvatarFallback > { initials } </ AvatarFallback >
38- </ Avatar >
21+ < UserAvatar userName = { userName } />
3922 < span > { userName } </ span >
4023 </ Button >
4124 </ DropdownMenuTrigger >
4225 < DropdownMenuContent >
43- < DropdownMenuItem onSelect = { handleSignOut } > Sign out </ DropdownMenuItem >
26+ < SignOutMenuItem / >
4427 </ DropdownMenuContent >
4528 </ DropdownMenu >
4629 ) ;
Original file line number Diff line number Diff line change 1+ import { DropdownMenuItem } from "@/components/ui/dropdown-menu" ;
2+ import { signOut } from "@/lib/auth/auth-client" ;
3+
4+ export function SignOutMenuItem ( ) {
5+ const handleSignOut = async ( ) => {
6+ await signOut ( ) ;
7+ } ;
8+
9+ return < DropdownMenuItem onSelect = { handleSignOut } > Sign out</ DropdownMenuItem > ;
10+ }
Original file line number Diff line number Diff line change 1+ import { Avatar , AvatarFallback } from "@/components/ui/avatar" ;
2+
3+ interface UserAvatarProps {
4+ userName : string ;
5+ }
6+
7+ function getInitials ( name : string ) : string {
8+ return name
9+ . split ( " " )
10+ . map ( ( word ) => word [ 0 ] )
11+ . join ( "" )
12+ . toUpperCase ( ) ;
13+ }
14+
15+ export function UserAvatar ( { userName } : UserAvatarProps ) {
16+ const initials = getInitials ( userName ) ;
17+
18+ return (
19+ < Avatar >
20+ < AvatarFallback > { initials } </ AvatarFallback >
21+ </ Avatar >
22+ ) ;
23+ }
You can’t perform that action at this time.
0 commit comments