The Hotel Booking App is designed to help users browse and favorite hotels across various locations. It follows Model–view–viewmodel (MVVM) and clean architecture principles for a modular and scalable structure, BLoC (Business Logic Component) pattern for state management, and GetIt for dependency injection. The project is structured around best practices to ensure maintainability, scalability, and ease of testing.
- Displays a comprehensive list of hotels with details such as name, price, and room features.
Each hotel card includes:
- Hotel name
- Hotel image
- Hotel price (total and per person)
- Room details (e.g., room type, boarding)
- Rating score and number of reviews
- Add hotels to a favorites list by tapping the heart icon.
- Manage your favorite hotels directly from the Favorites tab.
- Persist favorite hotels using Hive for local storage.
- Displays appropriate error messages when hotel data fails to load.
- Shows an empty state when no hotels match the search criteria.
- Model-View-ViewModel (MVVM) separates business logic from framework-specific code, leading to a modular and maintainable architecture.
- Clean architecture principles ensure scalability, testability, and flexibility.
- Using flutter_bloc for state management to achieve separation of concerns, reactive updates, and a clean codebase.
- GetIt is used for dependency injection, simplifying the management of dependencies and improving testability and modularity.
- Freezed is used with JSON Serializable to generate immutable data classes and handle serialization/deserialization.
- Mocktail: Provides an expressive API for creating and verifying mock objects in unit tests.
- bloc_test: Simplifies testing BLoC/Cubit logic by providing tools to simulate actions and verify state transitions.
Integration Testing: End-to-end tests ensure the complete functionality of the app works correctly across multiple platforms. Integration tests simulate real user interactions and verify that the entire app behaves as expected, from navigating screens to managing favorites. Using integration_test, tests can be automated to ensure reliability.
- flutter_bloc: For managing state transitions using the BLoC pattern.
- get_it: For dependency injection and service locator functionality.
- freezed: For creating immutable data classes and handling union types.
- hive: For local storage of favorite hotels.
This application has been tested on the following platforms:
- Android
- iOS
- macOS
.
├── data
│ ├── app_repository_imp.dart
│ ├── datasources
│ │ ├── favourite_local_data_source.dart
│ │ └── hotels_remote_data_source.dart
│ ├── dto_models
│ │ ├── hotel_dto.dart
│ │ ├── hotel_dto.freezed.dart
│ │ └── hotel_dto.g.dart
│ ├── error_handlers
│ │ └── dio_error_handler.dart
│ ├── mappers
│ │ ├── hotel_dto_mapper.dart
│ │ ├── hotel_hive_mapper.dart
│ │ └── mappers.dart
│ └── storage
│ ├── hotel_database_model.dart
│ └── hotel_database_model.g.dart
├── domain
│ ├── app_repository.dart
│ ├── entities
│ │ ├── hotel_entity.dart
│ │ └── hotel_entity.freezed.dart
│ ├── failure.dart
│ └── usecases
│ ├── favourite
│ │ ├── add_to_favourites_use_case.dart
│ │ ├── favourite_usecases.dart
│ │ ├── get_favourites_use_case.dart
│ │ └── remove_from_favourites_use_case.dart
│ └── hotel
│ └── fetch_hotels_use_case.dart
├── main.dart
├── presentation
│ ├── app_theme.dart
│ ├── cubits
│ │ ├── favourite
│ │ │ ├── favourite_cubit.dart
│ │ │ ├── favourite_cubit.freezed.dart
│ │ │ └── favourite_state.dart
│ │ └── hotel
│ │ ├── hotel_cubit.dart
│ │ ├── hotel_cubit.freezed.dart
│ │ └── hotel_state.dart
│ ├── router
│ │ ├── app_router.dart
│ │ └── app_router.gr.dart
│ └── screens
│ ├── account_screen.dart
│ ├── bottom_nav_screen.dart
│ ├── favourites_screen.dart
│ ├── hotels_screen.dart
│ ├── overview_screen.dart
│ ├── screens.dart
│ └── widgets
│ ├── hotel_card.dart
│ ├── hotel_details.dart
│ └── rating_badge.dart
└── setup.dart
- Flutter SDK: Make sure you have Flutter installed on your machine.
-
Clone the repository:
git clone https://github.com/sherifhasan/hotels_booking.git cd hotels_booking
-
Install dependencies:
flutter pub get
-
Generate output files:
dart run build_runner build --delete-conflicting-outputs
-
Run the app:
flutter run