124 lines
5 KiB
Vue
124 lines
5 KiB
Vue
<script setup>
|
||
import { computed, ref } from 'vue'
|
||
import SlideUploader from '@/Components/SlideUploader.vue'
|
||
|
||
const props = defineProps({
|
||
agendaItem: { type: Object, required: true },
|
||
serviceId: { type: Number, required: true },
|
||
serviceDate: { type: String, default: null },
|
||
})
|
||
|
||
const emit = defineEmits(['slides-updated'])
|
||
|
||
const showUploader = ref(false)
|
||
|
||
const responsibleNames = computed(() => {
|
||
const r = props.agendaItem.responsible
|
||
if (!r || !Array.isArray(r) || r.length === 0) return ''
|
||
return r.map((p) => p.name || p.title || p.personName || '').filter(Boolean).join(', ')
|
||
})
|
||
|
||
function onUploaded() {
|
||
showUploader.value = false
|
||
emit('slides-updated')
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div
|
||
class="rounded-lg border bg-white p-4"
|
||
:class="{
|
||
'border-l-4 border-emerald-500': agendaItem.slides?.length > 0,
|
||
'border-l-4 border-blue-400': agendaItem.is_announcement_position,
|
||
'border-l-4 border-purple-400': agendaItem.is_sermon && !agendaItem.is_announcement_position,
|
||
'border-gray-200': !agendaItem.slides?.length && !agendaItem.is_announcement_position && !agendaItem.is_sermon,
|
||
}"
|
||
data-testid="agenda-item-row"
|
||
>
|
||
<div class="flex items-start justify-between gap-4">
|
||
<div class="flex-1">
|
||
<!-- Position + Titel -->
|
||
<div class="flex items-center gap-2">
|
||
<span class="text-xs text-gray-400 tabular-nums">{{ agendaItem.position || agendaItem.sort_order }}.</span>
|
||
<h4 class="font-medium text-gray-900" data-testid="agenda-item-title">
|
||
{{ agendaItem.title }}
|
||
</h4>
|
||
</div>
|
||
|
||
<!-- Meta: Zeit, Dauer, Verantwortlich -->
|
||
<div class="mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-gray-400">
|
||
<span v-if="agendaItem.start">
|
||
🕐 {{ agendaItem.start }}
|
||
</span>
|
||
<span v-if="agendaItem.duration">
|
||
⏱ {{ agendaItem.duration }}
|
||
</span>
|
||
<span v-if="responsibleNames">
|
||
👤 {{ responsibleNames }}
|
||
</span>
|
||
</div>
|
||
|
||
<!-- Notiz (optional) -->
|
||
<p v-if="agendaItem.note" class="mt-1 text-xs text-gray-500">
|
||
{{ agendaItem.note }}
|
||
</p>
|
||
|
||
<!-- Badges -->
|
||
<div class="mt-1.5 flex gap-2">
|
||
<span
|
||
v-if="agendaItem.is_announcement_position"
|
||
class="inline-flex items-center gap-1 rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-700"
|
||
>
|
||
📢 Ankündigungen hier
|
||
</span>
|
||
<span
|
||
v-if="agendaItem.is_sermon"
|
||
class="inline-flex items-center gap-1 rounded-full bg-purple-100 px-2 py-0.5 text-xs font-medium text-purple-700"
|
||
>
|
||
📖 Predigt
|
||
</span>
|
||
</div>
|
||
|
||
<!-- Folien-Thumbnails (kompakt) -->
|
||
<div v-if="agendaItem.slides?.length" class="mt-2 flex gap-1">
|
||
<img
|
||
v-for="slide in agendaItem.slides.slice(0, 4)"
|
||
:key="slide.id"
|
||
:src="`/storage/slides/${slide.thumbnail_filename}`"
|
||
class="h-10 w-16 rounded border border-gray-200 object-cover"
|
||
:alt="slide.original_filename"
|
||
/>
|
||
<span
|
||
v-if="agendaItem.slides.length > 4"
|
||
class="flex h-10 w-16 items-center justify-center rounded border border-gray-200 text-xs text-gray-500"
|
||
>
|
||
+{{ agendaItem.slides.length - 4 }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- + Button -->
|
||
<button
|
||
class="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg border border-dashed border-gray-300 text-gray-400 transition-colors hover:border-blue-400 hover:text-blue-500"
|
||
data-testid="agenda-item-add-slides"
|
||
:title="showUploader ? 'Schließen' : 'Folien hinzufügen'"
|
||
@click="showUploader = !showUploader"
|
||
>
|
||
{{ showUploader ? '×' : '+' }}
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Folien-Upload (umschaltbar) -->
|
||
<div v-if="showUploader" class="mt-3 border-t pt-3">
|
||
<SlideUploader
|
||
type="agenda_item"
|
||
:service-id="serviceId"
|
||
:agenda-item-id="agendaItem.id"
|
||
:show-expire-date="false"
|
||
:inline="true"
|
||
@uploaded="onUploaded"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</template>
|