Skip to content

Commit 652414e

Browse files
authored
Merge pull request #6 from flutter-news-app-full-source-code/enhance_dashboard_docs
Enhance dashboard docs
2 parents d9e1e70 + a8f545f commit 652414e

File tree

12 files changed

+413
-141
lines changed

12 files changed

+413
-141
lines changed

astro.config.mjs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,35 @@ export default defineConfig({
9090
label: 'Features',
9191
collapsed: true,
9292
items: [
93+
{ label: 'Dashboard Overview', link: '/web-dashboard/features/dashboard-overview' },
94+
{ label: 'Content Management', link: '/web-dashboard/features/content-management' },
9395
{ label: 'App Configuration', link: '/web-dashboard/features/app-configuration' },
9496
{ label: 'Authentication', link: '/web-dashboard/features/authentication' },
95-
{ label: 'Content Management', link: '/web-dashboard/features/content-management' },
96-
{ label: 'Dashboard Overview', link: '/web-dashboard/features/dashboard-overview' },
97+
],
98+
},
99+
{
100+
label: 'Architecture',
101+
collapsed: true,
102+
items: [
103+
{ label: 'Overview', link: '/web-dashboard/architecture/overview' },
104+
{ label: 'State Management (BLoC)', link: '/web-dashboard/architecture/state-management' },
105+
{ label: 'Routing (go_router)', link: '/web-dashboard/architecture/routing' },
106+
],
107+
},
108+
{
109+
label: 'Guides',
110+
collapsed: true,
111+
items: [
112+
{ label: 'Theming & Customization', link: '/web-dashboard/guides/theming-and-customization' },
113+
{ label: 'Adding a New Language', link: '/web-dashboard/guides/adding-a-new-language' },
114+
],
115+
},
116+
{
117+
label: 'Manuals',
118+
collapsed: true,
119+
items: [
120+
{ label: 'Managing Content', link: '/web-dashboard/manuals/managing-content' },
121+
{ label: 'Configuring the Mobile App', link: '/web-dashboard/manuals/configuring-the-app' },
97122
],
98123
},
99124
{ label: 'Deployment', link: '/web-dashboard/deployment' },
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
title: Architecture Overview
3+
description: An overview of the architectural patterns and structure of the Flutter web dashboard.
4+
---
5+
6+
import { Aside } from '@astrojs/starlight/components';
7+
8+
The Flutter News App Web Dashboard is built upon a clean, scalable, and maintainable architecture that separates concerns into distinct layers. This approach, combined with the use of shared packages, ensures that the codebase is both robust and easy to extend.
9+
10+
### Layered Architecture
11+
12+
The dashboard follows a classic layered architecture, ensuring a clear separation of responsibilities:
13+
14+
1. **Presentation Layer (UI):** This is the user-facing layer, built with Flutter widgets. It is responsible for displaying the UI and capturing user input. It is kept as "dumb" as possible, meaning it contains minimal logic and simply reflects the state provided by the Business Logic Layer.
15+
16+
2. **Business Logic Layer (BLoC):** This layer contains the application's state management and business rules. We use the **BLoC (Business Logic Component)** pattern to manage the flow of information from user events to UI states. Feature-specific BLoCs (e.g., `ContentManagementBloc`, `DashboardBloc`) orchestrate data from the Repository Layer and emit states for the UI to consume.
17+
18+
3. **Repository Layer:** This layer abstracts the origin of the data. It provides a clean, simple API for the Business Logic Layer to access data, without needing to know whether the data is coming from a remote API or a local in-memory source. This is a key part of our strategy for testability and environment flexibility.
19+
20+
4. **Data Layer (Clients):** This is the lowest layer, responsible for the actual data retrieval. It consists of `Client` implementations that communicate with external sources. For the dashboard, this means either an `HttpDataClient` that makes requests to the API server or an `InMemoryDataClient` used for the demo environment.
21+
22+
<Aside>
23+
The Repository and Data layers are not implemented directly within the dashboard. Instead, the dashboard consumes them as shared packages, which are used across the entire ecosystem (including the mobile app and API server).
24+
</Aside>
25+
26+
### Core Principles
27+
28+
- **Dependency Injection:** Repositories and other services are provided to the widget tree using `RepositoryProvider` and `BlocProvider`. This decouples our components and makes them highly testable.
29+
- **Immutability:** All data models and BLoC states are immutable, which leads to more predictable state management and reduces the risk of side effects.
30+
- **Shared Packages:** The dashboard leverages a suite of shared packages for core functionality (e.g., `core`, `data_repository`, `auth_repository`, `ui_kit`). This promotes code reuse and consistency across the entire project ecosystem.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
title: Routing (go_router)
3+
description: An explanation of how navigation and routing are handled in the web dashboard using go_router.
4+
---
5+
6+
Navigation within the web dashboard is managed by the powerful [`go_router`](https://pub.dev/packages/go_router) package. This provides a robust, URL-based routing system that is essential for a web application.
7+
8+
Our routing configuration is centralized in the `lib/router/` directory.
9+
10+
### `StatefulShellRoute` for Persistent Navigation
11+
12+
The main dashboard interface, which includes the top app bar and the side navigation rail, is built using a `StatefulShellRoute`. This is a specialized route type from `go_router` that is perfect for creating scaffolded UI with persistent navigation.
13+
14+
It allows us to define several independent navigation "branches," one for each of our main sections:
15+
- Dashboard
16+
- Content Management
17+
- App Configuration
18+
19+
When a user navigates between these sections, `StatefulShellRoute` preserves the state of each branch, including the scroll position and any nested navigation.
20+
21+
### Authentication and Redirects
22+
23+
The router is tightly integrated with the `AppBloc` to handle authentication-based redirects automatically.
24+
25+
- The `GoRouter` is configured with a `refreshListenable` that listens to changes in the authentication status from the `AppBloc`.
26+
- A `redirect` function checks the user's authentication status on every navigation change.
27+
- If an unauthenticated user tries to access any page other than the sign-in page, they are automatically redirected to `/authentication`.
28+
- If an authenticated user tries to access the sign-in page, they are automatically redirected to the main `/dashboard`.
29+
30+
This ensures that the application's routes are always protected and that users are guided to the correct screen based on their session status.
31+
32+
### Named Routes
33+
34+
To prevent the use of hardcoded URL strings and to make navigation more maintainable, we use **named routes**. All route paths and names are defined as constants in the `lib/router/routes.dart` file.
35+
36+
When navigating, we use methods like `context.goNamed('routeName')` instead of `context.go('/some/path')`. This makes the code cleaner and less prone to errors if a URL path needs to be changed in the future.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
title: State Management (BLoC)
3+
description: An explanation of how the BLoC pattern is used for state management in the web dashboard.
4+
---
5+
6+
State management in the web dashboard is handled predictably and robustly using the **BLoC (Business Logic Component)** pattern. This pattern helps to separate business logic from the UI, leading to a more organized, testable, and scalable application.
7+
8+
We utilize two main categories of BLoCs:
9+
10+
### 1. Global `AppBloc`
11+
12+
The `AppBloc` is a high-level BLoC that is provided at the root of the application. It is responsible for managing global state that affects the entire application. Its key responsibilities include:
13+
14+
- **Authentication Status:** It listens to the `authStateChanges` stream from the `AuthRepository` and holds the current authentication status (`authenticated`, `unauthenticated`). This is used by the router to handle redirects.
15+
- **Current User:** It holds the `User` object for the currently authenticated user.
16+
- **User App Settings:** It loads and holds the `UserAppSettings`, which includes the user's preferred theme, language, and other display preferences. This allows the entire UI to react instantly to changes made in the settings page.
17+
18+
### 2. Feature-Specific BLoCs
19+
20+
Each major feature or section of the dashboard has its own dedicated BLoC to manage its specific state. This keeps the logic for each feature encapsulated and independent.
21+
22+
- **`DashboardBloc`:** Responsible for fetching and holding the dashboard summary statistics and the list of recent headlines.
23+
- **`ContentManagementBloc`:** Manages the state for the three content tabs (Headlines, Topics, Sources), including loading, paginating, and deleting content.
24+
- **`AppConfigurationBloc`:** Manages the state of the remote configuration form, tracking user edits, handling save operations, and managing the "dirty" state of the form.
25+
- **`AuthenticationBloc`:** Manages the state of the sign-in flow, such as handling loading states when a code is requested or verified.
26+
- **`SettingsBloc`:** Manages the state of the settings page, loading the user's current settings and processing update events.
27+
- **Create/Edit BLoCs:** Each create and edit page (e.g., `CreateHeadlineBloc`, `EditTopicBloc`) has its own BLoC to manage the state of the form fields, validation, and the submission process.
28+
29+
### The Flow of Data
30+
31+
The typical data flow for a feature follows this pattern:
32+
33+
1. **UI Event:** A user interacts with a widget, which dispatches an `Event` to its corresponding BLoC (e.g., `LoadHeadlinesRequested`).
34+
2. **BLoC Processes Event:** The BLoC receives the event, calls one or more methods on its injected `Repository` to fetch or update data.
35+
3. **Repository Fetches Data:** The `Repository` communicates with the `DataClient` to get data from the API or in-memory source.
36+
4. **BLoC Emits State:** Based on the result from the repository (success or failure), the BLoC emits a new `State` object.
37+
5. **UI Rebuilds:** A `BlocBuilder` or `BlocListener` in the UI layer listens for state changes and rebuilds the relevant parts of the widget tree to reflect the new state.

src/content/docs/web-dashboard/deployment.mdx

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ description: A guide to building and deploying the Flutter web dashboard to a pr
55

66
import { Steps, Aside } from '@astrojs/starlight/components';
77

8-
This guide covers the essential steps for deploying the Flutter News App Web Dashboard to a production hosting service.
8+
This guide outlines the process for deploying the Flutter News App Web Dashboard.
9+
10+
<Aside>
11+
To ensure you have the most reliable and up-to-date instructions, this guide will direct you to the official Flutter documentation. The process of building and deploying a Flutter web app is well-documented by the Flutter team, and their guide is the definitive resource for this task.
12+
</Aside>
913

1014
<Steps>
1115
1. **Configure for Production**
@@ -25,51 +29,13 @@ This guide covers the essential steps for deploying the Flutter News App Web Das
2529
Ensure that the `baseUrl` for the `production` environment in `lib/app/config/app_config.dart` points to the correct URL of your deployed [API Server](/docs/api-server/deployment/).
2630
</Aside>
2731

28-
2. **Build the Web Application**
29-
30-
Next, create a production-optimized build of the Flutter web app. This compiles the Dart code to JavaScript and bundles all necessary assets for web deployment.
31-
32-
Run the following command from the root of your web dashboard project:
33-
```bash
34-
flutter build web
35-
```
36-
This will generate a `build/web` directory containing all the static files for your web application.
37-
38-
3. **Choose a Hosting Provider**
39-
40-
You can deploy the contents of the `build/web` directory to any hosting service that supports static websites. Popular and easy-to-use choices include:
41-
42-
- [Firebase Hosting](https://firebase.google.com/docs/hosting)
43-
- [Vercel](https://vercel.com/)
44-
- [Netlify](https://www.netlify.com/for/web-applications/)
45-
- [GitHub Pages](https://docs.github.com/en/pages)
46-
47-
4. **Deploy the Application**
32+
2. **Follow the Official Flutter Deployment Guide**
4833

49-
Follow the deployment instructions for your chosen hosting provider. The general process involves:
34+
The Flutter team provides a comprehensive guide that covers everything you need to know about building and deploying a Flutter web application. This includes compiling your Dart code to JavaScript and deploying the output to various hosting services.
5035

51-
- Initializing the hosting service in your project directory.
52-
- Specifying the `build/web` directory as the public or publish directory.
53-
- Running the provider's deploy command from your terminal.
54-
55-
For example, if you were using Firebase Hosting, the commands would look something like this:
56-
57-
```bash
58-
# Install Firebase CLI (if you haven't already)
59-
npm install -g firebase-tools
60-
61-
# Log in to Firebase
62-
firebase login
63-
64-
# Initialize Firebase in your project
65-
firebase init hosting
66-
67-
# When prompted, set the public directory to "build/web"
68-
69-
# Deploy to Firebase Hosting
70-
firebase deploy
71-
```
36+
Please follow the official guide here:
37+
**[Build and release a web app](https://flutter.dev/docs/deployment/web)**
7238

73-
Once the deployment is complete, your web dashboard will be live at the URL provided by your hosting service.
39+
This guide will walk you through the `flutter build web` command and provide best practices for hosting the contents of the generated `build/web` directory.
7440

7541
</Steps>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
title: Adding a New Language
3+
description: A guide for developers on how to add a new language for localization.
4+
---
5+
6+
import { Steps } from '@astrojs/starlight/components';
7+
8+
The web dashboard is built with localization in mind, making it straightforward to add support for new languages. The process involves creating a new `.arb` file and updating a few places in the code.
9+
10+
<Steps>
11+
1. **Create a New `.arb` File**
12+
13+
Application strings are stored in Application Resource Bundle (`.arb`) files located in `lib/l10n/arb/`.
14+
15+
- Duplicate the `app_en.arb` file.
16+
- Rename the new file to `app_<language_code>.arb`, where `<language_code>` is the two-letter ISO 639-1 code for the new language (e.g., `app_es.arb` for Spanish).
17+
- Translate all the string values in the new file.
18+
19+
2. **Update `l10n.yaml`**
20+
21+
The `l10n.yaml` file in the root of the project configures the code generation for localization.
22+
23+
- Open `l10n.yaml`.
24+
- Add your new `.arb` file to the list.
25+
26+
```yaml title="l10n.yaml"
27+
arb-dir: lib/l10n/arb
28+
template-arb-file: app_en.arb
29+
output-localization-file: app_localizations.dart
30+
```
31+
32+
3. **Run Code Generation**
33+
34+
Flutter's localization tool will automatically generate the necessary Dart code to support the new language.
35+
36+
Run the following command in your terminal:
37+
```bash
38+
flutter gen-l10n
39+
```
40+
41+
4. **Update the Settings Page**
42+
43+
To make the new language selectable by the user, you need to add it to the settings page UI.
44+
45+
- Open `lib/settings/view/settings_page.dart`.
46+
- Locate the `_LanguageSelectionList` widget.
47+
- Add the new language code to the `_supportedLanguages` list.
48+
- Add a case to the `_getLanguageName` method to provide a display name for the new language.
49+
50+
```dart title="lib/settings/view/settings_page.dart"
51+
class _LanguageSelectionList extends StatelessWidget {
52+
// ...
53+
54+
String _getLanguageName(AppLanguage language, AppLocalizations l10n) {
55+
switch (language) {
56+
case 'en':
57+
return l10n.englishLanguage;
58+
case 'ar':
59+
return l10n.arabicLanguage;
60+
// Add your new language here
61+
case 'es':
62+
return 'Español'; // This should come from your .arb file
63+
}
64+
}
65+
66+
// Add your new language code here
67+
static const List<AppLanguage> _supportedLanguages = ['en', 'ar', 'es'];
68+
}
69+
```
70+
71+
</Steps>
72+
73+
After completing these steps, the new language will be fully integrated into the web dashboard.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
title: Theming & Customization
3+
description: A developer's guide to customizing the visual appearance of the web dashboard.
4+
---
5+
6+
The web dashboard's visual theme is managed through a centralized and flexible system, making it easy to customize the appearance to match your brand. The theming is handled within the shared `ui_kit` package, primarily in the `packages/ui-kit/lib/src/theme/app_theme.dart` file.
7+
8+
### Theming with `flex_color_scheme`
9+
10+
We use the powerful [`flex_color_scheme`](https://pub.dev/packages/flex_color_scheme) package to create and manage our `ThemeData`. This package simplifies the process of creating consistent and beautiful color schemes and component themes.
11+
12+
The core of the theming is in the `lightTheme()` and `darkTheme()` functions in `app_theme.dart`.
13+
14+
### Customizing Colors
15+
16+
You can change the entire color palette of the dashboard by modifying the `FlexScheme` used.
17+
18+
1. **Open `app.dart`:** Navigate to `apps/flutter-news-app-web-dashboard-full-source-code/lib/app/view/app.dart`.
19+
2. **Locate the Theme Generation:** Find the `build` method of the `_AppViewState` widget.
20+
3. **Change the `FlexScheme`:** The `accentTheme` from the user's settings is converted to a `FlexScheme`. You can change which `AppAccentTheme` enum value is the default in the `AppBloc` or modify the `toFlexScheme` extension to use different schemes from the `FlexScheme` enum.
21+
22+
```dart title="lib/app/view/app.dart"
23+
extension AppAccentThemeExtension on AppAccentTheme {
24+
FlexScheme get toFlexScheme {
25+
switch (this) {
26+
case AppAccentTheme.defaultBlue:
27+
// Change this to another FlexScheme, e.g., FlexScheme.deepPurple
28+
return FlexScheme.materialHc;
29+
case AppAccentTheme.newsRed:
30+
return FlexScheme.redWine;
31+
case AppAccentTheme.graphiteGray:
32+
return FlexScheme.outerSpace;
33+
}
34+
}
35+
}
36+
```
37+
38+
### Customizing Fonts
39+
40+
The application uses Google Fonts by default. You can change the default font or add new ones.
41+
42+
1. **Open `app_theme.dart`:** Navigate to `packages/ui-kit/lib/src/theme/app_theme.dart`.
43+
2. **Modify `_getGoogleFontTextTheme`:** This function maps a font family name (string) to a `GoogleFonts` text theme function. You can add new cases for other fonts available in the `google_fonts` package.
44+
3. **Update `_supportedFontFamilies`:** In `apps/flutter-news-app-web-dashboard-full-source-code/lib/settings/view/settings_page.dart`, add the new font family name to the `_supportedFontFamilies` list to make it available in the user's settings.
45+
46+
### Customizing Spacing
47+
48+
Consistent spacing is managed by the `AppSpacing` class in `packages/ui-kit/lib/src/constants/app_spacing.dart`. If you need to adjust the global spacing values (e.g., change the small spacing from `8.0` to `10.0`), you can do so in this file, and the changes will be reflected across the entire application.

0 commit comments

Comments
 (0)