Skip to content

Commit 72505ba

Browse files
committed
fix: make the username & appear on the menu after change
1 parent aae157e commit 72505ba

File tree

5 files changed

+116
-28
lines changed

5 files changed

+116
-28
lines changed

apps/web/auth.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ export const authOptions: NextAuthOptions = {
6868
credentials.password,
6969
user[0].password,
7070
)
71-
// if (!isValid) {
72-
// console.error('NextUser authentication failed: Invalid password')
73-
// throw new Error('Invalid credentials')
74-
// }
71+
if (!isValid) {
72+
console.error('NextUser authentication failed: Invalid password')
73+
throw new Error('Invalid credentials')
74+
}
7575
console.log('NextUser authenticated successfully')
7676
//* Return user details to be attached to the token
7777
return {
@@ -98,7 +98,28 @@ export const authOptions: NextAuthOptions = {
9898
strategy: 'jwt', //* NextAuth V > 4 needs to specify the session strategy
9999
},
100100
callbacks: {
101-
async jwt({ token, user, account }) {
101+
async jwt({ token, user, account, trigger, session }) {
102+
console.log(
103+
'JWT callback → trigger:',
104+
trigger,
105+
'session:',
106+
session ? 'present' : 'none',
107+
'user:',
108+
user ? 'present' : 'none',
109+
)
110+
111+
if (trigger === 'update' && session) {
112+
console.log(
113+
'JWT callback → handling update trigger, session payload:',
114+
session,
115+
)
116+
token.name = session.name ?? token.name
117+
token.slug = session.slug ?? token.slug
118+
token.email = session.email ?? token.email
119+
// If you want to refresh hasuraJwt on update, do it here (carefully, with try/catch).
120+
return token
121+
}
122+
102123
if (user) {
103124
//* Add user role to the token when signing in with Google
104125
if (account?.provider === 'google') {

apps/web/components/auth/user-login.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { UserMenu } from '@/components/layout/header/user-menu'
44
import { ProfileSidebar } from '@/components/layout/sidebar/profile-sidebar'
55
import { Button } from '@/components/ui/button'
66
import { Skeleton } from '@/components/ui/skeleton'
7+
import { useProfile } from '@/lib/hooks/use-profile'
78
import { isTokenExpired } from 'mb-lib'
89
import { useSession } from 'next-auth/react'
910
import Link from 'next/link'
@@ -12,8 +13,9 @@ import { ProfileSidebarSkeleton } from '../shared/skeletons/profile-sidebar-skel
1213

1314
export function UserLogin() {
1415
const { data: session, status } = useSession()
16+
const { sessionUser } = useProfile()
1517

16-
if (status === 'loading') {
18+
if (status === 'loading' && sessionUser === null) {
1719
return <Skeleton className="h-6 w-24" />
1820
}
1921

@@ -32,9 +34,9 @@ export function UserLogin() {
3234
return (
3335
<>
3436
<Suspense fallback={<ProfileSidebarSkeleton />}>
35-
<ProfileSidebar user={session.user} />
37+
{sessionUser && <ProfileSidebar user={sessionUser} />}
3638
</Suspense>
37-
<UserMenu user={session.user} />
39+
{sessionUser && <UserMenu user={sessionUser} />}
3840
</>
3941
)
4042
}

apps/web/components/routes/preferences/preference-section.tsx

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import type { PreferenceSetInput } from 'mb-genql'
4343
import { toSlug } from 'mb-lib'
4444
import { signOut, useSession } from 'next-auth/react'
4545
import { useTheme } from 'next-themes'
46+
import { useRouter } from 'next/navigation'
4647
import { useEffect, useState } from 'react'
4748
import { useAsyncFn } from 'react-use'
4849
import GoogleTranslate from './google-translation'
@@ -54,13 +55,15 @@ export function PreferenceSection({ title, items }: PreferenceSectionProps) {
5455
const [buttonType, setButtonType] = useState('')
5556
const { data: session, update } = useSession()
5657
const { customSonner } = useSonner()
57-
const { currentUser, getUserInfo, updateUserDetails } = useProfile()
58+
const { currentUser, getUserInfo, updateUserDetails, updateSessionUser } =
59+
useProfile()
5860
const [errorMessage, setErrorMessage] = useState('')
5961
const [isLoading, setIsLoading] = useState(false)
6062
const [sendindVEmail, setSendingVEmail] = useState(false)
6163
const [inputValue, setInputValue] = useState({ username: '', email: '' })
6264
const { setTheme, theme } = useTheme()
6365
const { fontSize, setFontSize } = useAccessibility()
66+
const router = useRouter()
6467

6568
useEffect(() => {
6669
if (currentUser) {
@@ -275,20 +278,13 @@ export function PreferenceSection({ title, items }: PreferenceSectionProps) {
275278

276279
await updateUserDetails(email ?? null, username ?? null, slug ?? null)
277280

278-
await update({
279-
...session,
280-
user: {
281-
...session.user,
282-
email: email || session.user.email,
283-
name: username || session.user.name,
284-
slug: slug || session.user.slug,
285-
},
281+
await updateSessionUser({
282+
...session.user,
283+
slug,
284+
name: username,
286285
})
287286

288-
//reidrect to updated profile
289-
290-
window.location.href = `/u/${slug}/s/pref`
291-
287+
router.push(`/u/${slug}/s/pref`)
292288
customSonner({
293289
type: 'success',
294290
text: 'Profile updated successfully.',

apps/web/lib/hooks/use-profile.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
'use client'
22

33
import {
4+
getUserByID,
45
getUserBySlug,
56
updateUser,
67
updateUserPersonality,
78
} from '@/services/hasura'
89
import type { User } from 'mb-genql'
10+
import type { Session } from 'next-auth'
911
import { useSession } from 'next-auth/react'
10-
import * as React from 'react'
12+
import React, { useEffect } from 'react'
1113
import { useSonner } from './useSonner'
1214

15+
type sessionUserType = Session['user'] | null
16+
1317
interface profileContextProps {
1418
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
1519
getUserInfo: (username: string) => Promise<any>
@@ -26,6 +30,8 @@ interface profileContextProps {
2630
name: string | null,
2731
slug: string | null,
2832
) => void
33+
sessionUser: sessionUserType
34+
updateSessionUser: (user: sessionUserType) => void
2935
}
3036

3137
const profileContext = React.createContext<profileContextProps | undefined>(
@@ -48,8 +54,32 @@ export function ProfileProvider({ children }: ProfileProviderProps) {
4854
const { data: session } = useSession()
4955

5056
const [currentUser, setCurrentUser] = React.useState<User | null>(null)
57+
const [sessionUser, setSessionUser] = React.useState<sessionUserType>(null)
5158
const { customSonner } = useSonner()
5259

60+
useEffect(() => {
61+
const loadUser = async () => {
62+
if (!session?.user?.id) return
63+
64+
const { user } = await getUserByID(session.user.id)
65+
if (user) {
66+
setSessionUser({
67+
id: user.userId,
68+
name: user.username,
69+
email: user.email,
70+
image: user.profilePicture,
71+
slug: user.slug,
72+
role: user.role,
73+
hasuraJwt: session.user.hasuraJwt,
74+
})
75+
}
76+
}
77+
loadUser()
78+
}, [session])
79+
const updateSessionUser = (user: sessionUserType) => {
80+
setSessionUser(user)
81+
}
82+
5383
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
5484
const getUserInfo = async (slug: string): Promise<any> => {
5585
if (!slug?.trim()) {
@@ -157,6 +187,8 @@ export function ProfileProvider({ children }: ProfileProviderProps) {
157187
currentUser,
158188
setCurrentUser,
159189
updateUserDetails,
190+
updateSessionUser,
191+
sessionUser,
160192
}}
161193
>
162194
{children}

apps/web/services/hasura/hasura.service.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ export async function getAllChatbots() {
185185
},
186186
},
187187
})
188-
189188
return chatbot as Chatbot[]
190189
}
191190

@@ -232,7 +231,6 @@ export async function getChatbots({
232231
},
233232
},
234233
})
235-
236234
return chatbot as Chatbot[]
237235
}
238236

@@ -467,7 +465,6 @@ export async function getThread({
467465
} else {
468466
console.error('Error fetching thread: ', error)
469467
}
470-
471468
return null
472469
}
473470
}
@@ -658,7 +655,6 @@ export async function createThread({
658655
model,
659656
slug,
660657
jwt,
661-
userId,
662658
parentThreadId,
663659
isPublic = false,
664660
}: Partial<CreateThreadParams>) {
@@ -1649,8 +1645,6 @@ export async function fetchChatbotMetadata({
16491645
),
16501646
}))
16511647

1652-
// console.log('transformedMetadata', transformedMetadata);
1653-
16541648
return transformedMetadata[0] as unknown as ChatbotMetadata
16551649
} catch (error) {
16561650
console.error('Error fetching chatbot metadata:', error)
@@ -2015,6 +2009,49 @@ export async function isUsernameTaken(username: string, jwt?: string) {
20152009
return result.user.length > 0
20162010
}
20172011

2012+
export async function getUserByID(userId: string) {
2013+
if (!userId) throw new Error('userId is required')
2014+
2015+
try {
2016+
const client = getHasuraClient({})
2017+
2018+
const { user } = await client.query({
2019+
user: {
2020+
__args: {
2021+
where: {
2022+
userId: { _eq: userId },
2023+
},
2024+
},
2025+
userId: true,
2026+
username: true,
2027+
email: true,
2028+
slug: true,
2029+
profilePicture: true,
2030+
role: true,
2031+
},
2032+
} as const)
2033+
2034+
if (!user || user.length === 0) {
2035+
return { user: null, error: 'User not found' }
2036+
}
2037+
2038+
return {
2039+
user: user[0],
2040+
error: null,
2041+
}
2042+
} catch (error) {
2043+
console.error('Error fetching user by ID:', {
2044+
error,
2045+
userId,
2046+
timestamp: new Date().toISOString(),
2047+
})
2048+
if (error instanceof Error) {
2049+
return { user: null, error: error.message }
2050+
}
2051+
return { user: null, error: 'Unexpected error while fetching user' }
2052+
}
2053+
}
2054+
20182055
export async function updateUser({
20192056
userId,
20202057
email,

0 commit comments

Comments
 (0)