Your commit message here

This commit is contained in:
2025-12-19 22:47:27 -06:00
parent 5d746d694e
commit 464692ce56
21 changed files with 3018 additions and 0 deletions

View File

@@ -28,6 +28,10 @@ class _HusbandHomeScreenState extends ConsumerState<HusbandHomeScreen> {
index: _selectedIndex,
children: [
const _HusbandDashboard(),
<<<<<<< HEAD
=======
const _HusbandWifeStatus(),
>>>>>>> 6742220 (Your commit message here)
const _HusbandTipsScreen(),
const _HusbandLearnScreen(),
const _HusbandSettingsScreen(),
@@ -58,6 +62,14 @@ class _HusbandHomeScreenState extends ConsumerState<HusbandHomeScreen> {
label: 'Home',
),
BottomNavigationBarItem(
<<<<<<< HEAD
=======
icon: Icon(Icons.favorite_border),
activeIcon: Icon(Icons.favorite),
label: 'Status',
),
BottomNavigationBarItem(
>>>>>>> 6742220 (Your commit message here)
icon: Icon(Icons.lightbulb_outline),
activeIcon: Icon(Icons.lightbulb),
label: 'Tips',
@@ -829,3 +841,278 @@ class _HusbandSettingsScreen extends ConsumerWidget {
);
}
}
<<<<<<< HEAD
=======
class _HusbandWifeStatus extends ConsumerWidget {
const _HusbandWifeStatus();
@override
Widget build(BuildContext context, WidgetRef ref) {
final user = ref.watch(userProfileProvider);
final cycleInfo = ref.watch(currentCycleInfoProvider);
final entries = ref.watch(cycleEntriesProvider);
final wifeName = user?.partnerName ?? "Wife";
final phase = cycleInfo['phase'] as CyclePhase;
final dayOfCycle = cycleInfo['dayOfCycle'] as int;
// Find today's entry
final todayEntry = entries.firstWhere(
(e) => DateUtils.isSameDay(e.date, DateTime.now()),
orElse: () => CycleEntry(
id: '',
date: DateTime.now(),
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
),
);
return SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Wife\'s Status',
style: GoogleFonts.outfit(
fontSize: 28,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 8),
Text(
'Real-time updates on how $wifeName is doing',
style: GoogleFonts.outfit(
fontSize: 14,
color: AppColors.warmGray,
),
),
const SizedBox(height: 24),
// Phase and Day summary
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: AppColors.navyBlue.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Row(
children: [
_buildStatusCircle(dayOfCycle, phase),
const SizedBox(width: 20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
phase.label,
style: GoogleFonts.outfit(
fontSize: 20,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
Text(
'Cycle Day $dayOfCycle',
style: GoogleFonts.outfit(
fontSize: 14,
color: AppColors.warmGray,
),
),
const SizedBox(height: 8),
Text(
phase.description,
style: GoogleFonts.outfit(
fontSize: 13,
color: AppColors.charcoal.withOpacity(0.8),
),
),
],
),
),
],
),
),
const SizedBox(height: 24),
// Symptoms for Today
if (todayEntry.hasSymptoms || todayEntry.mood != null) ...[
Text(
'Today\'s Logs',
style: GoogleFonts.outfit(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 12),
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColors.navyBlue.withOpacity(0.03),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColors.navyBlue.withOpacity(0.05)),
),
child: Column(
children: [
if (todayEntry.mood != null)
_buildLogTile(Icons.emoji_emotions_outlined, 'Mood', '${todayEntry.mood!.emoji} ${todayEntry.mood!.label}'),
if (todayEntry.hasSymptoms)
_buildLogTile(Icons.healing_outlined, 'Symptoms', _getSymptomsSummary(todayEntry)),
if (todayEntry.energyLevel != null)
_buildLogTile(Icons.flash_on, 'Energy', '${todayEntry.energyLevel}/5'),
],
),
),
const SizedBox(height: 24),
],
// Support Checklist
Text(
'Support Checklist',
style: GoogleFonts.outfit(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColors.navyBlue,
),
),
const SizedBox(height: 12),
..._generateChecklist(todayEntry, phase).map((item) => _buildCheckItem(item)),
const SizedBox(height: 40),
],
),
),
);
}
Widget _buildStatusCircle(int day, CyclePhase phase) {
return Container(
width: 70,
height: 70,
decoration: BoxDecoration(
color: phase.color.withOpacity(0.15),
shape: BoxShape.circle,
border: Border.all(color: phase.color.withOpacity(0.3), width: 2),
),
child: Center(
child: Text(
day.toString(),
style: GoogleFonts.outfit(
fontSize: 24,
fontWeight: FontWeight.w700,
color: phase.color,
),
),
),
);
}
Widget _buildLogTile(IconData icon, String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
children: [
Icon(icon, size: 20, color: AppColors.steelBlue),
const SizedBox(width: 12),
Text(
'$label: ',
style: GoogleFonts.outfit(fontWeight: FontWeight.w500, fontSize: 14),
),
Expanded(
child: Text(
value,
style: GoogleFonts.outfit(fontSize: 14, color: AppColors.charcoal),
),
),
],
),
);
}
Widget _buildCheckItem(String text) {
return Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.navyBlue.withOpacity(0.05)),
),
child: Row(
children: [
Icon(Icons.check_circle_outline, color: AppColors.sageGreen, size: 20),
const SizedBox(width: 12),
Expanded(
child: Text(
text,
style: GoogleFonts.outfit(fontSize: 14, color: AppColors.navyBlue),
),
),
],
),
);
}
String _getSymptomsSummary(CycleEntry entry) {
List<String> s = [];
if (entry.crampIntensity != null && entry.crampIntensity! > 0) s.add('Cramps');
if (entry.hasHeadache) s.add('Headache');
if (entry.hasBloating) s.add('Bloating');
if (entry.hasFatigue) s.add('Fatigue');
if (entry.hasLowerBackPain) s.add('Back Pain');
return s.isNotEmpty ? s.join(', ') : 'None';
}
List<String> _generateChecklist(CycleEntry entry, CyclePhase phase) {
List<String> list = [];
// Symptom-based tips
if (entry.crampIntensity != null && entry.crampIntensity! >= 3) {
list.add('Bring her a heating pad or hot water bottle.');
}
if (entry.hasHeadache) {
list.add('Suggest some quiet time with dimmed lights.');
}
if (entry.hasFatigue || (entry.energyLevel != null && entry.energyLevel! <= 2)) {
list.add('Take over dinner or household chores tonight.');
}
if (entry.mood == MoodLevel.sad || entry.mood == MoodLevel.verySad) {
list.add('Offer a listening ear and extra comfort.');
}
// Phase-based fallback tips
if (list.length < 3) {
switch (phase) {
case CyclePhase.menstrual:
list.add('Suggest a relaxing movie night.');
list.add('Bring her a warm tea or cocoa.');
break;
case CyclePhase.follicular:
list.add('Plan a fun outdoor activity.');
list.add('Compliment her renewed energy.');
break;
case CyclePhase.ovulation:
list.add('Plan a romantic date night.');
list.add('Focus on quality connection time.');
break;
case CyclePhase.luteal:
list.add('Surprise her with her favorite comfort snack.');
list.add('Be extra patient if she\'s easily frustrated.');
break;
}
}
return list.take(4).toList();
}
}
>>>>>>> 6742220 (Your commit message here)