Files
Tracker/lib/screens/husband/husband_home_screen.dart

1198 lines
45 KiB
Dart

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/user_profile.dart';
import '../../models/cycle_entry.dart';
import '../../models/scripture.dart';
import '../../providers/user_provider.dart';
import '../../theme/app_theme.dart';
import '../../services/notification_service.dart';
import '../calendar/calendar_screen.dart';
import 'husband_devotional_screen.dart';
import 'husband_settings_screen.dart';
import 'husband_learn_articles_screen.dart';
/// Husband's companion app main screen
class HusbandHomeScreen extends ConsumerStatefulWidget {
const HusbandHomeScreen({super.key});
@override
ConsumerState<HusbandHomeScreen> createState() => _HusbandHomeScreenState();
}
class _HusbandHomeScreenState extends ConsumerState<HusbandHomeScreen> {
int _selectedIndex = 0;
void navigateToSettings() {
setState(() {
_selectedIndex = 5;
});
}
@override
Widget build(BuildContext context) {
final husbandTheme = _husbandTheme;
final isDark = husbandTheme.brightness == Brightness.dark;
return Theme(
data: husbandTheme,
child: Builder(
builder: (context) => Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: IndexedStack(
index: _selectedIndex,
children: const [
_HusbandDashboard(),
CalendarScreen(readOnly: true), // Reused Calendar
HusbandDevotionalScreen(), // Devotional & Planning
_HusbandTipsScreen(),
HusbandLearnArticlesScreen(),
HusbandSettingsScreen(),
],
),
bottomNavigationBar: Container(
decoration: BoxDecoration(
color: isDark ? const Color(0xFF1E1E1E) : Colors.white,
boxShadow: [
BoxShadow(
color: (isDark ? Colors.black : AppColors.navyBlue)
.withValues(alpha: 0.1),
blurRadius: 10,
offset: const Offset(0, -2),
),
],
),
child: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: (index) => setState(() => _selectedIndex = index),
backgroundColor: isDark ? const Color(0xFF1E1E1E) : Colors.white,
selectedItemColor: Theme.of(context).colorScheme.primary,
unselectedItemColor: isDark ? Colors.grey : AppColors.warmGray,
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
activeIcon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.calendar_month_outlined),
activeIcon: Icon(Icons.calendar_month),
label: 'Calendar',
),
BottomNavigationBarItem(
icon: Icon(Icons.menu_book_outlined),
activeIcon: Icon(Icons.menu_book),
label: 'Devotion',
),
BottomNavigationBarItem(
icon: Icon(Icons.lightbulb_outline),
activeIcon: Icon(Icons.lightbulb),
label: 'Tips',
),
BottomNavigationBarItem(
icon: Icon(Icons.school_outlined),
activeIcon: Icon(Icons.school),
label: 'Learn',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings_outlined),
activeIcon: Icon(Icons.settings),
label: 'Settings',
),
],
),
),
),
),
);
}
ThemeData get _husbandTheme {
final user = ref.watch(userProfileProvider);
final husbandThemeMode = user?.husbandThemeMode ?? AppThemeMode.system;
final husbandAccentColor = user?.husbandAccentColor ?? '0xFF1A3A5C';
// Determine brightness based on husbandThemeMode
Brightness brightness = MediaQuery.platformBrightnessOf(context);
if (husbandThemeMode == AppThemeMode.light) {
brightness = Brightness.light;
} else if (husbandThemeMode == AppThemeMode.dark) {
brightness = Brightness.dark;
}
final isDark = brightness == Brightness.dark;
final accentColor = Color(int.parse(husbandAccentColor));
// Dark theme with good contrast
if (isDark) {
return ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color(0xFF121212),
colorScheme: ColorScheme.dark(
primary: accentColor,
secondary: const Color(0xFFD4A574), // Warm gold for contrast
surface: const Color(0xFF1E1E1E),
onSurface: Colors.white,
),
// Text theme with high contrast for dark mode
textTheme: TextTheme(
headlineLarge: GoogleFonts.outfit(
fontSize: 28,
fontWeight: FontWeight.bold,
color: Colors.white,
),
headlineMedium: GoogleFonts.outfit(
fontSize: 22,
fontWeight: FontWeight.w600,
color: Colors.white,
),
titleLarge: GoogleFonts.outfit(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.white,
),
titleMedium: GoogleFonts.outfit(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.white.withValues(alpha: 0.95),
),
bodyLarge: GoogleFonts.outfit(
fontSize: 16,
color: Colors.white.withValues(alpha: 0.9),
),
bodyMedium: GoogleFonts.outfit(
fontSize: 14,
color: Colors.white.withValues(alpha: 0.85),
),
bodySmall: GoogleFonts.outfit(
fontSize: 12,
color: Colors.white.withValues(alpha: 0.7),
),
labelLarge: GoogleFonts.outfit(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
appBarTheme: AppBarTheme(
backgroundColor: const Color(0xFF1E1E1E),
foregroundColor: Colors.white,
elevation: 0,
iconTheme: const IconThemeData(color: Colors.white),
titleTextStyle: GoogleFonts.outfit(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
cardTheme: CardThemeData(
color: const Color(0xFF2A2A2A),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
cardColor: const Color(0xFF2A2A2A),
dividerColor: Colors.white.withValues(alpha: 0.12),
iconTheme: const IconThemeData(color: Colors.white70),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: accentColor,
foregroundColor: Colors.white,
),
),
segmentedButtonTheme: SegmentedButtonThemeData(
style: SegmentedButton.styleFrom(
backgroundColor: const Color(0xFF2A2A2A),
foregroundColor: Colors.white70,
selectedBackgroundColor: accentColor,
selectedForegroundColor: Colors.white,
),
),
);
} else {
// Light theme
return ThemeData(
useMaterial3: true,
brightness: Brightness.light,
scaffoldBackgroundColor: AppColors.warmCream,
colorScheme: ColorScheme.light(
primary: accentColor,
secondary: AppColors.gold,
surface: Colors.white,
onSurface: AppColors.charcoal,
),
textTheme: TextTheme(
headlineLarge: GoogleFonts.outfit(
fontSize: 28,
fontWeight: FontWeight.bold,
color: AppColors.charcoal,
),
headlineMedium: GoogleFonts.outfit(
fontSize: 22,
fontWeight: FontWeight.w600,
color: AppColors.charcoal,
),
titleLarge: GoogleFonts.outfit(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColors.charcoal,
),
titleMedium: GoogleFonts.outfit(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColors.charcoal.withValues(alpha: 0.9),
),
bodyLarge: GoogleFonts.outfit(
fontSize: 16,
color: AppColors.charcoal,
),
bodyMedium: GoogleFonts.outfit(
fontSize: 14,
color: AppColors.charcoal.withValues(alpha: 0.85),
),
bodySmall: GoogleFonts.outfit(
fontSize: 12,
color: AppColors.warmGray,
),
labelLarge: GoogleFonts.outfit(
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.charcoal,
),
),
appBarTheme: AppBarTheme(
backgroundColor: AppColors.warmCream,
foregroundColor: accentColor,
elevation: 0,
iconTheme: IconThemeData(color: accentColor),
titleTextStyle: GoogleFonts.outfit(
fontSize: 20,
fontWeight: FontWeight.w600,
color: accentColor,
),
),
cardTheme: CardThemeData(
color: Colors.white,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
cardColor: Colors.white,
dividerColor: AppColors.lightGray,
iconTheme: const IconThemeData(color: AppColors.warmGray),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: accentColor,
foregroundColor: Colors.white,
),
),
segmentedButtonTheme: SegmentedButtonThemeData(
style: SegmentedButton.styleFrom(
backgroundColor: AppColors.lightGray,
foregroundColor: AppColors.charcoal,
selectedBackgroundColor: accentColor,
selectedForegroundColor: Colors.white,
),
),
);
}
}
}
class _HusbandDashboard extends ConsumerStatefulWidget {
const _HusbandDashboard();
@override
ConsumerState<_HusbandDashboard> createState() => _HusbandDashboardState();
}
class _HusbandDashboardState extends ConsumerState<_HusbandDashboard> {
Scripture? _currentScripture;
@override
void initState() {
super.initState();
_loadNewVerse();
}
void _loadNewVerse() {
setState(() {
_currentScripture = ScriptureDatabase().getHusbandScripture();
});
}
@override
Widget build(BuildContext context) {
final user = ref.watch(userProfileProvider);
final cycleInfo = ref.watch(currentCycleInfoProvider);
final wifeName = user?.partnerName ?? "Wife";
final phase = cycleInfo.phase;
final dayOfCycle = cycleInfo.dayOfCycle;
final daysUntilPeriod = cycleInfo.daysUntilPeriod;
final scripture =
_currentScripture ?? ScriptureDatabase().getHusbandScripture();
return SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Greeting
Text(
'Hey there,',
style: GoogleFonts.outfit(
fontSize: 16,
color: AppColors.warmGray,
),
),
Text(
'Husband',
style: GoogleFonts.outfit(
fontSize: 28,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 24),
// Wife's Cycle Status
Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [
AppColors.navyBlue,
AppColors.steelBlue,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.favorite,
color: Colors.white,
size: 22,
),
),
const SizedBox(width: 12),
Text(
'$wifeName\'s Cycle',
style: GoogleFonts.outfit(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.white.withValues(alpha: 0.9),
),
),
],
),
const SizedBox(height: 16),
Text(
'Day $dayOfCycle${phase.label}',
style: GoogleFonts.outfit(
fontSize: 24,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
const SizedBox(height: 4),
Text(
daysUntilPeriod > 0
? '~$daysUntilPeriod days until period'
: 'Period expected soon',
style: GoogleFonts.outfit(
fontSize: 14,
color: Colors.white.withValues(alpha: 0.8),
),
),
const SizedBox(height: 16),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(phase.emoji),
const SizedBox(width: 6),
Text(
_getPhaseHint(phase),
style: GoogleFonts.outfit(
fontSize: 12,
color: Colors.white,
),
),
],
),
),
],
),
),
const SizedBox(height: 20),
// Support Tip
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: AppColors.navyBlue.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: AppColors.gold.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.lightbulb_outline,
color: AppColors.gold,
size: 20,
),
),
const SizedBox(width: 12),
Text(
'How to Support Her',
style: GoogleFonts.outfit(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
],
),
const SizedBox(height: 12),
Text(
_getSupportTip(phase),
style: GoogleFonts.outfit(
fontSize: 14,
color: AppColors.charcoal,
height: 1.5,
),
),
],
),
),
const SizedBox(height: 20),
// Recent Cravings (Dynamic)
Builder(
builder: (context) {
// Get recent cravings from the last 3 days
final allEntries = ref.read(cycleEntriesProvider);
// Sort by date desc
final sortedEntries = List<CycleEntry>.from(allEntries)
..sort((a, b) => b.date.compareTo(a.date));
final recentCravings = <String>{};
final now = DateTime.now();
for (var entry in sortedEntries) {
if (now.difference(entry.date).inDays > 3) break;
if (entry.cravings != null) {
recentCravings.addAll(entry.cravings!);
}
}
if (recentCravings.isEmpty) return const SizedBox.shrink();
return Container(
width: double.infinity,
margin: const EdgeInsets.only(bottom: 20),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: AppColors.rose.withValues(alpha: 0.3)),
boxShadow: [
BoxShadow(
color: AppColors.rose.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: AppColors.rose.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.fastfood,
color: AppColors.rose,
size: 20,
),
),
const SizedBox(width: 12),
Text(
'She is Craving...',
style: GoogleFonts.outfit(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
],
),
const SizedBox(height: 12),
Wrap(
spacing: 8,
runSpacing: 8,
children: recentCravings
.map((craving) => Chip(
label: Text(craving),
backgroundColor:
AppColors.rose.withValues(alpha: 0.1),
labelStyle: GoogleFonts.outfit(
color: AppColors.navyBlue,
fontWeight: FontWeight.w500),
side: BorderSide.none,
))
.toList(),
),
],
),
);
},
),
// Scripture for Husbands
Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColors.gold.withValues(alpha: 0.15),
AppColors.warmCream,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: AppColors.gold.withValues(alpha: 0.3),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.menu_book,
color: AppColors.gold,
size: 20,
),
const SizedBox(width: 8),
Expanded(
child: Text(
'Scripture for Husbands',
style: GoogleFonts.outfit(
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.warmGray,
),
),
),
// Quick version toggle
GestureDetector(
onTap: () => _showVersionPicker(context, ref),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColors.gold.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
user?.bibleTranslation.label ?? 'ESV',
style: GoogleFonts.outfit(
fontSize: 11,
fontWeight: FontWeight.w600,
color: AppColors.gold,
),
),
const SizedBox(width: 2),
const Icon(Icons.arrow_drop_down,
color: AppColors.gold, size: 16),
],
),
),
),
],
),
const SizedBox(height: 12),
Text(
'"${scripture.getVerse(user?.bibleTranslation ?? BibleTranslation.esv)}"',
style: GoogleFonts.lora(
fontSize: 15,
fontStyle: FontStyle.italic,
color: AppColors.navyBlue,
height: 1.6,
),
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${scripture.reference}',
style: GoogleFonts.outfit(
fontSize: 12,
fontWeight: FontWeight.w500,
color: AppColors.warmGray,
),
),
GestureDetector(
onTap: _loadNewVerse,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColors.gold.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.refresh,
color: AppColors.gold, size: 14),
const SizedBox(width: 4),
Text(
'New Verse',
style: GoogleFonts.outfit(
fontSize: 11,
fontWeight: FontWeight.w500,
color: AppColors.gold,
),
),
],
),
),
),
],
),
],
),
),
const SizedBox(height: 20),
// Prayer Button
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: () => _showPrayerPrompt(context, phase),
icon: const Text('🙏', style: TextStyle(fontSize: 18)),
label: Text(
'Pray for $wifeName',
style: GoogleFonts.outfit(fontWeight: FontWeight.w500),
),
style: OutlinedButton.styleFrom(
foregroundColor: AppColors.navyBlue,
side: const BorderSide(color: AppColors.navyBlue),
padding: const EdgeInsets.symmetric(vertical: 14),
),
),
),
const SizedBox(height: 40),
],
),
),
);
}
String _getPhaseHint(CyclePhase phase) {
switch (phase) {
case CyclePhase.menstrual:
return 'She may need extra rest';
case CyclePhase.follicular:
return 'Energy is returning';
case CyclePhase.ovulation:
return 'Fertile window';
case CyclePhase.luteal:
return 'PMS may occur';
}
}
String _getSupportTip(CyclePhase phase) {
switch (phase) {
case CyclePhase.menstrual:
return 'This is a time when she needs extra care. Help with household tasks without being asked. '
'Bring her favorite warm drink, suggest low-key activities, and be extra patient.';
case CyclePhase.follicular:
return 'Her energy is returning! This is a great time to plan dates, work on projects together, '
'and affirm her strengths. She may be more talkative and social.';
case CyclePhase.ovulation:
return 'Prioritize connection time. Romance and quality time matter. '
'If you\'re trying to conceive, this is your fertile window.';
case CyclePhase.luteal:
return 'Be patient—PMS may affect her mood. Listen more, "fix" less. '
'Take initiative on responsibilities and surprise her with comfort foods.';
}
}
void _showVersionPicker(BuildContext context, WidgetRef ref) {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (context) => Container(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Choose Translation',
style: GoogleFonts.outfit(
fontSize: 20,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 16),
...BibleTranslation.values.map((translation) => ListTile(
title: Text(
translation.label,
style: GoogleFonts.outfit(fontWeight: FontWeight.w500),
),
trailing: ref.watch(userProfileProvider)?.bibleTranslation ==
translation
? const Icon(Icons.check, color: AppColors.sageGreen)
: null,
onTap: () async {
final profile = ref.read(userProfileProvider);
if (profile != null) {
await ref
.read(userProfileProvider.notifier)
.updateProfile(
profile.copyWith(bibleTranslation: translation),
);
}
if (context.mounted) Navigator.pop(context);
},
)),
],
),
),
);
}
void _showPrayerPrompt(BuildContext context, CyclePhase phase) {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (context) => Container(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'🙏 Prayer for Your Wife',
style: GoogleFonts.outfit(
fontSize: 20,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 20),
Text(
_getPrayer(phase),
textAlign: TextAlign.center,
style: GoogleFonts.lora(
fontSize: 16,
fontStyle: FontStyle.italic,
color: AppColors.charcoal,
height: 1.6,
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.navyBlue,
foregroundColor: Colors.white,
),
child: const Text('Amen'),
),
),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: TextButton.icon(
onPressed: () {
final user = ref.read(userProfileProvider);
NotificationService().showPartnerUpdateNotification(
title: 'Your husband prayed for you!',
body:
'${user?.name ?? 'He'} just finished praying for you during her ${phase.label.toLowerCase()} phase.',
);
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Sent to wife!')),
);
},
icon: const Icon(Icons.share, size: 18),
label: const Text('Share with Wife'),
style: TextButton.styleFrom(
foregroundColor: AppColors.navyBlue,
),
),
),
const SizedBox(height: 16),
],
),
),
);
}
String _getPrayer(CyclePhase phase) {
switch (phase) {
case CyclePhase.menstrual:
return '"Lord, I lift up my wife during this time of rest. '
'Give her body the renewal it needs and grant her Your peace. '
'Help me to serve her with patience and love. Amen."';
case CyclePhase.follicular:
return '"Father, thank You for my wife\'s renewed energy. '
'Bless her endeavors and help me to encourage and support her. '
'May our partnership glorify You. Amen."';
case CyclePhase.ovulation:
return '"Creator God, You have designed my wife fearfully and wonderfully. '
'Whatever Your plans for our family, help us trust Your timing. '
'Bless our marriage and intimacy. Amen."';
case CyclePhase.luteal:
return '"Lord, be near to my wife during this phase. '
'When emotions are difficult, grant her Your peace that passes understanding. '
'Help me to be patient, kind, and understanding. Amen."';
}
}
}
class _HusbandTipsScreen extends StatelessWidget {
const _HusbandTipsScreen();
@override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Supporting Her',
style: GoogleFonts.outfit(
fontSize: 28,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 8),
Text(
'Practical ways to love your wife well',
style: GoogleFonts.outfit(
fontSize: 14,
color: AppColors.warmGray,
),
),
const SizedBox(height: 24),
_buildTipCategory('During Her Period', [
'🏠 Help with household tasks without being asked',
'🍵 Bring her favorite comfort drink',
'📺 Suggest low-key activities (movies, quiet time)',
'🙏 Pray for her physical comfort',
]),
const SizedBox(height: 16),
// Period Supplies (Dynamic)
Consumer(
builder: (context, ref, child) {
final user = ref.watch(userProfileProvider);
if (user == null || !user.isPadTrackingEnabled) {
return const SizedBox.shrink();
}
final brand = user.padBrand ?? 'Not specified';
final flow = user.typicalFlowIntensity;
return Column(
children: [
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColors.menstrualPhase.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: AppColors.menstrualPhase
.withValues(alpha: 0.3)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: const Icon(Icons.shopping_bag_outlined,
color: AppColors.menstrualPhase, size: 20),
),
const SizedBox(width: 12),
Text(
'Period Supplies',
style: GoogleFonts.outfit(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
],
),
const SizedBox(height: 12),
Text(
'She uses:',
style: GoogleFonts.outfit(
fontSize: 14, color: AppColors.warmGray),
),
const SizedBox(height: 4),
Text(
brand,
style: GoogleFonts.outfit(
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColors.navyBlue),
),
if (flow != null) ...[
const SizedBox(height: 8),
Text(
'Typical Flow: $flow/5',
style: GoogleFonts.outfit(
fontSize: 14, color: AppColors.charcoal),
),
],
if (user.padAbsorbency != null) ...[
const SizedBox(height: 4),
Text(
'Absorbency: ${user.padAbsorbency}/5',
style: GoogleFonts.outfit(
fontSize: 14, color: AppColors.charcoal),
),
],
// Low Stock Warning
if (user.padInventoryCount <=
user.lowInventoryThreshold) ...[
const SizedBox(height: 12),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: AppColors.rose.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.rose),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.warning_amber_rounded,
color: AppColors.rose, size: 20),
const SizedBox(width: 8),
Text(
'LOW STOCK! (${user.padInventoryCount} left)',
style: GoogleFonts.outfit(
fontSize: 14,
fontWeight: FontWeight.bold,
color: AppColors.rose),
),
],
),
const SizedBox(height: 4),
GestureDetector(
onTap: () {
// Navigate to settings - usually done via a callback or provider
// For simplicity here, we can try to find the state but if it's private
// we may need a different approach. However, looking at the code,
// HusbandHomeScreen is the parent. We can use a notification or just fix the logic.
// Based on the error, let's try to notify the parent.
final state =
context.findAncestorStateOfType<
_HusbandHomeScreenState>();
if (state != null) {
state.navigateToSettings();
}
},
child: Text(
'Check Settings to Sync',
style: GoogleFonts.outfit(
fontSize: 12,
decoration: TextDecoration.underline,
color: AppColors.rose,
),
),
),
],
),
),
],
],
),
),
const SizedBox(height: 16),
],
);
},
),
_buildTipCategory('Follicular Phase', [
'🎉 Plan dates or activities—her energy is returning',
'💬 She may be more talkative and social',
'💪 Great time for projects together',
'❤️ Affirm her strengths and beauty',
]),
const SizedBox(height: 16),
_buildTipCategory('Luteal Phase (PMS)', [
'😌 Be patient—PMS may affect her mood',
'🍫 Surprise with comfort foods',
'🧹 Take initiative on responsibilities',
'👂 Listen more, "fix" less',
]),
const SizedBox(height: 16),
const SizedBox(height: 16),
// Her Favorites Section
Consumer(
builder: (context, ref, child) {
final user = ref.watch(userProfileProvider);
final favorites = user?.favoriteFoods;
if (favorites == null || favorites.isEmpty) {
return const SizedBox.shrink();
}
return Column(
children: [
_buildTipCategory(
'❤️ Her Favorites (Cheat Sheet)', favorites),
const SizedBox(height: 16),
],
);
},
),
_buildTipCategory('General Wisdom', [
'🗣️ Ask how she\'s feeling—and actually listen',
'📱 Put your phone down when she\'s talking',
'🌹 Small gestures matter more than grand ones',
'🙏 Pray for her daily',
]),
const SizedBox(height: 16),
_buildTipCategory("Men's Health", [
'💪 Exercise regularly to boost energy and mood',
'🥗 Eat a balanced diet rich in protein and vegetables',
'😴 Prioritize 7-8 hours of sleep for recovery',
'💧 Stay hydrated throughout the day',
'🧠 Practice stress management techniques',
]),
],
),
),
);
}
Widget _buildTipCategory(String title, List<String> tips) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: GoogleFonts.outfit(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 12),
...tips.map((tip) => Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
tip,
style: GoogleFonts.outfit(
fontSize: 14,
color: AppColors.charcoal,
height: 1.4,
),
),
)),
],
),
);
}
}