109 lines
3.5 KiB
Vue
109 lines
3.5 KiB
Vue
<script setup lang="ts">
|
|
import MainLayout from "@/Layouts/MainLayout.vue";
|
|
import GlassBox from "@/Components/FlightsGoneBy/GlassBox.vue";
|
|
import { Head } from "@inertiajs/vue3";
|
|
import { ref, computed} from "vue";
|
|
import {VFileInput} from "vuetify/components";
|
|
import {getCsrfToken} from "@/utils/helpers";
|
|
|
|
|
|
defineOptions({ layout: MainLayout });
|
|
|
|
const status = ref<"idle" | "uploading" | "success" | "error">("idle");
|
|
const importedCount = ref(0);
|
|
const errors = ref<string[]>([]);
|
|
const fileInput = ref<InstanceType<typeof VFileInput> | null>(null);
|
|
const selectedFile = ref<File | null>(null);
|
|
|
|
const blurb = computed(() => {
|
|
if (status.value === 'success') {
|
|
return `Successfully imported ${importedCount} flight${importedCount.value !== 1 ? 's' : ''}. You will just need to reconcile some mismatched airlines and airports.`;
|
|
}
|
|
return 'Import a CSV export from MyFlightRadar24. You will then be guided to reconcile any data mismatches.';
|
|
});
|
|
|
|
async function onFileChange(e: Event) {
|
|
const input = e.target as HTMLInputElement;
|
|
const file = input.files?.[0];
|
|
const actualFile = Array.isArray(file) ? file[0] : file;
|
|
if (!actualFile) return;
|
|
if (!file) return;
|
|
|
|
status.value = "uploading";
|
|
errors.value = [];
|
|
|
|
const form = new FormData();
|
|
form.append("csv", file);
|
|
|
|
try {
|
|
const response = await fetch(route("flights.import.store"), {
|
|
method: "POST",
|
|
headers: {
|
|
"X-CSRF-TOKEN": getCsrfToken(),
|
|
Accept: "application/json",
|
|
},
|
|
body: form,
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
errors.value = data.errors ?? [data.message ?? "Import failed."];
|
|
status.value = "error";
|
|
} else {
|
|
importedCount.value = data.imported;
|
|
status.value = "success";
|
|
}
|
|
} catch (e) {
|
|
console.error("Fetch error:", e);
|
|
errors.value = [String(e)];
|
|
status.value = "error";
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<Head title="Import" />
|
|
<GlassBox title="Import Your Flights">
|
|
<p v-if="status !== 'success'">
|
|
Import a CSV export from MyFlightRadar24. You will then be guided
|
|
to reconcile any data mismatches.
|
|
</p>
|
|
<p v-else-if="status === 'success'" type="success" >
|
|
Successfully imported {{ importedCount }} flight{{ importedCount !== 1 ? 's' : '' }}. You will just need to reconcile some mismatched airlines and airports.
|
|
</p>
|
|
<v-file-input
|
|
style="flex:0;width:100%"
|
|
prepend-icon=""
|
|
v-if="status !== 'uploading' && status !== 'success'"
|
|
label="Select CSV File"
|
|
accept=".csv"
|
|
@change="onFileChange"
|
|
ref="fileInput"
|
|
v-model="selectedFile"
|
|
/>
|
|
|
|
<div v-else-if="status === 'uploading'" class="d-flex align-center ga-3 mt-2">
|
|
<v-progress-circular indeterminate color="primary" />
|
|
<span>Importing your flights…</span>
|
|
</div>
|
|
|
|
<v-alert closable v-if="status === 'error'" type="error">
|
|
<div v-for="(err, i) in errors" :key="i">{{ err }}</div>
|
|
</v-alert>
|
|
|
|
<v-btn :href="route('reconcile')" v-if="status === 'success'" size="x-large" block >Reconcile Your Data</v-btn>
|
|
</GlassBox>
|
|
</template>
|
|
<style scoped>
|
|
h2{
|
|
font-size: 2rem;
|
|
}
|
|
|
|
p{
|
|
text-align: center;
|
|
width: 80%;
|
|
}
|
|
|
|
</style>
|