feat: FE calendar, context menu, dashboard

This commit is contained in:
Michael 2025-03-26 10:33:44 +01:00
parent ca005ebb0b
commit b389f37a1d
6 changed files with 123 additions and 84 deletions

View file

@ -1,34 +1,100 @@
<script setup lang="ts"> <script setup lang="ts">
import CalendarShowEvent from "@/components/content/partials/CalendarShowEvent.vue"; import CalendarShowEvent from "@/components/content/partials/CalendarShowEvent.vue";
import {useRouter} from "vue-router"; import {computed, onMounted, type Ref, ref} from "vue";
import {ref} from "vue";
import {useAuthStore} from "@/stores/auth.store.ts"; import {useAuthStore} from "@/stores/auth.store.ts";
import ShowCreateEditForm from "@partials/ShowCreateEditForm.vue";
import {baseShow, deleteShow} from "@models/show/show.ts";
import type {Show} from "@models/show/show";
import type {calendarShowEvent} from "@models/misc/calendarShowEvent.ts";
import type { PropType} from "vue";
import {baseShowInstance, getShowInstances, type ShowInstance} from "@models/show/showInstance.ts";
import {setShowInstancesForCalendar} from "@/composables/content/dashboard_page.ts";
const auth = useAuthStore(); const auth = useAuthStore();
const userRole = auth.userData.user.role; const userRole = auth.userData.user.role;
const editMode = ref(false); const editMode = ref(false);
const showCreateEditMode = ref(false);
const showInstanceCreateEditMode = ref(false);
const showInstances = ref<ShowInstance[]>([]);
let showSelected = ref(baseShow());
let selectedShowInstance = ref(baseShowInstance());
onMounted(async () => {
const today = new Date();
const startOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 1);
const options = {
withShow: true,
starts: startOfMonth.toISOString().split('T')[0], // Format as YYYY-MM-DD
};
showInstances.value = await getShowInstances(options);
});
const shows: Ref<calendarShowEvent[]> = computed(() => setShowInstancesForCalendar(showInstances.value));
const toggleEditMode = () => { const toggleEditMode = () => {
editMode.value = !editMode.value; editMode.value = !editMode.value;
}; };
const router = useRouter(); const contextMenuEditInstance = (showInstanceId: number) => {
const navigateToCreateShow = () => { selectedShowInstance.value = showInstances.value[showInstanceId];
// TODO Change route to correct one showInstanceCreateEditMode.value = true;
router.push({name: 'CreateShow'});
}; };
const contextMenuEditShow = (showInstanceId: number) => {
showSelected.value = showInstances.value[showInstanceId].show;
showCreateEditMode.value = true;
};
const contextMenuDeleteInstance = (showInstanceId: number) => {
// deleteShowInstance([showInstances.value[showInstanceId].id])
};
const contextMenuDeleteShow = (showInstanceId: number) => {
deleteShow([showInstances.value[showInstanceId].show.id])
};
const createShow = () => {
showSelected.value = baseShow();
showCreateEditMode.value = true;
};
const resetItemEdited = () => {
showSelected.value = baseShow()
selectedShowInstance.value = baseShowInstance();
showCreateEditMode.value = false;
showInstanceCreateEditMode.value = false;
}
const saveShow = () => {
}
</script> </script>
<template> <template>
<v-row class="ma-4 justify-space-around"> <template v-if="showCreateEditMode || showInstanceCreateEditMode">
<!-- TODO show only if user is Editor or admin--> <ShowCreateEditForm v-if="showCreateEditMode" :show="showSelected" @go-back="resetItemEdited" @save-show="saveShow"/>
<template v-if="userRole && (userRole == 'admin' || userRole == 'editor')"> <!-- <ShowInstanceCreateEditForm v-if="showInstanceCreateEditMode" :showInstance="selectedShowInstance">-->
<v-btn color="primary" @click="navigateToCreateShow">Crea show</v-btn> </template>
<v-btn color="secondary" @click="toggleEditMode">{{ editMode ? 'Disabilita modifica calendario' : 'Abilita modifica calendario' }}</v-btn> <template v-else>
</template> <v-row class="ma-4 justify-space-around">
</v-row> <template v-if="userRole && (userRole == 'admin' || userRole == 'editor')">
<CalendarShowEvent :edit-mode="editMode"/> <v-btn color="primary" @click="createShow">Crea show</v-btn>
<v-btn color="secondary" @click="toggleEditMode">{{ editMode ? 'Disabilita modifica calendario' : 'Abilita modifica calendario' }}</v-btn>
</template>
</v-row>
<CalendarShowEvent
:edit-mode="editMode"
:shows="shows"
@contextMenuEditInstance="contextMenuEditInstance"
@contextMenuEditShow="contextMenuEditShow"
@contextMenuDeleteInstance="contextMenuDeleteInstance"
@contextMenuDeleteShow="contextMenuDeleteShow"
/>
</template>
</template> </template>
<style scoped> <style scoped>

View file

