import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; import '../../models/cycle_entry.dart'; import '../../providers/user_provider.dart'; import '../../theme/app_theme.dart'; import 'package:uuid/uuid.dart'; class LogScreen extends ConsumerStatefulWidget { <<<<<<< HEAD const LogScreen({super.key}); ======= final DateTime? initialDate; const LogScreen({super.key, this.initialDate}); >>>>>>> 6742220 (Your commit message here) @override ConsumerState createState() => _LogScreenState(); } class _LogScreenState extends ConsumerState { <<<<<<< HEAD ======= late DateTime _selectedDate; String? _existingEntryId; >>>>>>> 6742220 (Your commit message here) bool _isPeriodDay = false; FlowIntensity? _flowIntensity; MoodLevel? _mood; int _energyLevel = 3; int _crampIntensity = 0; bool _hasHeadache = false; bool _hasBloating = false; bool _hasBreastTenderness = false; bool _hasFatigue = false; bool _hasAcne = false; <<<<<<< HEAD final TextEditingController _notesController = TextEditingController(); @override ======= bool _hasLowerBackPain = false; bool _hasConstipation = false; bool _hasDiarrhea = false; bool _hasInsomnia = false; int _stressLevel = 1; final TextEditingController _notesController = TextEditingController(); @override void initState() { super.initState(); _selectedDate = widget.initialDate ?? DateTime.now(); // Defer data loading to avoid build-time ref.read WidgetsBinding.instance.addPostFrameCallback((_) { _loadExistingData(); }); } void _loadExistingData() { final entries = ref.read(cycleEntriesProvider); try { final entry = entries.firstWhere( (e) => DateUtils.isSameDay(e.date, _selectedDate), ); setState(() { _existingEntryId = entry.id; _isPeriodDay = entry.isPeriodDay; _flowIntensity = entry.flowIntensity; _mood = entry.mood; _energyLevel = entry.energyLevel; _crampIntensity = entry.crampIntensity ?? 0; _hasHeadache = entry.hasHeadache; _hasBloating = entry.hasBloating; _hasBreastTenderness = entry.hasBreastTenderness; _hasFatigue = entry.hasFatigue; _hasAcne = entry.hasAcne; _hasLowerBackPain = entry.hasLowerBackPain; _hasConstipation = entry.hasConstipation; _hasDiarrhea = entry.hasDiarrhea; _hasInsomnia = entry.hasInsomnia; _stressLevel = entry.stressLevel ?? 1; _notesController.text = entry.notes ?? ''; }); } catch (_) { // No existing entry for this day } } @override >>>>>>> 6742220 (Your commit message here) void dispose() { _notesController.dispose(); super.dispose(); } Future _saveEntry() async { final entry = CycleEntry( <<<<<<< HEAD id: const Uuid().v4(), date: DateTime.now(), ======= id: _existingEntryId ?? const Uuid().v4(), date: _selectedDate, >>>>>>> 6742220 (Your commit message here) isPeriodDay: _isPeriodDay, flowIntensity: _isPeriodDay ? _flowIntensity : null, mood: _mood, energyLevel: _energyLevel, crampIntensity: _crampIntensity > 0 ? _crampIntensity : null, hasHeadache: _hasHeadache, hasBloating: _hasBloating, hasBreastTenderness: _hasBreastTenderness, hasFatigue: _hasFatigue, hasAcne: _hasAcne, <<<<<<< HEAD ======= hasLowerBackPain: _hasLowerBackPain, hasConstipation: _hasConstipation, hasDiarrhea: _hasDiarrhea, hasInsomnia: _hasInsomnia, stressLevel: _stressLevel > 1 ? _stressLevel : null, >>>>>>> 6742220 (Your commit message here) notes: _notesController.text.isNotEmpty ? _notesController.text : null, createdAt: DateTime.now(), updatedAt: DateTime.now(), ); <<<<<<< HEAD await ref.read(cycleEntriesProvider.notifier).addEntry(entry); ======= if (_existingEntryId != null) { await ref.read(cycleEntriesProvider.notifier).updateEntry(entry); } else { await ref.read(cycleEntriesProvider.notifier).addEntry(entry); } >>>>>>> 6742220 (Your commit message here) if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Entry saved!', style: GoogleFonts.outfit()), <<<<<<< HEAD backgroundColor: AppColors.sageGreen, ======= backgroundColor: AppColors.success, >>>>>>> 6742220 (Your commit message here) behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), ), ); <<<<<<< HEAD _resetForm(); ======= if (widget.initialDate != null) { Navigator.pop(context); } else { _resetForm(); } >>>>>>> 6742220 (Your commit message here) } } void _resetForm() { setState(() { <<<<<<< HEAD ======= _existingEntryId = null; >>>>>>> 6742220 (Your commit message here) _isPeriodDay = false; _flowIntensity = null; _mood = null; _energyLevel = 3; _crampIntensity = 0; _hasHeadache = false; _hasBloating = false; _hasBreastTenderness = false; _hasFatigue = false; _hasAcne = false; <<<<<<< HEAD ======= _hasLowerBackPain = false; _hasConstipation = false; _hasDiarrhea = false; _hasInsomnia = false; _stressLevel = 1; >>>>>>> 6742220 (Your commit message here) _notesController.clear(); }); } @override Widget build(BuildContext context) { <<<<<<< HEAD ======= final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; >>>>>>> 6742220 (Your commit message here) return SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header <<<<<<< HEAD Text( 'How are you feeling?', style: GoogleFonts.outfit( fontSize: 28, fontWeight: FontWeight.w600, color: AppColors.charcoal, ), ), Text( _formatDate(DateTime.now()), style: GoogleFonts.outfit( fontSize: 14, color: AppColors.warmGray, ), ======= Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'How are you feeling?', style: GoogleFonts.outfit( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), Text( _formatDate(_selectedDate), style: GoogleFonts.outfit( fontSize: 14, color: theme.colorScheme.onSurfaceVariant, ), ), ], ), if (widget.initialDate == null) IconButton( onPressed: () => ref.read(navigationProvider.notifier).setIndex(0), icon: const Icon(Icons.close), style: IconButton.styleFrom( backgroundColor: theme.colorScheme.surfaceVariant.withOpacity(0.5), ), ), ], >>>>>>> 6742220 (Your commit message here) ), const SizedBox(height: 24), // Period Toggle _buildSectionCard( <<<<<<< HEAD ======= context, >>>>>>> 6742220 (Your commit message here) title: 'Period', child: Row( children: [ Expanded( child: Text( 'Is today a period day?', style: GoogleFonts.outfit( fontSize: 16, <<<<<<< HEAD color: AppColors.charcoal, ======= color: theme.colorScheme.onSurface, >>>>>>> 6742220 (Your commit message here) ), ), ), Switch( value: _isPeriodDay, onChanged: (value) => setState(() => _isPeriodDay = value), activeColor: AppColors.menstrualPhase, ), ], ), ), // Flow Intensity (only if period day) if (_isPeriodDay) ...[ const SizedBox(height: 16), _buildSectionCard( <<<<<<< HEAD ======= context, >>>>>>> 6742220 (Your commit message here) title: 'Flow Intensity', child: Row( children: FlowIntensity.values.map((flow) { final isSelected = _flowIntensity == flow; return Expanded( child: GestureDetector( onTap: () => setState(() => _flowIntensity = flow), <<<<<<< HEAD child: Container( ======= child: AnimatedContainer( duration: const Duration(milliseconds: 200), >>>>>>> 6742220 (Your commit message here) margin: const EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( color: isSelected <<<<<<< HEAD ? AppColors.menstrualPhase.withOpacity(0.2) : AppColors.lightGray.withOpacity(0.1), borderRadius: BorderRadius.circular(10), border: isSelected ? Border.all(color: AppColors.menstrualPhase) : null, ======= ? 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), >>>>>>> 6742220 (Your commit message here) ), child: Column( children: [ Icon( Icons.water_drop, color: isSelected ? AppColors.menstrualPhase <<<<<<< HEAD : AppColors.warmGray, ======= : theme.colorScheme.onSurfaceVariant, >>>>>>> 6742220 (Your commit message here) size: 20, ), const SizedBox(height: 4), Text( flow.label, style: GoogleFonts.outfit( fontSize: 11, <<<<<<< HEAD color: isSelected ? AppColors.menstrualPhase : AppColors.warmGray, ======= fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, color: isSelected ? AppColors.menstrualPhase : theme.colorScheme.onSurfaceVariant, >>>>>>> 6742220 (Your commit message here) ), ), ], ), ), ), ); }).toList(), ), ), ], const SizedBox(height: 16), // Mood _buildSectionCard( <<<<<<< HEAD ======= context, >>>>>>> 6742220 (Your commit message here) title: 'Mood', child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: MoodLevel.values.map((mood) { final isSelected = _mood == mood; return GestureDetector( onTap: () => setState(() => _mood = mood), <<<<<<< HEAD child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isSelected ? AppColors.softGold.withOpacity(0.2) ======= child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isSelected ? AppColors.softGold.withOpacity(isDark ? 0.3 : 0.2) >>>>>>> 6742220 (Your commit message here) : Colors.transparent, borderRadius: BorderRadius.circular(12), border: isSelected ? Border.all(color: AppColors.softGold) <<<<<<< HEAD : null, ======= : Border.all(color: Colors.transparent), >>>>>>> 6742220 (Your commit message here) ), child: Column( children: [ Text( mood.emoji, style: TextStyle( fontSize: isSelected ? 32 : 28, ), ), const SizedBox(height: 4), Text( mood.label, style: GoogleFonts.outfit( fontSize: 10, <<<<<<< HEAD color: isSelected ? AppColors.softGold : AppColors.warmGray, ======= fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, color: isSelected ? AppColors.softGold : theme.colorScheme.onSurfaceVariant, >>>>>>> 6742220 (Your commit message here) ), ), ], ), ), ); }).toList(), ), ), const SizedBox(height: 16), <<<<<<< HEAD // Energy Level _buildSectionCard( title: 'Energy Level', child: Column( children: [ Row( children: [ const Icon(Icons.battery_1_bar, color: AppColors.warmGray), ======= // Energy & Stress Levels _buildSectionCard( context, title: 'Daily Levels', child: Column( children: [ // Energy Level Row( children: [ SizedBox( width: 80, child: Text( 'Energy', style: GoogleFonts.outfit( fontSize: 14, color: theme.colorScheme.onSurface, ), ), ), >>>>>>> 6742220 (Your commit message here) Expanded( child: Slider( value: _energyLevel.toDouble(), min: 1, max: 5, divisions: 4, <<<<<<< HEAD ======= activeColor: AppColors.sageGreen, >>>>>>> 6742220 (Your commit message here) onChanged: (value) { setState(() => _energyLevel = value.round()); }, ), ), <<<<<<< HEAD const Icon(Icons.battery_full, color: AppColors.sageGreen), ], ), Text( _getEnergyLabel(_energyLevel), style: GoogleFonts.outfit( fontSize: 13, color: AppColors.warmGray, ), ======= SizedBox( width: 50, child: Text( _getEnergyLabel(_energyLevel), textAlign: TextAlign.end, style: GoogleFonts.outfit( fontSize: 11, color: theme.colorScheme.onSurfaceVariant, ), ), ), ], ), const SizedBox(height: 12), // Stress Level Row( children: [ SizedBox( width: 80, child: Text( 'Stress', style: GoogleFonts.outfit( fontSize: 14, color: theme.colorScheme.onSurface, ), ), ), Expanded( child: Slider( value: _stressLevel.toDouble(), min: 1, max: 5, divisions: 4, activeColor: AppColors.ovulationPhase, onChanged: (value) { setState(() => _stressLevel = value.round()); }, ), ), SizedBox( width: 50, child: Text( '$_stressLevel/5', textAlign: TextAlign.end, style: GoogleFonts.outfit( fontSize: 12, color: theme.colorScheme.onSurfaceVariant, ), ), ), ], >>>>>>> 6742220 (Your commit message here) ), ], ), ), const SizedBox(height: 16), // Symptoms _buildSectionCard( <<<<<<< HEAD ======= context, >>>>>>> 6742220 (Your commit message here) title: 'Symptoms', child: Column( children: [ // Cramps Slider Row( children: [ SizedBox( width: 80, child: Text( 'Cramps', style: GoogleFonts.outfit( fontSize: 14, <<<<<<< HEAD color: AppColors.charcoal, ======= color: theme.colorScheme.onSurface, >>>>>>> 6742220 (Your commit message here) ), ), ), Expanded( child: Slider( value: _crampIntensity.toDouble(), min: 0, max: 5, divisions: 5, activeColor: AppColors.rose, onChanged: (value) { setState(() => _crampIntensity = value.round()); }, ), ), SizedBox( <<<<<<< HEAD width: 40, child: Text( _crampIntensity == 0 ? 'None' : '$_crampIntensity/5', style: GoogleFonts.outfit( fontSize: 12, color: AppColors.warmGray, ======= width: 50, child: Text( _crampIntensity == 0 ? 'None' : '$_crampIntensity/5', textAlign: TextAlign.end, style: GoogleFonts.outfit( fontSize: 11, color: theme.colorScheme.onSurfaceVariant, >>>>>>> 6742220 (Your commit message here) ), ), ), ], ), const SizedBox(height: 12), // Symptom Toggles Wrap( spacing: 8, runSpacing: 8, children: [ <<<<<<< HEAD _buildSymptomChip('Headache', _hasHeadache, (v) => setState(() => _hasHeadache = v)), _buildSymptomChip('Bloating', _hasBloating, (v) => setState(() => _hasBloating = v)), _buildSymptomChip('Breast Tenderness', _hasBreastTenderness, (v) => setState(() => _hasBreastTenderness = v)), _buildSymptomChip('Fatigue', _hasFatigue, (v) => setState(() => _hasFatigue = v)), _buildSymptomChip('Acne', _hasAcne, (v) => setState(() => _hasAcne = v)), ======= _buildSymptomChip(context, 'Headache', _hasHeadache, (v) => setState(() => _hasHeadache = v)), _buildSymptomChip(context, 'Bloating', _hasBloating, (v) => setState(() => _hasBloating = v)), _buildSymptomChip(context, 'Breast Tenderness', _hasBreastTenderness, (v) => setState(() => _hasBreastTenderness = v)), _buildSymptomChip(context, 'Fatigue', _hasFatigue, (v) => setState(() => _hasFatigue = v)), _buildSymptomChip(context, 'Acne', _hasAcne, (v) => setState(() => _hasAcne = v)), _buildSymptomChip(context, 'Back Pain', _hasLowerBackPain, (v) => setState(() => _hasLowerBackPain = v)), _buildSymptomChip(context, 'Constipation', _hasConstipation, (v) => setState(() => _hasConstipation = v)), _buildSymptomChip(context, 'Diarrhea', _hasDiarrhea, (v) => setState(() => _hasDiarrhea = v)), _buildSymptomChip(context, 'Insomnia', _hasInsomnia, (v) => setState(() => _hasInsomnia = v)), >>>>>>> 6742220 (Your commit message here) ], ), ], ), ), const SizedBox(height: 16), // Notes _buildSectionCard( <<<<<<< HEAD ======= context, >>>>>>> 6742220 (Your commit message here) title: 'Notes', child: TextField( controller: _notesController, maxLines: 3, decoration: InputDecoration( hintText: 'Add any notes about how you\'re feeling...', <<<<<<< HEAD hintStyle: GoogleFonts.outfit( color: AppColors.lightGray, fontSize: 14, ), border: InputBorder.none, ), style: GoogleFonts.outfit( fontSize: 14, color: AppColors.charcoal, ======= filled: true, fillColor: isDark ? theme.colorScheme.surface : theme.colorScheme.surfaceVariant.withOpacity(0.1), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), ), style: GoogleFonts.outfit( fontSize: 14, color: theme.colorScheme.onSurface, >>>>>>> 6742220 (Your commit message here) ), ), ), const SizedBox(height: 24), // Save Button SizedBox( width: double.infinity, <<<<<<< HEAD ======= height: 54, >>>>>>> 6742220 (Your commit message here) child: ElevatedButton( onPressed: _saveEntry, child: const Text('Save Entry'), ), ), const SizedBox(height: 40), ], ), ), ); } <<<<<<< HEAD Widget _buildSectionCard({required String title, required Widget child}) { ======= Widget _buildSectionCard(BuildContext context, {required String title, required Widget child}) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; >>>>>>> 6742220 (Your commit message here) return Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( <<<<<<< HEAD color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: AppColors.charcoal.withOpacity(0.05), ======= color: theme.cardTheme.color, borderRadius: BorderRadius.circular(16), border: Border.all(color: theme.colorScheme.outline.withOpacity(0.05)), boxShadow: isDark ? null : [ BoxShadow( color: Colors.black.withOpacity(0.05), >>>>>>> 6742220 (Your commit message here) blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: GoogleFonts.outfit( fontSize: 16, fontWeight: FontWeight.w600, <<<<<<< HEAD color: AppColors.charcoal, ======= color: theme.colorScheme.onSurface, >>>>>>> 6742220 (Your commit message here) ), ), const SizedBox(height: 12), child, ], ), ); } <<<<<<< HEAD Widget _buildSymptomChip(String label, bool isSelected, ValueChanged onChanged) { return GestureDetector( onTap: () => onChanged(!isSelected), child: Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), decoration: BoxDecoration( color: isSelected ? AppColors.lavender.withOpacity(0.3) : AppColors.lightGray.withOpacity(0.1), borderRadius: BorderRadius.circular(20), border: isSelected ? Border.all(color: AppColors.lavender) : null, ), child: Text( label, style: GoogleFonts.outfit( fontSize: 13, color: isSelected ? AppColors.ovulationPhase : AppColors.warmGray, fontWeight: isSelected ? FontWeight.w500 : FontWeight.w400, ======= Widget _buildSymptomChip(BuildContext context, String label, bool isSelected, ValueChanged onChanged) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; return Material( color: Colors.transparent, child: InkWell( onTap: () => onChanged(!isSelected), borderRadius: BorderRadius.circular(20), child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), decoration: BoxDecoration( color: isSelected ? theme.colorScheme.tertiary.withOpacity(isDark ? 0.3 : 0.2) : theme.colorScheme.surfaceVariant.withOpacity(0.3), borderRadius: BorderRadius.circular(20), border: isSelected ? Border.all(color: theme.colorScheme.tertiary) : Border.all(color: Colors.transparent), ), child: Text( label, style: GoogleFonts.outfit( fontSize: 13, color: isSelected ? theme.colorScheme.onSurface : theme.colorScheme.onSurfaceVariant, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, ), >>>>>>> 6742220 (Your commit message here) ), ), ), ); } String _formatDate(DateTime date) { <<<<<<< HEAD ======= final now = DateTime.now(); if (DateUtils.isSameDay(date, now)) { return 'Today, ${_getMonth(date.month)} ${date.day}'; } const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; return '${days[date.weekday - 1]}, ${_getMonth(date.month)} ${date.day}'; } String _getMonth(int month) { >>>>>>> 6742220 (Your commit message here) const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; <<<<<<< HEAD const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; return '${days[date.weekday - 1]}, ${months[date.month - 1]} ${date.day}'; ======= return months[month - 1]; >>>>>>> 6742220 (Your commit message here) } String _getEnergyLabel(int level) { switch (level) { case 1: return 'Very Low'; case 2: return 'Low'; case 3: return 'Normal'; case 4: return 'Good'; case 5: return 'Excellent'; default: return 'Normal'; } } }