Preview — /tmp/goseek-ai-provider-key-save-backup-20260529-101145/app/Filament/Resources/AiProviderResource.php

/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'),
        ];
    }
}