159 lines
6.9 KiB
PHP
159 lines
6.9 KiB
PHP
<?php
|
||
|
||
namespace App\Filament\Resources\InviteLayouts\Schemas;
|
||
|
||
use Filament\Forms\Components\ColorPicker;
|
||
use Filament\Forms\Components\Repeater;
|
||
use Filament\Forms\Components\Select;
|
||
use Filament\Forms\Components\Textarea;
|
||
use Filament\Forms\Components\TextInput;
|
||
use Filament\Forms\Components\Toggle;
|
||
use Filament\Schemas\Schema;
|
||
use Filament\Schemas\Components\Section;
|
||
use Illuminate\Support\Str;
|
||
|
||
class InviteLayoutForm
|
||
{
|
||
public static function configure(Schema $schema): Schema
|
||
{
|
||
return $schema->schema([
|
||
Section::make('Grunddaten')
|
||
->columns(2)
|
||
->schema([
|
||
TextInput::make('name')
|
||
->label('Name')
|
||
->required()
|
||
->maxLength(255)
|
||
->afterStateUpdated(fn (callable $set, $state) => $set('slug', Str::slug((string) $state ?? '')))
|
||
->reactive(),
|
||
TextInput::make('slug')
|
||
->label('Slug')
|
||
->required()
|
||
->maxLength(191)
|
||
->unique(ignoreRecord: true),
|
||
TextInput::make('subtitle')
|
||
->label('Unterzeile')
|
||
->maxLength(255)
|
||
->columnSpanFull(),
|
||
Textarea::make('description')
|
||
->label('Beschreibung')
|
||
->rows(4)
|
||
->columnSpanFull(),
|
||
Toggle::make('is_active')
|
||
->label('Aktiv')
|
||
->default(true),
|
||
]),
|
||
|
||
Section::make('Papier & Format')
|
||
->columns(3)
|
||
->schema([
|
||
Select::make('paper')
|
||
->label('Papierformat')
|
||
->options([
|
||
'a4' => 'A4 (210 × 297 mm)',
|
||
'a5' => 'A5 (148 × 210 mm)',
|
||
'a3' => 'A3 (297 × 420 mm)',
|
||
'custom' => 'Benutzerdefiniert',
|
||
])
|
||
->default('a4'),
|
||
Select::make('orientation')
|
||
->label('Ausrichtung')
|
||
->options([
|
||
'portrait' => 'Hochformat',
|
||
'landscape' => 'Querformat',
|
||
])
|
||
->default('portrait'),
|
||
TextInput::make('layout_options.formats')
|
||
->label('Formate (Komma getrennt)')
|
||
->default('pdf,svg')
|
||
->helperText('Bestimmt, welche Downloads angeboten werden.')
|
||
->dehydrateStateUsing(fn ($state) => collect(explode(',', (string) $state))
|
||
->map(fn ($value) => trim((string) $value))
|
||
->filter()
|
||
->values()
|
||
->all())
|
||
->afterStateHydrated(function (TextInput $component, $state) {
|
||
if (is_array($state)) {
|
||
$component->state(implode(',', $state));
|
||
}
|
||
}),
|
||
]),
|
||
|
||
Section::make('Farben')
|
||
->columns(5)
|
||
->schema([
|
||
ColorPicker::make('preview.background')
|
||
->label('Hintergrund')
|
||
->default('#F9FAFB'),
|
||
ColorPicker::make('preview.accent')
|
||
->label('Akzent')
|
||
->default('#6366F1'),
|
||
ColorPicker::make('preview.text')
|
||
->label('Text')
|
||
->default('#0F172A'),
|
||
ColorPicker::make('preview.secondary')
|
||
->label('Sekundär')
|
||
->default('#CBD5F5'),
|
||
ColorPicker::make('preview.badge')
|
||
->label('Badge')
|
||
->default('#2563EB'),
|
||
TextInput::make('preview.qr.size_px')
|
||
->label('QR-Größe (px)')
|
||
->numeric()
|
||
->default(320)
|
||
->columnSpan(2),
|
||
TextInput::make('preview.svg.width')
|
||
->label('SVG Breite')
|
||
->numeric()
|
||
->default(1080),
|
||
TextInput::make('preview.svg.height')
|
||
->label('SVG Höhe')
|
||
->numeric()
|
||
->default(1520),
|
||
]),
|
||
|
||
Section::make('Texte & Hinweise')
|
||
->columns(2)
|
||
->schema([
|
||
TextInput::make('layout_options.badge_label')
|
||
->label('Badge-Label')
|
||
->default('Digitale Gästebox'),
|
||
TextInput::make('layout_options.instructions_heading')
|
||
->label('Anleitungstitel')
|
||
->default("So funktioniert's"),
|
||
TextInput::make('layout_options.link_heading')
|
||
->label('Link-Titel')
|
||
->default('Alternative zum Einscannen'),
|
||
TextInput::make('layout_options.cta_label')
|
||
->label('CTA Label')
|
||
->default('Scan mich & starte direkt'),
|
||
TextInput::make('layout_options.cta_caption')
|
||
->label('CTA Untertitel')
|
||
->default('Scan mich & starte direkt'),
|
||
TextInput::make('layout_options.link_label')
|
||
->label('Link Text (optional)')
|
||
->helperText('Überschreibt den standardmäßigen Einladungslink.'),
|
||
TextInput::make('layout_options.logo_url')
|
||
->label('Logo URL')
|
||
->columnSpanFull(),
|
||
Repeater::make('instructions')
|
||
->label('Hinweise')
|
||
->maxItems(6)
|
||
->schema([
|
||
Textarea::make('value')
|
||
->label('Hinweistext')
|
||
->rows(2)
|
||
->required()
|
||
->maxLength(180),
|
||
])
|
||
->afterStateHydrated(function (Repeater $component, $state): void {
|
||
if (is_array($state) && ! empty($state) && ! is_array(current($state))) {
|
||
$component->state(array_map(fn ($value) => ['value' => $value], $state));
|
||
}
|
||
})
|
||
->dehydrateStateUsing(fn ($state) => collect($state)->pluck('value')->filter()->values()->all()),
|
||
]),
|
||
]);
|
||
}
|
||
}
|