Files
CVAtron/resources/js/components/SaveStatusIcon.vue
Matthias Guillitte b89fd67d57
Some checks failed
linter / quality (push) Successful in 4m14s
tests / ci (push) Failing after 12m30s
Bug fixes + Save status
2025-09-27 14:09:05 +02:00

59 lines
1.6 KiB
Vue

<script setup lang="ts">
import { useResumesStore } from '@/stores/resume';
import { computed, ref, watch } from 'vue';
import { CloudCheck, LoaderCircle, CircleAlert } from 'lucide-vue-next';
const resumeStore = useResumesStore();
const DISAPPEAR_DELAY = 5000;
const isSaving = computed(() => resumeStore.isSaving);
const error = ref<string | null>(null);
watch(() => resumeStore.savingError, (newError) => {
error.value = newError;
if (newError) {
showSaved.value = false;
}
});
const showSaved = ref(false);
let showSavedTimeout: ReturnType<typeof setTimeout>;
watch(isSaving, (newIsSaving: boolean) => {
if (!newIsSaving && !error.value) {
if (showSavedTimeout) {
clearTimeout(showSavedTimeout);
}
showSaved.value = true;
showSavedTimeout = setTimeout(() => {
showSaved.value = false;
}, DISAPPEAR_DELAY);
} else {
showSaved.value = false;
}
});
</script>
<template>
<div class="flex justify-between gap-2 items-center p-3 h-4">
<p class="text-red-400">{{ error }}</p>
<Transition mode="out-in" appear>
<CircleAlert class="w-4 h-4 text-red-500" v-if="error"/>
<LoaderCircle class="w-4 h-4 animate-spin" v-else-if="isSaving"/>
<CloudCheck class="w-4 h-4" v-else-if="showSaved" title="Sauvegardé"/>
</Transition>
</div>
</template>
<style lang="css" scoped>
.v-enter-active,
.v-leave-active {
transition: opacity 0.3s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
</style>