chore: install prettier
This commit is contained in:
@@ -1,135 +1,141 @@
|
||||
<!-- CountdownTimer.vue -->
|
||||
<template>
|
||||
<div class="countdown-wrapper">
|
||||
<span v-if="isExpired" class="tag is-danger">
|
||||
{{ isVietnamese ? 'Hết giờ' : 'Expired' }}
|
||||
<span
|
||||
v-if="isExpired"
|
||||
class="tag is-danger"
|
||||
>
|
||||
{{ isVietnamese ? "Hết giờ" : "Expired" }}
|
||||
</span>
|
||||
<span v-else class="tag" :class="tagClass">
|
||||
<span
|
||||
v-else
|
||||
class="tag"
|
||||
:class="tagClass"
|
||||
>
|
||||
<span class="countdown-text">{{ formattedTime }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { useStore } from '@/stores/index'
|
||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
|
||||
import { useStore } from "@/stores/index";
|
||||
|
||||
const props = defineProps({
|
||||
dateValue: {
|
||||
type: [String, Date],
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
default: 'HH:mm:ss'
|
||||
}
|
||||
})
|
||||
default: "HH:mm:ss",
|
||||
},
|
||||
});
|
||||
|
||||
const store = useStore()
|
||||
const { $dayjs } = useNuxtApp()
|
||||
const store = useStore();
|
||||
const { $dayjs } = useNuxtApp();
|
||||
|
||||
const timeRemaining = ref({
|
||||
days: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0
|
||||
})
|
||||
seconds: 0,
|
||||
});
|
||||
|
||||
const isExpired = ref(false)
|
||||
let intervalId = null
|
||||
const isExpired = ref(false);
|
||||
let intervalId = null;
|
||||
|
||||
const isVietnamese = computed(() => store.lang === 'vi')
|
||||
const isVietnamese = computed(() => store.lang === "vi");
|
||||
|
||||
const tagClass = computed(() => {
|
||||
const totalSeconds = timeRemaining.value.days * 86400 +
|
||||
timeRemaining.value.hours * 3600 +
|
||||
timeRemaining.value.minutes * 60 +
|
||||
timeRemaining.value.seconds
|
||||
const totalSeconds =
|
||||
timeRemaining.value.days * 86400 +
|
||||
timeRemaining.value.hours * 3600 +
|
||||
timeRemaining.value.minutes * 60 +
|
||||
timeRemaining.value.seconds;
|
||||
|
||||
if (totalSeconds <= 0) return 'is-danger'
|
||||
if (totalSeconds <= 3600) return 'is-warning' // <= 1 hour
|
||||
if (totalSeconds <= 86400) return 'is-info' // <= 1 day
|
||||
return 'is-primary' // > 1 day
|
||||
})
|
||||
if (totalSeconds <= 0) return "is-danger";
|
||||
if (totalSeconds <= 3600) return "is-warning"; // <= 1 hour
|
||||
if (totalSeconds <= 86400) return "is-info"; // <= 1 day
|
||||
return "is-primary"; // > 1 day
|
||||
});
|
||||
|
||||
const formattedTime = computed(() => {
|
||||
const { days, hours, minutes, seconds } = timeRemaining.value
|
||||
const { days, hours, minutes, seconds } = timeRemaining.value;
|
||||
|
||||
if (days > 0) {
|
||||
return isVietnamese
|
||||
? `${days}d ${hours}h ${minutes}m`
|
||||
: `${days}d ${hours}h ${minutes}m`
|
||||
}
|
||||
|
||||
if (hours > 0) {
|
||||
return isVietnamese
|
||||
? `${hours}h ${minutes}m ${seconds}s`
|
||||
: `${hours}h ${minutes}m ${seconds}s`
|
||||
return isVietnamese ? `${days}d ${hours}h ${minutes}m` : `${days}d ${hours}h ${minutes}m`;
|
||||
}
|
||||
|
||||
return isVietnamese
|
||||
? `${minutes}m ${seconds}s`
|
||||
: `${minutes}m ${seconds}s`
|
||||
})
|
||||
if (hours > 0) {
|
||||
return isVietnamese ? `${hours}h ${minutes}m ${seconds}s` : `${hours}h ${minutes}m ${seconds}s`;
|
||||
}
|
||||
|
||||
return isVietnamese ? `${minutes}m ${seconds}s` : `${minutes}m ${seconds}s`;
|
||||
});
|
||||
|
||||
const calculateTimeRemaining = () => {
|
||||
try {
|
||||
const targetDate = $dayjs(props.dateValue)
|
||||
const now = $dayjs()
|
||||
const targetDate = $dayjs(props.dateValue);
|
||||
const now = $dayjs();
|
||||
|
||||
if (now.isAfter(targetDate)) {
|
||||
isExpired.value = true
|
||||
timeRemaining.value = { days: 0, hours: 0, minutes: 0, seconds: 0 }
|
||||
return
|
||||
isExpired.value = true;
|
||||
timeRemaining.value = { days: 0, hours: 0, minutes: 0, seconds: 0 };
|
||||
return;
|
||||
}
|
||||
|
||||
isExpired.value = false
|
||||
const diff = targetDate.diff(now, 'second')
|
||||
isExpired.value = false;
|
||||
const diff = targetDate.diff(now, "second");
|
||||
|
||||
const days = Math.floor(diff / 86400)
|
||||
const hours = Math.floor((diff % 86400) / 3600)
|
||||
const minutes = Math.floor((diff % 3600) / 60)
|
||||
const seconds = diff % 60
|
||||
const days = Math.floor(diff / 86400);
|
||||
const hours = Math.floor((diff % 86400) / 3600);
|
||||
const minutes = Math.floor((diff % 3600) / 60);
|
||||
const seconds = diff % 60;
|
||||
|
||||
timeRemaining.value = { days, hours, minutes, seconds }
|
||||
timeRemaining.value = { days, hours, minutes, seconds };
|
||||
} catch (error) {
|
||||
console.error('Error calculating countdown:', error)
|
||||
isExpired.value = true
|
||||
console.error("Error calculating countdown:", error);
|
||||
isExpired.value = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const startCountdown = () => {
|
||||
calculateTimeRemaining()
|
||||
calculateTimeRemaining();
|
||||
|
||||
if (intervalId) clearInterval(intervalId)
|
||||
if (intervalId) clearInterval(intervalId);
|
||||
|
||||
intervalId = setInterval(() => {
|
||||
calculateTimeRemaining()
|
||||
calculateTimeRemaining();
|
||||
|
||||
if (isExpired.value && intervalId) {
|
||||
clearInterval(intervalId)
|
||||
intervalId = null
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
watch(() => props.dateValue, () => {
|
||||
startCountdown()
|
||||
}, { deep: true })
|
||||
watch(
|
||||
() => props.dateValue,
|
||||
() => {
|
||||
startCountdown();
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
startCountdown()
|
||||
})
|
||||
startCountdown();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId)
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.countdown-wrapper {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user