NavbarTokenExpiredTime.vue 1.45 KB
<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useKeycloakStore } from '@/@core/stores/keycloakStore'
import keycloakInstance from '@/keycloak'

const keycloakStore = useKeycloakStore()
const authenticated = computed(() => keycloakStore.authenticated)

const now = ref(Math.floor(Date.now() / 1000))
const tokenLifetime = ref(0)

let timer: ReturnType<typeof setInterval>

onMounted(() => {
  // Set tokenLifetime only once
  if (keycloakInstance.tokenParsed?.exp && keycloakInstance.tokenParsed?.iat)
    tokenLifetime.value = keycloakInstance.tokenParsed.exp - keycloakInstance.tokenParsed.iat

  timer = setInterval(() => {
    now.value = Math.floor(Date.now() / 1000)
  }, 1000)
})

onUnmounted(() => {
  clearInterval(timer)
})

const computedExpIn = computed(() => {
  return authenticated.value && keycloakInstance.tokenParsed?.exp
    ? Math.max(keycloakInstance.tokenParsed.exp - now.value, 0)
    : 0
})
</script>

<template>
  <div
    v-if="authenticated"
    class="me-4"
    style="position: relative; block-size: 40px; inline-size: 40px;"
  >
    <VProgressCircular
      :model-value="(computedExpIn / tokenLifetime) * 100"
      :size="40"
      :width="3"
      color="primary"
    />
    <div
      class="text-subtitle-1 font-weight-bold"
      style="position: absolute; inset-block-start: 50%; inset-inline-start: 50%; transform: translate(-50%, -50%);"
    >
      {{ computedExpIn }}
    </div>
  </div>
</template>