/tmp/goseek-ai-provider-key-save-backup-20260529-101145/app/Filament/Resources/AiProviderResource.php
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\AiProviderResource\Pages;
use App\Models\AiProvider;
use Filament\Schemas\Schema;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\TextInput;
use Filament\Schemas\Components\Select;
use Filament\Schemas\Components\Toggle;
use Filament\Schemas\Components\Textarea;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\IconColumn;
class AiProviderResource extends Resource
{
protected static ?string $model = AiProvider::class;
protected static ?string $navigationLabel = 'AI Providers';
protected static ?int $navigationSort = 2;
public static function getNavigationIcon(): string|\BackedEnum|null
{
return 'heroicon-o-cpu-chip';
}
public static function form(Schema $schema): Schema
{
return $schema->components([
Section::make('Provider Details')->schema([
TextInput::make('name')->required()->maxLength(100),
TextInput::make('slug')->required()->maxLength(50)
->helperText('Unique identifier e.g. anthropic, openai, groq'),
Select::make('type')
->options(['cloud' => 'Cloud API', 'local' => 'Local/Self-hosted'])
->required(),
TextInput::make('base_url')->maxLength(255)
->helperText('API base URL e.g. https://api.anthropic.com'),
Select::make('privacy_tier')
->options([
'1' => 'Tier 1 — On-premise',
'2' => 'Tier 2 — Private API',
'3' => 'Tier 3 — Shared API',
])->required()->default('2'),
Toggle::make('enabled')->label('Enabled'),
Toggle::make('is_local')->label('Local provider'),
TextInput::make('sort_order')->numeric()->default(0),
])->columns(2),
Section::make('API Key')->schema([
TextInput: [REDACTED]
->label('API Key')
[REDACTED SECRET-LIKE LINE]
->helperText('Leave blank to keep existing key. Stored encrypted.')
->dehydrated(false),
]),
Section::make('Available Models')->schema([
Textarea::make('models_json')
->label('Models (JSON)')
->helperText('JSON array: [{"id":"model-id","name":"Display Name"}]')
->rows(6)->dehydrated(false),
]),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('name')->searchable()->sortable(),
TextColumn::make('slug')->badge()->color('gray'),
TextColumn::make('type')->badge()
->color(fn($state) => $state === 'local' ? 'success' : 'info'),
TextColumn::make('privacy_tier')->badge()
->formatStateUsing(fn($state) => "Tier $state")
->color(fn($state) => match($state) { '1' => 'success', '2' => 'info', default => 'warning' }),
IconColumn::make('enabled')->boolean(),
TextColumn::make('sort_order')->sortable(),
])
->defaultSort('sort_order')
->recordUrl(fn($record) => static::getUrl('edit', ['record' => $record]));
}
public static function getPages(): array
{
return [
'index' => Pages\ListAiProviders::route('/'),
'create' => Pages\CreateAiProvider::route('/create'),
'edit' => Pages\EditAiProvider::route('/{record}/edit'),
];
}
}