<template> <div class="w-full md:max-w-md"> <div class="flex flex-col items-center"> <p class="text-xl font-medium">Backup hochladen</p> </div> <br /> <div class="hidden md:flex flex-col gap-2 py-7 bg-gray-200 justify-center items-center w-full grow rounded-lg" @drop.prevent="fileDrop" @dragover.prevent > <p class="text-lg text-dark-gray">Datei hierher ziehen</p> </div> <p class="hidden md:block text-center">oder</p> <div class="flex flex-row gap-2 items-center"> <input class="hidden!" type="file" ref="fileSelect" accept="application/JSON" @change=" (e) => { uploadFile((e.target as HTMLInputElement)?.files?.[0]); (e.target as HTMLInputElement).value = ''; } " multiple /> <button primary @click="openFileSelect">Datei auswählen</button> </div> <div class="flex flex-row gap-2 pt-4 items-center justify-center"> <Spinner v-if="status == 'loading'" class="my-auto" /> <SuccessCheckmark v-else-if="status?.status == 'success'" /> <FailureXMark v-else-if="status?.status == 'failed'" /> </div> <div class="flex flex-row justify-end"> <div class="flex flex-row gap-4 py-2"> <button primary-outline @click="closeModal" :disabled="status == 'loading' || status?.status == 'success'"> abbrechen </button> </div> </div> </div> </template> <script setup lang="ts"> import { defineComponent } from "vue"; import { mapState, mapActions } from "pinia"; import { useModalStore } from "@/stores/modal"; import Spinner from "@/components/Spinner.vue"; import SuccessCheckmark from "@/components/SuccessCheckmark.vue"; import FailureXMark from "@/components/FailureXMark.vue"; import { useBackupStore } from "@/stores/admin/management/backup"; </script> <script lang="ts"> export default defineComponent({ data() { return { status: null as null | "loading" | { status: "success" | "failed"; reason?: string }, timeout: undefined as any, }; }, beforeUnmount() { try { clearTimeout(this.timeout); } catch (error) {} }, methods: { ...mapActions(useModalStore, ["closeModal"]), ...mapActions(useBackupStore, ["uploadBackup"]), openFileSelect(event: Event) { (this.$refs.fileSelect as HTMLInputElement).click(); }, fileDrop(event: DragEvent) { const file = event.dataTransfer?.files[0]; if (file?.type.toLocaleLowerCase() != "application/json") return; this.uploadFile(file); }, uploadFile(file?: File) { if (!file) return; this.status = "loading"; this.uploadBackup(file) .then(() => { this.status = { status: "success" }; this.timeout = setTimeout(() => { this.closeModal(); }, 1500); }) .catch(() => { this.status = { status: "failed" }; }); }, }, }); </script>