This shows how to build a custom timetable and implement a custom Laravel validation rule.
First, we have a UserResource
where we can manage users and assign them roles with a class. If a user has the role of Teacher
, then a View schedule
link is shown.
app/Filament/Resources/Users/UserResource.php:
use Filament\Schemas\Schema;use App\Filament\Resources\Users\Pages\ListUsers;use App\Filament\Resources\Users\Pages\CreateUser;use App\Filament\Resources\Users\Pages\EditUser;use App\Models\User;use Filament\Resources\Resource;use Filament\Tables\Table;use App\Filament\Resources\Users\Schemas\UserForm;use App\Filament\Resources\Users\Tables\UsersTable;use Filament\Support\Icons\Heroicon; class UserResource extends Resource{ protected static ?string $model = User::class; protected static string | \BackedEnum | null $navigationIcon = Heroicon::OutlinedUsers; protected static string | \UnitEnum | null $navigationGroup = 'Users Management'; public static function form(Schema $schema): Schema { return UserForm::configure($schema); } public static function table(Table $table): Table { return UsersTable::configure($table); } // ...}
The form configuration is extracted to a separate schema class:
app/Filament/Resources/Users/Schemas/UserForm.php:
use Filament\Schemas\Schema;use Filament\Forms\Components\TextInput;use Filament\Schemas\Components\Group;use Filament\Forms\Components\Select;use Illuminate\Support\Facades\Hash; class UserForm{ public static function configure(Schema $schema): Schema { return $schema ->components([ TextInput::make('name') ->required() ->maxLength(255), TextInput::make('email') ->email() ->required() ->maxLength(255), TextInput::make('password') ->password() ->maxLength(255) ->dehydrateStateUsing(fn(string $state): string => Hash::make($state)) ->dehydrated(fn (?string $state): bool => filled($state)) ->required(fn (string $operation): bool => $operation === 'create'), Group::make() ->schema([ Select::make('roles') ->required() ->multiple() ->relationship('roles', 'name'), Select::make('schoolClass') ->required() ->label('Class') ->relationship('schoolClass', 'name'), ]) ->columns() ->columnSpanFull() ]); }}
And the table configuration is also in a separate class: