diff --git a/app/Filament/Resources/Groups/GroupResource.php b/app/Filament/Resources/Groups/GroupResource.php index 5e986ab..2023d95 100644 --- a/app/Filament/Resources/Groups/GroupResource.php +++ b/app/Filament/Resources/Groups/GroupResource.php @@ -13,7 +13,6 @@ use BackedEnum; use Filament\Resources\Resource; use Filament\Schemas\Schema; use Filament\Tables\Table; -use Illuminate\Contracts\Support\Htmlable; class GroupResource extends Resource { @@ -27,10 +26,7 @@ class GroupResource extends Resource protected static ?int $navigationSort = 1; - public static function getNavigationIcon(): string | BackedEnum | Htmlable | null - { - return 'icon-flight-takeoff'; - } + protected static string | BackedEnum | null $navigationIcon = 'icon-flight-takeoff'; public static function form(Schema $schema): Schema { diff --git a/app/Filament/Resources/Hotels/HotelResource.php b/app/Filament/Resources/Hotels/HotelResource.php new file mode 100644 index 0000000..cb71a6d --- /dev/null +++ b/app/Filament/Resources/Hotels/HotelResource.php @@ -0,0 +1,58 @@ +schema(HotelForm::schema()); + } + + public static function table(Table $table): Table + { + return $table->columns(HotelsTable::schema()); + } + + public static function getRelations(): array + { + return [ + RoomsRelationManager::class, + ]; + } + + public static function getPages(): array + { + return [ + 'index' => ListHotels::route('/'), + 'create' => CreateHotel::route('/create'), + 'edit' => EditHotel::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Hotels/Pages/CreateHotel.php b/app/Filament/Resources/Hotels/Pages/CreateHotel.php new file mode 100644 index 0000000..05f2c33 --- /dev/null +++ b/app/Filament/Resources/Hotels/Pages/CreateHotel.php @@ -0,0 +1,11 @@ +components([ + TextInput::make('name') + ->required() + ->maxLength(255), + ]); + } + + public function table(Table $table): Table + { + return $table + ->recordTitleAttribute('name') + ->columns([ + TextColumn::make('name') + ->searchable(), + ]) + ->filters([ + // + ]) + ->headerActions([ + CreateAction::make(), + AssociateAction::make(), + ]) + ->recordActions([ + EditAction::make(), + DissociateAction::make(), + DeleteAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DissociateBulkAction::make(), + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Hotels/Schemas/HotelForm.php b/app/Filament/Resources/Hotels/Schemas/HotelForm.php new file mode 100644 index 0000000..324ff67 --- /dev/null +++ b/app/Filament/Resources/Hotels/Schemas/HotelForm.php @@ -0,0 +1,38 @@ +required(), + + Forms\Components\Select::make('city') + ->options([ + 'Makkah' => 'Makkah', + 'Madinah' => 'Madinah', + ]) + ->required(), + + Forms\Components\FileUpload::make('image') + ->image(), + Forms\Components\FileUpload::make('images') + ->multiple(), + Forms\Components\TextInput::make('geo_location'), + + Forms\Components\TextInput::make('haram_distance') + ->required(), + + Forms\Components\TextInput::make('star') + ->required() + ->numeric() + ->minValue(1) + ->maxValue(5), + ]; + } +} diff --git a/app/Filament/Resources/Hotels/Tables/HotelsTable.php b/app/Filament/Resources/Hotels/Tables/HotelsTable.php new file mode 100644 index 0000000..940865a --- /dev/null +++ b/app/Filament/Resources/Hotels/Tables/HotelsTable.php @@ -0,0 +1,38 @@ +circular() + ->imageSize(60), + + Tables\Columns\TextColumn::make('name') + ->searchable(), + + Tables\Columns\TextColumn::make('city') + ->sortable(), + + Tables\Columns\TextColumn::make('haram_distance'), + + Tables\Columns\TextColumn::make('star') + ->sortable(), + + Tables\Columns\TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + + Tables\Columns\TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]; + } +} diff --git a/app/Filament/Resources/Rooms/Pages/CreateRoom.php b/app/Filament/Resources/Rooms/Pages/CreateRoom.php new file mode 100644 index 0000000..2ce724b --- /dev/null +++ b/app/Filament/Resources/Rooms/Pages/CreateRoom.php @@ -0,0 +1,11 @@ +columns(RoomsTable::schema()); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => ListRooms::route('/'), + 'create' => CreateRoom::route('/create'), + 'edit' => EditRoom::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Rooms/Schemas/RoomForm.php b/app/Filament/Resources/Rooms/Schemas/RoomForm.php new file mode 100644 index 0000000..2eef849 --- /dev/null +++ b/app/Filament/Resources/Rooms/Schemas/RoomForm.php @@ -0,0 +1,36 @@ +components([ + Forms\Components\Select::make('hotel_id') + ->relationship('hotel', 'name') + ->required(), + + Forms\Components\TextInput::make('name') + ->required(), + + Forms\Components\TextInput::make('floor') + ->required(), + + Forms\Components\FileUpload::make('images') + ->multiple(), + + Forms\Components\TextInput::make('bed_count') + ->required() + ->numeric() + ->default(1), + + Forms\Components\Checkbox::make('wide') + ->default(false) + ->required(), + ]); + } +} diff --git a/app/Filament/Resources/Rooms/Tables/RoomsTable.php b/app/Filament/Resources/Rooms/Tables/RoomsTable.php new file mode 100644 index 0000000..8010ec4 --- /dev/null +++ b/app/Filament/Resources/Rooms/Tables/RoomsTable.php @@ -0,0 +1,33 @@ +sortable(), + Tables\Columns\TextColumn::make('name') + ->searchable(), + Tables\Columns\TextColumn::make('floor') + ->searchable(), + Tables\Columns\TextColumn::make('bed_count') + ->numeric() + ->sortable(), + Tables\Columns\IconColumn::make('wide') + ->boolean(), + Tables\Columns\TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]; + } +} diff --git a/app/Models/Group.php b/app/Models/Group.php index 659534c..9601d0c 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -28,6 +28,11 @@ class Group extends Model 'end_date' => 'date', ]; + /** + * Get the name of the group + * + * @return Attribute + * */ public function name(): Attribute { return Attribute::make( diff --git a/app/Models/Hotel.php b/app/Models/Hotel.php new file mode 100644 index 0000000..203bc0c --- /dev/null +++ b/app/Models/Hotel.php @@ -0,0 +1,27 @@ + + */ + protected function casts(): array + { + return [ + 'images' => 'array', + ]; + } + + public function rooms(): HasMany + { + return $this->hasMany(Room::class); + } +} diff --git a/app/Models/Room.php b/app/Models/Room.php new file mode 100644 index 0000000..3dd7fd9 --- /dev/null +++ b/app/Models/Room.php @@ -0,0 +1,28 @@ + + */ + protected function casts(): array + { + return [ + 'images' => 'array', + 'wide' => 'boolean', + ]; + } + + public function hotel(): BelongsTo + { + return $this->belongsTo(Hotel::class); + } +} diff --git a/database/migrations/2025_08_31_160209_create_hotels_table.php b/database/migrations/2025_08_31_160209_create_hotels_table.php new file mode 100644 index 0000000..c11ef6a --- /dev/null +++ b/database/migrations/2025_08_31_160209_create_hotels_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('name'); + $table->text('image')->nullable(); + $table->json('images')->nullable(); + $table->json('geo_location')->nullable(); + $table->enum('city', ['Makkah', 'Madinah']); + $table->string('haram_distance'); + $table->unsignedTinyInteger('star')->default(1); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('hotels'); + } +}; diff --git a/database/migrations/2025_08_31_160212_create_rooms_table.php b/database/migrations/2025_08_31_160212_create_rooms_table.php new file mode 100644 index 0000000..ed962d6 --- /dev/null +++ b/database/migrations/2025_08_31_160212_create_rooms_table.php @@ -0,0 +1,33 @@ +id(); + $table->foreignId('hotel_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->string('floor'); + $table->json('images')->nullable(); + $table->unsignedTinyInteger('bed_count')->default(1); + $table->boolean('wide')->default(false); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('rooms'); + } +}; diff --git a/resources/svg/door-open.svg b/resources/svg/door-open.svg new file mode 100644 index 0000000..eb9fb6c --- /dev/null +++ b/resources/svg/door-open.svg @@ -0,0 +1 @@ + \ No newline at end of file