105 lines
3.3 KiB
PHP
105 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Admin;
|
|
|
|
use App\Models\MailTemplate;
|
|
use App\Services\Mail\MailTemplateRenderer;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Attributes\Validate;
|
|
use Livewire\Component;
|
|
|
|
/**
|
|
* The answers an operator gives over and over, written once.
|
|
*
|
|
* Most customer questions are the same five questions, and typing the answer
|
|
* again every time is how two customers get told two different things about the
|
|
* same subject.
|
|
*
|
|
* A template is not sent from here and never sent by itself: it is inserted into
|
|
* the compose field on a customer's page, placeholders already filled from that
|
|
* customer's record, and the last two sentences are still the operator's to
|
|
* write. What goes out is what they saw and edited.
|
|
*
|
|
* Creating happens in the form on this page — R20 exempts a create form that IS
|
|
* the page. Editing happens in a modal (Admin\EditMailTemplate), because a
|
|
* textarea growing inside a table row is the row-height jump R20 exists to stop.
|
|
*/
|
|
#[Layout('layouts.admin')]
|
|
class MailTemplates extends Component
|
|
{
|
|
#[Validate('required|string|max:255')]
|
|
public string $name = '';
|
|
|
|
#[Validate('required|string|max:255')]
|
|
public string $subject = '';
|
|
|
|
#[Validate('required|string|max:5000')]
|
|
public string $body = '';
|
|
|
|
public function mount(): void
|
|
{
|
|
$this->authorize('customers.manage');
|
|
}
|
|
|
|
public function create(): void
|
|
{
|
|
$this->authorize('customers.manage');
|
|
|
|
$data = $this->validate();
|
|
|
|
MailTemplate::create([
|
|
'name' => trim($data['name']),
|
|
'subject' => trim($data['subject']),
|
|
'body' => $data['body'],
|
|
// At the end of the list, where a new one belongs until somebody
|
|
// decides otherwise.
|
|
'sort' => (int) MailTemplate::query()->max('sort') + 10,
|
|
'active' => true,
|
|
]);
|
|
|
|
$this->reset(['name', 'subject', 'body']);
|
|
$this->dispatch('notify', message: __('templates.created'));
|
|
}
|
|
|
|
/**
|
|
* Retire one, or bring it back.
|
|
*
|
|
* Not deleted: an answer that is no longer given is still the answer
|
|
* somebody was given last year, and the register of sent mail refers to it.
|
|
*/
|
|
public function toggleActive(string $uuid): void
|
|
{
|
|
$this->authorize('customers.manage');
|
|
|
|
$template = MailTemplate::query()->where('uuid', $uuid)->first();
|
|
|
|
if ($template !== null) {
|
|
$template->update(['active' => ! $template->active]);
|
|
}
|
|
}
|
|
|
|
/** Move one up or down the list an operator picks from. */
|
|
public function move(string $uuid, int $by): void
|
|
{
|
|
$this->authorize('customers.manage');
|
|
|
|
$template = MailTemplate::query()->where('uuid', $uuid)->first();
|
|
|
|
if ($template !== null) {
|
|
$template->update(['sort' => max(0, $template->sort + $by)]);
|
|
}
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$this->authorize('customers.manage');
|
|
|
|
return view('livewire.admin.mail-templates', [
|
|
'templates' => MailTemplate::query()->orderBy('sort')->orderBy('name')->get(),
|
|
// The list IS the documentation: a token added to the renderer
|
|
// appears here without anybody remembering to write it down twice.
|
|
'placeholders' => MailTemplateRenderer::PLACEHOLDERS,
|
|
]);
|
|
}
|
|
}
|