schema([ TextInput::make('label') ->required() ->maxLength(255) ->live(onBlur: true) ->afterStateUpdated(function ($state, $set, ?ListingCustomField $record): void { $baseName = \Illuminate\Support\Str::slug((string) $state, '_'); $baseName = $baseName !== '' ? $baseName : 'custom_field'; $name = $baseName; $counter = 1; while (ListingCustomField::query() ->where('name', $name) ->when($record, fn ($query) => $query->whereKeyNot($record->getKey())) ->exists()) { $name = "{$baseName}_{$counter}"; $counter++; } $set('name', $name); }), TextInput::make('name') ->required() ->maxLength(255) ->regex('/^[a-z0-9_]+$/') ->helperText('Only lowercase letters, numbers and underscore.') ->unique(ignoreRecord: true), Select::make('type') ->required() ->options(ListingCustomField::typeOptions()) ->live(), Select::make('category_id') ->label('Category') ->options(fn (): array => Category::query() ->where('is_active', true) ->orderBy('name') ->pluck('name', 'id') ->all()) ->searchable() ->preload() ->nullable() ->helperText('Leave empty to apply this field to all categories.'), TagsInput::make('options') ->label('Select Options') ->placeholder('Add an option and press Enter') ->visible(fn ($get): bool => $get('type') === ListingCustomField::TYPE_SELECT) ->helperText('Used only for Select type fields.'), TextInput::make('sort_order') ->numeric() ->default(0), TextInput::make('placeholder') ->maxLength(255), Textarea::make('help_text') ->rows(2) ->maxLength(500), Toggle::make('is_required') ->default(false), Toggle::make('is_active') ->default(true), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('id')->sortable(), TextColumn::make('label')->searchable()->sortable(), TextColumn::make('name')->searchable()->copyable(), TextColumn::make('type')->sortable(), TextColumn::make('category.name')->label('Category')->default('All categories'), IconColumn::make('is_required')->boolean()->label('Required'), IconColumn::make('is_active')->boolean()->label('Active'), TextColumn::make('sort_order')->sortable(), ]) ->defaultSort('id', 'desc') ->actions([ EditAction::make(), DeleteAction::make(), ]); } public static function getPages(): array { return [ 'index' => Pages\ListListingCustomFields::route('/'), 'create' => Pages\CreateListingCustomField::route('/create'), 'edit' => Pages\EditListingCustomField::route('/{record}/edit'), ]; } }