feat: toasts
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { ref, onMounted, defineAsyncComponent } from "vue";
|
||||
const TaskList = defineAsyncComponent(() => import("@/components/TaskList.vue"));
|
||||
const PageFooter = defineAsyncComponent(() => import("@/components/PageFooter.vue"));
|
||||
const AlertsContainer = defineAsyncComponent(() => import("@/components/AlertsContainer.vue"));
|
||||
|
||||
const visible = ref<boolean>(false);
|
||||
|
||||
@@ -23,5 +24,6 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
<page-footer />
|
||||
<alerts-container />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import type { Alert } from '@/types';
|
||||
import { computed, ref } from 'vue';
|
||||
import { CircleX, CircleAlert, CircleCheck, Info } from '@lucide/vue';
|
||||
|
||||
const props = defineProps<{ alert: Alert }>();
|
||||
const dismissed = ref<boolean>(false);
|
||||
const visible = computed<boolean>(() => !dismissed.value && (new Date().getTime() - props.alert.created.getTime()) <= props.alert.seconds * 1000);
|
||||
|
||||
function onDismiss() {
|
||||
dismissed.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="visible" class="alert alert-info alert-soft cursor-pointer" :class="`alert-${alert.type}`" @click="onDismiss">
|
||||
<CircleX v-if="alert.type === 'error'" />
|
||||
<CircleAlert v-if="alert.type === 'warning'" />
|
||||
<CircleCheck v-if="alert.type === 'success'" />
|
||||
<Info v-if="alert.type === 'info'" />
|
||||
<span>{{ alert.message }}</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { useAlertStore } from '@/stores/alerts';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
const AlertItem = defineAsyncComponent(() => import("@/components/AlertItem.vue"));
|
||||
|
||||
const { alerts } = useAlertStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="toast select-none">
|
||||
<alert-item v-for="alert in alerts" :key="alert.created.getTime()" :alert="alert" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -2,6 +2,7 @@ import { createApp } from "vue";
|
||||
import { createI18n } from "vue-i18n";
|
||||
import App from "@/App.vue";
|
||||
import { getLang } from "@/lib/lang";
|
||||
import { createPinia } from "pinia";
|
||||
const en = await import("@lang/en.json");
|
||||
const fr = await import("@lang/fr.json");
|
||||
|
||||
@@ -14,4 +15,6 @@ const i18n = createI18n({
|
||||
},
|
||||
});
|
||||
|
||||
createApp(App).use(i18n).mount("#app");
|
||||
const pinia = createPinia();
|
||||
|
||||
createApp(App).use(i18n).use(pinia).mount("#app");
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import type { Alert } from '@/types';
|
||||
|
||||
export const useAlertStore = defineStore('alerts', () => {
|
||||
const alerts = ref<Alert[]>([]);
|
||||
|
||||
function addAlert(message: string, type: 'info' | 'success' | 'warning' | 'error', seconds: number) {
|
||||
alerts.value.push({ message, type, created: new Date(), seconds });
|
||||
}
|
||||
|
||||
function alertSuccess(message: string, seconds = 2) {
|
||||
addAlert(message, 'success', seconds);
|
||||
}
|
||||
|
||||
function alertInfo(message: string, seconds = 3) {
|
||||
addAlert(message, 'info', seconds);
|
||||
}
|
||||
|
||||
function alertWarning(message: string, seconds = 4) {
|
||||
addAlert(message, 'warning', seconds);
|
||||
}
|
||||
|
||||
function alertError(message: string, seconds = 5) {
|
||||
addAlert(message, 'error', seconds);
|
||||
}
|
||||
|
||||
return { alerts, alertSuccess, alertInfo, alertWarning, alertError };
|
||||
})
|
||||
@@ -39,3 +39,10 @@ export interface TaskUpdateData {
|
||||
check_date?: string | null;
|
||||
previous_check_date?: string | null;
|
||||
}
|
||||
|
||||
export interface Alert {
|
||||
message: string
|
||||
type: 'info' | 'success' | 'warning' | 'error'
|
||||
created: Date
|
||||
seconds: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user