Skip to content

Commit c04d1d9

Browse files
committed
Refactor DashboardHeader and DashboardAppBar for improved readability; streamline ProfilePage and UserRepository code
1 parent e956e67 commit c04d1d9

File tree

6 files changed

+228
-230
lines changed

6 files changed

+228
-230
lines changed

src/mobile-v3/lib/src/app/dashboard/pages/location_selection/location_selection_screen.dart

Lines changed: 122 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -47,51 +47,52 @@ class _LocationSelectionScreenState extends State<LocationSelectionScreen>
4747
UserPreferencesModel? userPreferences;
4848

4949
@override
50-
void initState() {
51-
super.initState();
52-
loggy.info('initState called');
50+
void initState() {
51+
super.initState();
52+
loggy.info('initState called');
5353

54-
_initializeUserData();
54+
_initializeUserData();
5555

56-
googlePlacesBloc = context.read<GooglePlacesBloc>()
57-
..add(ResetGooglePlaces());
56+
googlePlacesBloc = context.read<GooglePlacesBloc>()
57+
..add(ResetGooglePlaces());
5858

59-
loggy.info('Checking dashboard state');
60-
final dashboardBloc = context.read<DashboardBloc>();
61-
final currentState = dashboardBloc.state;
62-
loggy.info('Current dashboard state: ${currentState.runtimeType}');
59+
loggy.info('Checking dashboard state');
60+
final dashboardBloc = context.read<DashboardBloc>();
61+
final currentState = dashboardBloc.state;
62+
loggy.info('Current dashboard state: ${currentState.runtimeType}');
63+
64+
if (currentState is DashboardLoaded) {
65+
loggy.info('Dashboard already loaded, populating measurements');
66+
if (currentState.response.measurements != null) {
67+
loggy.info(
68+
'Found ${currentState.response.measurements!.length} measurements in loaded state');
69+
_populateMeasurements(currentState.response.measurements!);
70+
71+
// IMPORTANT ADDITION: Pre-select existing locations from the current DashboardState
72+
if (currentState.userPreferences != null &&
73+
currentState.userPreferences!.selectedSites.isNotEmpty) {
74+
final existingIds = currentState.userPreferences!.selectedSites
75+
.map((site) => site.id)
76+
.toSet();
6377

64-
if (currentState is DashboardLoaded) {
65-
loggy.info('Dashboard already loaded, populating measurements');
66-
if (currentState.response.measurements != null) {
67-
loggy.info(
68-
'Found ${currentState.response.measurements!.length} measurements in loaded state');
69-
_populateMeasurements(currentState.response.measurements!);
70-
71-
// IMPORTANT ADDITION: Pre-select existing locations from the current DashboardState
72-
if (currentState.userPreferences != null &&
73-
currentState.userPreferences!.selectedSites.isNotEmpty) {
74-
final existingIds = currentState.userPreferences!.selectedSites
75-
.map((site) => site.id)
76-
.toSet();
77-
78-
loggy.info('Pre-selecting ${existingIds.length} existing locations from dashboard state');
78+
loggy.info(
79+
'Pre-selecting ${existingIds.length} existing locations from dashboard state');
80+
setState(() {
81+
selectedLocations = existingIds;
82+
});
83+
}
84+
} else {
85+
loggy.warning('No measurements in loaded state');
7986
setState(() {
80-
selectedLocations = existingIds;
87+
isLoading = false;
88+
errorMessage = "No measurements available in loaded state";
8189
});
8290
}
8391
} else {
84-
loggy.warning('No measurements in loaded state');
85-
setState(() {
86-
isLoading = false;
87-
errorMessage = "No measurements available in loaded state";
88-
});
92+
loggy.info('Dispatching LoadDashboard event');
93+
dashboardBloc.add(LoadDashboard());
8994
}
90-
} else {
91-
loggy.info('Dispatching LoadDashboard event');
92-
dashboardBloc.add(LoadDashboard());
9395
}
94-
}
9596

9697
Future<void> _initializeUserData() async {
9798
try {
@@ -174,100 +175,99 @@ void initState() {
174175
// File: src/mobile-v3/lib/src/app/dashboard/pages/location_selection/location_selection_screen.dart
175176

176177
// Update the _saveSelectedLocations method in the LocationSelectionScreen
177-
Future<void> _saveSelectedLocations() async {
178-
loggy.info(
179-
'Save button pressed with ${selectedLocations.length} selected locations');
178+
Future<void> _saveSelectedLocations() async {
179+
loggy.info(
180+
'Save button pressed with ${selectedLocations.length} selected locations');
181+
182+
// Debug token
183+
await AuthHelper.debugToken();
184+
185+
// Check auth state from the bloc
186+
final authState = context.read<AuthBloc>().state;
187+
final isLoggedIn = authState is AuthLoaded;
188+
189+
loggy.info('Current auth state: ${authState.runtimeType}');
190+
loggy.info('Is user logged in? $isLoggedIn');
191+
192+
if (!isLoggedIn) {
193+
loggy.warning('❌ User not logged in, cannot save');
194+
ScaffoldMessenger.of(context).showSnackBar(
195+
const SnackBar(content: Text('Please log in to save your locations')),
196+
);
197+
return;
198+
}
180199

181-
// Debug token
182-
await AuthHelper.debugToken();
200+
// Use enhanced token checker
201+
final isExpired = await TokenDebugger.checkTokenExpiration();
202+
203+
if (isExpired) {
204+
loggy.warning('❌ Token is expired, cannot save');
205+
206+
ScaffoldMessenger.of(context).showSnackBar(
207+
SnackBar(
208+
content: const Text('Your session has expired. Please log in again.'),
209+
duration: const Duration(seconds: 8),
210+
action: SnackBarAction(
211+
label: 'Log In',
212+
onPressed: () {
213+
// Navigate directly to login screen
214+
Navigator.of(context).pushAndRemoveUntil(
215+
MaterialPageRoute(
216+
builder: (context) => const LoginPage(),
217+
),
218+
(route) => false,
219+
);
220+
},
221+
),
222+
),
223+
);
224+
return;
225+
}
183226

184-
// Check auth state from the bloc
185-
final authState = context.read<AuthBloc>().state;
186-
final isLoggedIn = authState is AuthLoaded;
227+
setState(() {
228+
isSaving = true;
229+
});
187230

188-
loggy.info('Current auth state: ${authState.runtimeType}');
189-
loggy.info('Is user logged in? $isLoggedIn');
231+
try {
232+
// IMPORTANT CHANGE: Instead of creating a new preference, we dispatch
233+
// the UpdateSelectedLocations event to the DashboardBloc, which will
234+
// merge these with existing locations
190235

191-
if (!isLoggedIn) {
192-
loggy.warning('❌ User not logged in, cannot save');
193-
ScaffoldMessenger.of(context).showSnackBar(
194-
const SnackBar(content: Text('Please log in to save your locations')),
195-
);
196-
return;
197-
}
236+
final dashboardBloc = context.read<DashboardBloc>();
198237

199-
// Use enhanced token checker
200-
final isExpired = await TokenDebugger.checkTokenExpiration();
201-
202-
if (isExpired) {
203-
loggy.warning('❌ Token is expired, cannot save');
204-
205-
ScaffoldMessenger.of(context).showSnackBar(
206-
SnackBar(
207-
content: const Text('Your session has expired. Please log in again.'),
208-
duration: const Duration(seconds: 8),
209-
action: SnackBarAction(
210-
label: 'Log In',
211-
onPressed: () {
212-
// Navigate directly to login screen
213-
Navigator.of(context).pushAndRemoveUntil(
214-
MaterialPageRoute(
215-
builder: (context) => const LoginPage(),
216-
),
217-
(route) => false,
218-
);
219-
},
220-
),
221-
),
222-
);
223-
return;
224-
}
225-
226-
setState(() {
227-
isSaving = true;
228-
});
229-
230-
try {
231-
// IMPORTANT CHANGE: Instead of creating a new preference, we dispatch
232-
// the UpdateSelectedLocations event to the DashboardBloc, which will
233-
// merge these with existing locations
234-
235-
final dashboardBloc = context.read<DashboardBloc>();
236-
237-
// Convert the Set to a List
238-
final locationIdsList = selectedLocations.toList();
239-
240-
loggy.info('Dispatching UpdateSelectedLocations with ${locationIdsList.length} locations');
241-
242-
// Dispatch the event
243-
dashboardBloc.add(UpdateSelectedLocations(locationIdsList));
244-
245-
// Show success message
246-
loggy.info('✅ Successfully dispatched update event');
247-
ScaffoldMessenger.of(context).showSnackBar(
248-
const SnackBar(content: Text('Locations saved successfully')),
249-
);
250-
251-
// Return to previous screen with the selected locations
252-
Navigator.pop(context, locationIdsList);
253-
} catch (e) {
254-
loggy.error('❌ Error saving locations: $e');
255-
loggy.error('Stack trace: ${StackTrace.current}');
256-
ScaffoldMessenger.of(context).showSnackBar(
257-
SnackBar(
258-
content: Text(
259-
'An error occurred while saving locations: ${e.toString()}')),
260-
);
261-
} finally {
262-
if (mounted) {
263-
setState(() {
264-
isSaving = false;
265-
});
266-
}
267-
}
268-
}
238+
// Convert the Set to a List
239+
final locationIdsList = selectedLocations.toList();
240+
241+
loggy.info(
242+
'Dispatching UpdateSelectedLocations with ${locationIdsList.length} locations');
269243

244+
// Dispatch the event
245+
dashboardBloc.add(UpdateSelectedLocations(locationIdsList));
270246

247+
// Show success message
248+
loggy.info('✅ Successfully dispatched update event');
249+
ScaffoldMessenger.of(context).showSnackBar(
250+
const SnackBar(content: Text('Locations saved successfully')),
251+
);
252+
253+
// Return to previous screen with the selected locations
254+
Navigator.pop(context, locationIdsList);
255+
} catch (e) {
256+
loggy.error('❌ Error saving locations: $e');
257+
loggy.error('Stack trace: ${StackTrace.current}');
258+
ScaffoldMessenger.of(context).showSnackBar(
259+
SnackBar(
260+
content: Text(
261+
'An error occurred while saving locations: ${e.toString()}')),
262+
);
263+
} finally {
264+
if (mounted) {
265+
setState(() {
266+
isSaving = false;
267+
});
268+
}
269+
}
270+
}
271271

272272
Future<void> _loadUserPreferences(String userId) async {
273273
try {

src/mobile-v3/lib/src/app/dashboard/widgets/dashboard_app_bar.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import '../../shared/widgets/loading_widget.dart';
1111

1212
class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
1313
const DashboardAppBar({super.key});
14-
14+
1515
@override
1616
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
17-
17+
1818
@override
1919
Widget build(BuildContext context) {
2020
return AppBar(
@@ -34,7 +34,7 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
3434
),
3535
);
3636
}
37-
37+
3838
Widget _buildThemeToggle(BuildContext context) {
3939
final themeBloc = context.read<ThemeBloc>();
4040
return GestureDetector(
@@ -48,7 +48,7 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
4848
),
4949
);
5050
}
51-
51+
5252
Widget _buildUserAvatar(BuildContext context) {
5353
return BlocBuilder<AuthBloc, AuthState>(
5454
builder: (context, authState) {
@@ -60,7 +60,7 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
6060
},
6161
);
6262
}
63-
63+
6464
Widget _buildGuestAvatar(BuildContext context) {
6565
return GestureDetector(
6666
onTap: () {
@@ -84,12 +84,13 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
8484
),
8585
);
8686
}
87-
87+
8888
Widget _buildUserProfileAvatar(BuildContext context) {
8989
return BlocBuilder<UserBloc, UserState>(
9090
builder: (context, userState) {
9191
if (userState is UserLoaded) {
92-
String firstName = userState.model.users[0].firstName[0].toUpperCase();
92+
String firstName =
93+
userState.model.users[0].firstName[0].toUpperCase();
9394
String lastName = userState.model.users[0].lastName[0].toUpperCase();
9495
return GestureDetector(
9596
onTap: () {
@@ -118,4 +119,4 @@ class DashboardAppBar extends StatelessWidget implements PreferredSizeWidget {
118119
},
119120
);
120121
}
121-
}
122+
}

src/mobile-v3/lib/src/app/dashboard/widgets/dashboard_header.dart

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,19 @@ class DashboardHeader extends StatelessWidget {
1313
Widget build(BuildContext context) {
1414
return PagePadding(
1515
padding: 16,
16-
child: Column(
17-
crossAxisAlignment: CrossAxisAlignment.start,
18-
children: [
19-
SizedBox(height: 16),
20-
_buildGreeting(context),
21-
Text(
22-
"Today's Air Quality • ${DateFormat.MMMMd().format(DateTime.now())}",
23-
style: TextStyle(
24-
fontSize: 18,
25-
fontWeight: FontWeight.w500,
26-
color: Theme.of(context).textTheme.headlineMedium?.color,
27-
),
16+
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
17+
SizedBox(height: 16),
18+
_buildGreeting(context),
19+
Text(
20+
"Today's Air Quality • ${DateFormat.MMMMd().format(DateTime.now())}",
21+
style: TextStyle(
22+
fontSize: 18,
23+
fontWeight: FontWeight.w500,
24+
color: Theme.of(context).textTheme.headlineMedium?.color,
2825
),
29-
SizedBox(height: 16)
30-
]
31-
),
26+
),
27+
SizedBox(height: 16)
28+
]),
3229
);
3330
}
3431

@@ -97,4 +94,4 @@ class DashboardHeader extends StatelessWidget {
9794
},
9895
);
9996
}
100-
}
97+
}

0 commit comments

Comments
 (0)