ff-admin/src/views/admin/club/calendar/Calendar.vue

153 lines
4.7 KiB
Vue

<template>
<MainTemplate>
<template #topBar>
<div class="flex flex-row items-center justify-between pt-5 pb-3 px-7">
<h1 class="font-bold text-xl h-8">Kalender</h1>
<div class="flex flex-row gap-2">
<PlusIcon class="text-gray-500 h-5 w-5 cursor-pointer" @click="select" />
<LinkIcon class="text-gray-500 h-5 w-5 cursor-pointer" @click="openLinkModal" />
</div>
</div>
</template>
<template #diffMain>
<div class="flex flex-col w-full h-full gap-2 justify-between px-7 overflow-hidden">
<FullCalendar :options="calendarOptions" class="max-h-full h-full" />
</div>
</template>
</MainTemplate>
</template>
<script setup lang="ts">
import { defineComponent, markRaw, defineAsyncComponent } from "vue";
import { mapActions, mapState } from "pinia";
import { useModalStore } from "@/stores/modal";
import MainTemplate from "@/templates/Main.vue";
import FullCalendar from "@fullcalendar/vue3";
import deLocale from "@fullcalendar/core/locales/de";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import { useCalendarStore } from "@/stores/admin/club/calendar";
import { useAbilityStore } from "@/stores/ability";
import { LinkIcon, PlusIcon } from "@heroicons/vue/24/outline";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {};
},
computed: {
...mapState(useCalendarStore, ["formattedItems"]),
...mapState(useAbilityStore, ["can"]),
calendarOptions() {
return {
timeZone: "local",
locale: deLocale,
plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
initialView: "dayGridMonth",
headerToolbar: {
left: "dayGridMonth,timeGridWeek",
center: "title",
right: "prev,today,next",
},
eventDisplay: "block",
weekends: true,
editable: true,
selectable: true,
selectMirror: false,
dayMaxEvents: true,
weekNumbers: true,
displayEventTime: true,
nowIndicator: true,
weekText: "KW",
allDaySlot: false,
events: this.formattedItems,
select: this.select,
eventClick: this.eventClick,
};
},
},
mounted() {
this.fetchCalendars();
},
methods: {
...mapActions(useModalStore, ["openModal"]),
...mapActions(useCalendarStore, ["fetchCalendars"]),
select(e: any) {
if (!this.can("create", "club", "calendar")) return;
this.openModal(
markRaw(defineAsyncComponent(() => import("@/components/admin/club/calendar/CreateCalendarModal.vue"))),
{
start: e?.startStr ?? new Date().toISOString(),
end: e?.endStr ?? new Date().toISOString(),
allDay: e?.allDay ?? false,
}
);
},
eventClick(e: any) {
if (!this.can("update", "club", "calendar")) return;
this.openModal(
markRaw(defineAsyncComponent(() => import("@/components/admin/club/calendar/UpdateCalendarModal.vue"))),
e.event.id
);
},
openLinkModal(e: any) {
this.openModal(
markRaw(defineAsyncComponent(() => import("@/components/admin/club/calendar/CalendarLinkModal.vue")))
);
},
},
});
/**
locale: deLocale,
events: this.absencesList.map((x) => ({
id: x.absenceId,
start: x.startDate,
end: x.endDate,
allday: true,
backgroundColor: this.getColorForAbsenceType(x.absenceType),
borderColor: '#ffffff',
title: this.getAbsenceType(x.absenceType) + ' ' + x.fullName,
})),
plugins: [
interactionPlugin,
dayGridPlugin,
timeGridPlugin,
listPlugin,
multiMonthPlugin,
],
initialView: 'dayGridMonth',
eventDisplay: 'block',
weekends: false,
editable: true,
selectable: true,
selectMirror: true,
dayMaxEvents: true,
weekNumbers: true,
displayEventTime: false,
weekText: 'KW',
validRange: { start: '2023-01-01', end: '' },
headerToolbar: {
left: 'today prev,next',
center: 'title',
right: 'listMonth,dayGridMonth,multiMonthYear,customview',
},
views: {
customview: {
type: 'multiMonth',
multiMonthMaxColumns: 1,
duration: { month: 12 },
buttonText: 'grid',
},
},
dateClick: this.handleDateSelect.bind(this),
datesSet: this.handleMonthChange.bind(this),
select: this.handleDateSelect.bind(this),
eventClick: this.handleEventClick.bind(this),
eventsSet: this.handleEvents.bind(this),
};
*/
</script>