Refactor and enhance UI components across multiple screens

- Updated date and time formatting in debug notifications screen for clarity.
- Wrapped context-dependent state updates in post-frame callbacks in history screen to ensure proper context usage.
- Improved layout and styling in settings screen by reordering radio list tiles.
- Enhanced logging in auto sync service for better error tracking.
- Added context mounted checks in notification router to prevent errors during navigation.
- Updated bulk take dialog to use new UI components from shadcn_ui package.
- Refactored take supplement dialog to utilize shadcn_ui for a more modern look and feel.
- Adjusted info chip and supplement card widgets to use updated color schemes and layouts.
- Updated pubspec.yaml and pubspec.lock to include new dependencies and versions.
This commit is contained in:
2025-08-31 19:15:32 +02:00
parent 6a2085f4e6
commit 666008f05d
15 changed files with 597 additions and 423 deletions

View File

@@ -166,7 +166,7 @@ class _AddSupplementScreenState extends State<AddSupplementScreen> {
Expanded(
flex: 1,
child: DropdownButtonFormField<String>(
value: controller.selectedUnit,
initialValue: controller.selectedUnit,
decoration: const InputDecoration(
labelText: 'Unit',
border: OutlineInputBorder(),
@@ -317,7 +317,7 @@ class _AddSupplementScreenState extends State<AddSupplementScreen> {
Expanded(
flex: 1,
child: DropdownButtonFormField<String>(
value: _selectedUnitType,
initialValue: _selectedUnitType,
decoration: const InputDecoration(
labelText: 'Type',
border: OutlineInputBorder(),

View File

@@ -164,7 +164,7 @@ class _ArchivedSupplementCard extends StatelessWidget {
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Theme.of(context).colorScheme.surfaceVariant.withValues(alpha: 0.3),
color: Theme.of(context).colorScheme.surfaceContainerHighest.withValues(alpha: 0.3),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withValues(alpha: 0.2),
width: 1,
@@ -262,7 +262,7 @@ class _ArchivedSupplementCard extends StatelessWidget {
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceVariant.withValues(alpha: 0.3),
color: Theme.of(context).colorScheme.surfaceContainerHighest.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(8),
),
child: Column(

View File

@@ -383,8 +383,8 @@ class _DebugNotificationsScreenState extends State<DebugNotificationsScreen> {
final createdAt = DateTime.fromMillisecondsSinceEpoch(e.createdAtEpochMs).toLocal();
// Format times more clearly
final scheduledStr = '${scheduledAt.toString().substring(0, 16)}';
final createdStr = '${createdAt.toString().substring(0, 16)}';
final scheduledStr = scheduledAt.toString().substring(0, 16);
final createdStr = createdAt.toString().substring(0, 16);
// Show status and timing info
final statusStr = inQueue ? '🟡 Pending' : '✅ Completed/Canceled';

View File

@@ -55,7 +55,9 @@ class _HistoryScreenState extends State<HistoryScreen> {
_selectedMonth--;
}
});
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
});
},
icon: const Icon(Icons.chevron_left),
),
@@ -85,7 +87,9 @@ class _HistoryScreenState extends State<HistoryScreen> {
_selectedMonth++;
}
});
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
});
}
},
icon: const Icon(Icons.chevron_right),
@@ -187,12 +191,15 @@ class _HistoryScreenState extends State<HistoryScreen> {
);
if (picked != null) {
if (!context.mounted) return;
setState(() {
_selectedMonth = picked.month;
_selectedYear = picked.year;
_selectedDay = picked; // Set the selected day to the picked date
});
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
});
}
}
@@ -210,13 +217,16 @@ class _HistoryScreenState extends State<HistoryScreen> {
ElevatedButton(
onPressed: () async {
await context.read<SupplementProvider>().deleteIntake(intakeId);
if (!context.mounted) return;
Navigator.of(context).pop();
// Force refresh of the UI
setState(() {});
// Force refresh of the current view data
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<SupplementProvider>().loadMonthlyIntakes(_selectedYear, _selectedMonth);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@@ -252,7 +262,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
final calendarHeight = isWideScreen ? 400.0 : calendarContentHeight;
return Card(
child: Container(
child: SizedBox(
height: calendarHeight,
child: Padding(
padding: const EdgeInsets.all(16),
@@ -261,20 +271,98 @@ class _HistoryScreenState extends State<HistoryScreen> {
children: [
// Calendar header (weekdays)
Row(
children: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
.map((day) => Expanded(
child: Center(
child: Text(
day,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
))
.toList(),
children: [
Expanded(
child: Center(
child: Text(
'Mon',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
),
SizedBox(width: 4),
Expanded(
child: Center(
child: Text(
'Tue',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
),
SizedBox(width: 4),
Expanded(
child: Center(
child: Text(
'Wed',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
),
SizedBox(width: 4),
Expanded(
child: Center(
child: Text(
'Thu',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
),
SizedBox(width: 4),
Expanded(
child: Center(
child: Text(
'Fri',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
),
SizedBox(width: 4),
Expanded(
child: Center(
child: Text(
'Sat',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
),
SizedBox(width: 4),
Expanded(
child: Center(
child: Text(
'Sun',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: isWideScreen ? 14 : 12,
),
),
),
),
],
),
const SizedBox(height: 8),
// Calendar grid
@@ -293,7 +381,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
final dayNumber = index - firstWeekday + 2;
if (dayNumber < 1 || dayNumber > daysInMonth) {
return const SizedBox(); // Empty cell
return const SizedBox.shrink(); // Empty cell
}
final date = DateTime(_selectedYear, _selectedMonth, dayNumber);

View File

@@ -67,8 +67,6 @@ class SettingsScreen extends StatelessWidget {
),
const SizedBox(height: 16),
RadioListTile<ThemeOption>(
title: const Text('Follow System'),
subtitle: const Text('Use system theme setting'),
value: ThemeOption.system,
groupValue: settingsProvider.themeOption,
onChanged: (value) {
@@ -76,10 +74,10 @@ class SettingsScreen extends StatelessWidget {
settingsProvider.setThemeOption(value);
}
},
title: const Text('Follow System'),
subtitle: const Text('Use system theme setting'),
),
RadioListTile<ThemeOption>(
title: const Text('Light Theme'),
subtitle: const Text('Always use light theme'),
value: ThemeOption.light,
groupValue: settingsProvider.themeOption,
onChanged: (value) {
@@ -87,10 +85,10 @@ class SettingsScreen extends StatelessWidget {
settingsProvider.setThemeOption(value);
}
},
title: const Text('Light Theme'),
subtitle: const Text('Always use light theme'),
),
RadioListTile<ThemeOption>(
title: const Text('Dark Theme'),
subtitle: const Text('Always use dark theme'),
value: ThemeOption.dark,
groupValue: settingsProvider.themeOption,
onChanged: (value) {
@@ -98,6 +96,8 @@ class SettingsScreen extends StatelessWidget {
settingsProvider.setThemeOption(value);
}
},
title: const Text('Dark Theme'),
subtitle: const Text('Always use dark theme'),
),
],
),