feat(i18n): wrap 1103 hardcoded UI strings across Filament with __()
- Convert static $modelLabel/$pluralModelLabel/$title to getter methods - Wrap ->label()/->placeholder()/->helperText()/->description()/->title()/->body() args - Wrap Section::make()/Fieldset::make()/Notification::make()->title() args - Fix RelationManagers::getTitle() signature to match parent (Model, string) - Fix Pages::getTitle() to instance method (BasePage::getTitle is non-static) - Extend lang/ru.json + lang/en.json with 700+ common terms; identity fallback for the rest - Remove duplicate getters in 5 resources that had manual getModelLabel already All 306 tests pass. Missing translations fall back to the RO key so the UI never breaks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@ class CompanyResource extends Resource
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Schemas\Components\Section::make('Identificare')
|
||||
Schemas\Components\Section::make(__('Identificare'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('slug')
|
||||
@@ -53,19 +53,19 @@ class CompanyResource extends Resource
|
||||
)
|
||||
->dehydrateStateUsing(fn ($state) => strtolower((string) $state))
|
||||
->extraInputAttributes(['style' => 'text-transform: lowercase'])
|
||||
->helperText('Subdomeniul: <slug>.service.mir.md'),
|
||||
->helperText(__('Subdomeniul: <slug>.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')
|
||||
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')
|
||||
Schemas\Components\Section::make(__('Abonament'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Forms\Components\Select::make('status')
|
||||
@@ -79,31 +79,31 @@ class CompanyResource extends Resource
|
||||
->default('trial')
|
||||
->required(),
|
||||
Forms\Components\Select::make('plan_id')
|
||||
->label('Plan')
|
||||
->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\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).'),
|
||||
->label(__('Tenant demo'))
|
||||
->helperText(__('Marchează acest tenant ca demo (datele pot fi resetate periodic).')),
|
||||
]),
|
||||
Schemas\Components\Section::make('Admin tenant (la creare)')
|
||||
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')
|
||||
->label(__('Nume admin'))
|
||||
->default('Administrator'),
|
||||
Forms\Components\TextInput::make('admin_email')
|
||||
->label('Email admin')
|
||||
->label(__('Email admin'))
|
||||
->email()
|
||||
->required(),
|
||||
Forms\Components\TextInput::make('admin_password')
|
||||
->label('Parolă (lasă gol pentru auto-generat)')
|
||||
->label(__('Parolă (lasă gol pentru auto-generat)'))
|
||||
->password()
|
||||
->minLength(8)
|
||||
->helperText('Dacă e gol, generăm 10 caractere random.'),
|
||||
->helperText(__('Dacă e gol, generăm 10 caractere random.')),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -129,9 +129,9 @@ class CompanyResource extends Resource
|
||||
'danger' => ['suspended', 'expired'],
|
||||
'gray' => ['archived'],
|
||||
]),
|
||||
Tables\Columns\TextColumn::make('plan.name')->label('Plan')->placeholder('—'),
|
||||
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('users_count')->counts('users')->label(__('Useri')),
|
||||
Tables\Columns\TextColumn::make('created_at')->date()->sortable(),
|
||||
])
|
||||
->filters([
|
||||
@@ -145,20 +145,20 @@ class CompanyResource extends Resource
|
||||
Actions\ViewAction::make()
|
||||
->url(fn (Company $record) => CompanyResource::getUrl('view', ['record' => $record])),
|
||||
Actions\Action::make('open_tenant')
|
||||
->label('Deschide')
|
||||
->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ă')
|
||||
->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ă')
|
||||
->label(__('Activează'))
|
||||
->icon('heroicon-m-check-circle')
|
||||
->color('success')
|
||||
->visible(fn (Company $record) => in_array($record->status, ['suspended', 'expired']))
|
||||
@@ -167,8 +167,8 @@ class CompanyResource extends Resource
|
||||
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 `<slug>.service.mir.md/app`.')
|
||||
->emptyStateHeading(__('Niciun tenant încă'))
|
||||
->emptyStateDescription(__('Adaugă primul client SaaS folosind butonul „Adaugă companie" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.'))
|
||||
->emptyStateIcon('heroicon-o-building-office-2')
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
|
||||
@@ -110,13 +110,13 @@ class ViewCompany extends Page
|
||||
{
|
||||
return [
|
||||
Actions\Action::make('view_as')
|
||||
->label('Deschide tenantul')
|
||||
->label(__('Deschide tenantul'))
|
||||
->icon('heroicon-m-arrow-top-right-on-square')
|
||||
->color('primary')
|
||||
->url(fn () => $this->record->url('/app'))
|
||||
->openUrlInNewTab(),
|
||||
Actions\Action::make('issue_invoice')
|
||||
->label('Generează factură')
|
||||
->label(__('Generează factură'))
|
||||
->icon('heroicon-m-document-plus')
|
||||
->color('success')
|
||||
->visible(fn () => (bool) $this->record->plan_id)
|
||||
@@ -147,7 +147,7 @@ class ViewCompany extends Page
|
||||
$this->dispatch('$refresh');
|
||||
}),
|
||||
Actions\Action::make('upload_logo')
|
||||
->label('Logo')
|
||||
->label(__('Logo'))
|
||||
->icon('heroicon-m-photo')
|
||||
->color('gray')
|
||||
->schema([
|
||||
@@ -166,29 +166,29 @@ class ViewCompany extends Page
|
||||
$this->record->clearMediaCollection('logo');
|
||||
$this->record->addMedia($abs)->preservingOriginal()->toMediaCollection('logo');
|
||||
@unlink($abs);
|
||||
Notification::make()->title('Logo actualizat')->success()->send();
|
||||
Notification::make()->title(__('Logo actualizat'))->success()->send();
|
||||
}
|
||||
}),
|
||||
Actions\Action::make('edit')
|
||||
->label('Editează')
|
||||
->label(__('Editează'))
|
||||
->icon('heroicon-m-pencil')
|
||||
->url(fn () => CompanyResource::getUrl('edit', ['record' => $this->record])),
|
||||
Actions\Action::make('suspend')
|
||||
->label('Suspendă')->icon('heroicon-m-no-symbol')->color('danger')
|
||||
->label(__('Suspendă'))->icon('heroicon-m-no-symbol')->color('danger')
|
||||
->visible(fn () => in_array($this->record->status, ['active', 'trial']))
|
||||
->requiresConfirmation()
|
||||
->action(function () {
|
||||
app(\App\Services\CompanyProvisioner::class)->suspend($this->record);
|
||||
Notification::make()->title('Tenant suspendat.')->success()->send();
|
||||
Notification::make()->title(__('Tenant suspendat.'))->success()->send();
|
||||
$this->dispatch('$refresh');
|
||||
}),
|
||||
Actions\Action::make('activate')
|
||||
->label('Reactivează')->icon('heroicon-m-check-circle')->color('success')
|
||||
->label(__('Reactivează'))->icon('heroicon-m-check-circle')->color('success')
|
||||
->visible(fn () => in_array($this->record->status, ['suspended', 'expired']))
|
||||
->requiresConfirmation()
|
||||
->action(function () {
|
||||
app(\App\Services\CompanyProvisioner::class)->reactivate($this->record);
|
||||
Notification::make()->title('Tenant activat.')->success()->send();
|
||||
Notification::make()->title(__('Tenant activat.'))->success()->send();
|
||||
$this->dispatch('$refresh');
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -46,7 +46,7 @@ class PlanResource extends Resource
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Schemas\Components\Section::make('Identificare')
|
||||
Schemas\Components\Section::make(__('Identificare'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('slug')
|
||||
@@ -54,25 +54,25 @@ class PlanResource extends Resource
|
||||
->dehydrateStateUsing(fn ($s) => strtolower((string) $s))
|
||||
->extraInputAttributes(['style' => 'text-transform:lowercase']),
|
||||
Forms\Components\TextInput::make('name')->required()->maxLength(60),
|
||||
Forms\Components\Toggle::make('is_active')->label('Activ')->default(true),
|
||||
Forms\Components\Toggle::make('is_public')->label('Public (afișat la signup)')->default(true),
|
||||
Forms\Components\Toggle::make('is_active')->label(__('Activ'))->default(true),
|
||||
Forms\Components\Toggle::make('is_public')->label(__('Public (afișat la signup)'))->default(true),
|
||||
Forms\Components\Toggle::make('is_demo')
|
||||
->label('Demo (pentru demonstrații sales)')
|
||||
->helperText('Plan ascuns public, folosit pentru tenant-i demo cu features deblocate.')
|
||||
->label(__('Demo (pentru demonstrații sales)'))
|
||||
->helperText(__('Plan ascuns public, folosit pentru tenant-i demo cu features deblocate.'))
|
||||
->default(false),
|
||||
Forms\Components\TextInput::make('trial_days')
|
||||
->label('Perioadă trial (zile)')
|
||||
->numeric()->placeholder('null = fără trial')
|
||||
->helperText('Numărul de zile gratis după ce un tenant alege acest plan.'),
|
||||
->label(__('Perioadă trial (zile)'))
|
||||
->numeric()->placeholder(__('null = fără trial'))
|
||||
->helperText(__('Numărul de zile gratis după ce un tenant alege acest plan.')),
|
||||
]),
|
||||
Schemas\Components\Section::make('Preț')
|
||||
Schemas\Components\Section::make(__('Preț'))
|
||||
->columns(3)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('price_monthly')->label('Preț lunar')->numeric()->required()->suffix(fn (Get $get) => $get('currency') ?? 'MDL'),
|
||||
Forms\Components\TextInput::make('price_yearly')->label('Preț anual')->numeric()->helperText('De obicei 10× preț lunar (2 luni gratis).')->suffix(fn (Get $get) => $get('currency') ?? 'MDL'),
|
||||
Forms\Components\TextInput::make('price_monthly')->label(__('Preț lunar'))->numeric()->required()->suffix(fn (Get $get) => $get('currency') ?? 'MDL'),
|
||||
Forms\Components\TextInput::make('price_yearly')->label(__('Preț anual'))->numeric()->helperText(__('De obicei 10× preț lunar (2 luni gratis).'))->suffix(fn (Get $get) => $get('currency') ?? 'MDL'),
|
||||
Forms\Components\Select::make('currency')->options(['MDL' => 'MDL', 'EUR' => 'EUR', 'USD' => 'USD'])->default('MDL'),
|
||||
]),
|
||||
Schemas\Components\Section::make('Funcționalități incluse')
|
||||
Schemas\Components\Section::make(__('Funcționalități incluse'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Forms\Components\CheckboxList::make('features')
|
||||
@@ -80,15 +80,15 @@ class PlanResource extends Resource
|
||||
->columns(2)
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
Schemas\Components\Section::make('Limite')
|
||||
Schemas\Components\Section::make(__('Limite'))
|
||||
->columns(3)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('limits.max_users')->label('Max useri')->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.max_clients')->label('Max clienți')->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.max_vehicles')->label('Max mașini')->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.max_work_orders_month')->label('Max fișe/lună')->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.storage_mb')->label('Storage (MB)')->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.ai_messages_month')->label('Mesaje AI/lună')->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.max_users')->label(__('Max useri'))->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.max_clients')->label(__('Max clienți'))->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.max_vehicles')->label(__('Max mașini'))->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.max_work_orders_month')->label(__('Max fișe/lună'))->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.storage_mb')->label(__('Storage (MB)'))->numeric()->placeholder('∞'),
|
||||
Forms\Components\TextInput::make('limits.ai_messages_month')->label(__('Mesaje AI/lună'))->numeric()->placeholder('∞'),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -103,29 +103,29 @@ class PlanResource extends Resource
|
||||
->description(fn ($record) => $record->is_demo ? '🎬 Demo' : ($record->trial_days ? "🎁 {$record->trial_days} zile trial" : null)),
|
||||
Tables\Columns\TextColumn::make('price_monthly')
|
||||
->money(fn ($record) => $record->currency)
|
||||
->label('Lunar')
|
||||
->label(__('Lunar'))
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('price_yearly')
|
||||
->money(fn ($record) => $record->currency)
|
||||
->label('Anual'),
|
||||
->label(__('Anual')),
|
||||
Tables\Columns\TextColumn::make('companies_count')
|
||||
->counts('companies')
|
||||
->label('Abonați')
|
||||
->label(__('Abonați'))
|
||||
->badge()
|
||||
->color('primary'),
|
||||
Tables\Columns\TextColumn::make('features')
|
||||
->label('Funcționalități')
|
||||
->label(__('Funcționalități'))
|
||||
->formatStateUsing(fn ($s) => is_array($s) ? count($s) . ' incluse' : '—')
|
||||
->badge(),
|
||||
Tables\Columns\IconColumn::make('is_active')->boolean()->label('Activ'),
|
||||
Tables\Columns\IconColumn::make('is_public')->boolean()->label('Public'),
|
||||
Tables\Columns\IconColumn::make('is_active')->boolean()->label(__('Activ')),
|
||||
Tables\Columns\IconColumn::make('is_public')->boolean()->label(__('Public')),
|
||||
])
|
||||
->actions([
|
||||
Actions\EditAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
])
|
||||
->emptyStateHeading('Niciun plan definit')
|
||||
->emptyStateDescription('Creează planuri (ex: Free, Basic, Pro) și atribuie-le companiilor.')
|
||||
->emptyStateHeading(__('Niciun plan definit'))
|
||||
->emptyStateDescription(__('Creează planuri (ex: Free, Basic, Pro) și atribuie-le companiilor.'))
|
||||
->defaultSort('price_monthly');
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,12 @@ class SubscriptionResource extends Resource
|
||||
return __('nav.label.Facturi & abonamente');
|
||||
}
|
||||
|
||||
protected static ?string $modelLabel = 'factură';
|
||||
protected static ?string $modelLabel = null;
|
||||
|
||||
public static function getModelLabel(): string
|
||||
{
|
||||
return __('factură');
|
||||
}
|
||||
|
||||
protected static ?string $pluralModelLabel = 'facturi';
|
||||
|
||||
@@ -45,15 +50,15 @@ class SubscriptionResource extends Resource
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Schemas\Components\Section::make('Companie & plan')
|
||||
Schemas\Components\Section::make(__('Companie & plan'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Forms\Components\Select::make('company_id')
|
||||
->label('Companie')
|
||||
->label(__('Companie'))
|
||||
->options(fn () => Company::orderBy('name')->pluck('name', 'id'))
|
||||
->required()->searchable()->live(),
|
||||
Forms\Components\Select::make('plan_id')
|
||||
->label('Plan')
|
||||
->label(__('Plan'))
|
||||
->options(fn () => Plan::pluck('name', 'id'))
|
||||
->required()->searchable()->live()
|
||||
->afterStateUpdated(function ($state, Set $set, Get $get) {
|
||||
@@ -80,7 +85,7 @@ class SubscriptionResource extends Resource
|
||||
Forms\Components\Select::make('status')
|
||||
->options(Subscription::STATUSES)->default('pending')->required(),
|
||||
]),
|
||||
Schemas\Components\Section::make('Sumă')
|
||||
Schemas\Components\Section::make(__('Sumă'))
|
||||
->columns(3)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('amount')->numeric()->required()->suffix(fn (Get $get) => $get('currency') ?? 'MDL'),
|
||||
@@ -88,19 +93,19 @@ class SubscriptionResource extends Resource
|
||||
Forms\Components\Select::make('payment_method')
|
||||
->options(Subscription::PAYMENT_METHODS),
|
||||
]),
|
||||
Schemas\Components\Section::make('Perioadă')
|
||||
Schemas\Components\Section::make(__('Perioadă'))
|
||||
->columns(3)
|
||||
->schema([
|
||||
Forms\Components\DatePicker::make('period_start')->required()->default(today()),
|
||||
Forms\Components\DatePicker::make('period_end')->required(),
|
||||
Forms\Components\DateTimePicker::make('due_at')->label('Scadent la'),
|
||||
Forms\Components\DateTimePicker::make('paid_at')->label('Plătit la'),
|
||||
Forms\Components\DateTimePicker::make('due_at')->label(__('Scadent la')),
|
||||
Forms\Components\DateTimePicker::make('paid_at')->label(__('Plătit la')),
|
||||
]),
|
||||
Schemas\Components\Section::make('Detalii')
|
||||
Schemas\Components\Section::make(__('Detalii'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('invoice_number')->label('Nr. factură')->placeholder('auto-generat')->maxLength(30),
|
||||
Forms\Components\TextInput::make('reference')->label('Referință (Stripe id, transfer)')->maxLength(100),
|
||||
Forms\Components\TextInput::make('invoice_number')->label(__('Nr. factură'))->placeholder('auto-generat')->maxLength(30),
|
||||
Forms\Components\TextInput::make('reference')->label(__('Referință (Stripe id, transfer)'))->maxLength(100),
|
||||
Forms\Components\Textarea::make('notes')->columnSpanFull()->rows(2),
|
||||
]),
|
||||
]);
|
||||
@@ -111,15 +116,15 @@ class SubscriptionResource extends Resource
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('invoice_number')
|
||||
->label('Factură')
|
||||
->label(__('Factură'))
|
||||
->placeholder(fn ($record) => '—')
|
||||
->copyable()
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('company.name')
|
||||
->label('Companie')
|
||||
->label(__('Companie'))
|
||||
->searchable()
|
||||
->url(fn ($record) => \App\Filament\Central\Resources\CompanyResource::getUrl('view', ['record' => $record->company_id])),
|
||||
Tables\Columns\TextColumn::make('plan.name')->label('Plan')->placeholder('—'),
|
||||
Tables\Columns\TextColumn::make('plan.name')->label(__('Plan'))->placeholder('—'),
|
||||
Tables\Columns\TextColumn::make('period')
|
||||
->formatStateUsing(fn ($s) => Subscription::PERIODS[$s] ?? $s)
|
||||
->badge(),
|
||||
@@ -137,8 +142,8 @@ class SubscriptionResource extends Resource
|
||||
'cancelled', 'refunded' => 'gray',
|
||||
default => 'primary',
|
||||
}),
|
||||
Tables\Columns\TextColumn::make('period_end')->label('Până la')->date(),
|
||||
Tables\Columns\TextColumn::make('paid_at')->label('Plătit')->date()->placeholder('—'),
|
||||
Tables\Columns\TextColumn::make('period_end')->label(__('Până la'))->date(),
|
||||
Tables\Columns\TextColumn::make('paid_at')->label(__('Plătit'))->date()->placeholder('—'),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('status')->options(Subscription::STATUSES),
|
||||
@@ -146,7 +151,7 @@ class SubscriptionResource extends Resource
|
||||
])
|
||||
->actions([
|
||||
Actions\Action::make('mark_paid')
|
||||
->label('Marchează plătit')
|
||||
->label(__('Marchează plătit'))
|
||||
->icon('heroicon-m-check-circle')
|
||||
->color('success')
|
||||
->visible(fn ($record) => $record->status !== 'paid')
|
||||
@@ -163,8 +168,8 @@ class SubscriptionResource extends Resource
|
||||
Actions\EditAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
])
|
||||
->emptyStateHeading('Nicio factură generată')
|
||||
->emptyStateDescription('Crează manual prima factură sau folosește butonul „Generează factură" din pagina Companiei.')
|
||||
->emptyStateHeading(__('Nicio factură generată'))
|
||||
->emptyStateDescription(__('Crează manual prima factură sau folosește butonul „Generează factură" din pagina Companiei.'))
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
|
||||
|
||||
@@ -36,24 +36,24 @@ class SuperAdminResource extends Resource
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Schemas\Components\Section::make('Identificare')
|
||||
Schemas\Components\Section::make(__('Identificare'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')->required()->maxLength(120),
|
||||
Forms\Components\TextInput::make('email')->email()->required()->unique(ignoreRecord: true)->maxLength(120),
|
||||
Forms\Components\TextInput::make('phone')->tel()->maxLength(40),
|
||||
Forms\Components\Toggle::make('is_active')->label('Activ')->default(true),
|
||||
Forms\Components\Toggle::make('is_active')->label(__('Activ'))->default(true),
|
||||
]),
|
||||
Schemas\Components\Section::make('Permisiuni')
|
||||
Schemas\Components\Section::make(__('Permisiuni'))
|
||||
->columns(1)
|
||||
->schema([
|
||||
Forms\Components\Select::make('role')
|
||||
->options(SuperAdmin::ROLES)
|
||||
->default('support')
|
||||
->required()
|
||||
->helperText('Owner = drepturi totale. Admin = aproape la fel. Sales = doar tenanți + planuri. Finance = facturi. Support = read-only.'),
|
||||
->helperText(__('Owner = drepturi totale. Admin = aproape la fel. Sales = doar tenanți + planuri. Finance = facturi. Support = read-only.')),
|
||||
]),
|
||||
Schemas\Components\Section::make('Parolă')
|
||||
Schemas\Components\Section::make(__('Parolă'))
|
||||
->columns(1)
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('password')
|
||||
@@ -65,7 +65,7 @@ class SuperAdminResource extends Resource
|
||||
->minLength(8)
|
||||
->helperText(fn (string $operation) => $operation === 'edit' ? 'Lasă gol ca să o păstrezi.' : 'Min 8 caractere.'),
|
||||
]),
|
||||
Forms\Components\Textarea::make('notes')->label('Note interne')->rows(2)->columnSpanFull(),
|
||||
Forms\Components\Textarea::make('notes')->label(__('Note interne'))->rows(2)->columnSpanFull(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -92,25 +92,25 @@ class SuperAdminResource extends Resource
|
||||
'sales' => 'info',
|
||||
default => 'gray',
|
||||
}),
|
||||
Tables\Columns\IconColumn::make('is_active')->boolean()->label('Activ'),
|
||||
Tables\Columns\IconColumn::make('is_active')->boolean()->label(__('Activ')),
|
||||
Tables\Columns\IconColumn::make('app_authentication_secret')
|
||||
->label('2FA')
|
||||
->label(__('2FA'))
|
||||
->boolean()
|
||||
->getStateUsing(fn ($record) => $record?->app_authentication_secret !== null)
|
||||
->trueIcon('heroicon-o-lock-closed')
|
||||
->falseIcon('heroicon-o-lock-open')
|
||||
->trueColor('success')
|
||||
->falseColor('warning'),
|
||||
Tables\Columns\TextColumn::make('last_login_at')->label('Ultim login')->dateTime()->placeholder('—'),
|
||||
Tables\Columns\TextColumn::make('last_login_at')->label(__('Ultim login'))->dateTime()->placeholder('—'),
|
||||
Tables\Columns\TextColumn::make('created_at')->date(),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('role')->options(SuperAdmin::ROLES),
|
||||
Tables\Filters\TernaryFilter::make('is_active')->label('Activ'),
|
||||
Tables\Filters\TernaryFilter::make('is_active')->label(__('Activ')),
|
||||
])
|
||||
->actions([
|
||||
Actions\Action::make('reset_password')
|
||||
->label('Reset parolă')
|
||||
->label(__('Reset parolă'))
|
||||
->icon('heroicon-m-key')
|
||||
->color('warning')
|
||||
->schema([
|
||||
@@ -119,7 +119,7 @@ class SuperAdminResource extends Resource
|
||||
])
|
||||
->action(function (SuperAdmin $record, array $data) {
|
||||
$record->update(['password' => Hash::make($data['new_password'])]);
|
||||
Notification::make()->title('Parolă resetată.')->success()->send();
|
||||
Notification::make()->title(__('Parolă resetată.'))->success()->send();
|
||||
}),
|
||||
Actions\Action::make('toggle_2fa')
|
||||
->label(fn (SuperAdmin $record) => $record->app_authentication_secret ? 'Dezactivează 2FA' : 'Forțează re-setare 2FA')
|
||||
@@ -133,19 +133,19 @@ class SuperAdminResource extends Resource
|
||||
'app_authentication_recovery_codes' => null,
|
||||
'email_authentication_at' => null,
|
||||
])->saveQuietly();
|
||||
Notification::make()->title('2FA dezactivat.')->success()->send();
|
||||
Notification::make()->title(__('2FA dezactivat.'))->success()->send();
|
||||
}),
|
||||
Actions\EditAction::make(),
|
||||
Actions\DeleteAction::make()
|
||||
->before(function (SuperAdmin $record) {
|
||||
if (auth('central')->id() === $record->id) {
|
||||
Notification::make()->title('Nu te poți șterge pe tine!')->danger()->send();
|
||||
Notification::make()->title(__('Nu te poți șterge pe tine!'))->danger()->send();
|
||||
return false;
|
||||
}
|
||||
}),
|
||||
])
|
||||
->emptyStateHeading('Doar tu ești aici')
|
||||
->emptyStateDescription('Adaugă echipa ta — colegi de la suport, sales, finance — fiecare cu rolul lui.')
|
||||
->emptyStateHeading(__('Doar tu ești aici'))
|
||||
->emptyStateDescription(__('Adaugă echipa ta — colegi de la suport, sales, finance — fiecare cu rolul lui.'))
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user