Refactor: Implement multi-item inventory for Pad Tracker and dynamic navigation

This commit is contained in:
2026-01-02 18:10:50 -06:00
parent 56683f5407
commit 8772b56f36
44 changed files with 3515 additions and 781 deletions

View File

@@ -6,6 +6,8 @@ import '../../providers/navigation_provider.dart';
import '../../providers/user_provider.dart';
import '../../theme/app_theme.dart';
import 'package:uuid/uuid.dart';
import '../../services/notification_service.dart';
import 'pad_tracker_screen.dart';
class LogScreen extends ConsumerStatefulWidget {
final DateTime? initialDate;
@@ -138,6 +140,24 @@ class _LogScreenState extends ConsumerState<LogScreen> {
await ref.read(cycleEntriesProvider.notifier).addEntry(entry);
}
// Trigger Notification if Period Start
if (_isPeriodDay && ref.read(userProfileProvider)?.notifyPeriodStart == true) {
// Check if this is likely Day 1 (simplified check: no period yesterday)
// meaningful logic requires checking previous entry, but for now we trust the user logging "Is today a period day?"
// better: check if *yesterday* was NOT a period day.
final entries = ref.read(cycleEntriesProvider);
final yesterday = _selectedDate.subtract(const Duration(days: 1));
final wasPeriodYesterday = entries.any((e) => DateUtils.isSameDay(e.date, yesterday) && e.isPeriodDay);
if (!wasPeriodYesterday) {
NotificationService().showLocalNotification(
id: 1001,
title: 'Period Started',
body: 'Period start recorded for ${_formatDate(_selectedDate)}.',
);
}
}
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@@ -261,55 +281,79 @@ class _LogScreenState extends ConsumerState<LogScreen> {
_buildSectionCard(
context,
title: 'Flow Intensity',
child: Row(
children: FlowIntensity.values.map((flow) {
final isSelected = _flowIntensity == flow;
return Expanded(
child: GestureDetector(
onTap: () => setState(() => _flowIntensity = flow),
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.symmetric(horizontal: 4),
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
color: isSelected
? AppColors.menstrualPhase
.withOpacity(isDark ? 0.3 : 0.2)
: theme.colorScheme.surfaceVariant
.withOpacity(0.3),
borderRadius: BorderRadius.circular(10),
border: isSelected
? Border.all(color: AppColors.menstrualPhase)
: Border.all(color: Colors.transparent),
),
child: Column(
children: [
Icon(
Icons.water_drop,
child: Column(
children: [
Row(
children: FlowIntensity.values.map((flow) {
final isSelected = _flowIntensity == flow;
return Expanded(
child: GestureDetector(
onTap: () => setState(() => _flowIntensity = flow),
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.symmetric(horizontal: 4),
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
color: isSelected
? AppColors.menstrualPhase
: theme.colorScheme.onSurfaceVariant,
size: 20,
.withOpacity(isDark ? 0.3 : 0.2)
: theme.colorScheme.surfaceVariant
.withOpacity(0.3),
borderRadius: BorderRadius.circular(10),
border: isSelected
? Border.all(color: AppColors.menstrualPhase)
: Border.all(color: Colors.transparent),
),
const SizedBox(height: 4),
Text(
flow.label,
style: GoogleFonts.outfit(
fontSize: 11,
fontWeight: isSelected
? FontWeight.w600
: FontWeight.w400,
color: isSelected
? AppColors.menstrualPhase
: theme.colorScheme.onSurfaceVariant,
),
child: Column(
children: [
Icon(
Icons.water_drop,
color: isSelected
? AppColors.menstrualPhase
: theme.colorScheme.onSurfaceVariant,
size: 20,
),
const SizedBox(height: 4),
Text(
flow.label,
style: GoogleFonts.outfit(
fontSize: 11,
fontWeight: isSelected
? FontWeight.w600
: FontWeight.w400,
color: isSelected
? AppColors.menstrualPhase
: theme.colorScheme.onSurfaceVariant,
),
),
],
),
],
),
),
);
}).toList(),
),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const PadTrackerScreen(),
),
);
},
icon: const Icon(Icons.timer_outlined),
label: const Text('Pad Tracker & Reminders'),
style: OutlinedButton.styleFrom(
foregroundColor: AppColors.menstrualPhase,
side: const BorderSide(color: AppColors.menstrualPhase),
),
),
);
}).toList(),
),
],
),
),
],