Files
zemailnator/app/Filament/Resources/Usernames/Schemas/UsernameForm.php
idevakk 4028a9a21e feat(usernames): update unique constraint to composite with type and provider
- Remove single unique constraint on username
  - Add composite unique constraint on username, username_type, and provider_type
  - Update Filament username form validation with custom unique rule
  - Add descriptive validation message for duplicate usernames
2025-12-09 10:14:50 -08:00

82 lines
3.3 KiB
PHP

<?php
namespace App\Filament\Resources\Usernames\Schemas;
use App\enum\ProviderType;
use App\enum\UsernameType;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ToggleButtons;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Illuminate\Validation\Rules\Unique;
class UsernameForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('username')
->columnSpan(1)
->alphaDash()
->helperText('Email: myusername@gmail.com | Username: myusername')
->required()
->unique(
table: 'usernames',
ignoreRecord: true,
modifyRuleUsing: function (Unique $rule, Get $get) {
return $rule
->where('username_type', $get('username_type'))
->where('provider_type', $get('provider_type'));
},
)
->validationMessages([
'unique' => 'The username already exists for this type and provider.',
]),
TextInput::make('daily_mailbox_limit')
->integer()
->minValue(1)
->default(100)
->helperText('How many mailboxes can be created with this domain daily')
->columnSpan(1)
->required(),
ToggleButtons::make('is_active')
->options([
true => 'Active',
false => 'Disabled',
])
->inline()
->default(true)
->columnSpanFull()
->required(),
Select::make('username_type')
->options(UsernameType::class)
->enum(UsernameType::class)
->required(),
Select::make('provider_type')
->options(ProviderType::class)
->enum(ProviderType::class)
->required(),
DateTimePicker::make('starts_at'),
DateTimePicker::make('ends_at'),
TextEntry::make('last_used_at')
->label('Last Used At')
->formatStateUsing(fn ($state) => $state ? $state->diffForHumans() : 'Never')
->visible(fn ($context) => $context === 'edit'),
TextEntry::make('checked_at')
->label('Last Checked At')
->formatStateUsing(fn ($state) => $state ? $state->diffForHumans() : 'Never')
->visible(fn ($context) => $context === 'edit'),
TextEntry::make('deleted_at')
->label('Deleted At')
->formatStateUsing(fn ($state) => $state ? $state->diffForHumans() : null)
->color('danger')
->icon('heroicon-o-trash')
->visible(fn ($record) => $record?->deleted_at !== null),
]);
}
}