@ -1,35 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type {Ref} from 'vue'; import type { PropType} from "vue";
import type {ShowInstances} from "@models/show/showInstances";
import type {ContextMenuType} from "@models/misc/contextMenu" import type {ContextMenuType} from "@models/misc/contextMenu"
import {type calendarShowEvent, calendarShowEventMenu} from "@models/misc/calendarShowEvent"; import type {calendarShowEvent, ShowEventActionTrigger} from "@models/misc/calendarShowEvent.ts";
import {calendarShowEventMenu} from "@models/misc/calendarShowEvent";
import {ref, computed, onMounted} from 'vue'; import {ref, computed, onMounted} from 'vue';
import {getShowInstances} from "@models/show/showInstances";
import ContextMenu from '@partials/ContextMenu.vue'; import ContextMenu from '@partials/ContextMenu.vue';
// Data const emit = defineEmits([
const showInstances = ref<ShowInstances[]>([]); 'contextMenuEditInstance',
onMounted(async () => { 'contextMenuEditShow',
showInstances.value = await getShowInstances({ 'contextMenuDeleteInstance',
withShow: true, 'contextMenuDeleteShow'
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
}
}
);
});
// Data
const calendar = ref(null); const calendar = ref(null);
const currentCalendarDate = ref(null); const currentCalendarDate = ref(null);
const selectedShowInstance = ref(null); const selectedShowInstance = ref(null);
@ -42,13 +26,16 @@ const contextMenu = ref<ContextMenuType>({
menu: calendarShowEventMenu menu: calendarShowEventMenu
}); });
// Props // Props
const props = defineProps({ const props = defineProps({
editMode: { editMode: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
shows: {
type: Array as PropType<calendarShowEvent[]>,
default: false,
}
}); });
// Funcs // Funcs
@ -65,32 +52,9 @@ const hideContextMenu = () => {
contextMenu.value.visible = false; contextMenu.value.visible = false;
}; };
const contextMenuAction = (action: ShowEventActionTrigger, item: Object) => {
const contextMenuAction = (action: string) => {
if (!selectedShowInstance.value) return; if (!selectedShowInstance.value) return;
emit(action, selectedShowInstance.value.showInstanceIndex);
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; contextMenu.value.visible = false;
}; };

View file

@ -4,7 +4,7 @@ import {menuEntryWithAction, menuEntryWithChildren} from "@models/misc/contextMe
import {type PropType} from 'vue'; import {type PropType} from 'vue';
const emit = defineEmits(['click']); const emit = defineEmits(['contextMenuAction']);
const props = defineProps({ const props = defineProps({
top: { top: {
@ -19,7 +19,7 @@ const props = defineProps({
}); });
function triggerAction(item: string) { function triggerAction(item: string) {
console.log(item); emit('contextMenuAction', item);
} }
</script> </script>

View file

@ -1,17 +1,17 @@
import {ref, reactive} from "vue"; import type {ShowInstance} from "@models/show/showInstance.ts";
import type {calendarShowEvent} from "@models/misc/calendarShowEvent.ts";
export function archive_page() { export const setShowInstancesForCalendar = (showInstances: ShowInstance[]): calendarShowEvent[] => {
const items = ref([]) return showInstances.flatMap((showInstance: ShowInstance, index: number) => {
const selected = ref([]) return {
const loading = ref(false) showInstanceIndex: index,
const search = ref('') showInstanceId: showInstance.id,
const listData = reactive({ title: showInstance.show.name,
'itemsPerPage': 5, color: showInstance.show.color,
'first_page': null, start: new Date(showInstance.starts),
'last_page': null, end: new Date(showInstance.ends),
'total_items': 0, timed: true
'page': 1, }
}) }
);
return { items, listData, selected, loading, search }
} }

View file

@ -1,6 +1,7 @@
import type {ContextMenu} from "@models/misc/contextMenu" import type {ContextMenu, ExtractActionTriggers} from "@models/misc/contextMenu"
export interface calendarShowEvent { export interface calendarShowEvent {
showInstanceIndex: Number,
showInstanceId: Number, showInstanceId: Number,
title: string, title: string,
color: string, color: string,
@ -9,6 +10,8 @@ export interface calendarShowEvent {
timed: boolean, timed: boolean,
} }
export type ShowEventActionTrigger = ExtractActionTriggers<typeof calendarShowEventMenu>;
export const calendarShowEventMenu: ContextMenu = { export const calendarShowEventMenu: ContextMenu = {
entries: [ entries: [
{ {

View file

@ -24,6 +24,12 @@ interface ContextMenuEntryWithChildren {
type ContextMenuEntry = ContextMenuEntryWithAction | ContextMenuEntryWithChildren; type ContextMenuEntry = ContextMenuEntryWithAction | ContextMenuEntryWithChildren;
export type ExtractActionTriggers<T> =
T extends { actionTrigger: infer U } ? U :
T extends { children: infer C } ? ExtractActionTriggers<C> :
T extends (infer R)[] ? ExtractActionTriggers<R> :
never;
export function menuEntryWithAction(entry: ContextMenuEntry): entry is ContextMenuEntryWithAction { export function menuEntryWithAction(entry: ContextMenuEntry): entry is ContextMenuEntryWithAction {
return 'actionTrigger' in entry; return 'actionTrigger' in entry;
} }