fix: user info

This commit is contained in:
2026-04-03 15:53:31 +02:00
parent 3083330fcd
commit 2f7e313c95
23 changed files with 82 additions and 62 deletions

View File

@@ -1,6 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { TooltipProvider } from 'reka-ui' import { TooltipProvider } from 'reka-ui'
import { RouterView } from 'vue-router' import { RouterView } from 'vue-router'
import { useAuthStore } from './stores/customer/auth'
const authStore = useAuthStore()
</script> </script>
<template> <template>
@@ -12,35 +15,3 @@ import { RouterView } from 'vue-router'
</template> </template>
<!-- <template>
<component :is="layoutComponent">
<Suspense>
<RouterView />
</Suspense>
</component>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import DefaultLayout from '@/layouts/default.vue'
import EmptyLayout from '@/layouts/empty.vue'
const route = useRoute()
const layouts = {
default: DefaultLayout,
auth: EmptyLayout
}
console.log(route.fullPath)
console.log(route.name)
console.log(route.matched)
const layoutComponent = computed(() => {
console.log(route.meta);
return layouts[route.meta.layout as keyof typeof layouts] || DefaultLayout
})
</script> -->

View File

@@ -38,7 +38,7 @@
import { useFetchJson } from '@/composable/useFetchJson' import { useFetchJson } from '@/composable/useFetchJson'
import LangSwitch from './inner/LangSwitch.vue' import LangSwitch from './inner/LangSwitch.vue'
import ThemeSwitch from './inner/ThemeSwitch.vue' import ThemeSwitch from './inner/ThemeSwitch.vue'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { currentLang } from '@/router/langs' import { currentLang } from '@/router/langs'
import type { LabelTrans, TopMenuItem } from '@/types' import type { LabelTrans, TopMenuItem } from '@/types'

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import LangSwitch from './inner/LangSwitch.vue' import LangSwitch from './inner/LangSwitch.vue'
import ThemeSwitch from './inner/ThemeSwitch.vue' import ThemeSwitch from './inner/ThemeSwitch.vue'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
const authStore = useAuthStore() const authStore = useAuthStore()
</script> </script>

View File

@@ -201,7 +201,7 @@
import { useEditable } from '@/composable/useConteditable'; import { useEditable } from '@/composable/useConteditable';
import Default from '@/layouts/default.vue'; import Default from '@/layouts/default.vue';
import { langs } from '@/router/langs'; import { langs } from '@/router/langs';
import { useProductStore } from '@/stores/product'; import { useProductStore } from '@/stores/admin/product';
import { useSettingsStore } from '@/stores/admin/settings'; import { useSettingsStore } from '@/stores/admin/settings';
import type { EditorToolbarItem } from '@nuxt/ui'; import type { EditorToolbarItem } from '@nuxt/ui';
import { onMounted, ref, watch } from 'vue'; import { onMounted, ref, watch } from 'vue';

View File

@@ -52,7 +52,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useCartStore } from '@/stores/user/cart' import { useCartStore } from '@/stores/customer/cart'
import { ref } from 'vue' import { ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'

View File

@@ -104,7 +104,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue' import { ref, computed, watch } from 'vue'
import { useAddressStore } from '@/stores/user/address' import { useAddressStore } from '@/stores/customer/address'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import Default from '@/layouts/default.vue' import Default from '@/layouts/default.vue'
const addressStore = useAddressStore() const addressStore = useAddressStore()

View File

@@ -152,8 +152,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue' import { ref, computed, watch } from 'vue'
import { useCartStore } from '@/stores/user/cart' import { useCartStore } from '@/stores/customer/cart'
import { useAddressStore } from '@/stores/user/address' import { useAddressStore } from '@/stores/customer/address'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import Default from '@/layouts/default.vue' import Default from '@/layouts/default.vue'

View File

@@ -104,7 +104,7 @@
import { computed } from 'vue' import { computed } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useCustomerStore } from '@/stores/customer' import { useCustomerStore } from '@/stores/customer'
import { useAddressStore } from '@/stores/user/address' import { useAddressStore } from '@/stores/customer/address'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import Default from '@/layouts/default.vue' import Default from '@/layouts/default.vue'
const router = useRouter() const router = useRouter()

View File

