Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/packages/kbx-ui/src/components/KbxFreshnessIndicator.vue
T

32 lines
1.3 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue'
import type { KbxDataFreshness } from '@kbx/contracts'
const props = withDefaults(defineProps<{
freshness: KbxDataFreshness
now?: number
}>(), { now: () => Date.now() })
const emit = defineEmits<{ refresh: [] }>()
const ageSeconds = computed(() => Math.max(0, Math.floor((props.now - new Date(props.freshness.observedAt).getTime()) / 1000)))
const stale = computed(() => props.freshness.staleAfterSeconds != null && ageSeconds.value > props.freshness.staleAfterSeconds)
const label = computed(() => {
if (ageSeconds.value < 10) return '방금 갱신'
if (ageSeconds.value < 60) return `${ageSeconds.value}초 전`
const minutes = Math.floor(ageSeconds.value / 60)
return `${minutes}분 전`
})
</script>
<template>
<button class="kbx-freshness" :class="{ stale }" type="button" @click="emit('refresh')" :title="freshness.source ? `출처: ${freshness.source}` : undefined">
<span aria-hidden="true"></span>
<span>{{ stale ? '최신 데이터 확인 필요' : label }}</span>
</button>
</template>
<style scoped>
.kbx-freshness { display:inline-flex; align-items:center; gap:4px; border:0; background:transparent; color:var(--kbx-color-text-muted); font-size:var(--kbx-font-sm); cursor:pointer; }
.kbx-freshness.stale { color:var(--kbx-color-warning); font-weight:600; }
</style>