ff-admin/src/views/admin/club/protocol/ProtocolPresence.vue

97 lines
3.3 KiB
Vue

<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">
&#8634; 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>