Your commit message here
This commit is contained in:
@@ -7,6 +7,10 @@ import '../../models/cycle_entry.dart';
|
||||
import '../../providers/user_provider.dart';
|
||||
import '../../services/cycle_service.dart';
|
||||
import '../../theme/app_theme.dart';
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
import '../log/log_screen.dart';
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
|
||||
class CalendarScreen extends ConsumerStatefulWidget {
|
||||
const CalendarScreen({super.key});
|
||||
@@ -141,6 +145,7 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
||||
),
|
||||
),
|
||||
calendarBuilders: CalendarBuilders(
|
||||
<<<<<<< HEAD
|
||||
markerBuilder: (context, date, events) {
|
||||
// Check if it's a logged period day
|
||||
final isLoggedPeriod = _isLoggedPeriodDay(date, entries);
|
||||
@@ -174,6 +179,58 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
||||
);
|
||||
}
|
||||
return null;
|
||||
=======
|
||||
markerBuilder: (context, date, entries) {
|
||||
final entry = _getEntryForDate(date, entries);
|
||||
|
||||
if (entry == null) {
|
||||
final phase = _getPhaseForDate(date, lastPeriodStart, cycleLength);
|
||||
if (phase != null) {
|
||||
return Positioned(
|
||||
bottom: 1,
|
||||
child: Container(
|
||||
width: 4,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: _getPhaseColor(phase).withOpacity(0.3),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// If we have an entry, show icons/markers
|
||||
return Positioned(
|
||||
bottom: 1,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (entry.isPeriodDay)
|
||||
Container(
|
||||
width: 6,
|
||||
height: 6,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 1),
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.menstrualPhase,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
if (entry.mood != null || entry.energyLevel != 3 || entry.hasSymptoms)
|
||||
Container(
|
||||
width: 6,
|
||||
height: 6,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 1),
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.softGold,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -279,6 +336,7 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
||||
Widget _buildDayInfo(DateTime date, DateTime? lastPeriodStart, int cycleLength, List<CycleEntry> entries) {
|
||||
final phase = _getPhaseForDate(date, lastPeriodStart, cycleLength);
|
||||
final entry = _getEntryForDate(date, entries);
|
||||
<<<<<<< HEAD
|
||||
final isLoggedPeriod = entry?.isPeriodDay ?? false;
|
||||
|
||||
return Container(
|
||||
@@ -287,10 +345,27 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
=======
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardTheme.color,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
<<<<<<< HEAD
|
||||
Text(
|
||||
'${_getMonthName(date.month)} ${date.day}, ${date.year}',
|
||||
style: GoogleFonts.outfit(
|
||||
@@ -352,6 +427,180 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
||||
phase?.description ?? 'No cycle data for this date',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
=======
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'${_getMonthName(date.month)} ${date.day}, ${date.year}',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
if (entry != null)
|
||||
const Icon(Icons.check_circle, color: AppColors.sageGreen, size: 20),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (phase != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: _getPhaseColor(phase).withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(phase.emoji),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
phase.label,
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _getPhaseColor(phase),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
if (entry == null)
|
||||
Text(
|
||||
phase?.description ?? 'No data for this date',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: AppColors.warmGray,
|
||||
),
|
||||
)
|
||||
else ...[
|
||||
// Period Detail
|
||||
if (entry.isPeriodDay)
|
||||
_buildDetailRow(Icons.water_drop, 'Period Day', AppColors.menstrualPhase,
|
||||
value: entry.flowIntensity?.label),
|
||||
|
||||
// Mood Detail
|
||||
if (entry.mood != null)
|
||||
_buildDetailRow(Icons.emoji_emotions_outlined, 'Mood', AppColors.softGold,
|
||||
value: '${entry.mood!.emoji} ${entry.mood!.label}'),
|
||||
|
||||
// Energy Detail
|
||||
_buildDetailRow(Icons.flash_on, 'Energy Level', AppColors.follicularPhase,
|
||||
value: _getEnergyLabel(entry.energyLevel)),
|
||||
|
||||
// Symptoms
|
||||
if (entry.hasSymptoms)
|
||||
_buildDetailRow(Icons.healing_outlined, 'Symptoms', AppColors.lavender,
|
||||
value: _getSymptomsString(entry)),
|
||||
|
||||
// Contextual Recommendation
|
||||
_buildRecommendation(entry),
|
||||
|
||||
// Notes
|
||||
if (entry.notes?.isNotEmpty == true)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Notes', style: GoogleFonts.outfit(fontSize: 12, fontWeight: FontWeight.w600, color: AppColors.warmGray)),
|
||||
const SizedBox(height: 4),
|
||||
Text(entry.notes!, style: GoogleFonts.outfit(fontSize: 14)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Action Buttons
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Log for ${_getMonthName(date.month)} ${date.day}'),
|
||||
),
|
||||
body: LogScreen(initialDate: date),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: Icon(entry != null ? Icons.edit_note : Icons.add_circle_outline),
|
||||
label: Text(entry != null ? 'Edit Log' : 'Add Log'),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.sageGreen,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildRecommendation(CycleEntry entry) {
|
||||
final scripture = ScriptureDatabase.getRecommendedScripture(entry);
|
||||
if (scripture == null) return const SizedBox.shrink();
|
||||
|
||||
final user = ref.read(userProfileProvider);
|
||||
final translation = user?.bibleTranslation ?? BibleTranslation.esv;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(top: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.softGold.withOpacity(isDark ? 0.15 : 0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColors.softGold.withOpacity(0.3)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.auto_awesome, color: AppColors.softGold, size: 18),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'Daily Encouragement',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.softGold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
'"${scripture.getVerse(translation)}"',
|
||||
style: GoogleFonts.lora(
|
||||
fontSize: 14,
|
||||
fontStyle: FontStyle.italic,
|
||||
color: isDark ? Colors.white : AppColors.charcoal,
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'— ${scripture.reference}',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
color: AppColors.warmGray,
|
||||
),
|
||||
),
|
||||
@@ -360,6 +609,59 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
Widget _buildDetailRow(IconData icon, String label, Color color, {String? value}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Icon(icon, color: color, size: 18),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 12,
|
||||
color: AppColors.warmGray,
|
||||
),
|
||||
),
|
||||
if (value != null)
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _getSymptomsString(CycleEntry entry) {
|
||||
List<String> s = [];
|
||||
if (entry.crampIntensity != null && entry.crampIntensity! > 0) s.add('Cramps (${entry.crampIntensity}/5)');
|
||||
if (entry.hasHeadache) s.add('Headache');
|
||||
if (entry.hasBloating) s.add('Bloating');
|
||||
if (entry.hasBreastTenderness) s.add('Breast Tenderness');
|
||||
if (entry.hasFatigue) s.add('Fatigue');
|
||||
if (entry.hasAcne) s.add('Acne');
|
||||
return s.join(', ');
|
||||
}
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
CyclePhase? _getPhaseForDate(DateTime date, DateTime? lastPeriodStart, int cycleLength) {
|
||||
if (lastPeriodStart == null) return null;
|
||||
|
||||
|
||||
@@ -6,10 +6,57 @@ import '../../providers/user_provider.dart';
|
||||
import '../../services/cycle_service.dart';
|
||||
import '../../models/cycle_entry.dart';
|
||||
import '../../theme/app_theme.dart';
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
import '../../widgets/scripture_card.dart';
|
||||
import '../../models/user_profile.dart';
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
|
||||
class DevotionalScreen extends ConsumerWidget {
|
||||
const DevotionalScreen({super.key});
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
Future<void> _showTranslationPicker(BuildContext context, WidgetRef ref, UserProfile? user) async {
|
||||
if (user == null) return;
|
||||
|
||||
final selected = await showModalBottomSheet<BibleTranslation>(
|
||||
context: context,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||
),
|
||||
builder: (context) => Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
child: Text(
|
||||
'Select Bible Translation',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
),
|
||||
...BibleTranslation.values.map((t) => ListTile(
|
||||
title: Text(t.label),
|
||||
trailing: user.bibleTranslation == t
|
||||
? Icon(Icons.check, color: AppColors.sageGreen)
|
||||
: null,
|
||||
onTap: () => Navigator.pop(context, t),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (selected != null) {
|
||||
await ref.read(userProfileProvider.notifier).updateProfile(
|
||||
user.copyWith(bibleTranslation: selected)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final user = ref.watch(userProfileProvider);
|
||||
@@ -71,6 +118,7 @@ class DevotionalScreen extends ConsumerWidget {
|
||||
const SizedBox(height: 32),
|
||||
|
||||
// Main Scripture Card
|
||||
<<<<<<< HEAD
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(24),
|
||||
@@ -130,6 +178,14 @@ class DevotionalScreen extends ConsumerWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
=======
|
||||
ScriptureCard(
|
||||
verse: scripture.getVerse(user?.bibleTranslation ?? BibleTranslation.esv),
|
||||
reference: scripture.reference,
|
||||
translation: (user?.bibleTranslation ?? BibleTranslation.esv).label,
|
||||
phase: phase,
|
||||
onTranslationTap: () => _showTranslationPicker(context, ref, user),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
<<<<<<< HEAD
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
=======
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
import '../../theme/app_theme.dart';
|
||||
import '../../models/user_profile.dart';
|
||||
import '../../models/cycle_entry.dart';
|
||||
@@ -14,6 +17,7 @@ import '../../widgets/cycle_ring.dart';
|
||||
import '../../widgets/scripture_card.dart';
|
||||
import '../../widgets/quick_log_buttons.dart';
|
||||
import '../../providers/user_provider.dart';
|
||||
<<<<<<< HEAD
|
||||
import '../../services/cycle_service.dart';
|
||||
|
||||
class HomeScreen extends ConsumerStatefulWidget {
|
||||
@@ -31,28 +35,60 @@ class _HomeScreenState extends ConsumerState<HomeScreen> {
|
||||
return Scaffold(
|
||||
body: IndexedStack(
|
||||
index: _selectedIndex,
|
||||
=======
|
||||
import '../../providers/navigation_provider.dart';
|
||||
import '../../services/cycle_service.dart';
|
||||
import '../../services/bible_utils.dart';
|
||||
|
||||
class HomeScreen extends ConsumerWidget {
|
||||
const HomeScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedIndex = ref.watch(navigationProvider);
|
||||
|
||||
return Scaffold(
|
||||
body: IndexedStack(
|
||||
index: selectedIndex,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
children: [
|
||||
const _DashboardTab(),
|
||||
const CalendarScreen(),
|
||||
const LogScreen(),
|
||||
const DevotionalScreen(),
|
||||
<<<<<<< HEAD
|
||||
_SettingsTab(onReset: () => setState(() => _selectedIndex = 0)),
|
||||
=======
|
||||
_SettingsTab(onReset: () => ref.read(navigationProvider.notifier).setIndex(0)),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
decoration: BoxDecoration(
|
||||
<<<<<<< HEAD
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.charcoal.withOpacity(0.1),
|
||||
=======
|
||||
color: Theme.of(context).bottomNavigationBarTheme.backgroundColor,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: (Theme.of(context).brightness == Brightness.dark ? Colors.black : AppColors.charcoal).withOpacity(0.1),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, -2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: BottomNavigationBar(
|
||||
<<<<<<< HEAD
|
||||
currentIndex: _selectedIndex,
|
||||
onTap: (index) => setState(() => _selectedIndex = index),
|
||||
=======
|
||||
currentIndex: selectedIndex,
|
||||
onTap: (index) => ref.read(navigationProvider.notifier).setIndex(index),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
items: const [
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.home_outlined),
|
||||
@@ -91,6 +127,7 @@ class _DashboardTab extends ConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
<<<<<<< HEAD
|
||||
final user = ref.watch(userProfileProvider);
|
||||
final cycleInfo = ref.watch(currentCycleInfoProvider);
|
||||
|
||||
@@ -100,6 +137,18 @@ class _DashboardTab extends ConsumerWidget {
|
||||
final cycleLength = user?.averageCycleLength ?? 28;
|
||||
|
||||
// Get scripture for current phase
|
||||
=======
|
||||
final name = ref.watch(userProfileProvider.select((u) => u?.name)) ?? 'Friend';
|
||||
final translation = ref.watch(userProfileProvider.select((u) => u?.bibleTranslation)) ?? BibleTranslation.esv;
|
||||
final role = ref.watch(userProfileProvider.select((u) => u?.role)) ?? UserRole.wife;
|
||||
final isMarried = ref.watch(userProfileProvider.select((u) => u?.isMarried)) ?? false;
|
||||
final averageCycleLength = ref.watch(userProfileProvider.select((u) => u?.averageCycleLength)) ?? 28;
|
||||
|
||||
final cycleInfo = ref.watch(currentCycleInfoProvider);
|
||||
final phase = cycleInfo['phase'] as CyclePhase;
|
||||
final dayOfCycle = cycleInfo['dayOfCycle'] as int;
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
final scripture = ScriptureDatabase.getScriptureForPhase(phase.name);
|
||||
|
||||
return SafeArea(
|
||||
@@ -108,6 +157,7 @@ class _DashboardTab extends ConsumerWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
<<<<<<< HEAD
|
||||
// Greeting
|
||||
_buildGreeting(name),
|
||||
const SizedBox(height: 24),
|
||||
@@ -137,15 +187,50 @@ class _DashboardTab extends ConsumerWidget {
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
_buildGreeting(context, name),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
Center(
|
||||
child: CycleRing(
|
||||
dayOfCycle: dayOfCycle,
|
||||
totalDays: averageCycleLength,
|
||||
phase: phase,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
|
||||
ScriptureCard(
|
||||
verse: scripture.getVerse(translation),
|
||||
reference: scripture.reference,
|
||||
translation: translation.label,
|
||||
phase: phase,
|
||||
onTranslationTap: () => BibleUtils.showTranslationPicker(context, ref),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
Text(
|
||||
'Quick Log',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const QuickLogButtons(),
|
||||
<<<<<<< HEAD
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Today's Tip - Only show if not just tracking or husband (though husband has own screen)
|
||||
if (user?.role == UserRole.wife)
|
||||
TipCard(phase: phase, isMarried: user?.isMarried ?? false),
|
||||
=======
|
||||
const SizedBox(height: 24),
|
||||
|
||||
if (role == UserRole.wife)
|
||||
TipCard(phase: phase, isMarried: isMarried),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
@@ -153,7 +238,12 @@ class _DashboardTab extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
Widget _buildGreeting(String name) {
|
||||
=======
|
||||
Widget _buildGreeting(BuildContext context, String name) {
|
||||
final theme = Theme.of(context);
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
final hour = DateTime.now().hour;
|
||||
String greeting;
|
||||
if (hour < 12) {
|
||||
@@ -174,15 +264,26 @@ class _DashboardTab extends ConsumerWidget {
|
||||
'$greeting,',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 16,
|
||||
<<<<<<< HEAD
|
||||
color: AppColors.warmGray,
|
||||
=======
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
Text(
|
||||
name,
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
style: theme.textTheme.displaySmall?.copyWith(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -192,19 +293,31 @@ class _DashboardTab extends ConsumerWidget {
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
<<<<<<< HEAD
|
||||
color: AppColors.blushPink,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.notifications_outlined,
|
||||
color: AppColors.rose,
|
||||
=======
|
||||
color: theme.colorScheme.primaryContainer.withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.notifications_outlined,
|
||||
color: theme.colorScheme.primary,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
|
||||
// Placeholder _calculateCycleInfo removed as it's now in CycleService
|
||||
=======
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
}
|
||||
|
||||
class _SettingsTab extends ConsumerWidget {
|
||||
@@ -213,6 +326,7 @@ class _SettingsTab extends ConsumerWidget {
|
||||
|
||||
Widget _buildSettingsTile(BuildContext context, IconData icon, String title, {VoidCallback? onTap}) {
|
||||
return ListTile(
|
||||
<<<<<<< HEAD
|
||||
leading: Icon(icon, color: AppColors.charcoal),
|
||||
title: Text(
|
||||
title,
|
||||
@@ -222,6 +336,16 @@ class _SettingsTab extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
trailing: Icon(Icons.chevron_right, color: AppColors.lightGray),
|
||||
=======
|
||||
leading: Icon(icon, color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8)),
|
||||
title: Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
trailing: const Icon(Icons.chevron_right, color: AppColors.lightGray),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
onTap: onTap ?? () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Settings coming soon!')),
|
||||
@@ -259,7 +383,14 @@ class _SettingsTab extends ConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
<<<<<<< HEAD
|
||||
final user = ref.watch(userProfileProvider);
|
||||
=======
|
||||
final name = ref.watch(userProfileProvider.select((u) => u?.name)) ?? 'Guest';
|
||||
final roleSymbol = ref.watch(userProfileProvider.select((u) => u?.role)) == UserRole.husband ? 'HUSBAND' : null;
|
||||
final relationshipStatus = ref.watch(userProfileProvider.select((u) => u?.relationshipStatus.name.toUpperCase())) ?? 'SINGLE';
|
||||
final translationLabel = ref.watch(userProfileProvider.select((u) => u?.bibleTranslation.label)) ?? 'ESV';
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
|
||||
return SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
@@ -269,14 +400,22 @@ class _SettingsTab extends ConsumerWidget {
|
||||
children: [
|
||||
Text(
|
||||
'Settings',
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
style: Theme.of(context).textTheme.displayMedium?.copyWith(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Profile Card
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
@@ -290,6 +429,14 @@ class _SettingsTab extends ConsumerWidget {
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
=======
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardTheme.color,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Theme.of(context).colorScheme.outline.withOpacity(0.05)),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -306,7 +453,11 @@ class _SettingsTab extends ConsumerWidget {
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
<<<<<<< HEAD
|
||||
user?.name.isNotEmpty == true ? user!.name[0].toUpperCase() : '?',
|
||||
=======
|
||||
name.isNotEmpty ? name[0].toUpperCase() : '?',
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
@@ -321,6 +472,7 @@ class _SettingsTab extends ConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
<<<<<<< HEAD
|
||||
user?.name ?? 'Guest',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 18,
|
||||
@@ -332,6 +484,16 @@ class _SettingsTab extends ConsumerWidget {
|
||||
user?.role == UserRole.husband
|
||||
? 'HUSBAND'
|
||||
: (user?.relationshipStatus.name.toUpperCase() ?? 'SINGLE'),
|
||||
=======
|
||||
name,
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
roleSymbol ?? relationshipStatus,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 12,
|
||||
letterSpacing: 1,
|
||||
@@ -341,27 +503,50 @@ class _SettingsTab extends ConsumerWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
<<<<<<< HEAD
|
||||
Icon(Icons.chevron_right, color: AppColors.warmGray),
|
||||
=======
|
||||
const Icon(Icons.chevron_right, color: AppColors.warmGray),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Settings Groups
|
||||
_buildSettingsGroup('Preferences', [
|
||||
_buildSettingsTile(context, Icons.notifications_outlined, 'Notifications'),
|
||||
=======
|
||||
_buildSettingsGroup(context, 'Preferences', [
|
||||
_buildSettingsTile(context, Icons.notifications_outlined, 'Notifications'),
|
||||
_buildSettingsTile(
|
||||
context,
|
||||
Icons.book_outlined,
|
||||
'Bible Version ($translationLabel)',
|
||||
onTap: () => BibleUtils.showTranslationPicker(context, ref),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
_buildSettingsTile(context, Icons.palette_outlined, 'Appearance'),
|
||||
_buildSettingsTile(context, Icons.lock_outline, 'Privacy'),
|
||||
]),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
<<<<<<< HEAD
|
||||
_buildSettingsGroup('Cycle', [
|
||||
=======
|
||||
_buildSettingsGroup(context, 'Cycle', [
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
_buildSettingsTile(context, Icons.calendar_today_outlined, 'Cycle Settings'),
|
||||
_buildSettingsTile(context, Icons.trending_up_outlined, 'Cycle History'),
|
||||
_buildSettingsTile(context, Icons.download_outlined, 'Export Data'),
|
||||
]),
|
||||
const SizedBox(height: 16),
|
||||
<<<<<<< HEAD
|
||||
_buildSettingsGroup('Account', [
|
||||
=======
|
||||
_buildSettingsGroup(context, 'Account', [
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
_buildSettingsTile(
|
||||
context,
|
||||
Icons.logout,
|
||||
@@ -376,7 +561,11 @@ class _SettingsTab extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
Widget _buildSettingsGroup(String title, List<Widget> tiles) {
|
||||
=======
|
||||
Widget _buildSettingsGroup(BuildContext context, String title, List<Widget> tiles) {
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -392,8 +581,14 @@ class _SettingsTab extends ConsumerWidget {
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
<<<<<<< HEAD
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
=======
|
||||
color: Theme.of(context).cardTheme.color,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Theme.of(context).colorScheme.outline.withOpacity(0.05)),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
child: Column(
|
||||
children: tiles,
|
||||
@@ -403,4 +598,7 @@ class _SettingsTab extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
|
||||
=======
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -7,13 +7,23 @@ 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<LogScreen> createState() => _LogScreenState();
|
||||
}
|
||||
|
||||
class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
late DateTime _selectedDate;
|
||||
String? _existingEntryId;
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
bool _isPeriodDay = false;
|
||||
FlowIntensity? _flowIntensity;
|
||||
MoodLevel? _mood;
|
||||
@@ -24,9 +34,61 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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();
|
||||
@@ -34,8 +96,13 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
|
||||
Future<void> _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,
|
||||
@@ -46,28 +113,60 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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;
|
||||
@@ -78,12 +177,26 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
_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),
|
||||
@@ -91,6 +204,7 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Header
|
||||
<<<<<<< HEAD
|
||||
Text(
|
||||
'How are you feeling?',
|
||||
style: GoogleFonts.outfit(
|
||||
@@ -105,11 +219,49 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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: [
|
||||
@@ -118,7 +270,11 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
'Is today a period day?',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 16,
|
||||
<<<<<<< HEAD
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
color: theme.colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -135,6 +291,10 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
if (_isPeriodDay) ...[
|
||||
const SizedBox(height: 16),
|
||||
_buildSectionCard(
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
context,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
title: 'Flow Intensity',
|
||||
child: Row(
|
||||
children: FlowIntensity.values.map((flow) {
|
||||
@@ -142,17 +302,31 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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: [
|
||||
@@ -160,7 +334,11 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
Icons.water_drop,
|
||||
color: isSelected
|
||||
? AppColors.menstrualPhase
|
||||
<<<<<<< HEAD
|
||||
: AppColors.warmGray,
|
||||
=======
|
||||
: theme.colorScheme.onSurfaceVariant,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
@@ -168,9 +346,16 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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)
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -187,6 +372,10 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
|
||||
// Mood
|
||||
_buildSectionCard(
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
context,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
title: 'Mood',
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
@@ -194,16 +383,29 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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: [
|
||||
@@ -218,9 +420,16 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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)
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -233,6 +442,7 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Energy Level
|
||||
_buildSectionCard(
|
||||
title: 'Energy Level',
|
||||
@@ -241,17 +451,43 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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),
|
||||
],
|
||||
),
|
||||
@@ -261,6 +497,59 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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)
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -270,6 +559,10 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
|
||||
// Symptoms
|
||||
_buildSectionCard(
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
context,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
title: 'Symptoms',
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -282,7 +575,11 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
'Cramps',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
<<<<<<< HEAD
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
color: theme.colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -299,12 +596,22 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
),
|
||||
),
|
||||
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)
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -316,11 +623,23 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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)
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -331,12 +650,17 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
|
||||
// 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,
|
||||
@@ -346,6 +670,18 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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)
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -355,6 +691,10 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
// Save Button
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
height: 54,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
child: ElevatedButton(
|
||||
onPressed: _saveEntry,
|
||||
child: const Text('Save Entry'),
|
||||
@@ -367,16 +707,32 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
<<<<<<< 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),
|
||||
),
|
||||
@@ -390,7 +746,11 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
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),
|
||||
@@ -400,6 +760,7 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
Widget _buildSymptomChip(String label, bool isSelected, ValueChanged<bool> onChanged) {
|
||||
return GestureDetector(
|
||||
onTap: () => onChanged(!isSelected),
|
||||
@@ -416,6 +777,36 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
fontSize: 13,
|
||||
color: isSelected ? AppColors.ovulationPhase : AppColors.warmGray,
|
||||
fontWeight: isSelected ? FontWeight.w500 : FontWeight.w400,
|
||||
=======
|
||||
Widget _buildSymptomChip(BuildContext context, String label, bool isSelected, ValueChanged<bool> 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)
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -423,12 +814,28 @@ class _LogScreenState extends ConsumerState<LogScreen> {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -140,8 +140,19 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
<<<<<<< HEAD
|
||||
// Different background color for husband flow
|
||||
final bgColor = _role == UserRole.husband ? AppColors.warmCream : AppColors.cream;
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
|
||||
// Different background color for husband flow
|
||||
final isHusband = _role == UserRole.husband;
|
||||
final bgColor = isHusband
|
||||
? (isDark ? const Color(0xFF1A1C1E) : AppColors.warmCream)
|
||||
: theme.scaffoldBackgroundColor;
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: bgColor,
|
||||
@@ -154,13 +165,22 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: SmoothPageIndicator(
|
||||
controller: _pageController,
|
||||
<<<<<<< HEAD
|
||||
count: _role == UserRole.husband ? 2 : 5,
|
||||
=======
|
||||
count: isHusband ? 2 : 5,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
effect: WormEffect(
|
||||
dotHeight: 8,
|
||||
dotWidth: 8,
|
||||
spacing: 12,
|
||||
<<<<<<< HEAD
|
||||
activeDotColor: _role == UserRole.husband ? AppColors.navyBlue : AppColors.sageGreen,
|
||||
dotColor: AppColors.lightGray.withOpacity(0.3),
|
||||
=======
|
||||
activeDotColor: isHusband ? AppColors.navyBlue : AppColors.sageGreen,
|
||||
dotColor: theme.colorScheme.outline.withOpacity(0.2),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -189,6 +209,11 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildRolePage() {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Column(
|
||||
@@ -215,10 +240,17 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
Text(
|
||||
'Who is this app for?',
|
||||
textAlign: TextAlign.center,
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
style: theme.textTheme.displayMedium?.copyWith(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
@@ -230,6 +262,10 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
height: 54,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
child: ElevatedButton(
|
||||
onPressed: _nextPage,
|
||||
style: ElevatedButton.styleFrom(
|
||||
@@ -244,10 +280,20 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildRoleOption(UserRole role, String title, String subtitle, IconData icon) {
|
||||
<<<<<<< HEAD
|
||||
final isSelected = _role == role;
|
||||
// Dynamic colors based on role selection
|
||||
final activeColor = role == UserRole.wife ? AppColors.sageGreen : AppColors.navyBlue;
|
||||
final activeBg = role == UserRole.wife ? AppColors.sageGreen.withOpacity(0.1) : AppColors.navyBlue.withOpacity(0.1);
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
final isSelected = _role == role;
|
||||
|
||||
// Dynamic colors based on role selection
|
||||
final activeColor = role == UserRole.wife ? AppColors.sageGreen : AppColors.navyBlue;
|
||||
final activeBg = activeColor.withOpacity(isDark ? 0.3 : 0.1);
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => setState(() => _role = role),
|
||||
@@ -255,6 +301,7 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
<<<<<<< HEAD
|
||||
color: isSelected ? activeBg : Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
@@ -268,18 +315,34 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
offset: const Offset(0, 4),
|
||||
)
|
||||
] : [],
|
||||
=======
|
||||
color: isSelected ? activeBg : theme.cardTheme.color,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: isSelected ? activeColor : theme.colorScheme.outline.withOpacity(0.1),
|
||||
width: isSelected ? 2 : 1,
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
<<<<<<< HEAD
|
||||
color: isSelected ? activeColor : AppColors.lightGray.withOpacity(0.1),
|
||||
=======
|
||||
color: isSelected ? activeColor : theme.colorScheme.surfaceVariant,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
<<<<<<< HEAD
|
||||
color: isSelected ? Colors.white : AppColors.warmGray,
|
||||
=======
|
||||
color: isSelected ? Colors.white : theme.colorScheme.onSurfaceVariant,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
@@ -290,18 +353,30 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
style: theme.textTheme.titleLarge?.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
subtitle,
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
color: AppColors.warmGray,
|
||||
=======
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -316,6 +391,10 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildNamePage() {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
final isHusband = _role == UserRole.husband;
|
||||
final activeColor = isHusband ? AppColors.navyBlue : AppColors.sageGreen;
|
||||
|
||||
@@ -327,18 +406,30 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
const SizedBox(height: 40),
|
||||
Text(
|
||||
isHusband ? 'What\'s your name, sir?' : 'What\'s your name?',
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: isHusband ? AppColors.navyBlue : AppColors.charcoal,
|
||||
=======
|
||||
style: theme.textTheme.displaySmall?.copyWith(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'We\'ll use this to personalize the app.',
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
color: AppColors.warmGray,
|
||||
=======
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
@@ -349,6 +440,7 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
hintText: 'Enter your name',
|
||||
prefixIcon: Icon(
|
||||
Icons.person_outline,
|
||||
<<<<<<< HEAD
|
||||
color: AppColors.warmGray,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
@@ -357,6 +449,16 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
),
|
||||
),
|
||||
style: GoogleFonts.outfit(fontSize: 16),
|
||||
=======
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(color: activeColor, width: 2),
|
||||
),
|
||||
),
|
||||
style: theme.textTheme.bodyLarge,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
textCapitalization: TextCapitalization.words,
|
||||
),
|
||||
|
||||
@@ -365,6 +467,7 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(
|
||||
@@ -372,16 +475,40 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
side: BorderSide(color: isHusband ? AppColors.navyBlue : AppColors.sageGreen),
|
||||
),
|
||||
child: const Text('Back'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: activeColor,
|
||||
side: BorderSide(color: activeColor),
|
||||
),
|
||||
child: const Text('Back'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: ElevatedButton(
|
||||
onPressed: (_name.isNotEmpty && !_isNavigating) ? _nextPage : null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: activeColor,
|
||||
),
|
||||
child: Text(isHusband ? 'Finish Setup' : 'Continue'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: ElevatedButton(
|
||||
onPressed: (_name.isNotEmpty && !_isNavigating) ? _nextPage : null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: activeColor,
|
||||
),
|
||||
child: Text(isHusband ? 'Finish Setup' : 'Continue'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -392,6 +519,11 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildRelationshipPage() {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Column(
|
||||
@@ -400,10 +532,17 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
const SizedBox(height: 40),
|
||||
Text(
|
||||
'Tell us about yourself',
|
||||
<<<<<<< HEAD
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.charcoal,
|
||||
=======
|
||||
style: theme.textTheme.displaySmall?.copyWith(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
@@ -418,17 +557,39 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(foregroundColor: AppColors.sageGreen, side: BorderSide(color: AppColors.sageGreen)),
|
||||
child: const Text('Back'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: AppColors.sageGreen,
|
||||
side: const BorderSide(color: AppColors.sageGreen)
|
||||
),
|
||||
child: const Text('Back'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: ElevatedButton(
|
||||
onPressed: (_relationshipStatus != null && !_isNavigating) ? _nextPage : null,
|
||||
child: const Text('Continue'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: ElevatedButton(
|
||||
onPressed: (_relationshipStatus != null && !_isNavigating) ? _nextPage : null,
|
||||
child: const Text('Continue'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -439,30 +600,67 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildRelationshipOption(RelationshipStatus status, String title, String subtitle, IconData icon) {
|
||||
<<<<<<< HEAD
|
||||
final isSelected = _relationshipStatus == status;
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
final isSelected = _relationshipStatus == status;
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
return GestureDetector(
|
||||
onTap: () => setState(() => _relationshipStatus = status),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
<<<<<<< HEAD
|
||||
color: isSelected ? AppColors.sageGreen.withOpacity(0.1) : Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: isSelected ? AppColors.sageGreen : AppColors.lightGray.withOpacity(0.5),
|
||||
=======
|
||||
color: isSelected ? AppColors.sageGreen.withOpacity(isDark ? 0.3 : 0.1) : theme.cardTheme.color,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: isSelected ? AppColors.sageGreen : theme.colorScheme.outline.withOpacity(0.1),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
width: isSelected ? 2 : 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
<<<<<<< HEAD
|
||||
Icon(icon, color: isSelected ? AppColors.sageGreen : AppColors.warmGray),
|
||||
=======
|
||||
Icon(
|
||||
icon,
|
||||
color: isSelected ? AppColors.sageGreen : theme.colorScheme.onSurfaceVariant
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
<<<<<<< HEAD
|
||||
Text(title, style: GoogleFonts.outfit(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.charcoal)),
|
||||
Text(subtitle, style: GoogleFonts.outfit(fontSize: 13, color: AppColors.warmGray)),
|
||||
=======
|
||||
Text(
|
||||
title,
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -474,13 +672,29 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildFertilityGoalPage() {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 40),
|
||||
<<<<<<< HEAD
|
||||
Text('What\'s your goal?', style: GoogleFonts.outfit(fontSize: 28, fontWeight: FontWeight.w600, color: AppColors.charcoal)),
|
||||
=======
|
||||
Text(
|
||||
'What\'s your goal?',
|
||||
style: theme.textTheme.displaySmall?.copyWith(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
const SizedBox(height: 32),
|
||||
_buildGoalOption(FertilityGoal.tryingToConceive, 'Trying to Conceive', 'Track fertile days', Icons.child_care_outlined),
|
||||
const SizedBox(height: 12),
|
||||
@@ -491,17 +705,39 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(foregroundColor: AppColors.sageGreen, side: BorderSide(color: AppColors.sageGreen)),
|
||||
child: const Text('Back'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: AppColors.sageGreen,
|
||||
side: const BorderSide(color: AppColors.sageGreen)
|
||||
),
|
||||
child: const Text('Back'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: ElevatedButton(
|
||||
onPressed: (_fertilityGoal != null && !_isNavigating) ? _nextPage : null,
|
||||
child: const Text('Continue'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: ElevatedButton(
|
||||
onPressed: (_fertilityGoal != null && !_isNavigating) ? _nextPage : null,
|
||||
child: const Text('Continue'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -512,30 +748,67 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildGoalOption(FertilityGoal goal, String title, String subtitle, IconData icon) {
|
||||
<<<<<<< HEAD
|
||||
final isSelected = _fertilityGoal == goal;
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
final isSelected = _fertilityGoal == goal;
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
return GestureDetector(
|
||||
onTap: () => setState(() => _fertilityGoal = goal),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
<<<<<<< HEAD
|
||||
color: isSelected ? AppColors.sageGreen.withOpacity(0.1) : Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: isSelected ? AppColors.sageGreen : AppColors.lightGray.withOpacity(0.5),
|
||||
=======
|
||||
color: isSelected ? AppColors.sageGreen.withOpacity(isDark ? 0.3 : 0.1) : theme.cardTheme.color,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: isSelected ? AppColors.sageGreen : theme.colorScheme.outline.withOpacity(0.1),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
width: isSelected ? 2 : 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
<<<<<<< HEAD
|
||||
Icon(icon, color: isSelected ? AppColors.sageGreen : AppColors.warmGray),
|
||||
=======
|
||||
Icon(
|
||||
icon,
|
||||
color: isSelected ? AppColors.sageGreen : theme.colorScheme.onSurfaceVariant
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
<<<<<<< HEAD
|
||||
Text(title, style: GoogleFonts.outfit(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.charcoal)),
|
||||
Text(subtitle, style: GoogleFonts.outfit(fontSize: 13, color: AppColors.warmGray)),
|
||||
=======
|
||||
Text(
|
||||
title,
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -547,16 +820,42 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
}
|
||||
|
||||
Widget _buildCyclePage() {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
final theme = Theme.of(context);
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 40),
|
||||
<<<<<<< HEAD
|
||||
Text('About your cycle', style: GoogleFonts.outfit(fontSize: 28, fontWeight: FontWeight.w600, color: AppColors.charcoal)),
|
||||
const SizedBox(height: 32),
|
||||
|
||||
Text('Average cycle length', style: GoogleFonts.outfit(fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.charcoal)),
|
||||
=======
|
||||
Text(
|
||||
'About your cycle',
|
||||
style: theme.textTheme.displaySmall?.copyWith(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
|
||||
Text(
|
||||
'Average cycle length',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
@@ -565,16 +864,39 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
min: 21,
|
||||
max: 40,
|
||||
divisions: 19,
|
||||
<<<<<<< HEAD
|
||||
onChanged: (value) => setState(() => _averageCycleLength = value.round()),
|
||||
),
|
||||
),
|
||||
Text('$_averageCycleLength days', style: GoogleFonts.outfit(fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.sageGreen)),
|
||||
=======
|
||||
activeColor: AppColors.sageGreen,
|
||||
onChanged: (value) => setState(() => _averageCycleLength = value.round()),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'$_averageCycleLength days',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.sageGreen
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
],
|
||||
),
|
||||
|
||||
// Irregular Cycle Checkbox
|
||||
CheckboxListTile(
|
||||
<<<<<<< HEAD
|
||||
title: Text('My cycles are irregular', style: GoogleFonts.outfit(fontSize: 14, color: AppColors.charcoal)),
|
||||
=======
|
||||
title: Text(
|
||||
'My cycles are irregular',
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
value: _isIrregularCycle,
|
||||
onChanged: (val) => setState(() => _isIrregularCycle = val ?? false),
|
||||
activeColor: AppColors.sageGreen,
|
||||
@@ -583,7 +905,17 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
<<<<<<< HEAD
|
||||
Text('Last period start date', style: GoogleFonts.outfit(fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.charcoal)),
|
||||
=======
|
||||
Text(
|
||||
'Last period start date',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
const SizedBox(height: 8),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
@@ -594,8 +926,16 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
lastDate: DateTime.now(),
|
||||
builder: (context, child) {
|
||||
return Theme(
|
||||
<<<<<<< HEAD
|
||||
data: Theme.of(context).copyWith(
|
||||
colorScheme: const ColorScheme.light(primary: AppColors.sageGreen, onPrimary: Colors.white, surface: Colors.white, onSurface: AppColors.charcoal),
|
||||
=======
|
||||
data: theme.copyWith(
|
||||
colorScheme: theme.colorScheme.copyWith(
|
||||
primary: AppColors.sageGreen,
|
||||
onPrimary: Colors.white,
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
child: child!,
|
||||
);
|
||||
@@ -605,12 +945,32 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
<<<<<<< HEAD
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColors.lightGray.withOpacity(0.5))),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.calendar_today, color: AppColors.warmGray),
|
||||
const SizedBox(width: 12),
|
||||
Text(_lastPeriodStart != null ? "${_lastPeriodStart!.month}/${_lastPeriodStart!.day}/${_lastPeriodStart!.year}" : "Select Date", style: GoogleFonts.outfit(fontSize: 16, color: AppColors.charcoal)),
|
||||
=======
|
||||
decoration: BoxDecoration(
|
||||
color: theme.cardTheme.color,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: theme.colorScheme.outline.withOpacity(0.1))
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.calendar_today, color: theme.colorScheme.onSurfaceVariant),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
_lastPeriodStart != null
|
||||
? "${_lastPeriodStart!.month}/${_lastPeriodStart!.day}/${_lastPeriodStart!.year}"
|
||||
: "Select Date",
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
color: theme.colorScheme.onSurface
|
||||
)
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -620,17 +980,39 @@ class _OnboardingScreenState extends ConsumerState<OnboardingScreen> {
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(foregroundColor: AppColors.sageGreen, side: BorderSide(color: AppColors.sageGreen)),
|
||||
child: const Text('Back'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: OutlinedButton(
|
||||
onPressed: _previousPage,
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: AppColors.sageGreen,
|
||||
side: const BorderSide(color: AppColors.sageGreen)
|
||||
),
|
||||
child: const Text('Back'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
<<<<<<< HEAD
|
||||
child: ElevatedButton(
|
||||
onPressed: (_lastPeriodStart != null && !_isNavigating) ? _nextPage : null,
|
||||
child: const Text('Get Started'),
|
||||
=======
|
||||
child: SizedBox(
|
||||
height: 54,
|
||||
child: ElevatedButton(
|
||||
onPressed: (_lastPeriodStart != null && !_isNavigating) ? _nextPage : null,
|
||||
child: const Text('Get Started'),
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user