The Absence Manager is an application designed to help clients manage and visualize employee absences efficiently. It follows Domain-Driven Design (DDD) and clean architecture for a modular architecture, 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. The app offers paginated lists, filtering capabilities, and an intuitive user experience for managing absences.
You can view a live demo of the app hosted on GitHub Pages at the following link:
- View a comprehensive list of absences with employee names and other relevant details.
- Initially displays the first 10 absences.
- Supports infinite scrolling to load more absences as you reach the end of the list.
- Displays the total number of absences in the system for tracking.
Each absence entry includes:
- Employee name
- Type of absence (e.g., Vacation, Sickness)
- Absence period (start and end dates)
- Optional member note
- Absence status (Requested, Confirmed, or Rejected)
- Optional admittance note
- Filter absences by type (e.g., Vacation, Sickness).
- Filter absences by date using a date range picker.
- Displays a loading indicator while fetching the list of absences.
- Shows an error message if the list of absences fails to load.
- Displays an empty state if no absences match the search criteria.
- Domain-Driven Design (DDD) separates domain logic from framework-specific code, leading to a modular and maintainable architecture.
- DDD principles in Flutter improve testability, scalability, and flexibility.
Using bloc for state management provides separation of concerns, flexibility, and reactive updates, ensuring a well-structured codebase.
- GETIT is used for dependency injection, simplifying singleton management and testing.
- Improves code organization and modularity.
- Freezed is used with JSON Serializable for generating immutable data classes and handling serialization/deserialization.
- Flutter hooks enhance readability by removing the need for
StatefulWidget
andsetState
, reducing boilerplate code
- Mocktail provides a clean and expressive API for creating and verifying mock objects in unit tests.
- bloc_test simplifies testing BLoC/Cubit by providing structured tools to simulate actions and verify state transitions. It ensures that given inputs result in expected outputs in BLoC’s state management.
- flutter_bloc: Manages state transitions using the BLoC pattern.
- get_it: Provides dependency injection and service locator capabilities.
- freezed: Creates immutable data classes and handles union types.
- flutter_hooks: Simplifies state management with a more reactive approach.
This application has been tested on the following platforms:
- Android
- iOS
- macOS
- Web
.
├── data
│ ├── app_repository_imp.dart
│ ├── datasource
│ │ ├── data_source.dart
│ │ └── local_data_source.dart
│ └── dto_models
│ ├── absence_dto.dart
│ ├── absence_dto.freezed.dart
│ ├── absence_dto.g.dart
│ ├── dto_models.dart
│ ├── member_dto.dart
│ ├── member_dto.freezed.dart
│ └── member_dto.g.dart
├── domain
│ ├── app_repository.dart
│ ├── entities
│ │ ├── absence_entity.dart
│ │ ├── absence_entity.freezed.dart
│ │ ├── entities.dart
│ │ ├── member_entity.dart
│ │ └── member_entity.freezed.dart
│ └── usecases
│ ├── filter_absences_by_date.dart
│ ├── filter_absences_by_type.dart
│ ├── load_initial_data.dart
│ ├── load_more_absences.dart
│ └── usecases.dart
├── injection.dart
├── main.dart
└── presentation
├── cubits
│ ├── absence_cubit.dart
│ ├── absence_cubit.freezed.dart
│ └── absence_state.dart
├── screens
│ ├── attendance_screen.dart
│ └── views
│ ├── absence_item.dart
│ ├── absence_list.dart
│ ├── filter_options.dart
│ └── views.dart
└── utils.dart
- Flutter SDK: Ensure you have Flutter installed on your machine.
-
Clone the repository:
git clone https://github.com/sherifhasan/absence_manager.git cd absence_manager
-
Install dependencies:
flutter pub get
-
Generate output files:
dart run build_runner build --delete-conflicting-outputs
-
Run the app:
flutter run