138 lines
3.3 KiB
Vue
138 lines
3.3 KiB
Vue
<script setup>
|
|
import TimetableCard from "@/components/settings/timetable-card.vue";
|
|
import { timetables, localTimetables, timetableId } from "@/store";
|
|
import { PlusIcon, PaperclipIcon } from "lucide-vue-next";
|
|
import { toRaw, ref } from "vue";
|
|
import download from "downloadjs";
|
|
|
|
function copyTimetable(timetable) {
|
|
const newTimetable = structuredClone(toRaw(timetable));
|
|
newTimetable.title = "Copy of " + timetable.title;
|
|
newTimetable.id = new Date().getTime();
|
|
localTimetables.value.push(newTimetable);
|
|
}
|
|
|
|
function createTimetable() {
|
|
localTimetables.value.push({
|
|
id: new Date().getTime(),
|
|
title: "New timetable",
|
|
data: [],
|
|
});
|
|
}
|
|
|
|
const fileInput = ref();
|
|
function importTimetable(event) {
|
|
const file = event.target.files[0];
|
|
if (!file) return;
|
|
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
const contents = e.target.result;
|
|
try {
|
|
const data = JSON.parse(contents);
|
|
if (!data.data) throw "Invalid data";
|
|
localTimetables.value.push(data);
|
|
} catch (e) {
|
|
console.log(e.stack);
|
|
alert("Import failed! Check your timetable file!");
|
|
}
|
|
};
|
|
reader.readAsText(file);
|
|
}
|
|
|
|
function exportTimetable(timetable) {
|
|
download(
|
|
JSON.stringify(timetable),
|
|
`timetable-${timetable.id}.json`,
|
|
"application/json"
|
|
);
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="content" v-if="$route.name == 'title.settings.timetable'">
|
|
<h2>{{ $t("settings.heading.localTimetables") }}</h2>
|
|
<div class="list">
|
|
<TimetableCard
|
|
v-for="timetable in localTimetables"
|
|
:key="timetable.id"
|
|
:timetable="timetable"
|
|
:selected="timetableId == timetable.id"
|
|
:editable="true"
|
|
@click="timetableId = timetable.id"
|
|
@edit="$router.push('timetable/edit/' + timetable.id)"
|
|
@copy="copyTimetable(timetable)"
|
|
@delete="
|
|
localTimetables.splice(
|
|
localTimetables.findIndex((e) => e.id == timetable.id),
|
|
1
|
|
)
|
|
"
|
|
@export="exportTimetable(timetable)"
|
|
/>
|
|
</div>
|
|
<div class="buttons">
|
|
<div class="create" @click="createTimetable">
|
|
<PlusIcon /> {{ $t("settings.text.createTimetable") }}
|
|
</div>
|
|
<div class="import" @click="fileInput.click()">
|
|
<PaperclipIcon /> {{ $t("settings.text.importTimetable") }}
|
|
<input
|
|
type="file"
|
|
ref="fileInput"
|
|
style="display: none"
|
|
@change="importTimetable"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<h2>{{ $t("settings.heading.remoteTimetables") }}</h2>
|
|
<div class="list">
|
|
<TimetableCard
|
|
v-for="timetable in timetables"
|
|
:key="timetable.id"
|
|
:timetable="timetable"
|
|
:selected="timetableId == timetable.id"
|
|
:editable="false"
|
|
@click="timetableId = timetable.id"
|
|
@copy="copyTimetable(timetable)"
|
|
@export="exportTimetable(timetable)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<RouterView v-else />
|
|
</template>
|
|
|
|
<style scoped>
|
|
h2 {
|
|
margin: 5px 0px;
|
|
}
|
|
|
|
p {
|
|
margin: 5px 0px;
|
|
}
|
|
|
|
.list {
|
|
display: grid;
|
|
gap: 8px;
|
|
}
|
|
|
|
.buttons {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin-top: 5px;
|
|
user-select: none;
|
|
}
|
|
|
|
.create,
|
|
.import {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 10px;
|
|
gap: 5px;
|
|
cursor: pointer;
|
|
}
|
|
</style>
|