gradido/frontend/src/components/SessionLogoutTimeout.vue
MateuszMichalowski a58ba48604
feat(frontend): fix postmigration fix (#3378)
* feat(frontend): migration fixes

* feat(admin): post migration fixes

* feat(admin): revert docker change

* feat(admin): update tests
2024-10-31 18:05:48 +01:00

124 lines
3.2 KiB
Vue

<template>
<div class="session-logout-timeout">
<BModal
id="modalSessionTimeOut"
class="bg-variant-danger"
hide-header-close
hide-header
hide-footer
no-close-on-backdrop
:model-value="sessionModalModel"
@update:modelValue="sessionModalModel = $event"
>
<BCard header-tag="header" footer-tag="footer">
<BCardText>
<div class="p-3 h2">{{ $t('session.warningText') }}</div>
<div class="p-3">
{{ $t('session.lightText') }}
</div>
<div class="p-3 h2 text-warning">
{{ $t('session.logoutIn') }}
<b>{{ formatTime(remainingTime) }}</b>
{{ $t('time.seconds') }}
</div>
</BCardText>
<BRow>
<BCol class="text-center">
<BButton size="lg" variant="success" @click="handleOk">
{{ $t('session.extend') }}
</BButton>
</BCol>
</BRow>
</BCard>
<template #modal-footer>
<BButton size="sm" variant="danger" @click="emit('logout')">
{{ $t('navigation.logout') }}
</BButton>
<BButton size="lg" variant="success" @click="handleOk">
{{ $t('session.extend') }}
</BButton>
</template>
</BModal>
</div>
</template>
<script setup>
import { ref, computed, onBeforeUnmount, watch, onMounted, onUnmounted } from 'vue'
import { useStore } from 'vuex'
import { useLazyQuery } from '@vue/apollo-composable'
import { verifyLogin } from '@/graphql/queries'
import { useModal } from 'bootstrap-vue-next'
const store = useStore()
const emit = defineEmits(['logout'])
const sessionModalModel = ref(false)
const { hide: hideModal } = useModal('modalSessionTimeOut')
const { load: verifyLoginQuery, loading, error } = useLazyQuery(verifyLogin)
const remainingTime = ref(0)
let intervalId = null
const tokenExpirationTime = computed(() => new Date(store.state.tokenTime * 1000))
const isTokenValid = computed(() => {
return remainingTime.value > 0
})
const calculateRemainingTime = () => {
const now = new Date()
const diff = tokenExpirationTime.value - now
remainingTime.value = Math.max(0, Math.floor(diff / 1000))
// Show modal if remaining time is 75 seconds or less
if (remainingTime.value <= 75) {
sessionModalModel.value = true
}
// Clear interval if time expired
if (remainingTime.value <= 0) {
clearInterval(intervalId)
}
}
const formatTime = (seconds) => {
if (seconds <= 0) return '00'
const remainingSeconds = seconds % 60
return `${remainingSeconds.toString().padStart(2, '0')}`
}
onMounted(() => {
calculateRemainingTime()
if (isTokenValid.value) {
intervalId = setInterval(calculateRemainingTime, 1000)
}
})
onUnmounted(() => {
if (intervalId) {
clearInterval(intervalId)
}
})
watch(remainingTime, (newTime) => {
if (newTime <= 0) {
emit('logout')
}
})
const handleOk = async (bvModalEvent) => {
bvModalEvent.preventDefault()
try {
await verifyLoginQuery()
if (error.value) {
emit('logout')
throw new Error('Login verification failed')
}
hideModal('modalSessionTimeOut')
} catch {
emit('logout')
}
}
</script>