✨ 🚧 Add admin api and ui for timetable management
This commit is contained in:
148
src/views/settings/AdminSettings.vue
Normal file
148
src/views/settings/AdminSettings.vue
Normal file
@ -0,0 +1,148 @@
|
||||
<script setup>
|
||||
import ExpandSection from "@/components/settings/expand-section.vue";
|
||||
import TimetableCard from "@/components/settings/timetable-card.vue";
|
||||
import { baseUrl } from "@/store";
|
||||
import { PlusIcon, SaveIcon, XIcon } from "lucide-vue-next";
|
||||
import { ref } from "vue";
|
||||
|
||||
const timetables = ref([]);
|
||||
async function fetchTimetables() {
|
||||
const response = await fetch(baseUrl + "/admin/timetable");
|
||||
if (response.status != 200) return;
|
||||
timetables.value = await response.json();
|
||||
}
|
||||
|
||||
async function deleteTimetable(id) {
|
||||
const response = await fetch(
|
||||
baseUrl + "/admin/timetable?id=" + encodeURIComponent(id),
|
||||
{ method: "delete" }
|
||||
);
|
||||
if (response.status != 200) alert("Delete failed!");
|
||||
fetchTimetables();
|
||||
}
|
||||
|
||||
const editId = ref(-1);
|
||||
const timetableName = ref();
|
||||
const timetableClass = ref();
|
||||
const timetableSource = ref();
|
||||
const timetableTrusted = ref(true);
|
||||
|
||||
async function createTimetable() {
|
||||
const response = await fetch(baseUrl + "/admin/timetable", {
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
title: timetableName.value,
|
||||
class: timetableClass.value,
|
||||
source: timetableSource.value,
|
||||
trusted: timetableTrusted.value,
|
||||
data: [],
|
||||
}),
|
||||
});
|
||||
if (response.status != 201) alert("Post failed!");
|
||||
fetchTimetables();
|
||||
}
|
||||
|
||||
async function updateTimetable() {
|
||||
const response = await fetch(
|
||||
baseUrl + "/admin/timetable?id=" + encodeURIComponent(editId.value),
|
||||
{
|
||||
method: "put",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
title: timetableName.value,
|
||||
class: timetableClass.value,
|
||||
source: timetableSource.value,
|
||||
trusted: timetableTrusted.value,
|
||||
}),
|
||||
}
|
||||
);
|
||||
if (response.status != 201) alert("Post failed!");
|
||||
fetchTimetables();
|
||||
}
|
||||
|
||||
fetchTimetables();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>Admin Settings</h1>
|
||||
<ExpandSection title="Timetables">
|
||||
<div class="list">
|
||||
<div class="create_options">
|
||||
<input type="text" placeholder="Name" v-model="timetableName" />
|
||||
<input type="text" placeholder="Class" v-model="timetableClass" />
|
||||
<input type="text" placeholder="Source" v-model="timetableSource" />
|
||||
<div>
|
||||
<input type="checkbox" v-model="timetableTrusted" />
|
||||
<span>Trusted</span>
|
||||
</div>
|
||||
<div class="button" v-if="editId == -1" @click="createTimetable()">
|
||||
<PlusIcon />
|
||||
<span>Create Timetable</span>
|
||||
</div>
|
||||
<div class="button" v-if="editId != -1" @click="updateTimetable()">
|
||||
<SaveIcon />
|
||||
<span>Save Timetable</span>
|
||||
</div>
|
||||
<div class="button" v-if="editId != -1" @click="editId = -1">
|
||||
<XIcon />
|
||||
<span>Cancel edit</span>
|
||||
</div>
|
||||
</div>
|
||||
<TimetableCard
|
||||
v-for="timetable in timetables"
|
||||
:key="timetable"
|
||||
:timetable="timetable"
|
||||
:editable="true"
|
||||
:selected="timetable.id == editId"
|
||||
:admin="true"
|
||||
@delete="deleteTimetable(timetable.id)"
|
||||
@edit="
|
||||
() => {
|
||||
editId = timetable.id;
|
||||
timetableName = timetable.title;
|
||||
timetableClass = timetable.class;
|
||||
timetableSource = timetable.source;
|
||||
timetableTrusted = timetable.trusted;
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</ExpandSection>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
h1 {
|
||||
margin: 0px 0px 10px;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
background-color: var(--element-color);
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.create_options {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user