Die Bereiche der FAQ-Seite lagen als verschachtelte Listen in sections, der Editor zeigte davon nur JSON-Text. Jetzt stehen alle Fragen in questions mit dem Feld category, Überschrift und Symbol der Bereiche in categories. FAQ::groups baut daraus die Seite (allgemeine Fragen zuerst), alte Einträge werden weiter dargestellt. FaqCategoriesSeeder stellt gespeicherte Einträge um (FAQ und Immobilien-FAQ), Texte bleiben. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
3.5 KiB
PHP
103 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Web\Components\Sections;
|
|
|
|
use Livewire\Component;
|
|
|
|
class FAQ extends Component
|
|
{
|
|
public $content = [];
|
|
|
|
public $bg = '';
|
|
|
|
public $section = '';
|
|
|
|
public function mount($bg = 'bg-background', $section = 'faq')
|
|
{
|
|
$this->bg = $bg;
|
|
$this->section = $section;
|
|
|
|
$this->content = cms_theme_section($this->section);
|
|
}
|
|
|
|
/**
|
|
* Fragen nach Bereich gruppiert, in Seitenreihenfolge: zuerst die allgemeinen Fragen ohne
|
|
* Bereich, dann die Bereiche aus `categories` (Überschrift + Symbol), zuletzt Bereiche, die nur
|
|
* an Fragen stehen. Leere Bereiche entfallen.
|
|
*
|
|
* @param array<string, mixed> $content
|
|
* @return list<array{title: ?string, icon: ?string, questions: list<array<string, mixed>>}>
|
|
*/
|
|
public static function groups(array $content): array
|
|
{
|
|
$content = self::flatten($content);
|
|
$groups = ['' => ['title' => null, 'icon' => null, 'questions' => []]];
|
|
|
|
foreach ($content['categories'] ?? [] as $category) {
|
|
$title = trim((string) ($category['title'] ?? ''));
|
|
|
|
if ($title !== '') {
|
|
$groups[$title] = ['title' => $title, 'icon' => ($category['icon'] ?? '') ?: 'question-mark-circle', 'questions' => []];
|
|
}
|
|
}
|
|
|
|
foreach ($content['questions'] ?? [] as $question) {
|
|
if (! is_array($question) || trim((string) ($question['question'] ?? '')) === '') {
|
|
continue;
|
|
}
|
|
|
|
$title = trim((string) ($question['category'] ?? ''));
|
|
$groups[$title] ??= ['title' => $title, 'icon' => 'question-mark-circle', 'questions' => []];
|
|
$groups[$title]['questions'][] = $question;
|
|
}
|
|
|
|
return array_values(array_filter($groups, fn (array $group): bool => $group['questions'] !== []));
|
|
}
|
|
|
|
/**
|
|
* Wandelt die frühere Form mit verschachtelten `sections` (Bereich mit eigener Fragenliste) in
|
|
* die flache Form um, die der Inhalte-Editor bearbeiten kann (09.10.2026): jede Frage trägt
|
|
* ihren Bereich in `category`, Überschrift und Symbol stehen in `categories`.
|
|
*
|
|
* @param array<string, mixed> $content
|
|
* @return array<string, mixed>
|
|
*/
|
|
public static function flatten(array $content): array
|
|
{
|
|
if (! isset($content['sections']) || ! is_array($content['sections'])) {
|
|
return $content;
|
|
}
|
|
|
|
$questions = array_map(
|
|
fn (mixed $question): mixed => is_array($question) ? [...$question, 'category' => $question['category'] ?? ''] : $question,
|
|
is_array($content['questions'] ?? null) ? $content['questions'] : [],
|
|
);
|
|
$categories = is_array($content['categories'] ?? null) ? $content['categories'] : [];
|
|
|
|
foreach ($content['sections'] as $section) {
|
|
if (! is_array($section)) {
|
|
continue;
|
|
}
|
|
|
|
$title = trim((string) ($section['title'] ?? ''));
|
|
$categories[] = ['title' => $title, 'icon' => (string) ($section['icon'] ?? '')];
|
|
|
|
foreach ($section['questions'] ?? [] as $question) {
|
|
if (is_array($question)) {
|
|
$questions[] = [...$question, 'category' => $title];
|
|
}
|
|
}
|
|
}
|
|
|
|
unset($content['sections']);
|
|
$content['questions'] = $questions;
|
|
$content['categories'] = $categories;
|
|
|
|
return $content;
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.web.components.sections.f-a-q', ['groups' => self::groups($this->content)]);
|
|
}
|
|
}
|