schema([ Forms\Components\Section::make('Group Information') ->schema([ Forms\Components\TextInput::make('title') ->label('Title (e.g., 2023-2024)') ->required() ->maxLength(255), Forms\Components\Textarea::make('subtitle') ->label('Subtitle') ->rows(2) ->columnSpanFull(), Forms\Components\Grid::make(3) ->schema([ Forms\Components\TextInput::make('sort') ->label('Sort Order') ->required() ->numeric() ->default(999) ->minValue(0), Forms\Components\Select::make('status') ->label('Status') ->required() ->options([ 'draft' => 'Draft', 'publish' => 'Publish', ]) ->default('publish'), Forms\Components\DateTimePicker::make('published_at') ->label('Publish Date') ->placeholder('Leave empty for immediate publish'), ]), ]) ->columns(1), Forms\Components\Section::make('Years') ->schema([ Forms\Components\Repeater::make('years') ->relationship() ->schema([ Forms\Components\Grid::make(4) ->schema([ Forms\Components\TextInput::make('year') ->label('Year') ->required() ->numeric() ->minValue(1900) ->maxValue(2100) ->unique( table: 'timeline_years', column: 'year', ignoreRecord: true, modifyRuleUsing: function ($rule, $get, $record) { $groupId = $get('../../id') ?? $record?->group_id ?? null; return $rule->where('group_id', $groupId); } ), Forms\Components\FileUpload::make('image') ->label('Image') ->image() ->directory('timeline') ->placeholder('Default: /images/img-timeline.png'), Forms\Components\TextInput::make('sort') ->label('Sort') ->required() ->numeric() ->default(999) ->minValue(0), Forms\Components\Select::make('status') ->label('Status') ->required() ->options([ 'draft' => 'Draft', 'publish' => 'Publish', ]) ->default('publish'), ]), Forms\Components\DateTimePicker::make('published_at') ->label('Publish Date') ->placeholder('Leave empty for immediate publish'), Forms\Components\Repeater::make('items') ->relationship() ->schema([ Forms\Components\Grid::make(3) ->schema([ Forms\Components\TextInput::make('title') ->label('Title') ->required() ->maxLength(255) ->columnSpan(2), Forms\Components\Select::make('type') ->label('Type') ->required() ->options([ 'aia' => 'AIA', 'ai' => 'AI', ]), ]), Forms\Components\Grid::make(2) ->schema([ Forms\Components\TextInput::make('sort') ->label('Sort') ->required() ->numeric() ->default(999) ->minValue(0), Forms\Components\Select::make('status') ->label('Status') ->required() ->options([ 'draft' => 'Draft', 'publish' => 'Publish', ]) ->default('publish'), ]), ]) ->label('Items (Stories)') ->defaultItems(0) ->collapsed() ->itemLabel(fn (array $state): ?string => $state['title'] ?? null) ->orderColumn('sort') ->reorderable(true) ->collapsible(), ]) ->label('Timeline Years') ->defaultItems(0) ->collapsed() ->itemLabel(fn (array $state): ?string => isset($state['year']) ? "Year {$state['year']}" : null) ->orderColumn('sort') ->reorderable(true) ->collapsible(), ]) ->columns(1), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('title') ->label('Title') ->searchable() ->sortable(), Tables\Columns\TextColumn::make('subtitle') ->label('Subtitle') ->limit(50) ->searchable() ->toggleable(), Tables\Columns\TextColumn::make('years_count') ->label('Years') ->counts('years') ->sortable(), Tables\Columns\TextColumn::make('sort') ->label('Sort') ->numeric() ->sortable(), Tables\Columns\BadgeColumn::make('status') ->label('Status') ->colors([ 'secondary' => 'draft', 'success' => 'publish', ]) ->sortable(), Tables\Columns\TextColumn::make('published_at') ->label('Publish Date') ->dateTime() ->sortable() ->toggleable(), Tables\Columns\TextColumn::make('updated_at') ->label('Updated At') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ Tables\Filters\SelectFilter::make('status') ->options([ 'draft' => 'Draft', 'publish' => 'Publish', ]), Tables\Filters\Filter::make('published_at') ->form([ Forms\Components\DatePicker::make('published_from') ->label('Published From'), Forms\Components\DatePicker::make('published_until') ->label('Published Until'), ]) ->query(function (Builder $query, array $data): Builder { return $query ->when( $data['published_from'], fn (Builder $query, $date): Builder => $query->whereDate('published_at', '>=', $date), ) ->when( $data['published_until'], fn (Builder $query, $date): Builder => $query->whereDate('published_at', '<=', $date), ); }), ]) ->actions([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ]) ->bulkActions([ // Bulk delete disabled as per spec ]) ->defaultSort('sort', 'asc'); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListTimelineGroups::route('/'), 'create' => Pages\CreateTimelineGroup::route('/create'), 'edit' => Pages\EditTimelineGroup::route('/{record}/edit'), ]; } }