Skip to content

feature:implemented the profile screen - #12

Open
aneesafatima wants to merge 2 commits into
AOSSIE-Org:mainfrom
aneesafatima:feature/user-profile-screen
Open

feature:implemented the profile screen#12
aneesafatima wants to merge 2 commits into
AOSSIE-Org:mainfrom
aneesafatima:feature/user-profile-screen

Conversation

@aneesafatima

@aneesafatima aneesafatima commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Week 9

What this PR does:

  • Built the full Profile screen UI (name, weight, transport preferences, tracking mode, sustainability thoughts, save/edit/delete user)
  • Added SectionHeader, TrackingOptionTile, and TransportChip widgets for the profile screen
  • Moved user_provider.dart from onboarding folder to core/providers so other features can use it
  • Added copyWith method to User model
  • Added updateUser and deleteUser methods to UserNotifier
  • Added deleteTrips method to TripsNotifier
  • Added new trackingOptions and transportPreferences data files with icons, replacing the old onboarding options file
  • Added a capitalize() string extension for tracking option labels
  • Changed tracking mode to use an enum (trackingOption) instead of plain strings
  • Fixed MapService.isPermissionGranted() to return a map with status and message instead of throwing errors, so the map screen can show a proper error message
  • Removed hardcoded/wrong Nominatim base URL
  • Fixed a bug in the map modal where onClose and onCompleted callbacks were swapped
  • Added monthly reset logic in main.dart so trips get cleared and reset dates get saved when a new month starts
  • Cleaned up unused debug prints and comments
  • Replaced flutter/cupertino imports with flutter/foundation where only debugPrint was needed
  • Moved loader.dart from shared widgets to core widgets

Screenshots/Recordings:

WhatsApp.Video.2026-07-26.at.21.51.03.mp4

(Android)

Screen_recording_20260726_214507.webm

Additional Notes:

Checklist

  • My code follows the project's code style and conventions
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contributing Guidelines

⚠️ AI Notice - Important!

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.

Summary by CodeRabbit

  • New Features
    • Added a complete profile screen to edit transport preferences, tracking mode, weight, and sustainability notes.
    • Added trip-history clearing from the profile, plus sign-out and export-data placeholder UI.
    • Introduced new transport/tracking selection components and a reusable loading indicator.
    • Added automatic monthly trip-data reset on app startup.
  • Bug Fixes
    • Improved location permission/service messaging and error details.
    • Corrected “Completed Trip” vs “Cancel Trip” behavior in the map modal.
    • Improved profile state syncing after save/update/delete actions.

@github-actions github-actions Bot added no-issue-linked PR is not linked to any issue size/XL Extra large PR (>500 lines changed) repeat-contributor PR from an external contributor who already had PRs merged needs-review labels Jul 26, 2026
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR adds shared transport and tracking models, synchronizes user and trip provider state with persistence, introduces a profile editing screen, adds monthly trip reset logic, and revises map permission and trip interaction flows.

Changes

Application state and user flows

Layer / File(s) Summary
Shared preference contracts and provider state
lib/core/..., lib/database/models/user.dart, lib/features/carbon/providers/summary_provider.dart
Adds preference data, color constants, User.copyWith, provider persistence updates, trip deletion, loading UI, and summary return cleanup.
Onboarding and profile editing
lib/features/onboarding/..., lib/features/profile/..., lib/core/widgets/modal.dart
Updates onboarding to use typed options and replaces the profile placeholder with editable preferences, data clearing, sign-out, and supporting widgets.
Startup monthly reset
lib/main.dart
Performs an asynchronous user reset check before launching the application.
Map permission and trip actions
lib/features/map/...
Returns structured permission results, updates location errors and trip actions, and corrects map modal callbacks.
Cross-feature provider and service wiring
lib/features/fitness/..., lib/database/database_helper.dart
Aligns provider and service imports and simplifies a boolean expression.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProfileScreen
  participant UserNotifier
  participant DatabaseHelper
  ProfileScreen->>UserNotifier: save updated profile
  UserNotifier->>DatabaseHelper: persist user
  DatabaseHelper-->>UserNotifier: persisted user
  UserNotifier-->>ProfileScreen: updated provider state
Loading

Possibly related PRs

Suggested reviewers: bhavik-mangla

Poem

