NavbarTokenExpiredTime.vue 1.54 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.refreshTokenParsed.exp - keycloakInstance.refreshTokenParsed.iat

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

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

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

const formattedExpIn = computed(() => {
  const minutes = Math.floor(computedExpIn.value / 60)
  const seconds = computedExpIn.value % 60

  return `${minutes}:${seconds.toString().padStart(2, '0')}`
})
</script>

<template>
  <div
    v-if="authenticated"
    class="me-4"
    style="position: relative; block-size: 55px; inline-size: 55px;"
  >
    <div
      class="text-subtitle-1 font-weight-bold"
      style="position: absolute; inset-block-start: 50%; inset-inline-start: 50%; transform: translate(-50%, -50%);"
    >
      {{ formattedExpIn }}
    </div>
  </div>
</template>