mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender-pwa.git
synced 2025-08-07 04:09:17 +02:00
feat:#4 view, calendar import, component
This commit is contained in:
115
frontend/src/components/CalendarViewer.vue
Normal file
115
frontend/src/components/CalendarViewer.vue
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
import FullCalendar from "@fullcalendar/vue3";
|
||||||
|
import { computed, ComputedRef, inject, Ref, ref, watch } from "vue";
|
||||||
|
import { CalendarOptions, DatesSetArg } from "@fullcalendar/core";
|
||||||
|
import allLocales from "@fullcalendar/core/locales-all";
|
||||||
|
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||||
|
import interactionPlugin from "@fullcalendar/interaction";
|
||||||
|
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||||
|
import iCalenderPlugin from "@fullcalendar/icalendar";
|
||||||
|
import router from "@/router";
|
||||||
|
import { formatYearMonthDay } from "@/helpers/dates.ts";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n({ useScope: "global" });
|
||||||
|
|
||||||
|
const mobilePage = inject("mobilePage") as Ref<boolean>;
|
||||||
|
const date: Ref<Date> = ref(new Date());
|
||||||
|
const feedUrl: Ref<string> = ref("https://cal.htwk-leipzig.de/api/feed?token=rk47mvraeb43t3g");
|
||||||
|
|
||||||
|
const fullCalendar = ref<InstanceType<typeof FullCalendar>>();
|
||||||
|
|
||||||
|
const calendarOptions: ComputedRef<CalendarOptions> = computed(() => ({
|
||||||
|
locales: allLocales,
|
||||||
|
locale: t("languageCode"),
|
||||||
|
plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin, iCalenderPlugin],
|
||||||
|
// local debugging of mobilePage variable in object creation on ternary expression
|
||||||
|
initialView: mobilePage.value ? "Day" : "week",
|
||||||
|
initialDate: date.value,
|
||||||
|
dayHeaderFormat: { weekday: "short", omitCommas: true },
|
||||||
|
slotDuration: "00:15:00",
|
||||||
|
eventTimeFormat: {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
hour12: false,
|
||||||
|
},
|
||||||
|
height: "auto",
|
||||||
|
views: {
|
||||||
|
week: {
|
||||||
|
type: "timeGrid",
|
||||||
|
slotLabelFormat: {
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "2-digit",
|
||||||
|
omitZeroMinute: false,
|
||||||
|
meridiem: false,
|
||||||
|
hour12: false,
|
||||||
|
},
|
||||||
|
dateAlignment: "week",
|
||||||
|
titleFormat: { month: "short", day: "numeric" },
|
||||||
|
slotMinTime: "06:00:00",
|
||||||
|
slotMaxTime: "22:00:00",
|
||||||
|
duration: { days: 7 },
|
||||||
|
firstDay: 1,
|
||||||
|
allDaySlot: false,
|
||||||
|
hiddenDays: [0],
|
||||||
|
},
|
||||||
|
Day: {
|
||||||
|
type: "timeGrid",
|
||||||
|
slotLabelFormat: {
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "2-digit",
|
||||||
|
omitZeroMinute: false,
|
||||||
|
meridiem: false,
|
||||||
|
hour12: false,
|
||||||
|
},
|
||||||
|
titleFormat: { month: "short", day: "numeric" },
|
||||||
|
slotMinTime: "06:00:00",
|
||||||
|
slotMaxTime: "22:00:00",
|
||||||
|
duration: { days: 1 },
|
||||||
|
allDaySlot: false,
|
||||||
|
hiddenDays: [0],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
headerToolbar: {
|
||||||
|
end: "prev,next today",
|
||||||
|
center: "title",
|
||||||
|
start: "week,Day",
|
||||||
|
},
|
||||||
|
|
||||||
|
datesSet: function (dateInfo: DatesSetArg) {
|
||||||
|
const view = dateInfo.view;
|
||||||
|
const offset = new Date().getTimezoneOffset();
|
||||||
|
const endDate = new Date(view.activeEnd.getTime() - offset * 60 * 1000);
|
||||||
|
router.replace({
|
||||||
|
query: {
|
||||||
|
...router.currentRoute.value.query,
|
||||||
|
date: formatYearMonthDay(endDate),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
url: feedUrl.value,
|
||||||
|
format: "ics",
|
||||||
|
failure: function () {
|
||||||
|
alert("There was an error while fetching the calendar events!");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
watch(mobilePage, () => {
|
||||||
|
fullCalendar.value?.getApi().changeView(mobilePage.value ? "Day" : "week");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FullCalendar ref="fullCalendar" :options="calendarOptions" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
:deep(.fc-toolbar.fc-header-toolbar) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
@@ -53,6 +53,11 @@ const items = computed(() => [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t("userCalendar"),
|
||||||
|
icon: "pi pi-fw pi-calendar",
|
||||||
|
route: "/user/calendar",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: t("faq"),
|
label: t("faq"),
|
||||||
icon: "pi pi-fw pi-book",
|
icon: "pi pi-fw pi-book",
|
||||||
|
0
frontend/src/helpers/ical.ts
Normal file
0
frontend/src/helpers/ical.ts
Normal file
@@ -2,6 +2,7 @@
|
|||||||
"languageCode": "de",
|
"languageCode": "de",
|
||||||
"createCalendar": "Kalender erstellen",
|
"createCalendar": "Kalender erstellen",
|
||||||
"editCalendar": "Kalender bearbeiten",
|
"editCalendar": "Kalender bearbeiten",
|
||||||
|
"userCalendar": "Dein Kalender",
|
||||||
"rooms": "Räume",
|
"rooms": "Räume",
|
||||||
"faq": "FAQ",
|
"faq": "FAQ",
|
||||||
"imprint": "Impressum",
|
"imprint": "Impressum",
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
"languageCode": "en",
|
"languageCode": "en",
|
||||||
"createCalendar": "create calendar",
|
"createCalendar": "create calendar",
|
||||||
"editCalendar": "edit calendar",
|
"editCalendar": "edit calendar",
|
||||||
|
"userCalendar": "user calendar",
|
||||||
"rooms": "rooms",
|
"rooms": "rooms",
|
||||||
"faq": "faq",
|
"faq": "faq",
|
||||||
"imprint": "imprint",
|
"imprint": "imprint",
|
||||||
|
@@ -27,6 +27,7 @@ const EditAdditionalModules = () =>
|
|||||||
const EditModules = () => import("../view/editCalendar/EditModules.vue");
|
const EditModules = () => import("../view/editCalendar/EditModules.vue");
|
||||||
const CourseSelection = () => import("../view/CourseSelection.vue");
|
const CourseSelection = () => import("../view/CourseSelection.vue");
|
||||||
const FreeRooms = () => import("../view/FreeRooms.vue");
|
const FreeRooms = () => import("../view/FreeRooms.vue");
|
||||||
|
const CalenderViewer = () => import("../view/UserCalendar.vue");
|
||||||
|
|
||||||
import i18n from "../i18n";
|
import i18n from "../i18n";
|
||||||
|
|
||||||
@@ -48,6 +49,11 @@ const router = createRouter({
|
|||||||
name: "free-rooms",
|
name: "free-rooms",
|
||||||
component: FreeRooms,
|
component: FreeRooms,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/user/calendar",
|
||||||
|
name: "user-calendar",
|
||||||
|
component: CalenderViewer,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/faq",
|
path: "/faq",
|
||||||
name: "faq",
|
name: "faq",
|
||||||
|
12
frontend/src/view/UserCalendar.vue
Normal file
12
frontend/src/view/UserCalendar.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
import CalendarViewer from "@/components/CalendarViewer.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<CalendarViewer />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
Reference in New Issue
Block a user