@@ -116,9 +116,9 @@
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useCustomerStore } from '@/stores/customer' import { useCustomerStore } from '@/stores/customer'
import { useAddressStore } from '@/stores/user/address' import { useAddressStore } from '@/stores/customer/address'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useCartStore } from '@/stores/user/cart' import { useCartStore } from '@/stores/customer/cart'
import Default from '@/layouts/default.vue' import Default from '@/layouts/default.vue'
const router = useRouter() const router = useRouter()
const customerStore = useCustomerStore() const customerStore = useCustomerStore()

View File

@@ -29,7 +29,7 @@ export async function useFetchJson<T = unknown>(url: string, opt?: RequestInit):
// Handle 401 — access token expired; try to refresh via the HTTPOnly refresh_token cookie // Handle 401 — access token expired; try to refresh via the HTTPOnly refresh_token cookie
if (res.status === 401) { if (res.status === 401) {
const { useAuthStore } = await import('@/stores/user/auth') const { useAuthStore } = await import('../stores/customer/auth')
const authStore = useAuthStore() const authStore = useAuthStore()
const refreshed = await authStore.refreshAccessToken() const refreshed = await authStore.refreshAccessToken()

View File

@@ -24,11 +24,12 @@
<template #footer> <template #footer>
<UDropdownMenu :items="userItems" :content="{ align: 'center', collisionPadding: 12 }" <UDropdownMenu :items="userItems" :content="{ align: 'center', collisionPadding: 12 }"
:ui="{ content: 'w-(--reka-dropdown-menu-trigger-width) min-w-48' }"> :ui="{ content: 'w-(--reka-dropdown-menu-trigger-width) min-w-48' }">
<UButton v-bind="user" :label="user?.name" trailing-icon="i-lucide-chevrons-up-down" color="neutral" <UButton v-bind="userStore.user" :label="userStore.user?.email" trailing-icon="i-lucide-chevrons-up-down" color="neutral"
variant="ghost" square class="w-full data-[state=open]:bg-elevated overflow-hidden" :ui="{ variant="ghost" square class="w-full data-[state=open]:bg-elevated overflow-hidden" :ui="{
trailingIcon: 'text-dimmed ms-auto' trailingIcon: 'text-dimmed ms-auto'
}" /> }" />
</UDropdownMenu> </UDropdownMenu>
<!-- first_name: '', last_name: '' -->
</template> </template>
</USidebar> </USidebar>
@@ -63,10 +64,14 @@ import { ref, computed, onMounted } from 'vue'
import { useColorMode } from '@vueuse/core' import { useColorMode } from '@vueuse/core'
import type { DropdownMenuItem, NavigationMenuItem } from '@nuxt/ui' import type { DropdownMenuItem, NavigationMenuItem } from '@nuxt/ui'
import { defineShortcuts, extractShortcuts } from '@nuxt/ui/runtime/composables/defineShortcuts.js' import { defineShortcuts, extractShortcuts } from '@nuxt/ui/runtime/composables/defineShortcuts.js'
import { LabelTrans, TopMenuItem } from '@/types' import { useAuthStore } from '../stores/customer/auth'
const authStore = useAuthStore()
const userStore = useUserStore()
await userStore.getUser()
const open = ref(true) const open = ref(true)
const authStore = useAuthStore()
const colorMode = useColorMode() const colorMode = useColorMode()
const teams = ref([ const teams = ref([
@@ -156,10 +161,11 @@ function getItems(state: 'collapsed' | 'expanded') {
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { currentLang } from '@/router/langs' import { currentLang } from '@/router/langs'
import { useFetchJson } from '@/composable/useFetchJson' import { useFetchJson } from '@/composable/useFetchJson'
import { useAuthStore } from '@/stores/user/auth'
import CountryCurrencySwitch from '@/components/inner/CountryCurrencySwitch.vue' import CountryCurrencySwitch from '@/components/inner/CountryCurrencySwitch.vue'
import LangSwitch from '@/components/inner/LangSwitch.vue' import LangSwitch from '@/components/inner/LangSwitch.vue'
import ThemeSwitch from '@/components/inner/ThemeSwitch.vue' import ThemeSwitch from '@/components/inner/ThemeSwitch.vue'
import type { LabelTrans, TopMenuItem } from '@/types'
import { useUserStore } from '@/stores/user'
const router = useRouter() const router = useRouter()
@@ -217,13 +223,6 @@ function transformMenu(
}) })
} }
const user = ref({
name: 'Benjamin Canac',
avatar: {
src: 'https://github.com/benjamincanac.png',
alt: 'Benjamin Canac'
}
})
const userItems = computed<DropdownMenuItem[][]>(() => [ const userItems = computed<DropdownMenuItem[][]>(() => [
[ [

View File

@@ -1,7 +1,7 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import { currentLang, langs, switchLocalization } from './langs' import { currentLang, langs, switchLocalization } from './langs'
import { getSettings } from './settings' import { getSettings } from './settings'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
import { getRoutes } from './menu' import { getRoutes } from './menu'
function isAuthenticated(): boolean { function isAuthenticated(): boolean {

View File

@@ -1,6 +1,5 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import type { Address } from './user/address'
export interface CustomerData { export interface CustomerData {
companyName: string companyName: string

View File

@@ -1,6 +1,7 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { useFetchJson } from '@/composable/useFetchJson' import { useFetchJson } from '@/composable/useFetchJson'
import { useUserStore } from '../user'
export interface User { export interface User {
id: string id: string
@@ -41,6 +42,8 @@ export const useAuthStore = defineStore('auth', () => {
_isAuthenticated.value = readIsAuthenticatedCookie() _isAuthenticated.value = readIsAuthenticatedCookie()
} }
// const auth = useAuthStore()
// const userStore = useUserStore()
async function login(email: string, password: string) { async function login(email: string, password: string) {
loading.value = true loading.value = true
error.value = null error.value = null
@@ -60,6 +63,7 @@ export const useAuthStore = defineStore('auth', () => {
user.value = response.user user.value = response.user
_syncAuthState() _syncAuthState()
// await userStore.getUser()
return true return true
} catch (e: any) { } catch (e: any) {

32
bo/src/stores/user.ts Normal file
View File

@@ -0,0 +1,32 @@
import type { User } from '@/types/user'
import { ref } from 'vue'
import { defineStore } from 'pinia'
import { useFetchJson } from '@/composable/useFetchJson'
export const useUserStore = defineStore('user', () => {
const error = ref<string | null>(null)
const user = ref<User | null>(null)
async function getUser() {
error.value = null
try {
const data = await useFetchJson<User>(`/api/v1/restricted/customer`)
console.log('getUser API response:', data)
const response: User = (data as any).items ?? data
console.log('User response:', response)
user.value = response
return response
} catch (err: any) {
error.value = err?.message ?? 'Unknown error'
return null
}
}
return {
error,
user,
getUser
}
})

15
bo/src/types/user.d.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
export interface User {
id: string
email: string
name: string
first_name?: string
last_name?: string
company_name?: string
company_email?: string
company_address?: Address
billing_address?: Address
regon?: string
nip?: string
vat?: string
}

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, defineAsyncComponent, ref } from 'vue' import { computed, defineAsyncComponent, ref } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
import { useValidation } from '@/composable/useValidation' import { useValidation } from '@/composable/useValidation'
import type { FormError } from '@nuxt/ui' import type { FormError } from '@nuxt/ui'
import { i18n } from '@/plugins/02_i18n' import { i18n } from '@/plugins/02_i18n'

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
import { useValidation } from '@/composable/useValidation' import { useValidation } from '@/composable/useValidation'
import type { FormError } from '@nuxt/ui' import type { FormError } from '@nuxt/ui'
import { i18n } from '@/plugins/02_i18n' import { i18n } from '@/plugins/02_i18n'

View File

@@ -117,7 +117,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, defineAsyncComponent } from 'vue' import { ref, computed, defineAsyncComponent } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
import { useValidation } from '@/composable/useValidation' import { useValidation } from '@/composable/useValidation'
import type { FormError } from '@nuxt/ui' import type { FormError } from '@nuxt/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'

View File

@@ -11,7 +11,7 @@ import {
LinearScale, LinearScale,
} from 'chart.js' } from 'chart.js'
import { getYears, getQuarters, getIssues, type QuarterData, type IssueTimeSummary } from '@/composable/useRepoApi' import { getYears, getQuarters, getIssues, type QuarterData, type IssueTimeSummary } from '@/composable/useRepoApi'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
import { i18n } from '@/plugins/02_i18n' import { i18n } from '@/plugins/02_i18n'
import type { TableColumn } from '@nuxt/ui' import type { TableColumn } from '@nuxt/ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/user/auth' import { useAuthStore } from '@/stores/customer/auth'
import { useValidation } from '@/composable/useValidation' import { useValidation } from '@/composable/useValidation'
import type { FormError } from '@nuxt/ui' import type { FormError } from '@nuxt/ui'
import { i18n } from '@/plugins/02_i18n' import { i18n } from '@/plugins/02_i18n'