Backend-WIP: Kontakt-Queue, Page-Cache, Validierungs-Feedback, i18n

Gebuendelt, da ueber gemeinsame lang-/Service-Dateien verschraenkt:
- Kontakt-Nachrichten: contact_messages-Tabelle + Model/Enums/Factory,
  Admin-Queue (livewire/admin/contact-messages), ContactController
  persistiert das Anliegen zusaetzlich zur Brand-Mail
- Page-Data-Cache (Services/Web/*PageData) + web-archive-Indizes auf
  press_releases
- Validierungs-Feedback + Company-Portal-Restriction (Feature-Tests)
- i18n-Auslagerung lang/de|en (auth, passwords, validation, static)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-09 15:38:11 +00:00
parent c6b5ec8479
commit fd8e050cb7
60 changed files with 3963 additions and 327 deletions

View file

@ -15,7 +15,8 @@ new #[Layout('components.layouts.app'), Title('Neue Firma')] class extends Compo
{
use WithFileUploads;
public string $portal = 'both';
#[Validate('required|in:'.Portal::Presseecho->value.','.Portal::Businessportal24->value)]
public string $portal = Portal::Presseecho->value;
#[Validate('required|min:3|max:255')]
public string $company_name = '';
@ -86,7 +87,7 @@ new #[Layout('components.layouts.app'), Title('Neue Firma')] class extends Compo
if ($this->logo) {
$stored = $imageService->storeCompanyLogo(
$this->logo,
$this->portal === Portal::Both->value ? Portal::Presseecho->value : $this->portal,
$this->portal,
$company->id,
);
@ -111,7 +112,13 @@ new #[Layout('components.layouts.app'), Title('Neue Firma')] class extends Compo
['code' => 'GB', 'name' => 'Großbritannien'],
['code' => 'US', 'name' => 'USA'],
]),
'portalOptions' => Portal::cases(),
// „Beide Portale" ist bei der Anlage nicht wählbar, damit neue
// Firmen ihre PMs nicht automatisch auf beiden Portalen
// veröffentlichen.
'portalOptions' => array_filter(
Portal::cases(),
fn (Portal $portalCase): bool => $portalCase !== Portal::Both,
),
];
}

View file

@ -4,6 +4,7 @@ use App\Enums\Portal;
use App\Models\Company;
use App\Services\Image\ImageService;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Validate;
@ -18,6 +19,12 @@ new #[Layout('components.layouts.app'), Title('Firma bearbeiten')] class extends
public string $portal = 'both';
/**
* Bestandsschutz: „Beide Portale" wird nur angeboten, wenn die Firma
* den Wert bereits trägt — neu zuweisen lässt er sich nicht mehr.
*/
public bool $allowBothPortal = false;
#[Validate('required|min:3|max:255')]
public string $company_name = '';
@ -78,6 +85,7 @@ new #[Layout('components.layouts.app'), Title('Firma bearbeiten')] class extends
}
$this->portal = $company->portal?->value ?? Portal::Both->value;
$this->allowBothPortal = $company->portal === Portal::Both || $company->portal === null;
$this->company_name = $company->name;
$this->description = '';
$this->email = $company->email ?? '';
@ -105,6 +113,18 @@ new #[Layout('components.layouts.app'), Title('Firma bearbeiten')] class extends
return;
}
$allowedPortals = [Portal::Presseecho->value, Portal::Businessportal24->value];
if ($company->portal === Portal::Both || $company->portal === null) {
$allowedPortals[] = Portal::Both->value;
}
if (! in_array($this->portal, $allowedPortals, true)) {
throw ValidationException::withMessages([
'portal' => __('„Beide Portale" kann nicht mehr neu zugewiesen werden.'),
]);
}
$slug = $company->generateUniqueSlug($this->company_name, ['portal' => $this->portal]);
$logoPath = $company->logo_path;
$logoVariants = $company->logo_variants;
@ -157,7 +177,10 @@ new #[Layout('components.layouts.app'), Title('Firma bearbeiten')] class extends
['code' => 'GB', 'name' => 'Großbritannien'],
['code' => 'US', 'name' => 'USA'],
]),
'portalOptions' => Portal::cases(),
'portalOptions' => array_filter(
Portal::cases(),
fn (Portal $portalCase): bool => $portalCase !== Portal::Both || $this->allowBothPortal,
),
];
}