columns([ TextColumn::make('forecast_for') ->label('Forecast for') ->date('d M Y') ->sortable(), TextColumn::make('direction') ->badge() ->color(fn (string $state) => match ($state) { 'rising' => 'warning', 'falling' => 'success', default => 'gray', }), TextColumn::make('magnitude_pence') ->label('Magnitude') ->state(fn (WeeklyForecast $record): string => self::formatMagnitude($record->magnitude_pence)) ->sortable(), TextColumn::make('ridge_confidence') ->label('Confidence') ->state(fn (WeeklyForecast $record): string => $record->ridge_confidence.'%') ->color(fn (WeeklyForecast $record) => $record->ridge_confidence < 40 ? 'warning' : null) ->sortable(), IconColumn::make('flagged_duty_change') ->label('Duty change') ->boolean() ->trueColor('warning'), TextColumn::make('model_version') ->searchable() ->limit(32) ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('generated_at') ->dateTime('d M Y H:i') ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->defaultSort('forecast_for', 'desc') ->filters([ SelectFilter::make('direction') ->multiple() ->options([ 'rising' => 'Rising', 'falling' => 'Falling', 'flat' => 'Flat', ]), Filter::make('high_confidence') ->label('High confidence') ->toggle() ->query(fn (Builder $query) => $query->where('ridge_confidence', '>=', 70)), Filter::make('flagged_duty_change') ->label('Duty-change-adjacent') ->toggle() ->query(fn (Builder $query) => $query->where('flagged_duty_change', true)), ]) ->recordActions([ ViewAction::make(), ]); } protected static function formatMagnitude(?int $magnitudePence): string { if ($magnitudePence === null) { return '—'; } $pence = round($magnitudePence / 100, 1); $sign = $pence > 0 ? '+' : ''; return $sign.$pence.'p'; } }