diff --git a/package-lock.json b/package-lock.json
index 0d095b6..a177a0d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -33,7 +33,7 @@
"prettier": "3.9.5",
"typescript": "~6.0.0",
"vite": "^8.1.5",
- "vite-plugin-pwa": "^1.2.0",
+ "vite-plugin-pwa": "^1.3.0",
"vite-plugin-vue-devtools": "^8.1.5",
"vitest": "^4.1.10",
"vue-eslint-parser": "^10.4.1",
@@ -9563,17 +9563,17 @@
}
},
"node_modules/vite-plugin-pwa": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz",
- "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.3.0.tgz",
+ "integrity": "sha512-c5kMgN+ITrOtHXp8PAtk2uOIEea6XjP/unCGxOWWBzQ6qa65qj/awHg0wf+QF9E/2u9vh86LqxPwzEPNbM2r5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.6",
"pretty-bytes": "^6.1.1",
"tinyglobby": "^0.2.10",
- "workbox-build": "^7.4.0",
- "workbox-window": "^7.4.0"
+ "workbox-build": "^7.4.1",
+ "workbox-window": "^7.4.1"
},
"engines": {
"node": ">=16.0.0"
@@ -9583,9 +9583,9 @@
},
"peerDependencies": {
"@vite-pwa/assets-generator": "^1.0.0",
- "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
- "workbox-build": "^7.4.0",
- "workbox-window": "^7.4.0"
+ "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+ "workbox-build": "^7.4.1",
+ "workbox-window": "^7.4.1"
},
"peerDependenciesMeta": {
"@vite-pwa/assets-generator": {
diff --git a/package.json b/package.json
index ec91716..79a7afe 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,7 @@
"prettier": "3.9.5",
"typescript": "~6.0.0",
"vite": "^8.1.5",
- "vite-plugin-pwa": "^1.2.0",
+ "vite-plugin-pwa": "^1.3.0",
"vite-plugin-vue-devtools": "^8.1.5",
"vitest": "^4.1.10",
"vue-eslint-parser": "^10.4.1",
diff --git a/src/components/BottomNav.vue b/src/components/BottomNav.vue
index 9e979d7..3e633da 100644
--- a/src/components/BottomNav.vue
+++ b/src/components/BottomNav.vue
@@ -17,8 +17,8 @@ const listsStore = useListsStore()
}}
- ⓘ
- About
+ ⚙
+ Account
@@ -55,10 +55,6 @@ const listsStore = useListsStore()
line-height: 1;
}
-.nav-item.is-active {
- color: var(--c-accent-strong);
-}
-
.nav-badge {
position: absolute;
top: 0.35rem;
diff --git a/src/stores/auth.ts b/src/stores/auth.ts
index a886024..af88a98 100644
--- a/src/stores/auth.ts
+++ b/src/stores/auth.ts
@@ -1,7 +1,8 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { loginApi, refreshApi, logoutApi, logoutAllApi } from '@/api/auth'
-import type { LoginPayload, TokenPair } from '@/types/auth'
+import type { AccessTokenClaims, LoginPayload, TokenPair } from '@/types/auth'
+import { decodeJwtPayload } from '@/utils/jwt'
export const useAuthStore = defineStore('auth', () => {
const accessToken = ref(localStorage.getItem('access_token'))
@@ -11,6 +12,12 @@ export const useAuthStore = defineStore('auth', () => {
const isAuthenticated = computed(() => !!accessToken.value)
+ const currentUser = computed(() =>
+ accessToken.value ? decodeJwtPayload(accessToken.value) : null,
+ )
+ const email = computed(() => currentUser.value?.email ?? null)
+ const username = computed(() => currentUser.value?.name ?? null)
+
function setTokens(tokens: TokenPair) {
accessToken.value = tokens.access_token
refreshToken.value = tokens.refresh_token
@@ -89,6 +96,9 @@ export const useAuthStore = defineStore('auth', () => {
isLoading,
error,
isAuthenticated,
+ currentUser,
+ email,
+ username,
setTokens,
clearTokens,
login,
diff --git a/src/types/auth.ts b/src/types/auth.ts
index 8fc43f3..abb032c 100644
--- a/src/types/auth.ts
+++ b/src/types/auth.ts
@@ -11,3 +11,15 @@ export interface TokenPair {
access_token: string
refresh_token: string
}
+
+export interface AccessTokenClaims {
+ user_id: string
+ email: string
+ name: string
+ exp: number
+}
+
+export interface ChangePasswordPayload {
+ old_password: string
+ new_password: string
+}
diff --git a/src/views/AboutView.vue b/src/views/AboutView.vue
index a267823..103fe5c 100644
--- a/src/views/AboutView.vue
+++ b/src/views/AboutView.vue
@@ -1,8 +1,13 @@