schema([
Forms\Components\Section::make('General')
->schema([
Forms\Components\TextInput::make('name')
->label('Name')
->autofocus()
->required()
->maxLength(255)
->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
$existingCategory = Category::where('company_id', auth()->user()->currentCompany->id)
->where('name', $value)
->where('type', $get('type'))
->first();
if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
$type = ucwords($get('type'));
$fail("The {$type} category \"{$value}\" already exists.");
}
};
}),
Forms\Components\Select::make('type')
->options(CategoryType::class)
->required()
->native(false)
->label('Type'),
Forms\Components\ColorPicker::make('color')
->required()
->label('Color'),
ToggleButton::make('enabled')
->label('Default'),
])->columns(),
]);
}
/**
* @throws Exception
*/
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->label('Name')
->weight('semibold')
->icon(static fn (Category $record) => $record->enabled ? 'heroicon-o-lock-closed' : null)
->tooltip(static fn (Category $record) => $record->enabled ? "Default {$record->type->getLabel()} Category" : null)
->iconPosition('after')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('type')
->label('Type')
->sortable()
->searchable(),
Tables\Columns\ColorColumn::make('color')
->label('Color')
->copyable()
->copyMessage('Color code copied'),
])
->filters([
Tables\Filters\SelectFilter::make('type')
->label('Type')
->multiple()
->options(CategoryType::class),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make()
->before(static function (Category $record, Tables\Actions\DeleteAction $action) {
if ($record->enabled) {
Notification::make()
->danger()
->title('Action Denied')
->body(__('The :name category is currently set as your default :type category and cannot be deleted. Please set a different category as your default before attempting to delete this one.', ['name' => $record->name, 'type' => $record->type->getLabel()]))
->persistent()
->send();
$action->cancel();
}
}),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make()
->before(static function (Collection $records, Tables\Actions\DeleteBulkAction $action) {
$defaultCategories = $records->filter(static function (Category $record) {
return $record->enabled;
});
if ($defaultCategories->isNotEmpty()) {
$defaultCategoryNames = $defaultCategories->pluck('name')->toArray();
Notification::make()
->danger()
->title('Action Denied')
->body(static function () use ($defaultCategoryNames) {
$message = __('The following categories are currently set as your default and cannot be deleted. Please set a different category as your default before attempting to delete these ones.') . '
';
$message .= implode('
', array_map(static function ($name) {
return '• ' . $name;
}, $defaultCategoryNames));
return $message;
})
->persistent()
->send();
$action->cancel();
}
}),
]),
])
->emptyStateActions([
Tables\Actions\CreateAction::make(),
]);
}
public static function getPages(): array
{
return [
'index' => Pages\ListCategories::route('/'),
'create' => Pages\CreateCategory::route('/create'),
'edit' => Pages\EditCategory::route('/{record}/edit'),
];
}
}