I’m a rabbit with settings to save,
Green icons hop through each brave wave.
Trips reset when new months appear,
Maps find permission, crisp and clear.
Profile buttons bounce with cheer!

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: implementing the profile screen.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/features/map/services/location_service.dart (1)

15-53: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return the same failure shape for permanently denied permission.

deniedForever still throws, so MapScreen falls back to a generic exception message instead of handling the documented {status, message} response. Return {'status': false, 'message': ...} here as well.

Proposed fix
     if (permission == LocationPermission.deniedForever) {
-      return Future.error(
-        'Location permissions are permanently denied, we cannot request permissions.',
-      );
+      return {
+        'status': false,
+        'message':
+            'Location permissions are permanently denied. Enable them in device settings.',
+      };
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/features/map/services/location_service.dart` around lines 15 - 53, Update
isPermissionGranted() so the LocationPermission.deniedForever branch returns the
same {'status': false, 'message': ...} map shape as other permission failures
instead of returning Future.error. Preserve the existing permanent-denial
message.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/core/providers/trips_provider.dart`:
- Around line 30-38: Update deleteTrips to log clearTrips failures with
deletion-specific context and rethrow the caught error so callers can handle
failed deletions. Await loadTrips only after a successful clear, and prevent the
reload from running when deletion fails.

In `@lib/core/providers/user_provider.dart`:
- Around line 22-31: Make saveUser() concurrency-safe by replacing the separate
query-then-insert/update sequence with an atomic database upsert or a
provider-level serialized write queue. Ensure concurrent updates cannot both
insert or overwrite newer profile data with stale User snapshots, while
preserving the final state assignment.

In `@lib/database/models/user.dart`:
- Around line 61-80: Update User.copyWith so callers can explicitly clear the
nullable sustainabilityThoughts field while preserving the existing value when
the argument is omitted. Use an explicit sentinel or equivalent
presence-tracking mechanism for sustainabilityThoughts, and ensure
copyWith(sustainabilityThoughts: null) produces a User with a null value rather
than retaining this.sustainabilityThoughts.

In `@lib/features/map/screens/map_screen.dart`:
- Around line 62-67: In the permission-check flow after awaiting
MapService.isPermissionGranted(), add an immediate mounted guard that returns
before the !res['status'] branch can call setState. Keep the existing
error-message handling unchanged.

In `@lib/features/onboarding/screens/user_info.dart`:
- Around line 393-394: Update the tracking help content used by the modal around
trackingModesInfo so its title/description or selectable option labels
consistently name the modes actually offered: Refresh, High, and Eco. Ensure no
conflicting Balanced or Eco-Friendly terminology remains in this tracking
guidance.

In `@lib/features/profile/screens/profile.dart`:
- Around line 375-384: Update the “Clear Stored Trips” ListTile onTap handler to
show a destructive-action confirmation dialog before clearing history; only
after the user confirms should it await
ref.read(tripProvider.notifier).deleteTrips(), and it must surface any deletion
failure using the screen’s existing error-handling mechanism.
- Around line 365-374: Update the Export Data ListTile in the profile screen to
prevent users from invoking the unimplemented action: either remove or hide the
tile, or disable it and display an explicit “Coming soon” state. Do not leave
the current enabled onTap handler that performs no action.

---

Outside diff comments:
In `@lib/features/map/services/location_service.dart`:
- Around line 15-53: Update isPermissionGranted() so the
LocationPermission.deniedForever branch returns the same {'status': false,
'message': ...} map shape as other permission failures instead of returning
Future.error. Preserve the existing permanent-denial message.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fe4e825e-157e-4c83-a432-8b915d2442ae

📥 Commits

Reviewing files that changed from the base of the PR and between 6beae3e and fa98990.

📒 Files selected for processing (28)
  • lib/core/config/app_constants.dart
  • lib/core/data/trackingOptions.dart
  • lib/core/data/transportPreferences.dart
  • lib/core/extensions/string_extensions.dart
  • lib/core/providers/trips_provider.dart
  • lib/core/providers/user_provider.dart
  • lib/core/widgets/loader.dart
  • lib/core/widgets/modal.dart
  • lib/database/database_helper.dart
  • lib/database/models/user.dart
  • lib/features/carbon/providers/summary_provider.dart
  • lib/features/fitness/screens/fitness_metrics_screen.dart
  • lib/features/fitness/screens/main_screen.dart
  • lib/features/fitness/services/health_service.dart
  • lib/features/map/screens/map_screen.dart
  • lib/features/map/services/location_service.dart
  • lib/features/map/widgets/location_button.dart
  • lib/features/map/widgets/map_modal.dart
  • lib/features/onboarding/data/onboarding_options.dart
  • lib/features/onboarding/screens/splash_screen.dart
  • lib/features/onboarding/screens/user_info.dart
  • lib/features/profile/.gitkeep
  • lib/features/profile/screens/profile.dart
  • lib/features/profile/widgets/section_header.dart
  • lib/features/profile/widgets/tracking_option_tile.dart
  • lib/features/profile/widgets/transport_chip.dart
  • lib/main.dart
  • lib/shared/widgets/.gitkeep
💤 Files with no reviewable changes (2)
  • lib/features/onboarding/data/onboarding_options.dart
  • lib/features/carbon/providers/summary_provider.dart

Comment on lines +30 to +38
Future<void> deleteTrips() async {
try {
await _databaseHelper.clearTrips();
state = [];
} catch (e) {
debugPrint("Error loading trips: $e");
}
loadTrips();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Propagate trip-deletion failures to the caller.

clearTrips() failures are logged and swallowed, so the UI cannot tell the user that their trips were not deleted. Log the deletion error, rethrow it (or return a failure result), and avoid the unawaited reload.

Proposed fix
 Future<void> deleteTrips() async {
   try {
     await _databaseHelper.clearTrips();
     state = [];
-  } catch (e) {
-    debugPrint("Error loading trips: $e");
+  } catch (e, st) {
+    debugPrint("Error deleting trips: $e\n$st");
+    rethrow;
   }
-  loadTrips();
 }
📝 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
Future<void> deleteTrips() async {
try {
await _databaseHelper.clearTrips();
state = [];
} catch (e) {
debugPrint("Error loading trips: $e");
}
loadTrips();
}
Future<void> deleteTrips() async {
try {
await _databaseHelper.clearTrips();
state = [];
} catch (e, st) {
debugPrint("Error deleting trips: $e\n$st");
rethrow;
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/core/providers/trips_provider.dart` around lines 30 - 38, Update
deleteTrips to log clearTrips failures with deletion-specific context and
rethrow the caught error so callers can handle failed deletions. Await loadTrips
only after a successful clear, and prevent the reload from running when deletion
fails.

Comment thread lib/core/providers/user_provider.dart Outdated
Comment on lines +22 to +31
Future<void> saveUser(User user) async {
await _databaseHelper.insert('user', user);
final existingUser = await _databaseHelper.queryUser();

if (existingUser == null) {
await _databaseHelper.insert('user', user);
} else {
await _databaseHelper.updateData('user', user);
}

state = user;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Serialize saveUser() or make the upsert atomic.

Concurrent profile updates can both observe the same existingUser, then write stale User snapshots in completion order. When no user exists, concurrent calls can also both attempt insertion. Use a database transaction/upsert or a provider-level write queue that merges from the latest state before persisting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/core/providers/user_provider.dart` around lines 22 - 31, Make saveUser()
concurrency-safe by replacing the separate query-then-insert/update sequence
with an atomic database upsert or a provider-level serialized write queue.
Ensure concurrent updates cannot both insert or overwrite newer profile data
with stale User snapshots, while preserving the final state assignment.

Comment thread lib/database/models/user.dart
Comment thread lib/features/map/screens/map_screen.dart
Comment on lines +393 to +394
trackingModesInfo["title"] ?? "Tracking modes",
trackingModesInfo["description"] ?? "",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the tracking help text with the selectable modes.

The UI offers Refresh, High, and Eco, but trackingModesInfo describes Balanced and Eco-Friendly instead. Update the shared description or option labels so the modal accurately documents the modes users can select.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/features/onboarding/screens/user_info.dart` around lines 393 - 394,
Update the tracking help content used by the modal around trackingModesInfo so
its title/description or selectable option labels consistently name the modes
actually offered: Refresh, High, and Eco. Ensure no conflicting Balanced or
Eco-Friendly terminology remains in this tracking guidance.

Comment on lines +365 to +374
ListTile(
leading: const Icon(Icons.download_outlined),
title: const Text(
'Export Data',
style: TextStyle(fontSize: 14),
),
onTap: () {
// To be implemented
},
),

@coderabbitai coderabbitai Bot Jul 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove or disable the unimplemented export action.

Export Data is enabled but does nothing when tapped. Hide it until implemented, or render it disabled with an explicit “Coming soon” state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/features/profile/screens/profile.dart` around lines 365 - 374, Update the
Export Data ListTile in the profile screen to prevent users from invoking the
unimplemented action: either remove or hide the tile, or disable it and display
an explicit “Coming soon” state. Do not leave the current enabled onTap handler
that performs no action.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This will be implemented this week

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@aneesafatima Understood. Since the enabled control currently has no effect, could you disable/hide it in this PR until the implementation lands? If it is intentionally deferred to a follow-up, would you like me to open an issue for it?

Comment on lines +375 to +384
ListTile(
leading: const Icon(Icons.delete_outline, color: _redColor),
title: const Text(
'Clear Stored Trips',
style: TextStyle(fontSize: 14, color: _redColor),
),
onTap: () {
ref.read(tripProvider.notifier).deleteTrips();
},
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Require confirmation before permanently clearing trip history.

This immediately deletes all stored trips with no confirmation or recovery path. Show a destructive-action confirmation dialog, then await deleteTrips() and surface any failure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/features/profile/screens/profile.dart` around lines 375 - 384, Update the
“Clear Stored Trips” ListTile onTap handler to show a destructive-action
confirmation dialog before clearing history; only after the user confirms should
it await ref.read(tripProvider.notifier).deleteTrips(), and it must surface any
deletion failure using the screen’s existing error-handling mechanism.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/features/profile/screens/profile.dart (2)

424-427: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Await user deletion before navigating away.

deleteUser() is started and ignored before routing to onboarding. A new onboarding save can race the deletion, and failures can leave the user believing sign-out succeeded while the database still contains the record.

Proposed fix
-              onPressed: () {
-                ref.read(userProvider.notifier).deleteUser();
-                context.goNamed('onboarding');
-              },
+              onPressed: () async {
+                await ref.read(userProvider.notifier).deleteUser();
+                if (!mounted) return;
+                context.goNamed('onboarding');
+              },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/features/profile/screens/profile.dart` around lines 424 - 427, Update the
onPressed handler to await the Future returned by userProvider’s deleteUser()
before calling context.goNamed('onboarding'). Preserve the existing onboarding
navigation, ensuring it occurs only after deletion completes and deletion
failures are not silently ignored.

305-317: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make sustainability thoughts a multiline field.

The TextField for “Sustainability Thoughts” has no maxLines or inputFormatters/TextInputType.multiline configuration, so it renders as a single-line input. Add multiline support so longer thoughts are easier to enter and read.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/features/profile/screens/profile.dart` around lines 305 - 317, Update the
Sustainability Thoughts TextField by configuring TextInputType.multiline and
allowing multiple lines with maxLines. Keep the existing controller, styling,
alignment, and decoration unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@lib/features/profile/screens/profile.dart`:
- Around line 424-427: Update the onPressed handler to await the Future returned
by userProvider’s deleteUser() before calling context.goNamed('onboarding').
Preserve the existing onboarding navigation, ensuring it occurs only after
deletion completes and deletion failures are not silently ignored.
- Around line 305-317: Update the Sustainability Thoughts TextField by
configuring TextInputType.multiline and allowing multiple lines with maxLines.
Keep the existing controller, styling, alignment, and decoration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 46778f52-ae12-4025-a516-ef9d686bb27e

📥 Commits

Reviewing files that changed from the base of the PR and between fa98990 and b6603ee.

📒 Files selected for processing (6)
  • lib/core/providers/trips_provider.dart
  • lib/core/providers/user_provider.dart
  • lib/features/map/screens/map_screen.dart
  • lib/features/onboarding/data/tracking_modes_info.dart
  • lib/features/profile/screens/profile.dart
  • lib/features/profile/trips_delete_modal_data.dart
💤 Files with no reviewable changes (2)
  • lib/core/providers/trips_provider.dart
  • lib/features/onboarding/data/tracking_modes_info.dart

@coderabbitai coderabbitai Bot mentioned this pull request Aug 3, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

GSoC needs-review no-issue-linked PR is not linked to any issue repeat-contributor PR from an external contributor who already had PRs merged size/XL Extra large PR (>500 lines changed)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant