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

98 lines
3.3 KiB
Vue
Raw Normal View History

2024-10-04 12:47:04 +02:00
<template>
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
2024-10-13 15:47:52 +02:00
<Spinner v-if="loading == 'loading'" class="mx-auto" />
<p v-else-if="loading == 'failed'" @click="fetchProtocolPresence" class="cursor-pointer">
&#8634; laden fehlgeschlagen
</p>
2024-10-15 16:24:29 +02:00
2025-01-20 09:43:48 +01:00
<MemberSearchSelect
title="Anwesende suchen"
:model-value="presence.map((p) => p.memberId)"
:disabled="!can('create', 'club', 'protocol')"
@add:difference="
2025-01-29 08:53:42 +01:00
(id: string) =>
2025-01-20 09:43:48 +01:00
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"
/>
2024-10-06 11:38:07 +02:00
<br />
<p>Anwesenheit</p>
2024-10-06 11:38:07 +02:00
<div class="flex flex-col gap-2 grow overflow-y-auto">
<div
v-for="member in presence"
:key="member.memberId"
2024-10-06 11:38:07 +02:00
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">
2025-01-19 13:42:42 +01:00
<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>
2024-11-24 15:31:08 +01:00
<TrashIcon
v-if="can('create', 'club', 'protocol')"
class="w-5 h-5 p-1 box-content cursor-pointer"
@click="removeSelected(member.memberId)"
2024-11-24 15:31:08 +01:00
/>
2024-10-06 11:38:07 +02:00
</div>
</div>
2024-10-04 12:47:04 +02:00
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
2024-10-15 16:24:29 +02:00
import { mapActions, mapState, mapWritableState } from "pinia";
2024-10-04 12:47:04 +02:00
import Spinner from "@/components/Spinner.vue";
2024-10-06 11:38:07 +02:00
import { TrashIcon } from "@heroicons/vue/24/outline";
2025-01-02 18:28:13 +01:00
import { useProtocolPresenceStore } from "@/stores/admin/club/protocol/protocolPresence";
2024-11-24 15:31:08 +01:00
import { useAbilityStore } from "@/stores/ability";
2025-01-20 09:43:48 +01:00
import MemberSearchSelect from "@/components/admin/MemberSearchSelect.vue";
import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
2024-10-04 12:47:04 +02:00
</script>
<script lang="ts">
export default defineComponent({
props: {
protocolId: String,
},
2024-10-06 11:38:07 +02:00
data() {
return {
query: "" as String,
2025-01-20 09:43:48 +01:00
members: [] as Array<MemberViewModel>,
2024-10-06 11:38:07 +02:00
};
},
2024-10-04 12:47:04 +02:00
computed: {
2024-10-15 16:24:29 +02:00
...mapWritableState(useProtocolPresenceStore, ["presence", "loading"]),
2024-11-24 15:31:08 +01:00
...mapState(useAbilityStore, ["can"]),
2025-01-19 13:42:42 +01:00
getMember() {
2025-01-29 08:53:42 +01:00
return (memberId: string) => {
2025-01-19 13:42:42 +01:00
return this.members.find((m) => memberId == m.id);
};
2024-10-15 16:24:29 +02:00
},
2024-10-06 11:38:07 +02:00
},
2025-01-20 09:43:48 +01:00
mounted() {},
2024-10-06 11:38:07 +02:00
methods: {
2024-10-13 15:47:52 +02:00
...mapActions(useProtocolPresenceStore, ["fetchProtocolPresence"]),
2025-01-29 08:53:42 +01:00
removeSelected(id: string) {
let index = this.presence.findIndex((s) => s.memberId == id);
2024-10-06 11:38:07 +02:00
if (index != -1) {
2024-10-15 16:24:29 +02:00
this.presence.splice(index, 1);
2024-10-06 11:38:07 +02:00
}
},
2024-10-04 12:47:04 +02:00
},
});
</script>