mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-08-04 02:39:14 +02:00
fixed merge issue with main
This commit is contained in:
36
frontend/src/api/fetchRoom.ts
Normal file
36
frontend/src/api/fetchRoom.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import {Event} from "../model/event.ts";
|
||||
|
||||
export async function fetchRoom(): Promise<string[]> {
|
||||
const rooms: string[] = [];
|
||||
await fetch("/api/rooms")
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
})
|
||||
.then((roomsResponse) => {
|
||||
roomsResponse.forEach((room: string) => rooms.push(room));
|
||||
});
|
||||
return rooms;
|
||||
}
|
||||
|
||||
export async function fetchEventsByRoomAndDuration(
|
||||
room: string,
|
||||
from_date: string,
|
||||
to_date: string,
|
||||
): Promise<Event[]> {
|
||||
const events: Event[] = [];
|
||||
await fetch("/api/schedule?room=" + room + "&from=" + from_date + "&to=" + to_date)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
return response.json();
|
||||
})
|
||||
.then((eventsResponse) => {
|
||||
console.log("Response:", eventsResponse);
|
||||
eventsResponse.forEach((event: Event) =>
|
||||
events.push(event));
|
||||
}).catch((error) => {
|
||||
console.log("Error fetching events: ", error);
|
||||
return null;
|
||||
})
|
||||
console.log("occupations: ", events);
|
||||
return events;
|
||||
}
|
@@ -12,6 +12,11 @@ const items = ref([
|
||||
icon: "pi pi-fw pi-pencil",
|
||||
url: "/edit",
|
||||
},
|
||||
{
|
||||
label: "Check Room Availability",
|
||||
icon: "pi pi-fw pi-calendar",
|
||||
url: "/rooms",
|
||||
},
|
||||
{
|
||||
label: "FAQ",
|
||||
icon: "pi pi-fw pi-book",
|
||||
|
50
frontend/src/components/RoomFinder.vue
Normal file
50
frontend/src/components/RoomFinder.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
import {Ref, ref} from "vue";
|
||||
import {fetchRoom} from "../api/fetchRoom.ts";
|
||||
import RoomOccupation from "./RoomOccupation.vue";
|
||||
|
||||
const rooms = async () => {
|
||||
return await fetchRoom();
|
||||
};
|
||||
|
||||
const roomsList: Ref<{ name: string }[]> = ref([]);
|
||||
const selectedRoom: Ref<{ name: string }> = ref({name: ""});
|
||||
|
||||
rooms().then(
|
||||
(data) =>
|
||||
(roomsList.value = data.map((room) => {
|
||||
return {name: room};
|
||||
})),
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-column">
|
||||
<div class="flex align-items-center justify-content-center h-4rem m-2">
|
||||
<h3 class="text-4xl">Raumfinder</h3>
|
||||
</div>
|
||||
<div
|
||||
class="flex align-items-center justify-content-center h-4rem border-round m-2"
|
||||
>
|
||||
<h5 class="text-2xl">Please select a room</h5>
|
||||
</div>
|
||||
<div
|
||||
class="flex align-items-center justify-content-center border-round m-2"
|
||||
>
|
||||
<Dropdown
|
||||
v-model="selectedRoom"
|
||||
:options="roomsList"
|
||||
class="w-full md:w-25rem mx-2"
|
||||
filter
|
||||
option-label="name"
|
||||
placeholder="Select a Room"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="m-6"
|
||||
>
|
||||
<RoomOccupation :room="selectedRoom.name"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
139
frontend/src/components/RoomOccupation.vue
Normal file
139
frontend/src/components/RoomOccupation.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<script lang="ts" setup>
|
||||
import FullCalendar from '@fullcalendar/vue3'
|
||||
import dayGridPlugin from '@fullcalendar/daygrid'
|
||||
import interactionPlugin from '@fullcalendar/interaction'
|
||||
import timeGridPlugin from '@fullcalendar/timegrid'
|
||||
import {computed, ref, Ref, watch} from "vue";
|
||||
import {CalendarOptions, EventInput} from "@fullcalendar/core";
|
||||
import {fetchEventsByRoomAndDuration} from "../api/fetchRoom.ts";
|
||||
|
||||
const props = defineProps({
|
||||
room: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
type CalenderEvent = {
|
||||
id: number;
|
||||
start: string;
|
||||
end: string;
|
||||
};
|
||||
|
||||
const currentDateFrom: Ref<string> = ref("");
|
||||
const currentDateTo: Ref<string> = ref("");
|
||||
const occupations: Ref<CalenderEvent[]> = ref([]);
|
||||
|
||||
const selectedRoom = computed(() => props.room);
|
||||
|
||||
watch(selectedRoom, (_newValue: string) => {
|
||||
getOccupation();
|
||||
});
|
||||
|
||||
const fullCalendar = ref<InstanceType<typeof FullCalendar>>()
|
||||
|
||||
async function getOccupation() {
|
||||
if (selectedRoom.value === "") {
|
||||
return;
|
||||
}
|
||||
const events = await fetchEventsByRoomAndDuration(
|
||||
selectedRoom.value,
|
||||
currentDateFrom.value,
|
||||
currentDateTo.value
|
||||
);
|
||||
occupations.value = events.map((event, index) => {
|
||||
return {
|
||||
id: index,
|
||||
start: event.start.replace(/\s\+\d{4}\s\w+$/, '').replace(' ', 'T'),
|
||||
end: event.end.replace(/\s\+\d{4}\s\w+$/, '').replace(' ', 'T')
|
||||
};
|
||||
});
|
||||
|
||||
let calendar = fullCalendar.value?.getApi()
|
||||
calendar?.refetchEvents()
|
||||
}
|
||||
|
||||
|
||||
const calendarOptions: CalendarOptions = {
|
||||
plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin],
|
||||
initialView: 'week',
|
||||
dayHeaderFormat: {weekday: 'short', omitCommas: true},
|
||||
slotDuration: "00:15:00",
|
||||
eventTimeFormat: {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false
|
||||
},
|
||||
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) {
|
||||
const view = dateInfo.view;
|
||||
const offset = (new Date()).getTimezoneOffset();
|
||||
const startDate = new Date(view.activeStart.getTime() - (offset*60*1000));
|
||||
const endDate = new Date(view.activeEnd.getTime() - (offset*60*1000));
|
||||
currentDateFrom.value = startDate.toISOString().split('T')[0]
|
||||
currentDateTo.value = endDate.toISOString().split('T')[0]
|
||||
getOccupation();
|
||||
},
|
||||
events: function(_info, successCallback, failureCallback) {
|
||||
if (occupations.value.length === 0){
|
||||
failureCallback(new Error("no events"))
|
||||
}else{
|
||||
successCallback(
|
||||
occupations.value.map((event) => {
|
||||
return {
|
||||
id: event.id.toString(),
|
||||
start: event.start,
|
||||
end: event.end,
|
||||
} as EventInput;
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<FullCalendar ref="fullCalendar" :options="calendarOptions"/>
|
||||
</template>
|
@@ -1,13 +1,16 @@
|
||||
export class Event {
|
||||
constructor(
|
||||
public name: string,
|
||||
public bookedAt: string,
|
||||
public course: string,
|
||||
public day: string,
|
||||
public start: string,
|
||||
public end: string,
|
||||
public prof: string,
|
||||
public week: string,
|
||||
public eventType: string,
|
||||
public rooms: string,
|
||||
public name: string,
|
||||
public notes: string,
|
||||
public prof: string,
|
||||
public rooms: string,
|
||||
public semester: string,
|
||||
public start: string,
|
||||
public week: string,
|
||||
) {}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import CalendarLink from "../components/CalendarLink.vue";
|
||||
import Imprint from "../components/ImprintPage.vue";
|
||||
import PrivacyPolicy from "../components/PrivacyPolicy.vue";
|
||||
import RenameModules from "../components/RenameModules.vue";
|
||||
import RoomFinder from "../components/RoomFinder.vue";
|
||||
import EditCalendarView from "../view/editCalendarView.vue";
|
||||
import EditAdditionalModules from "../components/editCalendar/EditAdditionalModules.vue";
|
||||
import EditModules from "../components/editCalendar/EditModules.vue";
|
||||
@@ -18,6 +19,11 @@ const router = createRouter({
|
||||
name: "course-selection",
|
||||
component: CourseSelection,
|
||||
},
|
||||
{
|
||||
path: "/rooms",
|
||||
name: "room-finder",
|
||||
component: RoomFinder,
|
||||
},
|
||||
{
|
||||
path: "/faq",
|
||||
name: "faq",
|
||||
|
Reference in New Issue
Block a user