sintonia_webapp/resources/js/components/content/partials/show/ShowForm.vue
2025-07-11 15:03:59 +02:00

249 lines
7.9 KiB
Vue

<script setup lang="ts">
import {ref, onMounted, type PropType} from "vue";
;
import ShowScheduleForm from "@partials/show/ShowScheduleForm.vue";
import {useShowStore} from "@stores/show/show.store.ts";
import {getUser} from "@models/User.ts";
import {getPlaylist} from "@models/playlist.ts";
import ColorPickerButton from "@partials/fields/misc/ColorPickerButton.vue";
import {useShowDaysStore} from "@stores/show/showDays.store.ts";
// Props and emits
const props = defineProps({
showId: {
type: Number as PropType<number | null>,
required: true,
},
showType: {
type: String as PropType<'show' | 'spot'>,
required: true,
validator: (value: string) => ['show', 'spot'].includes(value),
},
});
const emits = defineEmits(['go-back']);
// Data
let usersDJs = ref([])
let playlists = ref([])
const loading = ref(false);
const showScheduleFormMode = ref(false);
const isFormValid = ref(false);
// Store
const showStore = useShowStore()
const showDaysStore = useShowDaysStore()
// Funcs
onMounted(async () => {
loading.value = true
// Prepare show store
if (props.showId === null) {
showStore.resetShow()
showStore.currentShow.showType = props.showType
} else {
const withDjs = props.showType === 'show';
const selectedShow = await showStore.getShow(props.showId, {showType: props.showType, withDjs: withDjs})
showStore.loadShow(selectedShow)
showStore.currentShow.showType = props.showType
}
// fill store
let playlistOptions: { playlistType: 'show' | 'spot' } = { playlistType: 'spot' };
if (props.showType === 'show') {
usersDJs.value = await getUser({role: 'dj'});
playlistOptions.playlistType = 'show';
}
playlists.value = await getPlaylist(playlistOptions);
loading.value = false;
})
const toggleShowScheduleForm = () => {
showScheduleFormMode.value = !showScheduleFormMode.value;
}
const goBack = () => {
showScheduleFormMode.value = false;
showStore.resetShow()
showDaysStore.resetShowDays()
emits('go-back')
}
const createShow = () => {
showStore.currentShow.showDays = showDaysStore.currentShowDays;
showStore.createShow();
goBack()
}
</script>
<template>
<v-card
:disabled="loading"
:loading="loading"
>
<template v-slot:loader="{ isActive }">
<v-progress-linear
:active="isActive"
color="deep-purple"
height="4"
indeterminate
></v-progress-linear>
</template>
<v-card-title>
<h3>Trasmissione</h3>
</v-card-title>
<template v-if="showScheduleFormMode">
<ShowScheduleForm
:showId="showStore.currentShow.id"
@toggle-show-schedule-form="toggleShowScheduleForm"
@trigger-show-creation="createShow"
/>
</template>
<template v-else>
<v-form ref="form" v-model="isFormValid">
<v-card-text>
<v-row no-gutters>
<!-- Name Field -->
<v-col cols="12" md="6" lg="4">
<v-card>
<v-text-field
v-model="showStore.currentShow.name"
label="Nome"
density="compact"
@update:modelValue="value => showStore.updateField({ key: 'name', value })"
:rules="[v => !!v || 'Nome è obbligatorio']"
required="true"
/>
</v-card>
</v-col>
<!-- URL Field -->
<v-col v-if="props.showType == 'show'" cols="12" md="6" lg="4">
<v-card>
<v-text-field
v-model="showStore.currentShow.url"
label="URL"
density="compact"
:required="true"
@update:modelValue="value => showStore.updateField({ key: 'url', value })"
/>
</v-card>
</v-col>
<!-- Genre Field -->
<v-col cols="12" md="6" lg="4">
<v-card>
<v-text-field
v-model="showStore.currentShow.genre"
label="Genere"
density="compact"
:required="true"
@update:modelValue="value => showStore.updateField({ key: 'genre', value })"
/>
</v-card>
</v-col>
<!-- Description Field -->
<v-col cols="12" md="6" lg="4">
<v-card>
<v-textarea
v-model="showStore.currentShow.description"
label="Descrizione"
density="compact"
rows="2"
@update:modelValue="value => showStore.updateField({ key: 'description', value })"
/>
</v-card>
</v-col>
<!-- Background Color Picker -->
<v-col cols="12" md="6" lg="4">
<v-card>
<ColorPickerButton
v-model="showStore.currentShow.backgroundColor"
label="Colore di sfondo"
/>
</v-card>
</v-col>
<!-- Image Path File Input -->
<v-col cols="12" md="6" lg="4">
<v-card>
<v-file-input
v-model="showStore.currentShow.imagePath"
label="Percorso immagine"
density="compact"
type="file"
@update:modelValue="value => showStore.updateField({ key: 'imagePath', value })"
/>
</v-card>
</v-col>
<!-- Autoplaylist Conditional -->
<v-col cols="12" md="6" lg="4">
<v-card>
<v-card>
<v-checkbox
label="Utilizzare una playlist?"
v-model="showStore.currentShow.hasAutoplaylist"
></v-checkbox>
<v-checkbox
v-model="showStore.currentShow.autoplaylistRepeat"
label="Ripetere playlist?"
:disabled="!showStore.currentShow.hasAutoplaylist"
@update:modelValue="value => showStore.updateField({ key: 'autoplaylistRepeat', value })"
/>
<v-select
v-model="showStore.currentShow.autoplaylistId"
:items="playlists"
label="Playlist"
density="compact"
item-title="name"
item-value="id"
:disabled="!showStore.currentShow.hasAutoplaylist"
@update:modelValue="value => showStore.updateField({ key: 'autoplaylistId', value })"
/>
</v-card>
</v-card>
</v-col>
<!-- TODO Instead of the dj name, obj obj is shown -->
<!-- DJs Select -->
<v-col v-if="props.showType == 'show'" cols="12" md="6" lg="4">
<v-card>
<v-select
v-model="showStore.currentShow.showDjs"
:items="usersDJs"
label="DJs"
density="compact"
item-title="login"
item-value="id"
multiple
@update:modelValue="value => showStore.updateField({ key: 'showDjs', value })"
/>
</v-card>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-btn color="accent" @click="goBack">Torna indietro</v-btn>
<v-btn v-if="showStore.currentShow.id" color="accent" @click="showStore.updateShow()"
:disabled="!isFormValid">Salva
</v-btn>
<v-btn color="accent" @click="toggleShowScheduleForm" :disabled="!isFormValid">Regole di programmazione
</v-btn>
</v-card-actions>
</v-form>
</template>
</v-card>
</template>
<style scoped></style>