feat(ui): name overrides + namenseinblender setting

This commit is contained in:
Thorsten Bus 2026-05-31 03:41:24 +02:00
parent f948b5665c
commit b36ed6e221
4 changed files with 112 additions and 0 deletions

View file

@ -269,6 +269,8 @@ public function edit(Service $service): Response
'background_filename' => $service->background_filename,
'key_visual_url' => $service->key_visual_filename ? '/storage/'.$service->key_visual_filename : null,
'background_url' => $service->background_filename ? '/storage/'.$service->background_filename : null,
'moderator_name' => $service->moderator_name,
'preacher_name_override' => $service->preacher_name_override,
],
'serviceSongs' => $service->serviceSongs->map(fn ($ss) => [
'id' => $ss->id,
@ -367,6 +369,18 @@ public function finalize(Service $service): JsonResponse
]);
}
public function updateNameOverrides(Request $request, Service $service): RedirectResponse
{
$validated = $request->validate([
'moderator_name' => ['nullable', 'string', 'max:255'],
'preacher_name_override' => ['nullable', 'string', 'max:255'],
]);
$service->update($validated);
return back()->with('success', 'Namensangaben gespeichert.');
}
public function reopen(Service $service): RedirectResponse
{
$service->update([

View file

@ -98,6 +98,12 @@ function refreshPage() {
router.reload({ preserveScroll: true })
}
function updateNameOverride(field, value) {
router.patch(route('services.name-overrides.update', { service: props.service.id }), {
[field]: value || null,
}, { preserveScroll: true })
}
function scrollToInfoBlock() {
informationBlockRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
@ -406,6 +412,42 @@ async function downloadService() {
</div>
</div>
<!-- Name-Überschreibungen (Moderation & Predigt) -->
<div class="pb-4">
<div class="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div class="rounded-lg border border-gray-200 bg-white p-4 shadow-sm">
<label class="mb-1 block text-sm font-semibold text-gray-700" for="moderator_name">
Moderation Name (Überschreiben)
</label>
<input
id="moderator_name"
type="text"
:value="service.moderator_name ?? ''"
class="w-full rounded border border-gray-300 px-3 py-1.5 text-sm focus:border-blue-500 focus:outline-none"
placeholder="Aus dem Ablauf ermittelt"
data-testid="moderator-name-override"
@change="updateNameOverride('moderator_name', $event.target.value)"
/>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 shadow-sm">
<label class="mb-1 block text-sm font-semibold text-gray-700" for="preacher_name_override">
Predigt Name (Überschreiben)
</label>
<input
id="preacher_name_override"
type="text"
:value="service.preacher_name_override ?? ''"
class="w-full rounded border border-gray-300 px-3 py-1.5 text-sm focus:border-blue-500 focus:outline-none"
placeholder="Aus ChurchTools übernommen"
data-testid="preacher-name-override"
@change="updateNameOverride('preacher_name_override', $event.target.value)"
/>
</div>
</div>
</div>
</div>
<!-- Ablauf (Agenda) -->
<div class="py-6">
<div class="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">

View file

@ -23,6 +23,7 @@ const submenus = [
{ key: 'labels', label: 'Label-Import' },
{ key: 'agenda', label: 'Agenda' },
{ key: 'ccli', label: 'CCLI Import' },
{ key: 'namenseinblender', label: 'Namenseinblender' },
]
const activeSubmenu = ref('assignments')
@ -222,6 +223,60 @@ async function updateSetting(key, value) {
</details>
</div>
</div>
<!-- Namenseinblender Macro Settings -->
<div v-if="activeSubmenu === 'namenseinblender'" class="space-y-6">
<div>
<h3 class="text-base font-semibold text-gray-900">Namenseinblender-Makro</h3>
<p class="mt-1 text-sm text-gray-500">
Konfiguriere das ProPresenter-Makro, das für die Namenseinblendung bei Moderation und Predigt verwendet wird. Wenn kein Makro konfiguriert ist, werden keine Namensfolien generiert.
</p>
</div>
<div class="rounded-lg border border-gray-200 p-4 space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Makro-Name</label>
<input
type="text"
:value="settings.namenseinblender_macro_name || ''"
class="block w-full rounded-md border-gray-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500"
placeholder="z.B. Namenseinblender"
data-testid="namenseinblender-macro-name"
@change="updateSetting('namenseinblender_macro_name', $event.target.value)"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Makro-UUID</label>
<input
type="text"
:value="settings.namenseinblender_macro_uuid || ''"
class="block w-full rounded-md border-gray-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500 font-mono"
placeholder="UUID des Makros"
data-testid="namenseinblender-macro"
@change="updateSetting('namenseinblender_macro_uuid', $event.target.value)"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Collection-Name</label>
<input
type="text"
:value="settings.namenseinblender_macro_collection_name || '--MAIN--'"
class="block w-full rounded-md border-gray-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500"
placeholder="--MAIN--"
@change="updateSetting('namenseinblender_macro_collection_name', $event.target.value)"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Collection-UUID</label>
<input
type="text"
:value="settings.namenseinblender_macro_collection_uuid || ''"
class="block w-full rounded-md border-gray-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500 font-mono"
placeholder="UUID der Collection"
@change="updateSetting('namenseinblender_macro_collection_uuid', $event.target.value)"
/>
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -70,6 +70,7 @@
Route::get('/services/{service}/edit', [ServiceController::class, 'edit'])->name('services.edit');
Route::post('/services/{service}/key-visual', [ServiceImageController::class, 'storeKeyVisual'])->name('services.key-visual.store');
Route::post('/services/{service}/background', [ServiceImageController::class, 'storeBackground'])->name('services.background.store');
Route::patch('/services/{service}/name-overrides', [ServiceController::class, 'updateNameOverrides'])->name('services.name-overrides.update');
Route::get('/songs/{song}/translate', [TranslationController::class, 'page'])->name('songs.translate');
Route::get('/songs', function () {