components([ Schemas\Components\Section::make(__('Identificare')) ->columns(2) ->schema([ Forms\Components\TextInput::make('slug') ->required() ->alphaDash() ->maxLength(30) ->unique( ignoreRecord: true, modifyRuleUsing: fn ($rule) => $rule->whereNull('deleted_at'), ) ->dehydrateStateUsing(fn ($state) => strtolower((string) $state)) ->extraInputAttributes(['style' => 'text-transform: lowercase']) ->helperText(__('Subdomeniul: .service.mir.md')), Forms\Components\TextInput::make('name')->required()->maxLength(120), Forms\Components\TextInput::make('display_name')->maxLength(120), Forms\Components\TextInput::make('city')->maxLength(60), ]), Schemas\Components\Section::make(__('Contact')) ->columns(2) ->schema([ Forms\Components\TextInput::make('contact_name')->maxLength(120), Forms\Components\TextInput::make('phone')->tel()->maxLength(40), Forms\Components\TextInput::make('email')->email()->maxLength(120), ]), Schemas\Components\Section::make(__('Abonament')) ->columns(2) ->schema([ Forms\Components\Select::make('status') ->options([ 'trial' => 'Trial', 'active' => 'Activ', 'expired' => 'Expirat', 'suspended' => 'Suspendat', 'archived' => 'Arhivat', ]) ->default('trial') ->required(), Forms\Components\Select::make('plan_id') ->label(__('Plan')) ->options(fn () => Plan::pluck('name', 'id')) ->searchable(), Forms\Components\DateTimePicker::make('trial_ends_at')->label(__('Trial expiră la')), Forms\Components\DateTimePicker::make('active_until')->label(__('Abonament până la')), Forms\Components\Toggle::make('is_demo') ->label(__('Tenant demo')) ->helperText(__('Marchează acest tenant ca demo (datele pot fi resetate periodic).')), ]), Schemas\Components\Section::make(__('Admin tenant (la creare)')) ->columns(2) ->visible(fn (string $operation) => $operation === 'create') ->schema([ Forms\Components\TextInput::make('admin_name') ->label(__('Nume admin')) ->default('Administrator'), Forms\Components\TextInput::make('admin_email') ->label(__('Email admin')) ->email() ->required(), Forms\Components\TextInput::make('admin_password') ->label(__('Parolă (lasă gol pentru auto-generat)')) ->password() ->minLength(8) ->helperText(__('Dacă e gol, generăm 10 caractere random.')), ]), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('id')->sortable(), Tables\Columns\TextColumn::make('slug') ->searchable() ->copyable() ->url(fn (Company $record) => $record->url('/app')) ->openUrlInNewTab(), Tables\Columns\TextColumn::make('name') ->searchable()->sortable() ->description(fn ($record) => $record->is_demo ? '🎬 demo' : null), Tables\Columns\TextColumn::make('status') ->badge() ->colors([ 'success' => ['active'], 'warning' => ['trial'], 'danger' => ['suspended', 'expired'], 'gray' => ['archived'], ]), Tables\Columns\TextColumn::make('plan.name')->label(__('Plan'))->placeholder('—'), Tables\Columns\TextColumn::make('city')->toggleable(), Tables\Columns\TextColumn::make('users_count')->counts('users')->label(__('Useri')), Tables\Columns\TextColumn::make('created_at')->date()->sortable(), ]) ->filters([ Tables\Filters\SelectFilter::make('status')->options([ 'trial' => 'Trial', 'active' => 'Activ', 'expired' => 'Expirat', 'suspended' => 'Suspendat', 'archived' => 'Arhivat', ]), ]) ->recordUrl(fn (Company $record) => CompanyResource::getUrl('view', ['record' => $record])) ->actions([ Actions\ViewAction::make() ->url(fn (Company $record) => CompanyResource::getUrl('view', ['record' => $record])), Actions\Action::make('open_tenant') ->label(__('Deschide')) ->icon('heroicon-m-arrow-top-right-on-square') ->color('primary') ->url(fn (Company $record) => $record->url('/app')) ->openUrlInNewTab(), Actions\Action::make('suspend') ->label(__('Suspendă')) ->icon('heroicon-m-no-symbol') ->color('danger') ->visible(fn (Company $record) => in_array($record->status, ['active', 'trial'])) ->requiresConfirmation() ->action(fn (Company $record) => app(\App\Services\CompanyProvisioner::class)->suspend($record)), Actions\Action::make('activate') ->label(__('Activează')) ->icon('heroicon-m-check-circle') ->color('success') ->visible(fn (Company $record) => in_array($record->status, ['suspended', 'expired'])) ->requiresConfirmation() ->action(fn (Company $record) => app(\App\Services\CompanyProvisioner::class)->reactivate($record)), Actions\EditAction::make(), Actions\DeleteAction::make(), ]) ->emptyStateHeading(__('Niciun tenant încă')) ->emptyStateDescription(__('Adaugă primul client SaaS folosind butonul „Adaugă companie" — se va crea un tenant nou cu admin pe `.service.mir.md/app`.')) ->emptyStateIcon('heroicon-o-building-office-2') ->defaultSort('created_at', 'desc'); } public static function getPages(): array { return [ 'index' => Pages\ListCompanies::route('/'), 'create' => Pages\CreateCompany::route('/create'), 'view' => Pages\ViewCompany::route('/{record}'), 'edit' => Pages\EditCompany::route('/{record}/edit'), ]; } }