feat: implement agent dashboard UI with order management, service cat…#23
feat: implement agent dashboard UI with order management, service cat…#23ahmedalbatati3 wants to merge 1 commit intomainfrom
Conversation
…egorization, and application routing
📝 WalkthroughWalkthroughIntroduces enums for laundry service types and order statuses with localized labels. Adds a language controller for locale management and updates the router to pass additional state parameters. Significantly refactors the agent dashboard into a multi-tab layout with order filtering, and redesigns order management with conditional read-only modes. Includes new app bar action widget and color palette updates. Changes
Sequence DiagramsequenceDiagram
actor User
participant Dashboard as AgentDashboardScreen
participant OrderCard as Order Card Widget
participant Router as App Router
participant Management as AgentOrderManagementScreen
participant Controller as OrderStatus
User->>Dashboard: Opens dashboard with laundryType
Dashboard->>Dashboard: Filters orders by laundryType & status
Dashboard->>OrderCard: Renders order cards with status
User->>OrderCard: Taps on order card
OrderCard->>Router: context.push with orderId & status
Router->>Management: Navigate with initialStatus & isReadOnly=false
Management->>Management: Display status chips & update UI
User->>Management: Selects new status
Management->>Controller: Update _currentStatus
User->>Management: Confirms status change
Management->>Router: context.pop(updated status)
Router->>Dashboard: Return with new OrderStatus
Dashboard->>Dashboard: setState updates order status
Dashboard->>OrderCard: Rerender with updated status
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (6)
brightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart (1)
20-20: Drop the commented-out debug line.Proposed diff
final isArabic = LanguageController().isArabic; - // final isDark = Theme.of(context).brightness == Brightness.dark; - return Row(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@brightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart` at line 20, Remove the leftover commented-out debug line "// final isDark = Theme.of(context).brightness == Brightness.dark;" from AgentAppBarActions in agent_app_bar_actions.dart (the widget file containing the app bar actions), leaving no commented debug code; simply delete that line to keep the codebase clean.brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart (2)
50-52: Default profile values are Arabic-only.The initial values (e.g.
'مغسلة الخليج','laundry@example.com'is fine) hardcode Arabic text that becomes the AppBar title on the home tab regardless of the selected locale. For mock data this is acceptable, but consider deriving defaults from the language controller or leaving placeholders until a backend hydrates them.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart` around lines 50 - 52, The hardcoded Arabic default values in TextEditingController fields (_nameController, _phoneController, _emailController) cause the AppBar/home tab to show Arabic regardless of locale; change them to use localized placeholders or empty strings instead of fixed Arabic text. Locate the controller initializations in agent_dashboard_screen.dart and replace the literal defaults with either localization lookups (e.g., use your app's localization or language controller to supply a locale-appropriate default) or simply initialize with '' so the backend/hydration or localized placeholders populate the UI. Ensure the AppBar title derives from the same localized source or controller to stay consistent with the selected locale.
191-193: Brittle time-string localization byreplaceAll.Replacing Arabic time literals (
'الآن','أمس', …) with English strings is fragile — any new time label added to the mock data will silently render in Arabic on the English path. Modeltimeas a structured value (e.g.DateTime+ a formatter, or anenum OrderTimeLabelwith localized titles likeOrderStatus) so adding new values is compile-time safe.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart` around lines 191 - 193, The current UI uses brittle string replacements on order.time (isArabic ? order.time : order.time.replaceAll(...)) which breaks on any new/changed label; instead change the data model to carry a structured time value (e.g., add a DateTime field like order.timestamp or an enum like OrderTimeLabel on the Order model) and stop using replaceAll in agent_dashboard_screen.dart; in the widget that renders the Text (where order.time and isArabic are referenced) format that DateTime with intl/DateFormat (or map the enum to localized strings via your localization/i18n mechanism) so labels are produced from a formatter or localization lookup rather than ad-hoc string replacement.brightcleanproject/lib/core/enums/laundry_type.dart (1)
1-1: Remove the commented-out import.Leftover debug artifact; no code in this file uses
material.dart.Proposed diff
-// import 'package:flutter/material.dart'; - enum LaundryType {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@brightcleanproject/lib/core/enums/laundry_type.dart` at line 1, Remove the leftover commented import line "import 'package:flutter/material.dart';" from the top of the laundry_type.dart file since no code in this file uses material.dart; simply delete the commented-out import to clean up the file.brightcleanproject/lib/core/routing/app_router.dart (1)
69-76: Defensive cast onstate.extra.
state.extra as Map<String, dynamic>?succeeds whenextraisnull, but will throw aTypeErrorif a caller ever passes a differently shapedextra(e.g. a rawOrderStatus, aMap<String, Object>, etc.). Since this is a typed parameter reachable via deep links, prefer a safer pattern:Proposed diff
- final extra = state.extra as Map<String, dynamic>?; - final initialStatus = extra?['status'] as OrderStatus? ?? OrderStatus.received; - final isReadOnly = extra?['isReadOnly'] as bool? ?? false; + final extra = state.extra is Map<String, dynamic> + ? state.extra as Map<String, dynamic> + : const <String, dynamic>{}; + final initialStatus = extra['status'] is OrderStatus + ? extra['status'] as OrderStatus + : OrderStatus.received; + final isReadOnly = extra['isReadOnly'] is bool + ? extra['isReadOnly'] as bool + : false;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@brightcleanproject/lib/core/routing/app_router.dart` around lines 69 - 76, The current unconditional cast "state.extra as Map<String, dynamic>?" can throw if callers pass a differently shaped extra; update the extraction to be defensive by checking types at runtime: treat state.extra as a Map only when "state.extra is Map" (e.g. use "final extra = state.extra is Map ? state.extra as Map<String, dynamic>? : null"), and when reading initialStatus and isReadOnly handle alternate shapes (e.g. if state.extra is OrderStatus use that for initialStatus, or if state.extra is bool use that for isReadOnly), and fall back to the defaults used when values are absent; apply these changes around the code that computes initialStatus, isReadOnly and before constructing AgentOrderManagementScreen so no TypeError can occur.brightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dart (1)
51-68: Duplicate translation tables.
_translateServiceis also defined inagent_dashboard_screen.dart(with more entries), and_translateItem/_translateServicelive only on this widget. As the app grows, these will drift. Extract into a single localization helper (e.g.lib/core/localization/ar_en_terms.dart) and have both screens import it.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@brightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dart` around lines 51 - 68, Extract the duplicate translation logic from _translateItem and _translateService into a single shared localization helper (e.g., a class or top-level module like ArEnTerms with translateItem and translateService methods) and replace the local functions in agent_order_management_screen.dart and the duplicate _translateService in agent_dashboard_screen.dart to call the shared helper; move the full master translation maps into that helper, update imports in both screens to use ArEnTerms.translateItem/translateService, and remove the now-redundant local _translateItem/_translateService definitions from those widgets.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@brightcleanproject/lib/core/localization/language_controller.dart`:
- Around line 3-17: MaterialApp's locale is hardcoded so
LanguageController.toggleLanguage() has no effect; update main.dart to stop
using the hardcoded const Locale('ar','AE') and instead bind MaterialApp.locale
to LanguageController().locale using a ValueListenableBuilder (or equivalent
ListenableBuilder) so the app rebuilds when locale changes, add Locale('en')
(and a matching country code if desired) to supportedLocales so English is
allowed, and optionally persist the selected locale from LanguageController
(e.g., via SharedPreferences) so the choice survives restarts; key symbols to
change: LanguageController.locale, LanguageController.toggleLanguage,
MaterialApp.locale and supportedLocales.
In
`@brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart`:
- Around line 316-321: The three stat cards are computed from mixed scopes
(orders/_currentOrders vs _allOrders) causing double-counting; update the stat
calculations used in _buildStatCard so they all derive from a single baseline
list built from _allOrders filtered by widget.laundryType (e.g., final baseline
= _allOrders.where((o) => o.laundryType == widget.laundryType).toList()), then
compute counts from that baseline for OrderStatus.received,
OrderStatus.inProgress, and the completed set (OrderStatus.ready or
OrderStatus.delivered) to keep totals consistent; ensure you replace the current
uses of orders/_currentOrders in these three cards with the new baseline.
- Around line 50-52: The TextEditingController instances (_nameController,
_phoneController, _emailController) are created in the State but not disposed,
causing listener leaks; fix by adding an override of dispose() in the State that
calls _nameController.dispose(), _phoneController.dispose(), and
_emailController.dispose() and then calls super.dispose(); place this dispose()
implementation in the same State class that declares those controllers (e.g.,
the AgentDashboardScreen State).
- Around line 433-451: In _showEditDialog capture the initial controller.text
into a local variable (e.g., originalText) before showing the dialog and, in the
cancel button handler (the TextButton with child 'إلغاء'), restore
controller.text = originalText before popping so edits are reverted; also make
the UI strings (the AlertDialog title, TextField hint, cancel and save button
labels currently hardcoded as 'تعديل', 'أدخل ... الجديد', 'إلغاء', 'حفظ')
conditional on the existing isArabic flag (or the app's localization helper used
elsewhere) and replace those literals with the appropriate localized variants so
the dialog respects the screen's language setting.
In
`@brightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dart`:
- Around line 45-49: The hardcoded _items List<OrderItemMock> causes every order
in AgentOrderManagementScreen to show the same items regardless of the incoming
widget.orderId; change this to generate or look up items per orderId by either:
1) keying the mock data off widget.orderId (e.g., vary names/quantities/icons
based on widget.orderId) when constructing _items, or 2) replacing the hardcoded
list with a lookup that returns items from the same source as AgentOrderModel
(or a test fixture) using widget.orderId; update the initialization of _items
(and any constructor/ initState code that references OrderItemMock) so each
order rendered reflects widget.orderId.
- Around line 256-266: The SnackBar is shown immediately before calling
context.pop which causes it to be dismissed; remove the
ScaffoldMessenger.of(context).showSnackBar call from this widget (the onPressed
handler) and instead return the updated value via context.pop(_currentStatus)
only; then show the SnackBar from the caller screen after awaiting the push/pop
result (or if you prefer an inline approach, replace the SnackBar here with an
inline confirmation widget and delay the pop using Future.delayed). Locate the
onPressed that calls ScaffoldMessenger.of(context).showSnackBar and context.pop
in agent_order_management_screen and either (A) delete the showSnackBar line and
ensure the caller awaits the route result and shows the SnackBar there, or (B)
replace the SnackBar with an inline confirmation and delay context.pop to allow
it to be seen.
- Line 99: The project uses Color.withValues(alpha: ...) which requires Flutter
SDK >=3.27.0; either raise the SDK constraint to ^3.27.0 in pubspec.yaml or
replace all occurrences (31 total across agent_order_management_screen.dart and
agent_dashboard_screen.dart) of AppColors.<color>.withValues(alpha: X) with
AppColors.<color>.withOpacity(X) (e.g., update the colors lists used for
gradients and any color manipulations in functions/widgets like the
gradient/color arrays inside AgentOrderManagementScreen and
AgentDashboardScreen) to restore compatibility with the current ^3.10.8 SDK.
In
`@brightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart`:
- Around line 45-48: The notifications IconButton (Icons.notifications_outlined)
in the AgentAppBarActions widget currently has an empty onPressed handler,
creating a no-op; replace the empty handler by wiring it to a visible stub (for
example call showModalBottomSheet to display a simple "Notifications"
placeholder or Navigator.pushNamed to a stub NotificationsPage) or hide/remove
the button until implemented; alternatively, if you intend to implement later,
add a clear TODO comment on the IconButton's onPressed referencing the
Notifications feature so it is tracked. Ensure you modify the onPressed of the
IconButton in agent_app_bar_actions.dart (or remove the IconButton) and
reference the stub route/sheet name or TODO in the change.
- Around line 38-42: The project uses the Switch widget's activeThumbColor
property (seen in the AgentAppBarActions widget where Switch(value:
isLaundryOpen!, onChanged: onAvailabilityChanged, activeThumbColor:
AppColors.success)), which requires Flutter >=3.35.0; update the pubspec.yaml
environment block to add a flutter SDK lower-bound (for example flutter:
">=3.35.0") alongside the existing Dart sdk constraint so CI and local builds
use a compatible Flutter version.
---
Nitpick comments:
In `@brightcleanproject/lib/core/enums/laundry_type.dart`:
- Line 1: Remove the leftover commented import line "import
'package:flutter/material.dart';" from the top of the laundry_type.dart file
since no code in this file uses material.dart; simply delete the commented-out
import to clean up the file.
In `@brightcleanproject/lib/core/routing/app_router.dart`:
- Around line 69-76: The current unconditional cast "state.extra as Map<String,
dynamic>?" can throw if callers pass a differently shaped extra; update the
extraction to be defensive by checking types at runtime: treat state.extra as a
Map only when "state.extra is Map" (e.g. use "final extra = state.extra is Map ?
state.extra as Map<String, dynamic>? : null"), and when reading initialStatus
and isReadOnly handle alternate shapes (e.g. if state.extra is OrderStatus use
that for initialStatus, or if state.extra is bool use that for isReadOnly), and
fall back to the defaults used when values are absent; apply these changes
around the code that computes initialStatus, isReadOnly and before constructing
AgentOrderManagementScreen so no TypeError can occur.
In
`@brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart`:
- Around line 50-52: The hardcoded Arabic default values in
TextEditingController fields (_nameController, _phoneController,
_emailController) cause the AppBar/home tab to show Arabic regardless of locale;
change them to use localized placeholders or empty strings instead of fixed
Arabic text. Locate the controller initializations in
agent_dashboard_screen.dart and replace the literal defaults with either
localization lookups (e.g., use your app's localization or language controller
to supply a locale-appropriate default) or simply initialize with '' so the
backend/hydration or localized placeholders populate the UI. Ensure the AppBar
title derives from the same localized source or controller to stay consistent
with the selected locale.
- Around line 191-193: The current UI uses brittle string replacements on
order.time (isArabic ? order.time : order.time.replaceAll(...)) which breaks on
any new/changed label; instead change the data model to carry a structured time
value (e.g., add a DateTime field like order.timestamp or an enum like
OrderTimeLabel on the Order model) and stop using replaceAll in
agent_dashboard_screen.dart; in the widget that renders the Text (where
order.time and isArabic are referenced) format that DateTime with
intl/DateFormat (or map the enum to localized strings via your localization/i18n
mechanism) so labels are produced from a formatter or localization lookup rather
than ad-hoc string replacement.
In
`@brightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dart`:
- Around line 51-68: Extract the duplicate translation logic from _translateItem
and _translateService into a single shared localization helper (e.g., a class or
top-level module like ArEnTerms with translateItem and translateService methods)
and replace the local functions in agent_order_management_screen.dart and the
duplicate _translateService in agent_dashboard_screen.dart to call the shared
helper; move the full master translation maps into that helper, update imports
in both screens to use ArEnTerms.translateItem/translateService, and remove the
now-redundant local _translateItem/_translateService definitions from those
widgets.
In
`@brightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart`:
- Line 20: Remove the leftover commented-out debug line "// final isDark =
Theme.of(context).brightness == Brightness.dark;" from AgentAppBarActions in
agent_app_bar_actions.dart (the widget file containing the app bar actions),
leaving no commented debug code; simply delete that line to keep the codebase
clean.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0d77b787-a4e8-4548-b677-dd8f8a3592e9
📒 Files selected for processing (8)
brightcleanproject/lib/core/enums/laundry_type.dartbrightcleanproject/lib/core/enums/order_status.dartbrightcleanproject/lib/core/localization/language_controller.dartbrightcleanproject/lib/core/routing/app_router.dartbrightcleanproject/lib/core/theme/app_colors.dartbrightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dartbrightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dartbrightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart
| class LanguageController { | ||
| static final LanguageController _instance = LanguageController._internal(); | ||
| factory LanguageController() => _instance; | ||
| LanguageController._internal(); | ||
|
|
||
| final ValueNotifier<Locale> locale = ValueNotifier(const Locale('ar')); | ||
|
|
||
| bool get isArabic => locale.value.languageCode == 'ar'; | ||
|
|
||
| void toggleLanguage() { | ||
| locale.value = locale.value.languageCode == 'ar' | ||
| ? const Locale('en') | ||
| : const Locale('ar'); | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm the notifier is bound to MaterialApp and that persistence exists.
rg -nP -C3 'LanguageController\(\)\.locale|MaterialApp|locale\s*:\s*'
rg -nP 'SharedPreferences|shared_preferences' -C2Repository: Klvvr1/BrightClean
Length of output: 903
🏁 Script executed:
#!/bin/bash
# Find all usages of toggleLanguage
rg -n 'toggleLanguage' -B2 -A2
# Check if locale is bound anywhere to LanguageController
rg -n 'LanguageController\(\)\.locale|locale:\s*LanguageController' -B2 -A2
# Check if there are any locale-related listeners
rg -n 'ValueListenableBuilder.*locale|locale.*ValueListenableBuilder' -B1 -A1Repository: Klvvr1/BrightClean
Length of output: 1118
🏁 Script executed:
#!/bin/bash
# Check the agent_dashboard_screen.dart around that toggle to understand the intent
cat -n brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart | sed -n '395,415p'
# Check the full MaterialApp configuration in main.dart
cat -n brightcleanproject/lib/main.dart | sed -n '12,35p'
# Search for any locale binding in the codebase
rg -n "MaterialApp.*locale|locale.*LanguageController|MaterialApp\.router.*locale" -A5
</parameter>Repository: Klvvr1/BrightClean
Length of output: 1740
🏁 Script executed:
#!/bin/bash
# Check if there's any other place where locale might be bound or overridden
rg -n "locale\s*:" brightcleanproject/lib/main.dart -A1 -B1
# Check what supportedLocales contains
rg -n "supportedLocales" brightcleanproject/lib/main.dart -A5 -B1
# Verify if the LanguageController is even used for locale in MaterialApp anywhere
rg -n "LanguageController" brightcleanproject/lib/main.dart
</parameter>Repository: Klvvr1/BrightClean
Length of output: 445
Wire LanguageController.locale to MaterialApp.locale and add 'en' to supportedLocales.
The toggleLanguage() method in LanguageController is called from the Settings tab (agent_dashboard_screen.dart:404), but it has no effect on the app. In main.dart, MaterialApp.locale is hardcoded to const Locale('ar', 'AE') and is never bound to LanguageController.locale. Additionally, supportedLocales only includes Locale('ar', 'AE'), so even if wired, switching to 'en' would fail.
To fix:
- Add
Locale('en')tosupportedLocales - Bind
MaterialApp.localetoLanguageController().locale(useValueListenableBuilderif stateful, orListenableBuilderif available) - Consider persisting the selection via
SharedPreferences
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@brightcleanproject/lib/core/localization/language_controller.dart` around
lines 3 - 17, MaterialApp's locale is hardcoded so
LanguageController.toggleLanguage() has no effect; update main.dart to stop
using the hardcoded const Locale('ar','AE') and instead bind MaterialApp.locale
to LanguageController().locale using a ValueListenableBuilder (or equivalent
ListenableBuilder) so the app rebuilds when locale changes, add Locale('en')
(and a matching country code if desired) to supportedLocales so English is
allowed, and optionally persist the selected locale from LanguageController
(e.g., via SharedPreferences) so the choice survives restarts; key symbols to
change: LanguageController.locale, LanguageController.toggleLanguage,
MaterialApp.locale and supportedLocales.
| final TextEditingController _nameController = TextEditingController(text: 'مغسلة الخليج'); | ||
| final TextEditingController _phoneController = TextEditingController(text: '+966 50 123 4567'); | ||
| final TextEditingController _emailController = TextEditingController(text: 'laundry@example.com'); |
There was a problem hiding this comment.
TextEditingControllers are never disposed.
_nameController, _phoneController, and _emailController are created in the State but there's no dispose() override. Each time the screen is rebuilt/disposed these leak their internal listeners. Override dispose:
Proposed fix
final TextEditingController _emailController = TextEditingController(text: 'laundry@example.com');
+ `@override`
+ void dispose() {
+ _nameController.dispose();
+ _phoneController.dispose();
+ _emailController.dispose();
+ super.dispose();
+ }
+
`@override`
void initState() {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| final TextEditingController _nameController = TextEditingController(text: 'مغسلة الخليج'); | |
| final TextEditingController _phoneController = TextEditingController(text: '+966 50 123 4567'); | |
| final TextEditingController _emailController = TextEditingController(text: 'laundry@example.com'); | |
| final TextEditingController _nameController = TextEditingController(text: 'مغسلة الخليج'); | |
| final TextEditingController _phoneController = TextEditingController(text: '+966 50 123 4567'); | |
| final TextEditingController _emailController = TextEditingController(text: 'laundry@example.com'); | |
| `@override` | |
| void dispose() { | |
| _nameController.dispose(); | |
| _phoneController.dispose(); | |
| _emailController.dispose(); | |
| super.dispose(); | |
| } | |
| `@override` | |
| void initState() { |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart`
around lines 50 - 52, The TextEditingController instances (_nameController,
_phoneController, _emailController) are created in the State but not disposed,
causing listener leaks; fix by adding an override of dispose() in the State that
calls _nameController.dispose(), _phoneController.dispose(), and
_emailController.dispose() and then calls super.dispose(); place this dispose()
implementation in the same State class that declares those controllers (e.g.,
the AgentDashboardScreen State).
| _buildStatCard(isArabic ? 'طلبات استلمت' : 'Received', orders.where((o) => o.status == OrderStatus.received).length.toString(), AppColors.primary, Icons.download_rounded), | ||
| const SizedBox(width: 12), | ||
| _buildStatCard(isArabic ? 'قيد التنفيذ' : 'In Progress', orders.where((o) => o.status == OrderStatus.inProgress).length.toString(), AppColors.tertiary, Icons.sync_rounded), | ||
| const SizedBox(width: 12), | ||
| _buildStatCard(isArabic ? 'مكتمل' : 'Completed', _allOrders.where((o) => o.laundryType == widget.laundryType && (o.status == OrderStatus.ready || o.status == OrderStatus.delivered)).length.toString(), AppColors.success, Icons.check_circle_rounded), | ||
| ], |
There was a problem hiding this comment.
"Completed" stat can double-count with "In Progress".
orders here is _currentOrders (filtered to status != delivered), so OrderStatus.ready orders are counted by the "Completed" tile and also appear in the home list (and potentially contribute to other visual states). Additionally, "Received"/"In Progress" read from orders, but "Completed" reads from _allOrders — mixing scopes makes the totals inconsistent when laundryType filtering or future status filters change. Consider computing all three from the same baseline (_allOrders filtered by widget.laundryType) so the stats are mutually consistent.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart`
around lines 316 - 321, The three stat cards are computed from mixed scopes
(orders/_currentOrders vs _allOrders) causing double-counting; update the stat
calculations used in _buildStatCard so they all derive from a single baseline
list built from _allOrders filtered by widget.laundryType (e.g., final baseline
= _allOrders.where((o) => o.laundryType == widget.laundryType).toList()), then
compute counts from that baseline for OrderStatus.received,
OrderStatus.inProgress, and the completed set (OrderStatus.ready or
OrderStatus.delivered) to keep totals consistent; ensure you replace the current
uses of orders/_currentOrders in these three cards with the new baseline.
| void _showEditDialog(String title, TextEditingController controller) { | ||
| showDialog( | ||
| context: context, | ||
| builder: (context) => AlertDialog( | ||
| title: Text('تعديل $title'), | ||
| content: TextField( | ||
| controller: controller, | ||
| decoration: InputDecoration(hintText: 'أدخل $title الجديد'), | ||
| ), | ||
| actions: [ | ||
| TextButton(onPressed: () => Navigator.pop(context), child: const Text('إلغاء')), | ||
| ElevatedButton(onPressed: () { | ||
| setState(() {}); | ||
| Navigator.pop(context); | ||
| }, child: const Text('حفظ')), | ||
| ], | ||
| ), | ||
| ); | ||
| } |
There was a problem hiding this comment.
Edit dialog: Cancel doesn't revert, and strings are hardcoded Arabic.
Two issues in _showEditDialog:
- The
TextFieldis live-bound to the passed controller, so any keystrokes persist even when the user taps “إلغاء” (Cancel). Keep a snapshot of the original text and restore it on cancel. 'تعديل','أدخل ... الجديد','إلغاء','حفظ'are Arabic-only even when the app is in English — inconsistent with the rest of this screen which honoursisArabic.
Sketch
- void _showEditDialog(String title, TextEditingController controller) {
+ void _showEditDialog(String title, TextEditingController controller) {
+ final isArabic = LanguageController().isArabic;
+ final original = controller.text;
showDialog(
context: context,
builder: (context) => AlertDialog(
- title: Text('تعديل $title'),
+ title: Text(isArabic ? 'تعديل $title' : 'Edit $title'),
content: TextField(
controller: controller,
- decoration: InputDecoration(hintText: 'أدخل $title الجديد'),
+ decoration: InputDecoration(
+ hintText: isArabic ? 'أدخل $title الجديد' : 'Enter new $title',
+ ),
),
actions: [
- TextButton(onPressed: () => Navigator.pop(context), child: const Text('إلغاء')),
- ElevatedButton(onPressed: () {
- setState(() {});
- Navigator.pop(context);
- }, child: const Text('حفظ')),
+ TextButton(
+ onPressed: () {
+ controller.text = original;
+ Navigator.pop(context);
+ },
+ child: Text(isArabic ? 'إلغاء' : 'Cancel'),
+ ),
+ ElevatedButton(
+ onPressed: () {
+ setState(() {});
+ Navigator.pop(context);
+ },
+ child: Text(isArabic ? 'حفظ' : 'Save'),
+ ),
],
),
);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart`
around lines 433 - 451, In _showEditDialog capture the initial controller.text
into a local variable (e.g., originalText) before showing the dialog and, in the
cancel button handler (the TextButton with child 'إلغاء'), restore
controller.text = originalText before popping so edits are reverted; also make
the UI strings (the AlertDialog title, TextField hint, cancel and save button
labels currently hardcoded as 'تعديل', 'أدخل ... الجديد', 'إلغاء', 'حفظ')
conditional on the existing isArabic flag (or the app's localization helper used
elsewhere) and replace those literals with the appropriate localized variants so
the dialog respects the screen's language setting.
| onPressed: () { | ||
| ScaffoldMessenger.of(context).showSnackBar( | ||
| SnackBar( | ||
| content: Text(isArabic ? 'تم تحديث حالة الطلب بنجاح' : 'Order status updated successfully'), | ||
| backgroundColor: AppColors.success, | ||
| behavior: SnackBarBehavior.floating, | ||
| shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), | ||
| ), | ||
| ); | ||
| context.pop(_currentStatus); | ||
| }, |
There was a problem hiding this comment.
SnackBar shown immediately before context.pop will be dismissed.
showSnackBar queues the snack on the nearest ScaffoldMessenger, but the very next statement pops this route. In practice the SnackBar either appears on the previous screen (if the messenger is app-level) or flashes and is torn down. Either show it on the previous screen after pop, or replace with an inline confirmation and delay the pop.
Suggested pattern
onPressed: () {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(isArabic ? 'تم تحديث حالة الطلب بنجاح' : 'Order status updated successfully'),
- backgroundColor: AppColors.success,
- behavior: SnackBarBehavior.floating,
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
- ),
- );
context.pop(_currentStatus);
},Then show the confirmation on the caller (dashboard) once the awaited result arrives.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| onPressed: () { | |
| ScaffoldMessenger.of(context).showSnackBar( | |
| SnackBar( | |
| content: Text(isArabic ? 'تم تحديث حالة الطلب بنجاح' : 'Order status updated successfully'), | |
| backgroundColor: AppColors.success, | |
| behavior: SnackBarBehavior.floating, | |
| shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), | |
| ), | |
| ); | |
| context.pop(_currentStatus); | |
| }, | |
| onPressed: () { | |
| context.pop(_currentStatus); | |
| }, |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@brightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dart`
around lines 256 - 266, The SnackBar is shown immediately before calling
context.pop which causes it to be dismissed; remove the
ScaffoldMessenger.of(context).showSnackBar call from this widget (the onPressed
handler) and instead return the updated value via context.pop(_currentStatus)
only; then show the SnackBar from the caller screen after awaiting the push/pop
result (or if you prefer an inline approach, replace the SnackBar here with an
inline confirmation widget and delay the pop using Future.delayed). Locate the
onPressed that calls ScaffoldMessenger.of(context).showSnackBar and context.pop
in agent_order_management_screen and either (A) delete the showSnackBar line and
ensure the caller awaits the route result and shows the SnackBar there, or (B)
replace the SnackBar with an inline confirmation and delay context.pop to allow
it to be seen.
| IconButton( | ||
| icon: const Icon(Icons.notifications_outlined), | ||
| onPressed: () {}, | ||
| ), |
There was a problem hiding this comment.
Notifications button is a no-op.
onPressed: () {} gives the appearance of an interactive notifications entry point but does nothing. Either wire it up (even if just to a stub route/bottom-sheet), hide the button until implemented, or leave a // TODO comment so it's tracked.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@brightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart`
around lines 45 - 48, The notifications IconButton
(Icons.notifications_outlined) in the AgentAppBarActions widget currently has an
empty onPressed handler, creating a no-op; replace the empty handler by wiring
it to a visible stub (for example call showModalBottomSheet to display a simple
"Notifications" placeholder or Navigator.pushNamed to a stub NotificationsPage)
or hide/remove the button until implemented; alternatively, if you intend to
implement later, add a clear TODO comment on the IconButton's onPressed
referencing the Notifications feature so it is tracked. Ensure you modify the
onPressed of the IconButton in agent_app_bar_actions.dart (or remove the
IconButton) and reference the stub route/sheet name or TODO in the change.
|
closes#12 |
|
Fix issues from the CodeRabbit Bot that were Submited In Each File, unviewed |
closes#12
…egorization, and application routing
Summary by CodeRabbit
Release Notes
New Features
Improvements