schema([ SchemaTabs::make('Übersetzungen') ->tabs([ SchemaTab::make('Deutsch') ->schema([ TextInput::make('title.de') ->label('Titel') ->required() ->maxLength(255) ->live() ->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) { if (($get('slug') ?? '') !== Str::slug($state)) { return; } $set('slug', Str::slug($state)); }), MarkdownEditor::make('content.de') ->label('Inhalt') ->required() ->columnSpanFull(), TextInput::make('excerpt.de') ->label('Auszug') ->maxLength(255), TextInput::make('meta_title.de') ->label('Meta-Titel') ->maxLength(255), Textarea::make('meta_description.de') ->label('Meta-Beschreibung') ->maxLength(65535) ->columnSpanFull(), ]) ->columns(2), SchemaTab::make('Englisch') ->schema([ TextInput::make('title.en') ->label('Titel') ->maxLength(255), MarkdownEditor::make('content.en') ->label('Inhalt') ->columnSpanFull(), TextInput::make('excerpt.en') ->label('Auszug') ->maxLength(255), TextInput::make('meta_title.en') ->label('Meta-Titel') ->maxLength(255), Textarea::make('meta_description.en') ->label('Meta-Beschreibung') ->maxLength(65535) ->columnSpanFull(), ]) ->columns(2), ]) ->columnSpanFull(), Section::make('Bild und Kategorie') ->schema([ TextInput::make('slug') ->label('Slug') ->required() ->unique(BlogPost::class, 'slug', ignoreRecord: true) ->maxLength(255) ->columnSpanFull(), FileUpload::make('featured_image') ->label('Featured Image') ->image() ->directory('blog') ->visibility('public'), Select::make('blog_category_id') ->label('Kategorie') ->options(fn () => BlogCategory::query() ->orderBy('slug') ->get() ->mapWithKeys(fn (BlogCategory $category) => [ $category->getKey() => $category->name['de'] ?? $category->name['en'] ?? $category->slug, ])->toArray()) ->searchable() ->required() ->preload() ->createOptionForm([ TextInput::make('name_de') ->label('Name (DE)') ->required() ->maxLength(255) ->afterStateUpdated(fn (Set $set, $state) => $set('name_en', $state)), TextInput::make('name_en') ->label('Name (EN)') ->maxLength(255), TextInput::make('slug') ->label('Slug') ->required() ->unique(\App\Models\BlogCategory::class, 'slug', ignoreRecord: true) ->maxLength(255), ]) ->createOptionUsing(function (array $data) { $nameDe = $data['name_de'] ?? null; $nameEn = $data['name_en'] ?? null; $category = BlogCategory::create([ 'slug' => $data['slug'], 'is_visible' => true, 'name' => [ 'de' => $nameDe ?: ($nameEn ?: $data['slug']), 'en' => $nameEn ?: ($nameDe ?: $data['slug']), ], 'description' => null, ]); return $category->getKey(); }), ]) ->columns(2), Section::make('Veröffentlichung') ->schema([ Toggle::make('is_published') ->label('Veröffentlicht'), DateTimePicker::make('published_at') ->label('Veröffentlicht am') ->displayFormat('Y-m-d H:i:s') ->default(now()), ]), ]); } public static function mutateFormDataBeforeCreate(array $data): array { return $data; } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('title') ->label('Titel (DE)') ->getStateUsing(fn ($record) => $record->getTranslation('title', 'de')) ->searchable() ->limit(50) ->url(fn ($record) => static::getUrl('edit', ['record' => $record])) ->sortable(), TextColumn::make('category_label') ->label('Kategorie') ->badge() ->getStateUsing(function ($record) { $raw = $record->category?->name ?? null; if (is_string($raw) && $raw !== '') { $decoded = json_decode($raw, true); if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) { $raw = $decoded; } } if (is_array($raw)) { return $raw['de'] ?? $raw['en'] ?? '—'; } if (is_string($raw) && $raw !== '') { return $raw; } return '—'; }) ->color('primary'), IconColumn::make('is_published') ->label('Veröffentlicht') ->boolean() ->trueIcon('heroicon-o-check-circle') ->falseIcon('heroicon-o-x-circle'), TextColumn::make('published_at') ->label('Veröffentlichungsdatum') ->icon('heroicon-o-calendar') ->dateTime('d.m.Y H:i') ->sortable(), TextColumn::make('created_at') ->label('Erstellt am') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ TernaryFilter::make('is_published') ->label('Veröffentlicht'), ]) ->actions([ DeleteAction::make() ->icon('heroicon-o-trash') ->label(''), ]) ->bulkActions([ BulkActionGroup::make([ DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListPosts::route('/'), 'create' => Pages\CreatePost::route('/create'), 'view' => Pages\ViewPost::route('/{record}'), 'edit' => Pages\EditPost::route('/{record}/edit'), ]; } public static function getEloquentQuery(): Builder { return parent::getEloquentQuery() ->withoutGlobalScopes([ SoftDeletingScope::class, ]); } }