<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="fetchNewsletterDates" class="cursor-pointer"> ↺ laden fehlgeschlagen </p> <div class="flex flex-col gap-2 h-full overflow-y-auto"> <details v-for="item in dates" class="flex flex-col gap-2 rounded-lg w-full justify-between border border-primary overflow-hidden min-h-fit" > <summary class="flex flex-row gap-2 bg-primary p-2 w-full justify-between items-center cursor-pointer"> <svg indicator class="fill-white stroke-white opacity-75 w-4 h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" > <path d="M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z" /> </svg> <p class="w-full text-white"> {{ item.calendar.title }}: {{ item.calendar.allDay ? new Date(item.calendar.starttime ?? "").toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric", }) : new Date(item.calendar.starttime ?? "").toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric", hour: "2-digit", minute: "2-digit", }) }} </p> <TrashIcon v-if="can('create', 'club', 'newsletter')" class="w-5 h-5 p-1 box-content cursor-pointer text-white" @click.prevent="removeSelected(item.calendarId)" /> </summary> <div class="flex flex-col gap-2 px-1"> <input type="text" name="title" id="title" placeholder="alternativer Titel" autocomplete="off" v-model="item.diffTitle" @keyup.prevent :disabled="!can('create', 'club', 'newsletter')" /> <div> <QuillEditor id="top" theme="snow" placeholder="alternative Beschreibung..." style="height: 150px; max-height: 150px; min-height: 150px" contentType="html" :toolbar="toolbarOptions" v-model:content="item.diffDescription" :enable="can('create', 'club', 'newsletter')" :style="!can('create', 'club', 'newsletter') ? 'opacity: 75%; background: rgb(243 244 246)' : ''" /> </div> </div> </details> </div> <form class="flex flex-row md:flex-row gap-2" @submit.prevent="addEntry"> <select id="date" ref="date" value="" required> <option value="" disabled>Datum wählen</option> <option v-for="cal in filteredCalendar" :key="cal.id" :value="cal.id"> {{ cal.allDay ? new Date(cal.starttime).toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric", }) : new Date(cal.starttime).toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric", hour: "2-digit", minute: "2-digit", }) }} - {{ cal.title }} </option> </select> <button type="submit" primary class="!w-fit">hinzufügen</button> </form> </div> </template> <script setup lang="ts"> import { defineComponent } from "vue"; import { mapActions, mapState, mapWritableState } from "pinia"; import Spinner from "@/components/Spinner.vue"; import { QuillEditor } from "@vueup/vue-quill"; import "@vueup/vue-quill/dist/vue-quill.snow.css"; import { toolbarOptions } from "@/helpers/quillConfig"; import { useNewsletterDatesStore } from "@/stores/admin/newsletterDates"; import { useAbilityStore } from "@/stores/ability"; import { useCalendarStore } from "@/stores/admin/calendar"; import type { CalendarViewModel } from "@/viewmodels/admin/calendar.models"; import { TrashIcon } from "@heroicons/vue/24/outline"; import cloneDeep from "lodash.clonedeep"; import type { NewsletterDatesViewModel } from "@/viewmodels/admin/newsletterDates.models"; </script> <script lang="ts"> export default defineComponent({ props: { newsletterId: String, }, computed: { ...mapWritableState(useNewsletterDatesStore, ["dates", "loading"]), ...mapState(useCalendarStore, ["calendars"]), ...mapState(useAbilityStore, ["can"]), filteredCalendar() { return this.calendars.filter( (c) => !this.dates.map((d) => d.calendarId).includes(c.id) && new Date(c.starttime) >= new Date() ); }, sortedDates() { return this.dates.sort( (a: NewsletterDatesViewModel, b: NewsletterDatesViewModel) => new Date(a.calendar.starttime).getTime() - new Date(b.calendar.starttime).getTime() ); }, calendarData() { return (dateId: string) => this.calendars.find((c) => c.id == dateId); }, }, mounted() { this.fetchNewsletterDates(); this.fetchCalendars(); }, methods: { ...mapActions(useNewsletterDatesStore, ["fetchNewsletterDates"]), ...mapActions(useCalendarStore, ["fetchCalendars"]), addEntry(e: any) { const formData = e.target.elements; const dateId = formData.date.value; this.dates.push({ newsletterId: parseInt(this.newsletterId ?? "0"), calendarId: dateId, diffTitle: "", diffDescription: "", calendar: cloneDeep(this.calendarData(dateId)) as CalendarViewModel, }); (this.$refs.date as HTMLSelectElement).value = ""; }, removeSelected(id: string) { let index = this.dates.findIndex((d) => d.calendarId == id); if (index != -1) { this.dates.splice(index, 1); } }, }, }); </script>