Skip to content

feat: implement agent dashboard UI with order management, service cat…#23

Open
ahmedalbatati3 wants to merge 1 commit intomainfrom
agent_screen_change_status
Open

feat: implement agent dashboard UI with order management, service cat…#23
ahmedalbatati3 wants to merge 1 commit intomainfrom
agent_screen_change_status

Conversation

@ahmedalbatati3
Copy link
Copy Markdown
Collaborator

@ahmedalbatati3 ahmedalbatati3 commented Apr 24, 2026

closes#12
…egorization, and application routing

Summary by CodeRabbit

Release Notes

  • New Features

    • Added multi-language support with Arabic/English toggle
    • Service categorization for different laundry types (clothes, vehicles, carpets, AC units, tanks, solar panels)
    • Order status tracking with visual indicators and progress badges
    • Dashboard navigation with Home, Orders history, and Settings sections
  • Improvements

    • Enhanced agent dashboard with modern, reorganized layout
    • Improved order management interface with read-only mode for completed orders
    • Updated app color scheme for improved visual consistency

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

📝 Walkthrough

Walkthrough

Introduces 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

Cohort / File(s) Summary
Enums
brightcleanproject/lib/core/enums/laundry_type.dart, brightcleanproject/lib/core/enums/order_status.dart
Introduces LaundryType enum with six service categories and OrderStatus enum with four states, each carrying localized Arabic/English titles. OrderStatus also includes UI color mappings.
Core Infrastructure
brightcleanproject/lib/core/localization/language_controller.dart, brightcleanproject/lib/core/routing/app_router.dart, brightcleanproject/lib/core/theme/app_colors.dart
Adds singleton LanguageController for locale switching. Updates router to extract and pass OrderStatus and isReadOnly from route extras. Refreshes color palette values and repositions status colors.
Agent Dashboard & Order Management
brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart, brightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dart
Converts AgentDashboardScreen to StatefulWidget with multi-tab navigation, order filtering by laundryType, and interactive order cards. Redesigns AgentOrderManagementScreen with initialStatus and isReadOnly parameters, conditional editing UI, and modern status chips.
Agent UI Widgets
brightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart
New AgentAppBarActions widget providing conditional availability switch, notification icon, and settings button with locale-aware labels.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hops of joy through code so bright,
New enums dance in morning light,
Orders flow through status lanes,
While locales switch through arabic chains,
Dashboard blooms in multi-tab delight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main changes: implementing an agent dashboard UI with order management and service categorization. It is specific, clear, and reflects the primary focus of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent_screen_change_status

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 by replaceAll.

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. Model time as a structured value (e.g. DateTime + a formatter, or an enum OrderTimeLabel with localized titles like OrderStatus) 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 on state.extra.

state.extra as Map<String, dynamic>? succeeds when extra is null, but will throw a TypeError if a caller ever passes a differently shaped extra (e.g. a raw OrderStatus, a Map<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.

_translateService is also defined in agent_dashboard_screen.dart (with more entries), and _translateItem/_translateService live 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

📥 Commits

Reviewing files that changed from the base of the PR and between dd557aa and 623bf35.

📒 Files selected for processing (8)
  • brightcleanproject/lib/core/enums/laundry_type.dart
  • brightcleanproject/lib/core/enums/order_status.dart
  • brightcleanproject/lib/core/localization/language_controller.dart
  • brightcleanproject/lib/core/routing/app_router.dart
  • brightcleanproject/lib/core/theme/app_colors.dart
  • brightcleanproject/lib/features/agent/presentation/agent_dashboard_screen.dart
  • brightcleanproject/lib/features/agent/presentation/agent_order_management_screen.dart
  • brightcleanproject/lib/features/agent/presentation/widgets/agent_app_bar_actions.dart

Comment on lines +3 to +17
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');
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 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' -C2

Repository: 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 -A1

Repository: 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:

  1. Add Locale('en') to supportedLocales
  2. Bind MaterialApp.locale to LanguageController().locale (use ValueListenableBuilder if stateful, or ListenableBuilder if available)
  3. 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.

Comment on lines +50 to +52
final TextEditingController _nameController = TextEditingController(text: 'مغسلة الخليج');
final TextEditingController _phoneController = TextEditingController(text: '+966 50 123 4567');
final TextEditingController _emailController = TextEditingController(text: 'laundry@example.com');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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).

Comment on lines +316 to +321
_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),
],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

"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.

Comment on lines +433 to 451
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('حفظ')),
],
),
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Edit dialog: Cancel doesn't revert, and strings are hardcoded Arabic.

Two issues in _showEditDialog:

  1. The TextField is 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.
  2. 'تعديل', 'أدخل ... الجديد', 'إلغاء', 'حفظ' are Arabic-only even when the app is in English — inconsistent with the rest of this screen which honours isArabic.
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.

Comment on lines +256 to +266
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);
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
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.

Comment on lines +45 to +48
IconButton(
icon: const Icon(Icons.notifications_outlined),
onPressed: () {},
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

@ahmedalbatati3
Copy link
Copy Markdown
Collaborator Author

closes#12

Repository owner deleted a comment from coderabbitai Bot Apr 28, 2026
@Klvvr1 Klvvr1 closed this Apr 28, 2026
@Klvvr1
Copy link
Copy Markdown
Owner

Klvvr1 commented Apr 28, 2026

Fix issues from the CodeRabbit Bot that were Submited In Each File, unviewed

@Klvvr1 Klvvr1 deleted the agent_screen_change_status branch April 28, 2026 01:18
@Klvvr1 Klvvr1 restored the agent_screen_change_status branch April 28, 2026 02:49
@Klvvr1 Klvvr1 reopened this Apr 28, 2026
Repository owner deleted a comment from coderabbitai Bot Apr 28, 2026
Repository owner deleted a comment from coderabbitai Bot Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants