83 lines
2.9 KiB
PHP
83 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Admin;
|
|
|
|
use App\Models\PlanFamily;
|
|
use App\Services\Billing\PlanCatalogue;
|
|
use LivewireUI\Modal\ModalComponent;
|
|
|
|
/**
|
|
* The marketing presentation of one plan line: who it is for, the sentence
|
|
* under its name on the price sheet, and whether it carries the
|
|
* "recommended" mark.
|
|
*
|
|
* These were a hardcoded array in LandingController, keyed on exactly four
|
|
* plan keys — a plan created under any other key rendered on the public page
|
|
* with no copy at all. They live on the family, not a version: a version is
|
|
* what gets published and superseded, but "who this is for" and "which one
|
|
* plan we point a visitor towards" are a stance about the product line, not a
|
|
* capability that changes with a price.
|
|
*/
|
|
class EditPlanFamily extends ModalComponent
|
|
{
|
|
public string $uuid = '';
|
|
|
|
public string $audience = '';
|
|
|
|
public string $note = '';
|
|
|
|
public bool $recommended = false;
|
|
|
|
public function mount(string $uuid): void
|
|
{
|
|
$this->authorize('plans.manage'); // modals bypass the route middleware
|
|
|
|
$family = PlanFamily::query()->where('uuid', $uuid)->firstOrFail();
|
|
$this->uuid = $uuid;
|
|
$this->audience = (string) $family->audience;
|
|
$this->note = (string) $family->note;
|
|
$this->recommended = (bool) $family->is_recommended;
|
|
}
|
|
|
|
public function save()
|
|
{
|
|
$this->authorize('plans.manage');
|
|
|
|
$data = $this->validate([
|
|
'audience' => 'nullable|string|max:255',
|
|
'note' => 'nullable|string|max:500',
|
|
'recommended' => 'boolean',
|
|
]);
|
|
|
|
$family = PlanFamily::query()->where('uuid', $this->uuid)->firstOrFail();
|
|
|
|
PlanFamily::query()->whereKey($family->getKey())->update([
|
|
'audience' => $data['audience'] !== '' ? $data['audience'] : null,
|
|
'note' => $data['note'] !== '' ? $data['note'] : null,
|
|
]);
|
|
|
|
// The singular invariant — only one family recommended at a time —
|
|
// lives in the catalogue service, not here: two operators recommending
|
|
// two different plans at the same moment must not both win.
|
|
if ($data['recommended']) {
|
|
app(PlanCatalogue::class)->recommend($family);
|
|
} elseif ($family->is_recommended) {
|
|
PlanFamily::query()->whereKey($family->getKey())->update(['is_recommended' => false]);
|
|
}
|
|
|
|
$this->dispatch('notify', message: __('plans.marketing_saved'));
|
|
|
|
return $this->redirectRoute('admin.plans', navigate: true);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.admin.edit-plan-family', [
|
|
// Read again rather than from the mounted properties: the header
|
|
// shows the plan's name, and that can change under an operator's
|
|
// own hands while a second tab has this modal open.
|
|
'family' => PlanFamily::query()->where('uuid', $this->uuid)->firstOrFail(),
|
|
]);
|
|
}
|
|
}
|