CluPilotCloud/resources/views/livewire/admin/mail-templates.blade.php

111 lines
7.1 KiB
PHP

<div class="mx-auto max-w-[1120px] space-y-5">
<div class="animate-rise">
<h1 class="text-2xl font-bold tracking-tight text-ink">{{ __('templates.title') }}</h1>
<p class="mt-1 max-w-[75ch] text-sm text-muted">{{ __('templates.subtitle') }}</p>
</div>
<div class="grid gap-5 lg:grid-cols-[1fr_320px] lg:items-start">
<div class="space-y-5">
{{-- The list. Order is the operator's own, because the order they
think in is neither alphabetical nor the order these happened to
be written in. --}}
<div class="overflow-hidden rounded-lg border border-line bg-surface shadow-xs animate-rise">
<h2 class="border-b border-line px-6 py-4 font-semibold text-ink">{{ __('templates.list') }}</h2>
@if ($templates->isEmpty())
<p class="p-8 text-center text-sm text-muted">{{ __('templates.empty') }}</p>
@else
<ul class="divide-y divide-line">
@foreach ($templates as $template)
<li wire:key="tpl-{{ $template->uuid }}" class="px-6 py-4">
<div class="flex flex-wrap items-baseline gap-x-3 gap-y-1">
<span @class(['font-medium', 'text-ink' => $template->active, 'text-muted line-through' => ! $template->active])>
{{ $template->name }}
</span>
@if (! $template->active)
<x-ui.badge status="warning">{{ __('templates.retired') }}</x-ui.badge>
@endif
<span class="ml-auto flex items-center gap-1">
{{-- Two clicks, one value each, no height
change: R20's exception. --}}
<button type="button" wire:click="move('{{ $template->uuid }}', -15)"
class="rounded p-1.5 text-muted hover:text-ink" aria-label="{{ __('templates.up') }}">
<x-ui.icon name="chevron-down" class="size-4 rotate-180" />
</button>
<button type="button" wire:click="move('{{ $template->uuid }}', 15)"
class="rounded p-1.5 text-muted hover:text-ink" aria-label="{{ __('templates.down') }}">
<x-ui.icon name="chevron-down" class="size-4" />
</button>
</span>
</div>
<p class="mt-1 text-sm text-body">{{ $template->subject }}</p>
<p class="mt-1.5 line-clamp-2 text-xs leading-relaxed text-muted">{{ $template->body }}</p>
<div class="mt-3 flex flex-wrap gap-2">
{{-- R20: editing opens a modal. A five-line
textarea in a list row is the height jump
the rule exists to stop. --}}
<x-ui.button variant="secondary" size="sm"
x-on:click="$dispatch('openModal', { component: 'admin.edit-mail-template', arguments: { uuid: '{{ $template->uuid }}' } })">
<x-ui.icon name="pencil" class="size-4" />{{ __('templates.edit') }}
</x-ui.button>
<x-ui.button variant="ghost" size="sm" wire:click="toggleActive('{{ $template->uuid }}')">
{{ $template->active ? __('templates.retire') : __('templates.restore') }}
</x-ui.button>
</div>
</li>
@endforeach
</ul>
@endif
</div>
{{-- Creating. A form that IS the page rather than a modal R20
exempts exactly this, because nothing is being edited in place. --}}
<form wire:submit="create" class="space-y-4 rounded-lg border border-line bg-surface p-6 shadow-xs animate-rise [animation-delay:60ms]">
<h2 class="font-semibold text-ink">{{ __('templates.new') }}</h2>
<div class="grid gap-4 sm:grid-cols-2">
<x-ui.input name="name" wire:model="name" :label="__('templates.name')" :placeholder="__('templates.name_hint')" />
<x-ui.input name="subject" wire:model="subject" :label="__('templates.subject')" :placeholder="__('templates.subject_hint')" />
</div>
<div>
<label for="body" class="block text-sm font-medium text-body">{{ __('templates.body') }}</label>
<textarea id="body" rows="8" wire:model="body"
class="mt-1.5 block w-full rounded border border-line bg-surface px-3.5 py-2.5 text-sm text-ink placeholder:text-faint"
placeholder="{{ __('templates.body_hint') }}"></textarea>
@error('body')<p class="mt-1.5 text-xs text-danger">{{ $message }}</p>@enderror
</div>
<x-ui.button type="submit" variant="primary" wire:loading.attr="disabled" wire:target="create">
<x-ui.icon name="plus" class="size-4" />{{ __('templates.create') }}
</x-ui.button>
</form>
</div>
{{-- The placeholders, rendered from the renderer's own list so a token
added there appears here without anybody writing it down twice. --}}
<div class="space-y-4 rounded-lg border border-line bg-surface p-6 shadow-xs animate-rise [animation-delay:120ms] lg:sticky lg:top-6">
<h2 class="font-semibold text-ink">{{ __('templates.placeholders') }}</h2>
<p class="text-xs leading-relaxed text-muted">{{ __('templates.placeholders_note') }}</p>
<dl class="space-y-3">
@foreach ($placeholders as $token => $explanation)
{{-- Assembled in PHP, not inline: Blade's echo tag ends at
the first }} it finds, so a literal one inside the
expression cuts the tag in half and compiles to
nonsense. Caught by the test that renders this page. --}}
@php $literal = '{{'.$token.'}}'; @endphp
<div>
<dt class="select-all font-mono text-xs font-semibold text-accent-text">{{ $literal }}</dt>
<dd class="mt-0.5 text-xs leading-relaxed text-muted">{{ __($explanation) }}</dd>
</div>
@endforeach
</dl>
<p class="border-t border-line pt-3 text-xs leading-relaxed text-muted">{{ __('templates.unknown_note') }}</p>
</div>
</div>
</div>