This project demonstrates how to create a custom timetable with Calendar views, lessons, and teacher management.
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/UserResource.php:
use App\Filament\Pages\Timetable;use Illuminate\Support\Facades\Hash;use App\Models\User;use Filament\Forms;use Filament\Forms\Form;use Filament\Resources\Resource;use Filament\Tables;use Filament\Tables\Table;use Illuminate\Database\Eloquent\Builder; class UserResource extends Resource{ protected static ?string $model = User::class; protected static ?string $navigationIcon = 'heroicon-o-users'; protected static ?string $navigationGroup = 'Users Management'; public static function form(Form $form): Form { return $form ->schema([ Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\TextInput::make('email') ->email() ->required() ->maxLength(255), Forms\Components\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'), Forms\Components\Group::make() ->schema([ Forms\Components\Select::make('roles') ->required() ->multiple() ->relationship('roles', 'name'), Forms\Components\Select::make('schoolClass') ->required() ->label('Class') ->relationship('schoolClass', 'name'), ]) ->columns() ->columnSpanFull() ]); } public static function table(Table $table): Table { return $table ->modifyQueryUsing(fn (Builder $query): Builder => $query->with('roles')) ->columns([ Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('email'), Tables\Columns\TextColumn::make('roles.name') ->badge(), Tables\Columns\TextColumn::make('schoolClass.name'), ]) ->filters([ // ]) ->actions([ Tables\Actions\Action::make('viewSchedule') ->icon('heroicon-o-clock') ->url(fn (User $record): string => Timetable::getUrl(['teacher_id' => $record->id])) ->visible(fn (User $record): bool => $record->roles->contains('name', 'Teacher')), Tables\Actions\EditAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } // ...}
We have a SchoolClassResource
where we can create a class. In the table, we also show a link to view a schedule.
app/Filament/Resources/SchoolClassResource.php:
use App\Filament\Pages\Timetable;use App\Models\SchoolClass;use Filament\Forms;use Filament\Forms\Form;use Filament\Resources\Resource;use Filament\Tables;use Filament\Tables\Table; class SchoolClassResource extends Resource{ protected static ?string $model = SchoolClass::class; protected static ?string $navigationIcon = 'heroicon-o-academic-cap'; protected static ?string $navigationGroup = 'School'; protected static ?int $navigationSort = 1; public static function form(Form $form): Form { return $form ->schema([ Forms\Components\TextInput::make('name') ->required(), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('name'), ]) ->filters([ // ]) ->actions([ Tables\Actions\Action::make('viewSchedule') ->icon('heroicon-o-clock') ->url(fn (SchoolClass $record): string => Timetable::getUrl(['class_id' => $record->id])), // ...
Next, we will build: