<template> <div class="flex flex-col gap-2 h-full w-full overflow-y-auto"> <Spinner v-if="loading == 'loading'" class="mx-auto" /> <p v-else-if="loading == 'failed'" @click="fetchProtocolPresence" class="cursor-pointer"> ↺ laden fehlgeschlagen </p> <MemberSearchSelect title="Anwesende suchen" :model-value="presence.map((p) => p.memberId)" :disabled="!can('create', 'club', 'protocol')" @add:difference=" (id: string) => presence.push({ memberId: id, absent: false, excused: true, protocolId: parseInt(protocolId ?? '') }) " @add:member="(s) => members.push(s)" @add:member-by-array="(s) => members.push(...s)" @remove:difference="removeSelected" /> <br /> <p>Anwesenheit</p> <div class="flex flex-col gap-2 grow overflow-y-auto"> <div v-for="member in presence" :key="member.memberId" class="flex flex-row h-fit w-full border border-primary rounded-md bg-primary p-2 text-white justify-between items-center" > <div class="flex flex-col items-start"> <p> {{ getMember(member.memberId)?.lastname }}, {{ getMember(member.memberId)?.firstname }} {{ getMember(member.memberId)?.nameaffix ? `- ${getMember(member.memberId)?.nameaffix}` : "" }} </p> <div class="flex flex-row gap-4"> <label class="flex flex-row gap-2 items-center"> <input type="checkbox" v-model="member.absent" /> war abwesend </label> <label v-if="member.absent" class="flex flex-row gap-2 items-center"> <input type="checkbox" v-model="member.excused" /> ist entschuldigt </label> </div> </div> <TrashIcon v-if="can('create', 'club', 'protocol')" class="w-5 h-5 p-1 box-content cursor-pointer" @click="removeSelected(member.memberId)" /> </div> </div> </div> </template> <script setup lang="ts"> import { defineComponent } from "vue"; import { mapActions, mapState, mapWritableState } from "pinia"; import Spinner from "@/components/Spinner.vue"; import { TrashIcon } from "@heroicons/vue/24/outline"; import { useProtocolPresenceStore } from "@/stores/admin/club/protocol/protocolPresence"; import { useAbilityStore } from "@/stores/ability"; import MemberSearchSelect from "@/components/admin/MemberSearchSelect.vue"; import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models"; </script> <script lang="ts"> export default defineComponent({ props: { protocolId: String, }, data() { return { query: "" as String, members: [] as Array<MemberViewModel>, }; }, computed: { ...mapWritableState(useProtocolPresenceStore, ["presence", "loading"]), ...mapState(useAbilityStore, ["can"]), getMember() { return (memberId: string) => { return this.members.find((m) => memberId == m.id); }; }, }, mounted() {}, methods: { ...mapActions(useProtocolPresenceStore, ["fetchProtocolPresence"]), removeSelected(id: string) { let index = this.presence.findIndex((s) => s.memberId == id); if (index != -1) { this.presence.splice(index, 1); } }, }, }); </script>