Skip to content

Commit b781e9e

Browse files
committed
feat: add avatar to product landing page for logged in users
See: DF-128
1 parent f35338b commit b781e9e

File tree

8 files changed

+94
-44
lines changed

8 files changed

+94
-44
lines changed

frontend/components/bc/DataWrapper.vue

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
<script setup lang="ts">
22
// The DataWrapper is for loading the Data that used in the whole app.
33
// We can't load the data directly in the app.vue as this would conflict with some providers being initialized there.
4-
const {
5-
getUser,
6-
} = useUserStore()
74
const { networkInfo } = useNetworkStore()
85
const { secondsPerSlot } = networkInfo.value
96
const { counter } = useInterval(secondsPerSlot)
@@ -12,8 +9,6 @@ const { refreshLatestState } = useLatestStateStore()
129
await useAsyncData('latest_state', () => refreshLatestState(), {
1310
watch: [ counter ],
1411
})
15-
16-
await useAsyncData('get_user', () => getUser())
1712
</script>
1813

1914
<template>

frontend/i18n/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"base": {
3+
"action": {
4+
"open_user_menu": "Open user menu"
5+
},
36
"beaconchain_homepage": "Beaconchain Homepage",
47
"common": {
58
"close": "Close",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export const useUserSession = () => {
2+
const data = useState<Awaited<ReturnType<typeof getUser>>>('user-session')
3+
const hasSession = computed(() => !!data.value)
4+
const requestFetch = useRequestFetch()
5+
const getUser = async () => {
6+
const result = await requestFetch('/api/bff/users/me')
7+
.catch((error) => {
8+
// session_id invalid or expired
9+
if (error?.status === 401) return
10+
throw createError({
11+
statusCode: error?.status || 500,
12+
statusMessage: error?.statusMessage || 'Unknown error',
13+
})
14+
})
15+
data.value = result
16+
return result
17+
}
18+
return {
19+
data,
20+
getUser,
21+
hasSession,
22+
}
23+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default defineNuxtRouteMiddleware(async () => {
2+
const {
3+
getUser,
4+
hasSession,
5+
} = useUserSession()
6+
if (!hasSession.value) {
7+
await callOnce(async () => {
8+
await getUser()
9+
})
10+
}
11+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default defineNuxtConfig({
2+
$meta: {
3+
name: 'auth',
4+
},
5+
})
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { FetchError } from 'ofetch'
2+
import type { InternalGetUserInfoResponse } from '~/types/api/user'
3+
4+
const config = useRuntimeConfig()
5+
const headers = {
6+
'x-ssr-secret': config.private.ssrSecret,
7+
}
8+
9+
export default defineEventHandler(async (event) => {
10+
const hasSessionCookie = getCookie(event, 'session_id')
11+
if (!hasSessionCookie) return
12+
13+
try {
14+
return await event.$fetch<InternalGetUserInfoResponse>('/users/me', {
15+
baseURL: config.public.apiClient,
16+
headers,
17+
}).then(({ data }) => data)
18+
}
19+
catch (error) {
20+
throw createError({
21+
statusCode: (error as FetchError).statusCode,
22+
statusMessage: (error as FetchError).statusMessage,
23+
})
24+
}
25+
})

frontend/layers/base/app/components/BaseNavigation.vue

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
<script setup lang="ts">
22
import type { BaseNavigationItem } from '#layers/base/app/components/BaseNavigationItem.vue'
33
4-
const { navigateToV1Login } = useV1Login()
4+
defineProps<{
5+
items: BaseNavigationItem[],
6+
}>()
7+
const {
8+
navigateToV1Login,
9+
} = useV1Login()
510
const { t: $t } = useTranslation()
611
const emit = defineEmits<{
712
(e: 'open'): void,
813
}>()
914
const handleClick = () => {
1015
emit('open')
1116
}
12-
defineProps<{
13-
items: BaseNavigationItem[],
14-
}>()
17+
const { hasSession } = useUserSession()
18+
const v1Domain = useV1Domain()
1519
</script>
1620

1721
<template>
@@ -50,11 +54,23 @@ defineProps<{
5054
/>
5155
</li>
5256
</ul>
53-
<BaseButton
54-
@click="navigateToV1Login"
55-
>
56-
{{ $t('base.common.log_in') }}
57-
</BaseButton>
57+
<span>
58+
<span v-if="hasSession">
59+
<BaseButtonIcon
60+
variant="secondary"
61+
screenreader-text="base.action.open_user_menu"
62+
name="user"
63+
@click="navigateTo(`${v1Domain}/user/settings`, { external: true })"
64+
/>
65+
</span>
66+
<span v-else>
67+
<BaseButton
68+
@click="navigateToV1Login"
69+
>
70+
{{ $t('base.common.log_in') }}
71+
</BaseButton>
72+
</span>
73+
</span>
5874
</div>
5975
</nav>
6076
</template>

frontend/stores/useUserStore.ts

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,11 @@
1-
import type {
2-
InternalGetUserInfoResponse, UserInfo,
3-
} from '~/types/api/user'
4-
5-
const userStore = defineStore('user-store', () => {
6-
const data = ref<null | undefined | UserInfo>()
7-
return { data }
8-
})
9-
101
export function useUserStore() {
2+
const { data } = useUserSession()
113
const { fetch } = useCustomFetch()
12-
const { data } = storeToRefs(userStore())
134
const router = useRouter()
145

15-
const setUser = (user?: UserInfo) => {
16-
data.value = user
17-
}
18-
19-
async function getUser() {
20-
try {
21-
const res = await fetch<InternalGetUserInfoResponse>(
22-
'USER',
23-
)
24-
setUser(res.data)
25-
return res.data
26-
}
27-
catch {
28-
setUser(undefined)
29-
return null
30-
}
31-
}
32-
336
const doLogout = async () => {
347
await fetch('LOGOUT')
35-
setUser(undefined)
8+
data.value = undefined
369
router.replace('/')
3710
}
3811

@@ -52,7 +25,6 @@ export function useUserStore() {
5225

5326
return {
5427
doLogout,
55-
getUser,
5628
hasV1Notifications,
5729
isLoggedIn,
5830
premium_perks,

0 commit comments

Comments
 (0)