Flutter frontend for pcv4maxpro.
A few resources to get you started if this is your first Flutter project:
For help getting started with Flutter, view the online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.
This Flutter project is largely based on the domain-driven design guidelines from ResoCoder and is divided primarily into 4 layers:
- Presentation - Flutter pages and widgets
- Application - UI state and event logic
- Domain - core abstractions of basic components
- Infrastructure - external API calls and exception handling
These layers live in their respective folders under lib/
.
Each feature in the app can require code in multiple layers. Note that the application and infrastructure layers should not talk to each other directly, only through the domain layer.
Dependencies are automatically managed using injectable,
which uses code generation to automatically register services marked with @injectable
.
In order to run the project simply use
flutter run
or your IDE runner.
When working on a feature, first determine the layers that must be modified. Generally, you would start with the domain layer and move into the outer layers.
This project relies heavily on several tools that work using code generation, namely:
When working with these packages, start code generation by running:
flutter pub run build_runner watch --delete-conflicting-outputs
This layer uses freezed
a lot,
so make sure to run the code generation command if edit things here.
If the feature requires additional abstractions such as interfaces, entities, or failures, those would be placed in that feature's folder in the domain layer.
Simple examples of these can be seen here:
- Interface -
IAuthFacade
- Entity -
User
- Failure -
AuthFailure
This layer uses freezed
and injectable
a lot,
so make sure to run the code generation command if edit things here.
This layer describes the possible states and events of the UI.
The general pattern for state is to have a freezed
union for the UI state,
and in the case of forms a freezed
data class for the form state.
Simple examples of these can be seen here:
- UI state -
AuthState
- Form state -
SignInFormState
In order to change the state,
the UI must emit events which are also defined as a freezed
union, such as:
- UI events -
AuthEvent
- Form events -
SignInFormEvent
These events are then handled by the BLoC (Business Logic Component), which changes the state as needed based on events it receives. See it in action here:
- UI Bloc -
AuthBloc
- Form Bloc -
SignInFormBloc
The presentation layer is made-up entirely of Flutter-specific code and widgets. The directory layout is as follows:
- app_widget.dart - root Flutter widget, MaterialApp
- pages - Flutter code for pages and UI components
- routes - aggregate all the pages into URL-style paths
Each page the class name should end in Page
(e.g. SignInPage),
it should have its own directory, and can have a widgets
subfolder for its components.
To make a page accessible, add a route for it in app_router.dart
and run the code generation command.
This generates a corresponding class to the page, e.g. SignInPageRoute
for SignInPage
in app_router.gr.dart
The infrastructure layer should implement interfaces defined in the domain layer, such as:
- implements
IAuthFacade
-Auth0AuthFacade