miniplan/public/src/views/PlanView.vue
2023-09-18 11:51:41 +02:00

198 lines
4.9 KiB
Vue

<script setup lang="ts">
import {onMounted, reactive, ref, toRaw, computed} from "vue";
import TablePlan from "@/components/TablePlan.vue";
import {API} from "@/services/api";
import type {Gottesdienst, Mark, PlanModel, SimplifiedMinistrant} from "@/models/models";
import MobilePlan from "@/components/MobilePlan.vue";
import PlanActionBar from "@/components/PlanActionBar.vue";
import {Auth} from "@/services/auth";
const MAX_WIDTH_MOBILE = 600;
const plan = reactive<{
gottesdienste: Gottesdienst[],
ministranten: SimplifiedMinistrant[],
marks: Mark[],
editable: string[]
}>({
gottesdienste: [],
ministranten: [],
marks: [],
editable: []
})
const mobile = ref(window.innerWidth <= MAX_WIDTH_MOBILE)
const editedMarks = reactive<Mark[]>([]);
const editPlanAdmin = ref(false)
const sortedGottesdienste = computed(() => {
return plan.gottesdienste.sort((a, b) => {
console.log(a, b)
return a.date - b.date
})
})
async function addGodi(data, validate) {
console.log("Test")
console.log(data)
let date = Date.parse(data.date + "T" + data.time);
let attendance = data.attendance && data.attendance != ""
? Date.parse(data.date + "T" + data.attendance)
: (date - 1000 * 60 * 30)
console.log(date, attendance, data.date + "T" + data.attendance)
let newGodi = await API.addGottesdienst(
data.name,
new Date(date),
new Date(attendance),
0
)
console.log(newGodi)
plan.gottesdienste.push(newGodi);
validate()
}
async function deleteGottedienst(id) {
let deleted = await API.deleteGottesdienst(id)
if (deleted) {
let index = plan.gottesdienste.findIndex(godi => godi.id == id)
plan.gottesdienste.splice(index, 1)
}
}
onMounted(async () => {
let fetchedPlan = await API.getPlan(0)
plan.gottesdienste = fetchedPlan.gottesdienste
plan.ministranten = fetchedPlan.ministranten
plan.marks = fetchedPlan.marks
Auth.checkForToken()
})
Auth.loggedInSubject.subscribe(loggedIn => {
if (loggedIn) {
plan.editable = Auth.getPrivileges()
if(Auth.getUser() == "admin"){
editPlanAdmin.value = true
}
}else {
editPlanAdmin.value = false
plan.editable = []
}
})
window.addEventListener("resize", (ev) => {
mobile.value = window.innerWidth <= MAX_WIDTH_MOBILE
})
function getMarks(): Mark[] {
return plan.marks.filter((mark: Mark) => {
let difMark = editedMarks.find((m: Mark) => m.gid == mark.gid && m.mid == mark.mid)
return !difMark
}).concat(editedMarks);
}
function getDif(): Mark[] {
return editedMarks.filter((mark: Mark) => {
let sameMark = plan.marks.find((m: Mark) => m.gid == mark.gid && m.mid == mark.mid)
return (!sameMark && mark.value != 0) || (sameMark && mark.value != sameMark.value)
})
}
async function saveChanges() {
const saved = await API.setMarks(getDif())
if(saved) {
plan.marks = getMarks()
editedMarks.length = 0
}
}
async function resetPassword(username: string) {
const result = await API.resetPassword(username)
alert("Neues Passwort für " + username + "\n\n" + result.password)
console.log(result)
}
function canEdit(username: string) {
return plan.editable.includes(username)
}
function toggleMark(gid, mid) {
// TODO: track changes
const username = plan.ministranten.find(m => m.id == mid)?.username
if (!canEdit(username)) return;
let mark = editedMarks.find(m => m.mid == mid && m.gid == gid);
if (mark) {
mark.value = ((mark.value + 2) % 3) - 1
} else {
mark = {
gid, mid, value: 1
}
editedMarks.push(mark)
}
}
</script>
<template>
<main>
<TablePlan
:gottesdienste="sortedGottesdienste"
:ministranten="plan.ministranten"
:marks="getMarks()"
:editable="plan.editable"
:edit="editPlanAdmin"
:small-mode="editPlanAdmin"
@added="addGodi"
@delete="deleteGottedienst"
@toggle-mark="toggleMark"
@end-edit="editPlanAdmin = false"
@reset-password="resetPassword"
class="plan table"
v-if="!mobile">
</TablePlan>
<MobilePlan
:gottesdienste="sortedGottesdienste"
:ministranten="plan.ministranten"
:marks="getMarks()"
:editable="plan.editable"
@toggle-mark="toggleMark"
class="plan mobile"
v-else>
</MobilePlan>
<PlanActionBar
class="action-bar"
:save="getDif().length > 0"
:plan="false"
:godi="true"
@save="saveChanges()"
/>
</main>
</template>
<style scoped lang="less">
.plan {
padding-bottom: 100px;
}
.plan.table {
width: 100%;
}
.action-bar {
position: fixed;
bottom: 0;
z-index: 100;
}
</style>