feat(FE ShowCalendar): set up

This commit is contained in:
Michael 2025-03-19 10:58:47 +01:00
parent 2fe757b2a6
commit be52121e72

View file

@ -0,0 +1,139 @@
<script setup lang="ts">
import type {Ref} from 'vue';
import type {ShowInstances} from "@models/show/showInstances";
import type {ContextMenuType} from "@models/misc/contextMenu"
import {type calendarShowEvent, calendarShowEventMenu} from "@models/misc/calendarShowEvent";
import {ref, computed, onMounted} from 'vue';
import {getShowInstances} from "@models/show/showInstances";
import ContextMenu from '@partials/ContextMenu.vue';
// Data
const showInstances = ref<ShowInstances[]>([]);
onMounted(async () => {
showInstances.value = await getShowInstances({
withShow: true,
starts: `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`,
});
});
const shows: Ref<calendarShowEvent[]> = computed(() => {
return showInstances.value.flatMap(showInstance => {
return {
showInstanceId: showInstance.id,
title: showInstance.show.name,
color: showInstance.show.color,
start: new Date(showInstance.starts),
end: new Date(showInstance.ends),
timed: true
}
}
);
});
const calendar = ref(null);
const currentCalendarDate = ref(null);
const selectedShowInstance = ref(null);
const contextMenu = ref<ContextMenuType>({
visible: false,
position: {
top: 0,
left: 0,
},
menu: calendarShowEventMenu
});
// Props
const props = defineProps({
editMode: {
type: Boolean,
default: false,
},
});
// Funcs
const openContextMenu = (showInstance: Record<string, unknown>, browserEvent: MouseEvent) => {
if (!props.editMode) return;
selectedShowInstance.value = showInstance;
contextMenu.value.visible = true;
contextMenu.value.position.top = browserEvent.y;
contextMenu.value.position.left = browserEvent.x + 5;
};
const hideContextMenu = () => {
contextMenu.value.visible = false;
};
const contextMenuAction = (action: string) => {
if (!selectedShowInstance.value) return;
switch (action) {
case 'contextMenuEditInstance':
console.log('Edit instance', selectedShowInstance.value);
// Add logic to edit the instance here
break;
case 'contextMenuEditShow':
console.log('Edit show', selectedShowInstance.value);
// Add logic to edit the show here
break;
case 'contextMenuDeleteInstance':
console.log('Delete instance', selectedShowInstance.value);
// Add logic to delete the instance here
break;
case 'contextMenuDeleteShow':
console.log('Delete show', selectedShowInstance.value);
// Add logic to delete the show here
break;
default:
console.log('Unknown action:', action);
break;
}
contextMenu.value.visible = false;
};
const formatTime = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'});
}
</script>
<template>
<v-calendar
ref="calendar"
v-model="currentCalendarDate"
:events="shows"
:event-margin-bottom="3"
@contextmenu:event="openContextMenu"
>
<template v-slot:event="{ event }">
<div
class="v-event mx-1 event-content"
:style="{ backgroundColor: event.color as string }"
@click="(e) => openContextMenu(event, e)"
@click.self="hideContextMenu"
>
<span>{{ event.title }}</span>
<br/>
<span>{{ formatTime(event.start as string) }} - {{ formatTime(event.end as string) }}</span>
</div>
</template>
</v-calendar>
<ContextMenu v-if="contextMenu.visible" @contextMenuAction="contextMenuAction" :event="selectedShowInstance"
:menu="contextMenu.menu" :top="contextMenu.position.top" :left="contextMenu.position.left"/>
</template>
<style scoped>
.event-content {
position: relative;
white-space: normal;
line-height: 1.2;
padding: 4px 8px;
background-color: #7492b9;
border-radius: 8px;
color: white;
}
</style>