2023-01-17 18:25:56 +00:00
|
|
|
<template>
|
2025-12-28 01:10:28 +00:00
|
|
|
<BulmaDrawer header="Türchen bearbeiten" :opening="load_doors">
|
2023-10-27 15:09:44 +00:00
|
|
|
<nav class="level is-mobile mb-0" style="overflow-x: auto">
|
2023-09-14 13:57:20 +00:00
|
|
|
<BulmaButton
|
|
|
|
|
:disabled="current_step === 0"
|
|
|
|
|
class="level-item is-link"
|
|
|
|
|
@click="current_step--"
|
2025-12-28 16:35:10 +00:00
|
|
|
:icon="['fas', 'fa-backward']"
|
2023-09-14 13:57:20 +00:00
|
|
|
/>
|
2023-09-14 13:54:23 +00:00
|
|
|
|
2023-09-14 13:57:20 +00:00
|
|
|
<BulmaBreadcrumbs
|
|
|
|
|
:steps="steps"
|
|
|
|
|
v-model="current_step"
|
|
|
|
|
class="level-item mb-0"
|
|
|
|
|
/>
|
2023-09-14 13:54:23 +00:00
|
|
|
|
2023-09-14 13:57:20 +00:00
|
|
|
<BulmaButton
|
|
|
|
|
:disabled="current_step === 2"
|
|
|
|
|
class="level-item is-link"
|
|
|
|
|
@click="current_step++"
|
2025-12-28 16:35:10 +00:00
|
|
|
:icon="['fas', 'fa-forward']"
|
2023-09-14 13:57:20 +00:00
|
|
|
/>
|
2023-09-14 13:54:23 +00:00
|
|
|
</nav>
|
2023-01-19 00:22:01 +00:00
|
|
|
|
2023-09-21 10:03:53 +00:00
|
|
|
<div class="card-content pb-0">
|
|
|
|
|
<div v-if="doors.length > 0" class="content">
|
|
|
|
|
<p>Für diese Tage ist ein Türchen vorhanden:</p>
|
|
|
|
|
<div class="tags">
|
|
|
|
|
<span
|
|
|
|
|
v-for="(door, index) in doors.toSorted((a, b) => a.day - b.day)"
|
|
|
|
|
:key="`door-${index}`"
|
|
|
|
|
class="tag is-primary"
|
|
|
|
|
>
|
|
|
|
|
{{ door.day }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-12-25 19:56:25 +00:00
|
|
|
<DoorPlacer v-if="current_step === 0" v-model="doors" />
|
|
|
|
|
<DoorChooser v-if="current_step === 1" v-model="doors" />
|
2023-09-10 03:38:24 +00:00
|
|
|
<div v-if="current_step === 2" class="card-content">
|
2025-12-25 19:56:25 +00:00
|
|
|
<Calendar :doors="doors" />
|
2023-09-10 00:54:29 +00:00
|
|
|
</div>
|
2023-09-09 22:18:16 +00:00
|
|
|
|
2023-09-10 03:38:24 +00:00
|
|
|
<footer class="card-footer is-flex is-justify-content-space-around">
|
2023-09-10 00:54:29 +00:00
|
|
|
<BulmaButton
|
2023-09-10 03:38:24 +00:00
|
|
|
class="card-footer-item is-danger"
|
2023-09-10 00:54:29 +00:00
|
|
|
@click="on_download"
|
2025-12-28 16:35:10 +00:00
|
|
|
:icon="['fas', 'fa-cloud-arrow-down']"
|
2023-09-13 14:07:09 +00:00
|
|
|
:busy="loading_doors"
|
2023-09-10 00:54:29 +00:00
|
|
|
text="Laden"
|
|
|
|
|
/>
|
|
|
|
|
<BulmaButton
|
2023-09-10 03:38:24 +00:00
|
|
|
class="card-footer-item is-warning"
|
2023-09-10 00:54:29 +00:00
|
|
|
@click="on_discard"
|
2025-12-28 16:35:10 +00:00
|
|
|
:icon="['fas', 'fa-trash']"
|
2023-09-10 00:54:29 +00:00
|
|
|
text="Löschen"
|
|
|
|
|
/>
|
|
|
|
|
<BulmaButton
|
2023-09-10 03:38:24 +00:00
|
|
|
class="card-footer-item is-success"
|
2023-09-10 00:54:29 +00:00
|
|
|
@click="on_upload"
|
2025-12-28 16:35:10 +00:00
|
|
|
:icon="['fas', 'fa-cloud-arrow-up']"
|
2023-09-13 14:07:09 +00:00
|
|
|
:busy="saving_doors"
|
2023-09-10 00:54:29 +00:00
|
|
|
text="Speichern"
|
|
|
|
|
/>
|
2023-09-10 03:38:24 +00:00
|
|
|
</footer>
|
2023-09-09 22:18:16 +00:00
|
|
|
</BulmaDrawer>
|
2023-01-17 18:25:56 +00:00
|
|
|
</template>
|
|
|
|
|
|
2025-11-30 20:14:21 +00:00
|
|
|
<script setup lang="ts">
|
2024-08-27 00:25:42 +00:00
|
|
|
import { API } from "@/lib/api";
|
|
|
|
|
import { APIError } from "@/lib/api_error";
|
2026-02-12 21:59:41 +00:00
|
|
|
import type { DoorSaved } from "@/lib/model";
|
2024-08-23 16:38:04 +00:00
|
|
|
import { Door } from "@/lib/rects/door";
|
2024-08-27 00:25:42 +00:00
|
|
|
import { toast } from "bulma-toast";
|
2025-12-05 02:12:33 +00:00
|
|
|
import { ref } from "vue";
|
2026-02-12 21:59:41 +00:00
|
|
|
import type { BCStep } from "../bulma/Breadcrumbs.vue";
|
2023-01-17 18:25:56 +00:00
|
|
|
|
2023-09-13 16:08:05 +00:00
|
|
|
import Calendar from "../Calendar.vue";
|
2024-08-26 19:09:43 +00:00
|
|
|
import BulmaBreadcrumbs from "../bulma/Breadcrumbs.vue";
|
2023-09-13 16:08:05 +00:00
|
|
|
import BulmaButton from "../bulma/Button.vue";
|
2023-09-14 12:51:30 +00:00
|
|
|
import BulmaDrawer from "../bulma/Drawer.vue";
|
2023-09-13 16:08:05 +00:00
|
|
|
import DoorChooser from "../editor/DoorChooser.vue";
|
|
|
|
|
import DoorPlacer from "../editor/DoorPlacer.vue";
|
2023-01-24 00:14:50 +00:00
|
|
|
|
2025-12-07 03:28:00 +00:00
|
|
|
const steps: BCStep[] = [
|
2025-12-28 16:24:25 +00:00
|
|
|
{ label: "Platzieren", icon: ["fas", "fa-crosshairs"] },
|
|
|
|
|
{ label: "Ordnen", icon: ["fas", "fa-list-ol"] },
|
|
|
|
|
{ label: "Vorschau", icon: ["fas", "fa-magnifying-glass"] },
|
2025-11-30 20:14:21 +00:00
|
|
|
];
|
|
|
|
|
|
2025-12-07 03:28:00 +00:00
|
|
|
const doors = ref<Door[]>([]);
|
2025-12-05 02:12:33 +00:00
|
|
|
const current_step = ref(0);
|
2025-12-07 03:28:00 +00:00
|
|
|
const loading_doors = ref(false);
|
|
|
|
|
const saving_doors = ref(false);
|
2025-11-30 20:14:21 +00:00
|
|
|
|
2025-12-28 16:35:10 +00:00
|
|
|
async function load_doors(): Promise<void> {
|
2025-12-27 14:01:03 +00:00
|
|
|
try {
|
|
|
|
|
const data = await API.request<DoorSaved[]>("admin/doors");
|
|
|
|
|
|
|
|
|
|
doors.value.length = 0;
|
|
|
|
|
for (const value of data) {
|
|
|
|
|
doors.value.push(Door.load(value));
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
APIError.alert(error);
|
|
|
|
|
throw null;
|
|
|
|
|
}
|
2025-11-30 20:14:21 +00:00
|
|
|
}
|
2023-09-07 16:44:44 +00:00
|
|
|
|
2025-12-28 16:35:10 +00:00
|
|
|
async function save_doors(): Promise<void> {
|
2025-12-27 14:01:03 +00:00
|
|
|
try {
|
2025-11-30 20:14:21 +00:00
|
|
|
const data: DoorSaved[] = [];
|
2023-09-07 20:54:11 +00:00
|
|
|
|
2025-12-07 03:28:00 +00:00
|
|
|
for (const door of doors.value) {
|
2025-11-30 20:14:21 +00:00
|
|
|
data.push(door.save());
|
2023-09-09 22:18:16 +00:00
|
|
|
}
|
2025-11-30 20:14:21 +00:00
|
|
|
|
2025-12-27 14:01:03 +00:00
|
|
|
await API.request<void>({
|
|
|
|
|
endpoint: "admin/doors",
|
|
|
|
|
method: "PUT",
|
|
|
|
|
data: data,
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
APIError.alert(error);
|
|
|
|
|
throw null;
|
|
|
|
|
}
|
2025-11-30 20:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
2025-12-28 16:35:10 +00:00
|
|
|
async function on_download(): Promise<void> {
|
2025-11-30 20:14:21 +00:00
|
|
|
if (confirm("Aktuelle Änderungen verwerfen und Status vom Server laden?")) {
|
2025-12-07 03:28:00 +00:00
|
|
|
loading_doors.value = true;
|
2025-11-30 20:14:21 +00:00
|
|
|
|
2025-12-27 14:01:03 +00:00
|
|
|
try {
|
|
|
|
|
load_doors();
|
|
|
|
|
|
|
|
|
|
toast({
|
|
|
|
|
message: "Erfolgreich!",
|
|
|
|
|
type: "is-success",
|
|
|
|
|
duration: 2e3,
|
|
|
|
|
});
|
|
|
|
|
} finally {
|
|
|
|
|
loading_doors.value = false;
|
|
|
|
|
}
|
2023-09-09 22:18:16 +00:00
|
|
|
}
|
2025-11-30 20:14:21 +00:00
|
|
|
}
|
2023-09-09 22:18:16 +00:00
|
|
|
|
2025-12-28 16:35:10 +00:00
|
|
|
function on_discard(): void {
|
2025-11-30 20:14:21 +00:00
|
|
|
if (confirm("Alle Türchen löschen? (nur lokal)")) {
|
|
|
|
|
// empty `doors` array
|
2025-12-07 03:28:00 +00:00
|
|
|
doors.value.length = 0;
|
2023-09-09 22:18:16 +00:00
|
|
|
}
|
2025-11-30 20:14:21 +00:00
|
|
|
}
|
2023-09-09 22:18:16 +00:00
|
|
|
|
2025-12-28 16:35:10 +00:00
|
|
|
async function on_upload(): Promise<void> {
|
2025-11-30 20:14:21 +00:00
|
|
|
if (confirm("Aktuelle Änderungen an den Server schicken?")) {
|
2025-12-07 03:28:00 +00:00
|
|
|
saving_doors.value = true;
|
2025-11-30 20:14:21 +00:00
|
|
|
|
2025-12-27 14:01:03 +00:00
|
|
|
try {
|
|
|
|
|
save_doors();
|
|
|
|
|
load_doors();
|
|
|
|
|
|
|
|
|
|
toast({
|
|
|
|
|
message: "Erfolgreich!",
|
|
|
|
|
type: "is-success",
|
|
|
|
|
duration: 2e3,
|
|
|
|
|
});
|
|
|
|
|
} finally {
|
|
|
|
|
saving_doors.value = false;
|
|
|
|
|
}
|
2023-09-09 22:18:16 +00:00
|
|
|
}
|
2023-09-07 20:54:11 +00:00
|
|
|
}
|
2023-09-09 22:18:16 +00:00
|
|
|
</script>
|