1717 <code
1818 class =" hidden select-none cursor-pointer sm:inline-block rounded bg-gray-100 dark:bg-gray-800 px-2 py-0.5 text-xs font-mono text-gray-900 dark:text-gray-100 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
1919 @click =" copyPayloadUrl" >
20- /api/payload/{{ shortSlug(selectedToken) }}
20+ /api/payload/{{ friendlyId || shortSlug(selectedToken) }}
2121 </code >
2222 </UTooltip >
2323 </div >
6868 <div v-if =" showMobileExtras && hasMobileExtras" id =" header-mobile-extras"
6969 class =" mt-3 grid gap-3 rounded-lg border border-gray-200 dark:border-gray-800 bg-white/90 dark:bg-gray-900/90 p-3 shadow-sm md:hidden" >
7070 <ClientOnly >
71+ <code v-if =" selectedToken"
72+ class =" select-none cursor-pointer sm:inline-block rounded bg-gray-100 dark:bg-gray-800 px-2 py-0.5 text-xs font-mono text-gray-900 dark:text-gray-100 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
73+ @click =" copyPayloadUrl" >
74+ /api/payload/{{ friendlyId || shortSlug(selectedToken) }}
75+ </code >
76+
7177 <UButton v-if =" sessionInfo && sessionRestoreEnabled " color="neutral" variant="soft" size="sm"
7278 icon="i-lucide-user" @click =" copySessionId " >
7379 {{ sessionInfo.friendlyId }}
95101<script setup lang="ts">
96102import { computed , watch , onMounted , onUnmounted , ref } from ' vue'
97103import { useRoute } from ' vue-router'
98- import { useTokens } from ' ~/composables/useTokens '
104+ import { useTokensStore } from ' ~/stores/tokens '
99105import { useSSE } from ' ~/composables/useSSE'
100106import type { SSEEventPayload } from ' ~~/shared/types'
101107import { notify } from ' ~/composables/useNotificationBridge'
@@ -105,22 +111,38 @@ const route = useRoute()
105111const colorMode = useColorMode ()
106112const runtimeConfig = useRuntimeConfig ()
107113
108- const { tokens, loadTokens, deleteToken : removeToken } = useTokens ()
114+ const tokensStore = useTokensStore ()
115+ const { data : tokens, refetch : refetchTokens } = tokensStore .useTokensList ()
116+ const { mutateAsync : deleteToken } = tokensStore .useDeleteToken ()
117+
109118const sse = useSSE ()
110119
111120const sessionRestoreEnabled = runtimeConfig .public ?.sessionRestoreEnabled !== false
112121
113122const selectedToken = ref <string >(' ' )
123+ const friendlyId = ref <string >(' ' )
114124const isDeleting = ref (false )
115125const showDeleteModal = ref (false )
116126const showRestoreModal = ref (false )
117127const sessionInfo = ref <{ friendlyId: string } | null >(null )
118128const authRequired = ref (false )
119129const showMobileExtras = ref (false )
120130
131+ // Query for the currently selected token to get friendlyId
132+ const { data : currentTokenData } = tokensStore .useToken (selectedToken )
133+
134+ // Watch for changes in token data to update friendlyId
135+ watch (currentTokenData , (tokenData ) => {
136+ if (tokenData ) {
137+ friendlyId .value = tokenData .friendlyId || ' '
138+ } else {
139+ friendlyId .value = ' '
140+ }
141+ })
142+
121143const checkAuthStatus = async () => {
122144 try {
123- const response = await $fetch (' /api/auth/status' )
145+ const response = await $fetch <{ required : boolean }> (' /api/auth/status' )
124146 authRequired .value = response .required
125147 } catch {
126148 authRequired .value = false
@@ -135,7 +157,7 @@ watch(selectedToken, newVal => {
135157
136158const loadSessionInfo = async () => {
137159 try {
138- const data = await $fetch (' /api/session' )
160+ const data = await $fetch <{ friendlyId : string }> (' /api/session' )
139161 if (data ?.friendlyId ) {
140162 sessionInfo .value = { friendlyId: data .friendlyId }
141163 }
@@ -165,12 +187,12 @@ const copySessionId = async () => {
165187}
166188
167189const copyPayloadUrl = async () => {
168- if (! selectedToken .value ) {
190+ if (! selectedToken .value && ! friendlyId . value ) {
169191 return
170192 }
171193
172194 const origin = ' undefined' !== typeof window ? window .location .origin : ' '
173- const url = ` ${origin }/api/payload/${selectedToken .value } `
195+ const url = ` ${origin }/api/payload/${friendlyId . value || selectedToken .value } `
174196
175197 try {
176198 if (false === (await copyText (url ))) {
@@ -203,12 +225,13 @@ const tokenOptions = computed(() => {
203225 })
204226})
205227
206- watch (() => route .path , (path ) => {
228+ watch (() => route .path , async (path ) => {
207229 const match = path .match (/ \/ token\/ (. + )/ )
208230 if (match && match [1 ]) {
209231 selectedToken .value = match [1 ]
210232 } else {
211233 selectedToken .value = ' '
234+ friendlyId .value = ' '
212235 }
213236 showMobileExtras .value = false
214237}, { immediate: true })
@@ -228,13 +251,12 @@ function handleClientEvent(payload: SSEEventPayload) {
228251 return
229252 }
230253
231- loadTokens ()
254+ refetchTokens ()
232255}
233256
234257let unsubscribe: (() => void ) | null = null
235258
236259onMounted (async () => {
237- await loadTokens ()
238260 await loadSessionInfo ()
239261 await checkAuthStatus ()
240262 unsubscribe = sse .onAny (handleClientEvent )
@@ -257,7 +279,7 @@ const toggleMobileExtras = () => {
257279
258280const handleLogout = async () => {
259281 try {
260- await $fetch (' /api/auth/logout' , { method: ' POST' })
282+ await $fetch <{ ok : boolean }> (' /api/auth/logout' , { method: ' POST' })
261283 notify ({
262284 title: ' Logged out' ,
263285 description: ' You have been logged out successfully.' ,
@@ -296,7 +318,7 @@ const confirmDelete = async () => {
296318 const activeIndex = currentTokens .findIndex ((t : { id: string }) => t .id === selectedToken .value )
297319 const fallback = activeIndex !== - 1 ? currentTokens [activeIndex + 1 ] ?? currentTokens [activeIndex - 1 ] : undefined
298320
299- await removeToken (selectedToken .value )
321+ await deleteToken (selectedToken .value )
300322
301323 if (fallback ) {
302324 await navigateTo (` /token/${fallback .id } ` )
0 commit comments