columns(3) ->components([ Section::make('Details') ->columnSpan(2) ->components([ TextInput::make('name') ->required() ->live(onBlur: true) ->afterStateUpdated(function (string $operation, $state, callable $set) { if ($operation === 'create') { $set('slug', Str::slug($state)); } }), TextInput::make('slug') ->required() ->unique(McpServer::class, 'slug', ignoreRecord: true) ->helperText('Used in the URL, e.g. /mcp-servers/your-slug'), Textarea::make('description') ->required() ->rows(4) ->columnSpanFull(), TextInput::make('url') ->label('Repository / homepage URL') ->url() ->required(), TextInput::make('docs_url') ->label('Documentation URL') ->url(), TextInput::make('logo_url') ->label('Logo URL') ->url(), Textarea::make('install_command') ->label('Install command') ->rows(2) ->helperText('e.g. npx -y @modelcontextprotocol/server-filesystem /path') ->columnSpanFull(), Textarea::make('config_example') ->label('Example client configuration') ->rows(6) ->helperText('The JSON snippet a user pastes into their MCP client config') ->columnSpanFull(), TagsInput::make('capabilities') ->placeholder('Add a capability and press enter') ->helperText('e.g. Read files, Write files, List directories') ->columnSpanFull(), TagsInput::make('tags') ->placeholder('Add a tag and press enter') ->helperText('e.g. official, read-only, requires-api-key') ->columnSpanFull(), ]), Section::make('Classification') ->columnSpan(1) ->components([ Select::make('category') ->options(config('mcp_servers.categories')) ->required() ->searchable(), Select::make('transport') ->options(config('mcp_servers.transports')), TextInput::make('language') ->helperText('e.g. TypeScript, Python'), ]), Section::make('Moderation') ->columnSpan(3) ->columns(4) ->components([ Toggle::make('approved') ->helperText('Only approved servers are shown publicly.') ->default(false), Toggle::make('featured') ->helperText('Highlight this server.') ->default(false), Select::make('user_id') ->label('Submitted by') ->relationship('user', 'name') ->searchable() ->preload(), TextInput::make('views') ->numeric() ->default(0) ->disabled() ->dehydrated(), TextInput::make('clicks') ->numeric() ->default(0) ->disabled() ->dehydrated(), ]), ]); } }