diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 7bb2df6..d2146d2 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,14 @@ +<<<<<<< HEAD distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +======= +#Fri Dec 19 21:26:00 CST 2025 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +>>>>>>> 6742220 (Your commit message here) diff --git a/lib/main.dart b/lib/main.dart index 27a5b49..ecdcc96 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -24,6 +24,10 @@ void main() async { Hive.registerAdapter(CervicalMucusTypeAdapter()); Hive.registerAdapter(CyclePhaseAdapter()); Hive.registerAdapter(UserRoleAdapter()); +<<<<<<< HEAD +======= + Hive.registerAdapter(BibleTranslationAdapter()); +>>>>>>> 6742220 (Your commit message here) // Open boxes await Hive.openBox('user_profile'); diff --git a/lib/models/cycle_entry.dart b/lib/models/cycle_entry.dart index 5e38657..3650ccc 100644 --- a/lib/models/cycle_entry.dart +++ b/lib/models/cycle_entry.dart @@ -1,4 +1,9 @@ import 'package:hive/hive.dart'; +<<<<<<< HEAD +======= +import 'package:flutter/material.dart'; +import '../theme/app_theme.dart'; +>>>>>>> 6742220 (Your commit message here) part 'cycle_entry.g.dart'; @@ -111,6 +116,24 @@ class CycleEntry extends HiveObject { @HiveField(11) bool hasAcne; +<<<<<<< HEAD +======= + @HiveField(22) + bool hasLowerBackPain; + + @HiveField(23) + bool hasConstipation; + + @HiveField(24) + bool hasDiarrhea; + + @HiveField(25) + int? stressLevel; // 1-5 + + @HiveField(26) + bool hasInsomnia; + +>>>>>>> 6742220 (Your commit message here) @HiveField(12) double? basalBodyTemperature; // in Fahrenheit @@ -154,6 +177,14 @@ class CycleEntry extends HiveObject { this.hasBreastTenderness = false, this.hasFatigue = false, this.hasAcne = false, +<<<<<<< HEAD +======= + this.hasLowerBackPain = false, + this.hasConstipation = false, + this.hasDiarrhea = false, + this.stressLevel, + this.hasInsomnia = false, +>>>>>>> 6742220 (Your commit message here) this.basalBodyTemperature, this.cervicalMucus, this.ovulationTestPositive, @@ -173,7 +204,16 @@ class CycleEntry extends HiveObject { hasBreastTenderness || hasFatigue || hasAcne || +<<<<<<< HEAD (crampIntensity != null && crampIntensity! > 0); +======= + hasLowerBackPain || + hasConstipation || + hasDiarrhea || + hasInsomnia || + (crampIntensity != null && crampIntensity! > 0) || + (stressLevel != null && stressLevel! > 1); +>>>>>>> 6742220 (Your commit message here) /// Check if NFP data is logged bool get hasNFPData => @@ -189,7 +229,16 @@ class CycleEntry extends HiveObject { if (hasBreastTenderness) count++; if (hasFatigue) count++; if (hasAcne) count++; +<<<<<<< HEAD if (crampIntensity != null && crampIntensity! > 0) count++; +======= + if (hasLowerBackPain) count++; + if (hasConstipation) count++; + if (hasDiarrhea) count++; + if (hasInsomnia) count++; + if (crampIntensity != null && crampIntensity! > 0) count++; + if (stressLevel != null && stressLevel! > 1) count++; +>>>>>>> 6742220 (Your commit message here) return count; } @@ -207,6 +256,14 @@ class CycleEntry extends HiveObject { bool? hasBreastTenderness, bool? hasFatigue, bool? hasAcne, +<<<<<<< HEAD +======= + bool? hasLowerBackPain, + bool? hasConstipation, + bool? hasDiarrhea, + int? stressLevel, + bool? hasInsomnia, +>>>>>>> 6742220 (Your commit message here) double? basalBodyTemperature, CervicalMucusType? cervicalMucus, bool? ovulationTestPositive, @@ -231,6 +288,14 @@ class CycleEntry extends HiveObject { hasBreastTenderness: hasBreastTenderness ?? this.hasBreastTenderness, hasFatigue: hasFatigue ?? this.hasFatigue, hasAcne: hasAcne ?? this.hasAcne, +<<<<<<< HEAD +======= + hasLowerBackPain: hasLowerBackPain ?? this.hasLowerBackPain, + hasConstipation: hasConstipation ?? this.hasConstipation, + hasDiarrhea: hasDiarrhea ?? this.hasDiarrhea, + stressLevel: stressLevel ?? this.stressLevel, + hasInsomnia: hasInsomnia ?? this.hasInsomnia, +>>>>>>> 6742220 (Your commit message here) basalBodyTemperature: basalBodyTemperature ?? this.basalBodyTemperature, cervicalMucus: cervicalMucus ?? this.cervicalMucus, ovulationTestPositive: ovulationTestPositive ?? this.ovulationTestPositive, @@ -319,6 +384,35 @@ extension CyclePhaseExtension on CyclePhase { return '🌙'; } } +<<<<<<< HEAD +======= + + Color get color { + switch (this) { + case CyclePhase.menstrual: + return AppColors.menstrualPhase; + case CyclePhase.follicular: + return AppColors.follicularPhase; + case CyclePhase.ovulation: + return AppColors.ovulationPhase; + case CyclePhase.luteal: + return AppColors.lutealPhase; + } + } + + List get gradientColors { + switch (this) { + case CyclePhase.menstrual: + return [AppColors.rose, AppColors.menstrualPhase, AppColors.blushPink]; + case CyclePhase.follicular: + return [AppColors.sageGreen, AppColors.follicularPhase, AppColors.sageGreen.withOpacity(0.7)]; + case CyclePhase.ovulation: + return [AppColors.lavender, AppColors.ovulationPhase, AppColors.rose]; + case CyclePhase.luteal: + return [AppColors.lutealPhase, AppColors.lavender, AppColors.blushPink]; + } + } +>>>>>>> 6742220 (Your commit message here) String get description { switch (this) { diff --git a/lib/models/cycle_entry.g.dart b/lib/models/cycle_entry.g.dart index d5f210a..2ee11e5 100644 --- a/lib/models/cycle_entry.g.dart +++ b/lib/models/cycle_entry.g.dart @@ -29,6 +29,14 @@ class CycleEntryAdapter extends TypeAdapter { hasBreastTenderness: fields[9] as bool, hasFatigue: fields[10] as bool, hasAcne: fields[11] as bool, +<<<<<<< HEAD +======= + hasLowerBackPain: fields[22] as bool, + hasConstipation: fields[23] as bool, + hasDiarrhea: fields[24] as bool, + stressLevel: fields[25] as int?, + hasInsomnia: fields[26] as bool, +>>>>>>> 6742220 (Your commit message here) basalBodyTemperature: fields[12] as double?, cervicalMucus: fields[13] as CervicalMucusType?, ovulationTestPositive: fields[14] as bool?, @@ -45,7 +53,11 @@ class CycleEntryAdapter extends TypeAdapter { @override void write(BinaryWriter writer, CycleEntry obj) { writer +<<<<<<< HEAD ..writeByte(22) +======= + ..writeByte(27) +>>>>>>> 6742220 (Your commit message here) ..writeByte(0) ..write(obj.id) ..writeByte(1) @@ -70,6 +82,19 @@ class CycleEntryAdapter extends TypeAdapter { ..write(obj.hasFatigue) ..writeByte(11) ..write(obj.hasAcne) +<<<<<<< HEAD +======= + ..writeByte(22) + ..write(obj.hasLowerBackPain) + ..writeByte(23) + ..write(obj.hasConstipation) + ..writeByte(24) + ..write(obj.hasDiarrhea) + ..writeByte(25) + ..write(obj.stressLevel) + ..writeByte(26) + ..write(obj.hasInsomnia) +>>>>>>> 6742220 (Your commit message here) ..writeByte(12) ..write(obj.basalBodyTemperature) ..writeByte(13) diff --git a/lib/models/scripture.dart b/lib/models/scripture.dart index 1135dd8..9117489 100644 --- a/lib/models/scripture.dart +++ b/lib/models/scripture.dart @@ -1,18 +1,37 @@ +<<<<<<< HEAD /// Scripture model for daily verses and devotionals class Scripture { final String verse; +======= +import 'user_profile.dart'; + +/// Scripture model for daily verses and devotionals +class Scripture { + final Map verses; +>>>>>>> 6742220 (Your commit message here) final String reference; final String? reflection; final List applicablePhases; final List applicableContexts; const Scripture({ +<<<<<<< HEAD required this.verse, +======= + required this.verses, +>>>>>>> 6742220 (Your commit message here) required this.reference, this.reflection, this.applicablePhases = const [], this.applicableContexts = const [], }); +<<<<<<< HEAD +======= + + String getVerse(BibleTranslation translation) { + return verses[translation] ?? verses[BibleTranslation.esv] ?? verses.values.first; + } +>>>>>>> 6742220 (Your commit message here) } /// Pre-defined scriptures for the app @@ -20,17 +39,38 @@ class ScriptureDatabase { /// Scriptures for menstrual phase (rest, comfort) static const List menstrualScriptures = [ Scripture( +<<<<<<< HEAD verse: "Come to me, all you who are weary and burdened, and I will give you rest.", +======= + verses: { + BibleTranslation.esv: "Come to me, all who labor and are heavy laden, and I will give you rest.", + BibleTranslation.niv: "Come to me, all you who are weary and burdened, and I will give you rest.", + BibleTranslation.nkjv: "Come to me, all you who labor and are heavy laden, and I will give you rest.", + BibleTranslation.nlt: "Come to me, all of you who are weary and carry heavy burdens, and I will give you rest.", + BibleTranslation.nasb: "Come to Me, all who are weary and burdened, and I will give you rest.", + BibleTranslation.kjv: "Come unto me, all ye that labour and are heavy laden, and I will give you rest.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Matthew 11:28", reflection: "Your body is doing important work. Rest is not weakness—it's wisdom.", applicablePhases: ['menstrual'], ), Scripture( +<<<<<<< HEAD verse: "He gives strength to the weary and increases the power of the weak.", +======= + verses: { + BibleTranslation.esv: "He gives power to the faint, and to him who has no might he increases strength.", + BibleTranslation.niv: "He gives strength to the weary and increases the power of the weak.", + BibleTranslation.nkjv: "He gives power to the weak, and to those who have no might He increases strength.", + BibleTranslation.nasb: "He gives strength to the weary, and to the one who lacks might He increases power.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Isaiah 40:29", applicablePhases: ['menstrual'], ), Scripture( +<<<<<<< HEAD verse: "The Lord is my shepherd; I shall not want. He makes me lie down in green pastures.", reference: "Psalm 23:1-2", applicablePhases: ['menstrual'], @@ -46,22 +86,50 @@ class ScriptureDatabase { reference: "2 Corinthians 12:9", applicablePhases: ['menstrual'], ), +======= + verses: { + BibleTranslation.esv: "The LORD is my shepherd; I shall not want. He makes me lie down in green pastures.", + BibleTranslation.niv: "The LORD is my shepherd, I lack nothing. He makes me lie down in green pastures.", + BibleTranslation.nkjv: "The LORD is my shepherd; I shall not want. He makes me to lie down in green pastures.", + }, + reference: "Psalm 23:1-2", + applicablePhases: ['menstrual'], + ), +>>>>>>> 6742220 (Your commit message here) ]; /// Scriptures for follicular phase (renewal, strength) static const List follicularScriptures = [ Scripture( +<<<<<<< HEAD verse: "She is clothed with strength and dignity; she can laugh at the days to come.", +======= + verses: { + BibleTranslation.esv: "Strength and dignity are her clothing, and she laughs at the time to come.", + BibleTranslation.niv: "She is clothed with strength and dignity; she can laugh at the days to come.", + BibleTranslation.nkjv: "Strength and honor are her clothing; she shall rejoice in time to come.", + BibleTranslation.nlt: "She is clothed with strength and dignity, and she laughs without fear of the future.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Proverbs 31:25", reflection: "You're entering a season of renewed energy. Use it for His glory.", applicablePhases: ['follicular'], ), Scripture( +<<<<<<< HEAD verse: "I can do all this through him who gives me strength.", +======= + verses: { + BibleTranslation.esv: "I can do all things through him who strengthens me.", + BibleTranslation.niv: "I can do all this through him who gives me strength.", + BibleTranslation.nkjv: "I can do all things through Christ who strengthens me.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Philippians 4:13", applicablePhases: ['follicular'], ), Scripture( +<<<<<<< HEAD verse: "But those who hope in the Lord will renew their strength. They will soar on wings like eagles.", reference: "Isaiah 40:31", applicablePhases: ['follicular'], @@ -76,17 +144,35 @@ class ScriptureDatabase { reference: "Zephaniah 3:17", applicablePhases: ['follicular'], ), +======= + verses: { + BibleTranslation.esv: "but they who wait for the LORD shall renew their strength; they shall mount up with wings like eagles.", + BibleTranslation.niv: "but those who hope in the LORD will renew their strength. They will soar on wings like eagles.", + }, + reference: "Isaiah 40:31", + applicablePhases: ['follicular'], + ), +>>>>>>> 6742220 (Your commit message here) ]; /// Scriptures for ovulation phase (creation, beauty) static const List ovulationScriptures = [ Scripture( +<<<<<<< HEAD verse: "For you created my inmost being; you knit me together in my mother's womb. I praise you because I am fearfully and wonderfully made.", +======= + verses: { + BibleTranslation.esv: "For you formed my inmost parts; you knitted me together in my mother's womb. I praise you, for I am fearfully and wonderfully made.", + BibleTranslation.niv: "For you created my inmost being; you knit me together in my mother’s womb. I praise you because I am fearfully and wonderfully made.", + BibleTranslation.nkjv: "For You formed my inward parts; You covered me in my mother’s womb. I will praise You, for I am fearfully and wonderfully made.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Psalm 139:13-14", reflection: "Your body reflects the incredible creativity of God.", applicablePhases: ['ovulation'], ), Scripture( +<<<<<<< HEAD verse: "Children are a heritage from the Lord, offspring a reward from him.", reference: "Psalm 127:3", applicablePhases: ['ovulation'], @@ -101,22 +187,48 @@ class ScriptureDatabase { reference: "James 1:17", applicablePhases: ['ovulation'], ), +======= + verses: { + BibleTranslation.esv: "Behold, children are a heritage from the LORD, the fruit of the womb a reward.", + BibleTranslation.niv: "Children are a heritage from the LORD, offspring a reward from him.", + BibleTranslation.nkjv: "Behold, children are a heritage from the LORD, the fruit of the womb is a reward.", + }, + reference: "Psalm 127:3", + applicablePhases: ['ovulation'], + ), +>>>>>>> 6742220 (Your commit message here) ]; /// Scriptures for luteal phase / TWW (patience, trust) static const List lutealScriptures = [ Scripture( +<<<<<<< HEAD verse: "For I know the plans I have for you, declares the Lord, plans to prosper you and not to harm you, plans to give you hope and a future.", +======= + verses: { + BibleTranslation.esv: "For I know the plans I have for you, declares the LORD, plans for welfare and not for evil, to give you a future and a hope.", + BibleTranslation.niv: "For I know the plans I have for you,” declares the LORD, “plans to prosper you and not to harm you, plans to give you hope and a future.", + BibleTranslation.nkjv: "For I know the thoughts that I think toward you, says the LORD, thoughts of peace and not of evil, to give you a future and a hope.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Jeremiah 29:11", reflection: "Whatever this season holds, God's plans for you are good.", applicablePhases: ['luteal'], ), Scripture( +<<<<<<< HEAD verse: "Do not be anxious about anything, but in every situation, by prayer and petition, with thanksgiving, present your requests to God.", +======= + verses: { + BibleTranslation.esv: "do not be anxious about anything, but in everything by prayer and supplication with thanksgiving let your requests be made known to God.", + BibleTranslation.niv: "Do not be anxious about anything, but in every situation, by prayer and petition, with thanksgiving, present your requests to God.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Philippians 4:6", applicablePhases: ['luteal'], ), Scripture( +<<<<<<< HEAD verse: "Trust in the Lord with all your heart and lean not on your own understanding.", reference: "Proverbs 3:5", applicablePhases: ['luteal'], @@ -136,16 +248,33 @@ class ScriptureDatabase { reference: "Psalm 27:14", applicablePhases: ['luteal'], ), +======= + verses: { + BibleTranslation.esv: "Trust in the LORD with all your heart, and do not lean on your own understanding.", + BibleTranslation.niv: "Trust in the LORD with all your heart and lean not on your own understanding.", + }, + reference: "Proverbs 3:5", + applicablePhases: ['luteal'], + ), +>>>>>>> 6742220 (Your commit message here) ]; /// Scriptures for husbands static const List husbandScriptures = [ Scripture( +<<<<<<< HEAD verse: "Husbands, love your wives, just as Christ loved the church and gave himself up for her.", +======= + verses: { + BibleTranslation.esv: "Husbands, love your wives, as Christ loved the church and gave himself up for her.", + BibleTranslation.niv: "Husbands, love your wives, just as Christ loved the church and gave himself up for her.", + }, +>>>>>>> 6742220 (Your commit message here) reference: "Ephesians 5:25", reflection: "Love sacrificially—putting her needs before your own.", ), Scripture( +<<<<<<< HEAD verse: "Husbands, in the same way be considerate as you live with your wives, and treat them with respect.", reference: "1 Peter 3:7", ), @@ -169,11 +298,20 @@ class ScriptureDatabase { verse: "He who finds a wife finds what is good and receives favor from the Lord.", reference: "Proverbs 18:22", ), +======= + verses: { + BibleTranslation.esv: "Likewise, husbands, live with your wives in an understanding way, showing honor to the woman.", + BibleTranslation.niv: "Husbands, in the same way be considerate as you live with your wives, and treat them with respect.", + }, + reference: "1 Peter 3:7", + ), +>>>>>>> 6742220 (Your commit message here) ]; /// General womanhood scriptures static const List womanhoodScriptures = [ Scripture( +<<<<<<< HEAD verse: "Charm is deceptive, and beauty is fleeting; but a woman who fears the Lord is to be praised.", reference: "Proverbs 31:30", ), @@ -191,6 +329,102 @@ class ScriptureDatabase { ), ]; +======= + verses: { + BibleTranslation.esv: "Charm is deceitful, and beauty is vain, but a woman who fears the LORD is to be praised.", + BibleTranslation.niv: "Charm is deceptive, and beauty is fleeting; but a woman who fears the LORD is to be praised.", + }, + reference: "Proverbs 31:30", + ), + Scripture( + verses: { + BibleTranslation.esv: "She opens her mouth with wisdom, and the teaching of kindness is on her tongue.", + BibleTranslation.niv: "She opens her mouth with wisdom, and the teaching of kindness is on her tongue.", + }, + reference: "Proverbs 31:26", + ), + ]; + + /// Scriptures for specific needs (contextual) + static const Map> contextualScriptures = { + 'pain': [ + Scripture( + verses: { + BibleTranslation.esv: "The LORD is near to the brokenhearted and saves the crushed in spirit.", + BibleTranslation.niv: "The LORD is close to the brokenhearted and saves those who are crushed in spirit.", + }, + reference: "Psalm 34:18", + reflection: "He sees your pain and draws near to you in your discomfort.", + ), + Scripture( + verses: { + BibleTranslation.esv: "Cast your burden on the LORD, and he will sustain you.", + BibleTranslation.niv: "Cast your cares on the LORD and he will sustain you.", + }, + reference: "Psalm 55:22", + ), + ], + 'fatigue': [ + Scripture( + verses: { + BibleTranslation.esv: "He gives power to the faint, and to him who has no might he increases strength.", + BibleTranslation.niv: "He gives strength to the weary and increases the power of the weak.", + }, + reference: "Isaiah 40:29", + ), + Scripture( + verses: { + BibleTranslation.esv: "My grace is sufficient for you, for my power is made perfect in weakness.", + BibleTranslation.niv: "My grace is sufficient for you, for my power is made perfect in weakness.", + }, + reference: "2 Corinthians 12:9", + ), + ], + 'anxiety': [ + Scripture( + verses: { + BibleTranslation.esv: "When the cares of my heart are many, your consolations cheer my soul.", + BibleTranslation.niv: "When anxiety was great within me, your consolation brought me joy.", + }, + reference: "Psalm 94:19", + ), + Scripture( + verses: { + BibleTranslation.esv: "Peace I leave with you; my peace I give to you. Not as the world gives do I give to you. Let not your hearts be troubled, neither let them be afraid.", + BibleTranslation.niv: "Peace I leave with you; my peace I give to you. I do not give to you as the world gives. Do not let your hearts be troubled and do not be afraid.", + }, + reference: "John 14:27", + ), + ], + 'joy': [ + Scripture( + verses: { + BibleTranslation.esv: "The LORD is my strength and my shield; in him my heart trusts, and I am helped; my heart exults, and with my song I give thanks to him.", + BibleTranslation.niv: "The LORD is my strength and my shield; my heart trusts in him, and he helps me. My heart leaps for joy, and with my song I praise him.", + }, + reference: "Psalm 28:7", + ), + ], + }; + + /// Get recommended scripture based on entry + static Scripture? getRecommendedScripture(CycleEntry entry) { + if (entry.mood == MoodLevel.verySad || entry.mood == MoodLevel.sad || (entry.stressLevel != null && entry.stressLevel! > 3)) { + return contextualScriptures['anxiety']![DateTime.now().day % contextualScriptures['anxiety']!.length]; + } + if ((entry.crampIntensity != null && entry.crampIntensity! >= 3) || entry.hasHeadache || entry.hasLowerBackPain) { + return contextualScriptures['pain']![DateTime.now().day % contextualScriptures['pain']!.length]; + } + if (entry.hasFatigue || entry.hasInsomnia || (entry.energyLevel != null && entry.energyLevel! <= 2)) { + return contextualScriptures['fatigue']![DateTime.now().day % contextualScriptures['fatigue']!.length]; + } + if (entry.mood == MoodLevel.veryHappy) { + return contextualScriptures['joy']![DateTime.now().day % contextualScriptures['joy']!.length]; + } + return null; + } + +>>>>>>> 6742220 (Your commit message here) /// Get scripture for current phase static Scripture getScriptureForPhase(String phase) { final List scriptures; diff --git a/lib/models/user_profile.dart b/lib/models/user_profile.dart index 8ea8446..520ecb1 100644 --- a/lib/models/user_profile.dart +++ b/lib/models/user_profile.dart @@ -28,6 +28,25 @@ enum FertilityGoal { justTracking, } +<<<<<<< HEAD +======= +@HiveType(typeId: 9) +enum BibleTranslation { + @HiveField(0) + esv, + @HiveField(1) + niv, + @HiveField(2) + nkjv, + @HiveField(3) + nlt, + @HiveField(4) + nasb, + @HiveField(5) + kjv, +} + +>>>>>>> 6742220 (Your commit message here) /// User profile model @HiveType(typeId: 2) class UserProfile extends HiveObject { @@ -75,6 +94,12 @@ class UserProfile extends HiveObject { @HiveField(15, defaultValue: false) bool isIrregularCycle; +<<<<<<< HEAD +======= + + @HiveField(16, defaultValue: BibleTranslation.esv) + BibleTranslation bibleTranslation; +>>>>>>> 6742220 (Your commit message here) UserProfile({ required this.id, @@ -90,9 +115,15 @@ class UserProfile extends HiveObject { required this.createdAt, required this.updatedAt, this.partnerName, +<<<<<<< HEAD this.role = UserRole.wife, this.isIrregularCycle = false, +======= + this.role = UserRole.wife, + this.isIrregularCycle = false, + this.bibleTranslation = BibleTranslation.esv, +>>>>>>> 6742220 (Your commit message here) }); /// Check if user is married @@ -129,9 +160,15 @@ class UserProfile extends HiveObject { DateTime? createdAt, DateTime? updatedAt, String? partnerName, +<<<<<<< HEAD UserRole? role, bool? isIrregularCycle, +======= + UserRole? role, + bool? isIrregularCycle, + BibleTranslation? bibleTranslation, +>>>>>>> 6742220 (Your commit message here) }) { return UserProfile( id: id ?? this.id, @@ -147,13 +184,35 @@ class UserProfile extends HiveObject { createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? DateTime.now(), partnerName: partnerName ?? this.partnerName, +<<<<<<< HEAD role: role ?? this.role, isIrregularCycle: isIrregularCycle ?? this.isIrregularCycle, +======= + role: role ?? this.role, + isIrregularCycle: isIrregularCycle ?? this.isIrregularCycle, + bibleTranslation: bibleTranslation ?? this.bibleTranslation, +>>>>>>> 6742220 (Your commit message here) ); } } +<<<<<<< HEAD +======= +extension BibleTranslationExtension on BibleTranslation { + String get label { + switch (this) { + case BibleTranslation.esv: return 'ESV'; + case BibleTranslation.niv: return 'NIV'; + case BibleTranslation.nkjv: return 'NKJV'; + case BibleTranslation.nlt: return 'NLT'; + case BibleTranslation.nasb: return 'NASB'; + case BibleTranslation.kjv: return 'KJV'; + } + } +} + +>>>>>>> 6742220 (Your commit message here) @HiveType(typeId: 8) enum UserRole { @HiveField(0) diff --git a/lib/models/user_profile.g.dart b/lib/models/user_profile.g.dart index dbcc2ff..cffe0dd 100644 --- a/lib/models/user_profile.g.dart +++ b/lib/models/user_profile.g.dart @@ -32,13 +32,23 @@ class UserProfileAdapter extends TypeAdapter { partnerName: fields[12] as String?, role: fields[14] == null ? UserRole.wife : fields[14] as UserRole, isIrregularCycle: fields[15] == null ? false : fields[15] as bool, +<<<<<<< HEAD +======= + bibleTranslation: fields[16] == null + ? BibleTranslation.esv + : fields[16] as BibleTranslation, +>>>>>>> 6742220 (Your commit message here) ); } @override void write(BinaryWriter writer, UserProfile obj) { writer +<<<<<<< HEAD ..writeByte(15) +======= + ..writeByte(16) +>>>>>>> 6742220 (Your commit message here) ..writeByte(0) ..write(obj.id) ..writeByte(1) @@ -68,7 +78,13 @@ class UserProfileAdapter extends TypeAdapter { ..writeByte(14) ..write(obj.role) ..writeByte(15) +<<<<<<< HEAD ..write(obj.isIrregularCycle); +======= + ..write(obj.isIrregularCycle) + ..writeByte(16) + ..write(obj.bibleTranslation); +>>>>>>> 6742220 (Your commit message here) } @override @@ -170,6 +186,68 @@ class FertilityGoalAdapter extends TypeAdapter { typeId == other.typeId; } +<<<<<<< HEAD +======= +class BibleTranslationAdapter extends TypeAdapter { + @override + final int typeId = 9; + + @override + BibleTranslation read(BinaryReader reader) { + switch (reader.readByte()) { + case 0: + return BibleTranslation.esv; + case 1: + return BibleTranslation.niv; + case 2: + return BibleTranslation.nkjv; + case 3: + return BibleTranslation.nlt; + case 4: + return BibleTranslation.nasb; + case 5: + return BibleTranslation.kjv; + default: + return BibleTranslation.esv; + } + } + + @override + void write(BinaryWriter writer, BibleTranslation obj) { + switch (obj) { + case BibleTranslation.esv: + writer.writeByte(0); + break; + case BibleTranslation.niv: + writer.writeByte(1); + break; + case BibleTranslation.nkjv: + writer.writeByte(2); + break; + case BibleTranslation.nlt: + writer.writeByte(3); + break; + case BibleTranslation.nasb: + writer.writeByte(4); + break; + case BibleTranslation.kjv: + writer.writeByte(5); + break; + } + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is BibleTranslationAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +>>>>>>> 6742220 (Your commit message here) class UserRoleAdapter extends TypeAdapter { @override final int typeId = 8; diff --git a/lib/providers/navigation_provider.dart b/lib/providers/navigation_provider.dart new file mode 100644 index 0000000..018d1da --- /dev/null +++ b/lib/providers/navigation_provider.dart @@ -0,0 +1,14 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +/// Provider to manage the bottom navigation index across the app +final navigationProvider = StateNotifierProvider((ref) { + return NavigationNotifier(); +}); + +class NavigationNotifier extends StateNotifier { + NavigationNotifier() : super(0); + + void setIndex(int index) { + state = index; + } +} diff --git a/lib/screens/calendar/calendar_screen.dart b/lib/screens/calendar/calendar_screen.dart index 8d026e7..7da5a11 100644 --- a/lib/screens/calendar/calendar_screen.dart +++ b/lib/screens/calendar/calendar_screen.dart @@ -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 { ), ), 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 { ); } 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 { Widget _buildDayInfo(DateTime date, DateTime? lastPeriodStart, int cycleLength, List 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 { 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 { 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 { ); } +<<<<<<< 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 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; diff --git a/lib/screens/devotional/devotional_screen.dart b/lib/screens/devotional/devotional_screen.dart index 0abe813..fb4c772 100644 --- a/lib/screens/devotional/devotional_screen.dart +++ b/lib/screens/devotional/devotional_screen.dart @@ -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 _showTranslationPicker(BuildContext context, WidgetRef ref, UserProfile? user) async { + if (user == null) return; + + final selected = await showModalBottomSheet( + 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), diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 2f5f80c..535f536 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -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 { 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 tiles) { +======= + Widget _buildSettingsGroup(BuildContext context, String title, List 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) diff --git a/lib/screens/husband/husband_home_screen.dart b/lib/screens/husband/husband_home_screen.dart index c047c62..38341fb 100644 --- a/lib/screens/husband/husband_home_screen.dart +++ b/lib/screens/husband/husband_home_screen.dart @@ -28,6 +28,10 @@ class _HusbandHomeScreenState extends ConsumerState { 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 { 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 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 _generateChecklist(CycleEntry entry, CyclePhase phase) { + List 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) diff --git a/lib/screens/log/log_screen.dart b/lib/screens/log/log_screen.dart index 7b35a06..66817cb 100644 --- a/lib/screens/log/log_screen.dart +++ b/lib/screens/log/log_screen.dart @@ -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 createState() => _LogScreenState(); } class _LogScreenState extends ConsumerState { +<<<<<<< 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 { 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 { Future _saveEntry() async { final entry = CycleEntry( +<<<<<<< HEAD id: const Uuid().v4(), date: DateTime.now(), +======= + id: _existingEntryId ?? const Uuid().v4(), + date: _selectedDate, +>>>>>>> 6742220 (Your commit message here) isPeriodDay: _isPeriodDay, flowIntensity: _isPeriodDay ? _flowIntensity : null, mood: _mood, @@ -46,28 +113,60 @@ class _LogScreenState extends ConsumerState { 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 { _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 { crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header +<<<<<<< HEAD Text( 'How are you feeling?', style: GoogleFonts.outfit( @@ -105,11 +219,49 @@ class _LogScreenState extends ConsumerState { 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 { '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 { 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 { 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 { 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 { 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 { // Mood _buildSectionCard( +<<<<<<< HEAD +======= + context, +>>>>>>> 6742220 (Your commit message here) title: 'Mood', child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -194,16 +383,29 @@ class _LogScreenState extends ConsumerState { 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 { 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 { const SizedBox(height: 16), +<<<<<<< HEAD // Energy Level _buildSectionCard( title: 'Energy Level', @@ -241,17 +451,43 @@ class _LogScreenState extends ConsumerState { 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 { 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 { // Symptoms _buildSectionCard( +<<<<<<< HEAD +======= + context, +>>>>>>> 6742220 (Your commit message here) title: 'Symptoms', child: Column( children: [ @@ -282,7 +575,11 @@ class _LogScreenState extends ConsumerState { '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 { ), ), 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 { 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 { // 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 { 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 { // 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 { ); } +<<<<<<< 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 { 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 { ); } +<<<<<<< HEAD Widget _buildSymptomChip(String label, bool isSelected, ValueChanged onChanged) { return GestureDetector( onTap: () => onChanged(!isSelected), @@ -416,6 +777,36 @@ class _LogScreenState extends ConsumerState { fontSize: 13, color: isSelected ? AppColors.ovulationPhase : AppColors.warmGray, fontWeight: isSelected ? FontWeight.w500 : FontWeight.w400, +======= + Widget _buildSymptomChip(BuildContext context, String label, bool isSelected, ValueChanged onChanged) { + final theme = Theme.of(context); + final isDark = theme.brightness == Brightness.dark; + + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () => onChanged(!isSelected), + borderRadius: BorderRadius.circular(20), + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), + decoration: BoxDecoration( + color: isSelected + ? theme.colorScheme.tertiary.withOpacity(isDark ? 0.3 : 0.2) + : theme.colorScheme.surfaceVariant.withOpacity(0.3), + borderRadius: BorderRadius.circular(20), + border: isSelected + ? Border.all(color: theme.colorScheme.tertiary) + : Border.all(color: Colors.transparent), + ), + child: Text( + label, + style: GoogleFonts.outfit( + fontSize: 13, + color: isSelected ? theme.colorScheme.onSurface : theme.colorScheme.onSurfaceVariant, + fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, + ), +>>>>>>> 6742220 (Your commit message here) ), ), ), @@ -423,12 +814,28 @@ class _LogScreenState extends ConsumerState { } 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) { diff --git a/lib/screens/onboarding/onboarding_screen.dart b/lib/screens/onboarding/onboarding_screen.dart index 98a15a9..ad2e013 100644 --- a/lib/screens/onboarding/onboarding_screen.dart +++ b/lib/screens/onboarding/onboarding_screen.dart @@ -140,8 +140,19 @@ class _OnboardingScreenState extends ConsumerState { @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 { 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 { } 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 { 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 { 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 { } 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 { 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 { 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 { 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 { } 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 { 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 { hintText: 'Enter your name', prefixIcon: Icon( Icons.person_outline, +<<<<<<< HEAD color: AppColors.warmGray, ), focusedBorder: OutlineInputBorder( @@ -357,6 +449,16 @@ class _OnboardingScreenState extends ConsumerState { ), ), 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 { Row( children: [ Expanded( +<<<<<<< HEAD child: OutlinedButton( onPressed: _previousPage, style: OutlinedButton.styleFrom( @@ -372,16 +475,40 @@ class _OnboardingScreenState extends ConsumerState { 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 { } 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 { 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 { 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 { } 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 { } 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 { 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 { } 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 { } 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 { 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 { ), 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 { 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 { }, 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 { 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) ), ), ], diff --git a/lib/services/bible_utils.dart b/lib/services/bible_utils.dart new file mode 100644 index 0000000..6ac602b --- /dev/null +++ b/lib/services/bible_utils.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../models/user_profile.dart'; +import '../models/scripture.dart'; +import '../theme/app_theme.dart'; +import '../providers/user_provider.dart'; + +class BibleUtils { + static Future showTranslationPicker(BuildContext context, WidgetRef ref) async { + final user = ref.read(userProfileProvider); + if (user == null) return; + + final selected = await showModalBottomSheet( + 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 + ? const 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) + ); + } + } +} diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart index ed05973..a8c6369 100644 --- a/lib/theme/app_theme.dart +++ b/lib/theme/app_theme.dart @@ -248,6 +248,7 @@ class AppTheme { useMaterial3: true, brightness: Brightness.dark, +<<<<<<< HEAD colorScheme: const ColorScheme.dark( primary: AppColors.sageGreen, secondary: AppColors.rose, @@ -258,12 +259,73 @@ class AppTheme { scaffoldBackgroundColor: const Color(0xFF121212), +======= + // Color Scheme + colorScheme: ColorScheme.dark( + primary: AppColors.sageGreen, + secondary: AppColors.rose, + tertiary: AppColors.lavender, + surface: const Color(0xFF1E1E1E), + error: AppColors.error, + onPrimary: Colors.white, + onSecondary: Colors.white, + onSurface: Colors.white, + onSurfaceVariant: Colors.white70, + outline: Colors.white.withOpacity(0.1), + ), + + // Scaffold + scaffoldBackgroundColor: const Color(0xFF121212), + + // AppBar + appBarTheme: AppBarTheme( + backgroundColor: const Color(0xFF121212), + foregroundColor: Colors.white, + elevation: 0, + centerTitle: true, + titleTextStyle: GoogleFonts.outfit( + fontSize: 20, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + ), + + // Text Theme +>>>>>>> 6742220 (Your commit message here) textTheme: TextTheme( displayLarge: GoogleFonts.outfit( fontSize: 32, fontWeight: FontWeight.w600, color: Colors.white, ), +<<<<<<< HEAD +======= + displayMedium: GoogleFonts.outfit( + fontSize: 28, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + headlineLarge: GoogleFonts.outfit( + fontSize: 24, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + headlineMedium: GoogleFonts.outfit( + fontSize: 20, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + titleLarge: GoogleFonts.outfit( + fontSize: 18, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + titleMedium: GoogleFonts.outfit( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.white, + ), +>>>>>>> 6742220 (Your commit message here) bodyLarge: GoogleFonts.outfit( fontSize: 16, fontWeight: FontWeight.w400, @@ -274,6 +336,7 @@ class AppTheme { fontWeight: FontWeight.w400, color: Colors.white70, ), +<<<<<<< HEAD ), cardTheme: CardTheme( @@ -282,6 +345,121 @@ class AppTheme { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), +======= + bodySmall: GoogleFonts.outfit( + fontSize: 12, + fontWeight: FontWeight.w400, + color: Colors.white54, + ), + labelLarge: GoogleFonts.outfit( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + ), + + // Card Theme + cardTheme: CardTheme( + color: const Color(0xFF1E1E1E), + elevation: 0, // Material 3 uses color/opacity for elevation in dark mode + shadowColor: Colors.transparent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: BorderSide(color: Colors.white.withOpacity(0.05)), + ), + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + ), + + // Button Themes + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: AppColors.sageGreen, + foregroundColor: Colors.white, + elevation: 0, + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + textStyle: GoogleFonts.outfit( + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + ), + + outlinedButtonTheme: OutlinedButtonThemeData( + style: OutlinedButton.styleFrom( + foregroundColor: AppColors.sageGreen, + side: BorderSide(color: AppColors.sageGreen.withOpacity(0.5), width: 1.5), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + textStyle: GoogleFonts.outfit( + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ), + + // Input Decoration + inputDecorationTheme: InputDecorationTheme( + filled: true, + fillColor: const Color(0xFF1E1E1E), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: BorderSide(color: Colors.white.withOpacity(0.1)), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: BorderSide(color: Colors.white.withOpacity(0.1)), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide(color: AppColors.sageGreen, width: 2), + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), + hintStyle: GoogleFonts.outfit( + color: Colors.white38, + fontSize: 14, + ), + ), + + // Bottom Navigation + bottomNavigationBarTheme: BottomNavigationBarThemeData( + backgroundColor: const Color(0xFF1E1E1E), + selectedItemColor: AppColors.sageGreen, + unselectedItemColor: Colors.white38, + type: BottomNavigationBarType.fixed, + elevation: 0, + selectedLabelStyle: GoogleFonts.outfit( + fontSize: 12, + fontWeight: FontWeight.w500, + ), + unselectedLabelStyle: GoogleFonts.outfit( + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + + // Slider Theme + sliderTheme: SliderThemeData( + activeTrackColor: AppColors.sageGreen, + inactiveTrackColor: Colors.white.withOpacity(0.1), + thumbColor: AppColors.sageGreen, + overlayColor: AppColors.sageGreen.withOpacity(0.2), + trackHeight: 4, + tickMarkShape: const RoundSliderTickMarkShape(), + activeTickMarkColor: Colors.white24, + inactiveTickMarkColor: Colors.white10, + ), + + // Divider + dividerTheme: DividerThemeData( + color: Colors.white.withOpacity(0.05), + thickness: 1, + space: 24, +>>>>>>> 6742220 (Your commit message here) ), ); } @@ -289,19 +467,35 @@ class AppTheme { /// Scripture text style TextStyle scriptureStyle(BuildContext context, {double? fontSize}) { +<<<<<<< HEAD return GoogleFonts.lora( fontSize: fontSize ?? 16, fontStyle: FontStyle.italic, color: AppColors.charcoal, +======= + final isDark = Theme.of(context).brightness == Brightness.dark; + return GoogleFonts.lora( + fontSize: fontSize ?? 16, + fontStyle: FontStyle.italic, + color: isDark ? Colors.white : AppColors.charcoal, +>>>>>>> 6742220 (Your commit message here) height: 1.6, ); } /// Scripture reference style TextStyle scriptureRefStyle(BuildContext context) { +<<<<<<< HEAD return GoogleFonts.outfit( fontSize: 12, fontWeight: FontWeight.w500, color: AppColors.warmGray, +======= + final isDark = Theme.of(context).brightness == Brightness.dark; + return GoogleFonts.outfit( + fontSize: 12, + fontWeight: FontWeight.w500, + color: isDark ? Colors.white54 : AppColors.warmGray, +>>>>>>> 6742220 (Your commit message here) ); } diff --git a/lib/widgets/cycle_ring.dart b/lib/widgets/cycle_ring.dart index 8e9fbe5..9d3074e 100644 --- a/lib/widgets/cycle_ring.dart +++ b/lib/widgets/cycle_ring.dart @@ -4,7 +4,11 @@ import 'dart:math' as math; import '../theme/app_theme.dart'; import '../models/cycle_entry.dart'; +<<<<<<< HEAD class CycleRing extends StatelessWidget { +======= +class CycleRing extends StatefulWidget { +>>>>>>> 6742220 (Your commit message here) final int dayOfCycle; final int totalDays; final CyclePhase phase; @@ -17,6 +21,7 @@ class CycleRing extends StatelessWidget { }); @override +<<<<<<< HEAD Widget build(BuildContext context) { final progress = dayOfCycle / totalDays; final daysUntilNextPeriod = totalDays - dayOfCycle; @@ -82,12 +87,128 @@ class CycleRing extends StatelessWidget { style: GoogleFonts.outfit( fontSize: 12, color: AppColors.warmGray, +======= + State createState() => _CycleRingState(); +} + +class _CycleRingState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _animation; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 1500), + ); + _animation = CurvedAnimation( + parent: _controller, + curve: Curves.easeOutCubic, + ); + _controller.forward(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final targetProgress = widget.dayOfCycle / widget.totalDays; + final daysUntilNextPeriod = widget.totalDays - widget.dayOfCycle; + final isDark = Theme.of(context).brightness == Brightness.dark; + + return AnimatedBuilder( + animation: _animation, + builder: (context, child) { + final currentProgress = targetProgress * _animation.value; + + return SizedBox( + width: 220, + height: 220, + child: Stack( + alignment: Alignment.center, + children: [ + // Background ring + CustomPaint( + size: const Size(220, 220), + painter: _CycleRingPainter( + progress: currentProgress, + phase: widget.phase, + isDark: isDark, + ), + ), + + // Center content with scale and fade animation + Transform.scale( + scale: 0.8 + (0.2 * _animation.value), + child: Opacity( + opacity: _animation.value, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Day ${widget.dayOfCycle}', + style: Theme.of(context).textTheme.displayMedium?.copyWith( + fontSize: 32, + fontWeight: FontWeight.w600, + color: Theme.of(context).colorScheme.onSurface, + ), + ), + const SizedBox(height: 4), + Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: _getPhaseColor(widget.phase).withOpacity(isDark ? 0.3 : 0.2), + borderRadius: BorderRadius.circular(20), + border: isDark ? Border.all(color: _getPhaseColor(widget.phase).withOpacity(0.5)) : null, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + widget.phase.emoji, + style: const TextStyle(fontSize: 14), + ), + const SizedBox(width: 6), + Text( + widget.phase.label, + style: GoogleFonts.outfit( + fontSize: 14, + fontWeight: FontWeight.w500, + color: isDark ? Colors.white : _getPhaseColor(widget.phase), + ), + ), + ], + ), + ), + const SizedBox(height: 8), + Text( + daysUntilNextPeriod > 0 + ? '$daysUntilNextPeriod days until period' + : 'Period expected', + style: Theme.of(context).textTheme.bodySmall?.copyWith( + fontSize: 12, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ], + ), +>>>>>>> 6742220 (Your commit message here) ), ), ], ), +<<<<<<< HEAD ], ), +======= + ); + }, +>>>>>>> 6742220 (Your commit message here) ); } @@ -108,8 +229,18 @@ class CycleRing extends StatelessWidget { class _CycleRingPainter extends CustomPainter { final double progress; final CyclePhase phase; +<<<<<<< HEAD _CycleRingPainter({required this.progress, required this.phase}); +======= + final bool isDark; + + _CycleRingPainter({ + required this.progress, + required this.phase, + required this.isDark, + }); +>>>>>>> 6742220 (Your commit message here) @override void paint(Canvas canvas, Size size) { @@ -119,7 +250,11 @@ class _CycleRingPainter extends CustomPainter { // Background arc final bgPaint = Paint() +<<<<<<< HEAD ..color = AppColors.lightGray.withOpacity(0.2) +======= + ..color = (isDark ? Colors.white : AppColors.lightGray).withOpacity(isDark ? 0.05 : 0.1) +>>>>>>> 6742220 (Your commit message here) ..style = PaintingStyle.stroke ..strokeWidth = strokeWidth ..strokeCap = StrokeCap.round; @@ -152,7 +287,11 @@ class _CycleRingPainter extends CustomPainter { final dotY = center.dy + radius * math.sin(dotAngle); final dotPaint = Paint() +<<<<<<< HEAD ..color = Colors.white +======= + ..color = isDark ? const Color(0xFF1E1E1E) : Colors.white +>>>>>>> 6742220 (Your commit message here) ..style = PaintingStyle.fill; final dotBorderPaint = Paint() diff --git a/lib/widgets/quick_log_buttons.dart b/lib/widgets/quick_log_buttons.dart index 33c37b0..d654239 100644 --- a/lib/widgets/quick_log_buttons.dart +++ b/lib/widgets/quick_log_buttons.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +<<<<<<< HEAD import 'package:google_fonts/google_fonts.dart'; import '../theme/app_theme.dart'; import '../screens/log/log_screen.dart'; @@ -36,11 +37,56 @@ class QuickLogButtons extends StatelessWidget { label: 'Symptoms', color: AppColors.lavender, onTap: () => _navigateToLog(context), +======= +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:google_fonts/google_fonts.dart'; +import '../theme/app_theme.dart'; +import '../providers/navigation_provider.dart'; + +class QuickLogButtons extends ConsumerWidget { + const QuickLogButtons({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Row( + children: [ + _buildQuickButton( + context, + icon: Icons.water_drop_outlined, + label: 'Period', + color: AppColors.menstrualPhase, + onTap: () => _navigateToLog(ref), + ), + const SizedBox(width: 12), + _buildQuickButton( + context, + icon: Icons.emoji_emotions_outlined, + label: 'Mood', + color: AppColors.softGold, + onTap: () => _navigateToLog(ref), + ), + const SizedBox(width: 12), + _buildQuickButton( + context, + icon: Icons.flash_on_outlined, + label: 'Energy', + color: AppColors.follicularPhase, + onTap: () => _navigateToLog(ref), + ), + const SizedBox(width: 12), + _buildQuickButton( + context, + icon: Icons.healing_outlined, + label: 'Symptoms', + color: AppColors.lavender, + onTap: () => _navigateToLog(ref), +>>>>>>> 6742220 (Your commit message here) ), ], ); } +<<<<<<< HEAD void _navigateToLog(BuildContext context) { // Navigate to the Log tab (index 2) of HomeScreen if possible, // but since we are inside a tab, we can't easily switch the parent tab index without context. Using a provider or callback would be best. @@ -59,11 +105,21 @@ class QuickLogButtons extends StatelessWidget { } Widget _buildQuickButton({ +======= + void _navigateToLog(WidgetRef ref) { + // Navigate to the Log tab (index 2) + ref.read(navigationProvider.notifier).setIndex(2); + } + + Widget _buildQuickButton( + BuildContext context, { +>>>>>>> 6742220 (Your commit message here) required IconData icon, required String label, required Color color, required VoidCallback onTap, }) { +<<<<<<< HEAD return Expanded( child: GestureDetector( onTap: onTap, @@ -87,6 +143,38 @@ class QuickLogButtons extends StatelessWidget { ), ), ], +======= + final isDark = Theme.of(context).brightness == Brightness.dark; + + return Expanded( + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: Container( + padding: const EdgeInsets.symmetric(vertical: 16), + decoration: BoxDecoration( + color: color.withOpacity(isDark ? 0.2 : 0.15), + borderRadius: BorderRadius.circular(12), + border: isDark ? Border.all(color: color.withOpacity(0.3)) : null, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(icon, color: color, size: 24), + const SizedBox(height: 6), + Text( + label, + style: GoogleFonts.outfit( + fontSize: 11, + fontWeight: FontWeight.w600, + color: isDark ? Colors.white.withOpacity(0.9) : color, + ), + ), + ], + ), +>>>>>>> 6742220 (Your commit message here) ), ), ), diff --git a/lib/widgets/scripture_card.dart b/lib/widgets/scripture_card.dart index 3b2f482..4dab9b8 100644 --- a/lib/widgets/scripture_card.dart +++ b/lib/widgets/scripture_card.dart @@ -6,35 +6,66 @@ import '../models/cycle_entry.dart'; class ScriptureCard extends StatelessWidget { final String verse; final String reference; +<<<<<<< HEAD final CyclePhase phase; +======= + final String? translation; + final CyclePhase phase; + final VoidCallback? onTranslationTap; +>>>>>>> 6742220 (Your commit message here) const ScriptureCard({ super.key, required this.verse, required this.reference, +<<<<<<< HEAD required this.phase, +======= + this.translation, + required this.phase, + this.onTranslationTap, +>>>>>>> 6742220 (Your commit message here) }); @override Widget build(BuildContext context) { +<<<<<<< HEAD return Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: LinearGradient( colors: _getGradientColors(phase), +======= + final theme = Theme.of(context); + final isDark = theme.brightness == Brightness.dark; + + return Container( + width: double.infinity, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: _getGradientColors(context, phase), +>>>>>>> 6742220 (Your commit message here) begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), +<<<<<<< HEAD boxShadow: [ BoxShadow( color: _getPhaseColor(phase).withOpacity(0.2), +======= + border: Border.all(color: isDark ? Colors.white.withOpacity(0.05) : Colors.black.withOpacity(0.05)), + boxShadow: [ + BoxShadow( + color: _getPhaseColor(phase).withOpacity(isDark ? 0.05 : 0.15), +>>>>>>> 6742220 (Your commit message here) blurRadius: 15, offset: const Offset(0, 8), ), ], ), +<<<<<<< HEAD child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -90,10 +121,103 @@ class ScriptureCard extends StatelessWidget { ), ), ], +======= + child: Material( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Scripture icon + Row( + children: [ + Container( + width: 32, + height: 32, + decoration: BoxDecoration( + color: (isDark ? Colors.white : Colors.black).withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon( + Icons.menu_book_outlined, + size: 18, + color: isDark ? Colors.white70 : AppColors.charcoal.withOpacity(0.8), + ), + ), + const SizedBox(width: 8), + Text( + 'Today\'s Verse', + style: theme.textTheme.labelLarge?.copyWith( + fontSize: 12, + color: isDark ? Colors.white60 : AppColors.charcoal.withOpacity(0.7), + letterSpacing: 0.5, + ), + ), + ], + ), + const SizedBox(height: 16), + + // Verse + Text( + '"$verse"', + style: scriptureStyle(context, fontSize: 17), + ), + const SizedBox(height: 12), + + // Reference & Translation + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '— $reference', + style: scriptureRefStyle(context).copyWith(fontSize: 13, fontWeight: FontWeight.w600), + ), + if (translation != null) + InkWell( + onTap: onTranslationTap, + borderRadius: BorderRadius.circular(8), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), + decoration: BoxDecoration( + color: (isDark ? Colors.white : Colors.black).withOpacity(0.05), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: (isDark ? Colors.white : Colors.black).withOpacity(0.1), + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + translation!, + style: scriptureRefStyle(context).copyWith( + fontSize: 10, + fontWeight: FontWeight.w800, + letterSpacing: 0.8, + ), + ), + const SizedBox(width: 4), + Icon( + Icons.swap_horiz, + size: 14, + color: isDark ? Colors.white38 : AppColors.warmGray, + ), + ], + ), + ), + ), + ], + ), + ], + ), + ), +>>>>>>> 6742220 (Your commit message here) ), ); } +<<<<<<< HEAD List _getGradientColors(CyclePhase phase) { switch (phase) { case CyclePhase.menstrual: @@ -115,6 +239,32 @@ class ScriptureCard extends StatelessWidget { return [ AppColors.lutealPhase.withOpacity(0.3), AppColors.cream, +======= + List _getGradientColors(BuildContext context, CyclePhase phase) { + final isDark = Theme.of(context).brightness == Brightness.dark; + final baseColor = isDark ? const Color(0xFF1E1E1E) : AppColors.cream; + + switch (phase) { + case CyclePhase.menstrual: + return [ + AppColors.menstrualPhase.withOpacity(isDark ? 0.15 : 0.6), + baseColor, + ]; + case CyclePhase.follicular: + return [ + AppColors.follicularPhase.withOpacity(isDark ? 0.15 : 0.3), + baseColor, + ]; + case CyclePhase.ovulation: + return [ + AppColors.ovulationPhase.withOpacity(isDark ? 0.15 : 0.5), + baseColor, + ]; + case CyclePhase.luteal: + return [ + AppColors.lutealPhase.withOpacity(isDark ? 0.15 : 0.3), + baseColor, +>>>>>>> 6742220 (Your commit message here) ]; } } diff --git a/lib/widgets/tip_card.dart b/lib/widgets/tip_card.dart index 2820e70..4f8effc 100644 --- a/lib/widgets/tip_card.dart +++ b/lib/widgets/tip_card.dart @@ -15,17 +15,31 @@ class TipCard extends StatelessWidget { @override Widget build(BuildContext context) { +<<<<<<< HEAD +======= + final theme = Theme.of(context); + final isDark = theme.brightness == Brightness.dark; +>>>>>>> 6742220 (Your commit message here) final tip = _getTipForPhase(phase, isMarried); 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.cardColor, + borderRadius: BorderRadius.circular(16), + border: isDark ? Border.all(color: Colors.white.withOpacity(0.05)) : null, + boxShadow: [ + BoxShadow( + color: (isDark ? Colors.black : AppColors.charcoal).withOpacity(0.05), +>>>>>>> 6742220 (Your commit message here) blurRadius: 10, offset: const Offset(0, 4), ), @@ -38,7 +52,11 @@ class TipCard extends StatelessWidget { width: 40, height: 40, decoration: BoxDecoration( +<<<<<<< HEAD color: AppColors.sageGreen.withOpacity(0.15), +======= + color: AppColors.sageGreen.withOpacity(isDark ? 0.2 : 0.15), +>>>>>>> 6742220 (Your commit message here) borderRadius: BorderRadius.circular(10), ), child: const Icon( @@ -54,21 +72,57 @@ class TipCard extends StatelessWidget { children: [ Text( 'Today\'s Tip', +<<<<<<< HEAD style: GoogleFonts.outfit( fontSize: 14, fontWeight: FontWeight.w600, color: AppColors.charcoal, +======= + style: theme.textTheme.titleMedium?.copyWith( + fontSize: 14, + fontWeight: FontWeight.w600, +>>>>>>> 6742220 (Your commit message here) ), ), const SizedBox(height: 4), Text( tip, +<<<<<<< HEAD style: GoogleFonts.outfit( fontSize: 13, color: AppColors.warmGray, height: 1.4, ), ), +======= + style: theme.textTheme.bodyMedium?.copyWith( + fontSize: 13, + height: 1.4, + ), + ), + const SizedBox(height: 12), + InkWell( + onTap: () => _showDetailedInsights(context), + child: Row( + children: [ + Text( + 'Learn More', + style: GoogleFonts.outfit( + fontSize: 12, + fontWeight: FontWeight.w600, + color: AppColors.sageGreen, + ), + ), + const SizedBox(width: 4), + const Icon( + Icons.arrow_forward_ios, + size: 10, + color: AppColors.sageGreen, + ), + ], + ), + ), +>>>>>>> 6742220 (Your commit message here) ], ), ), @@ -77,6 +131,7 @@ class TipCard extends StatelessWidget { ); } +<<<<<<< HEAD String _getTipForPhase(CyclePhase phase, bool isMarried) { switch (phase) { case CyclePhase.menstrual: @@ -90,6 +145,123 @@ class TipCard extends StatelessWidget { return 'You may feel more social and confident during this phase. It\'s a great time for important conversations and presentations.'; case CyclePhase.luteal: return 'As you enter the luteal phase, focus on nourishing foods, adequate sleep, and stress management. Be gentle with yourself.'; +======= + void _showDetailedInsights(BuildContext context) { + final details = _getDetailsForPhase(phase); + showDialog( + context: context, + builder: (context) => AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + title: Column( + children: [ + Text( + 'Phase Insight: ${phase.label}', + textAlign: TextAlign.center, + style: GoogleFonts.outfit(fontWeight: FontWeight.w600), + ), + const SizedBox(height: 8), + Text( + phase.emoji, + style: const TextStyle(fontSize: 32), + ), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildDetailSection('Nutrition', details['nutrition']!, Icons.restaurant), + const SizedBox(height: 16), + _buildDetailSection('Movement', details['movement']!, Icons.fitness_center), + const SizedBox(height: 16), + Text( + 'Note: While these are general trends, your body is unique. Always listen to your own energy levels.', + style: GoogleFonts.outfit( + fontSize: 11, + fontStyle: FontStyle.italic, + color: AppColors.warmGray, + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text('Got it', style: GoogleFonts.outfit(color: AppColors.sageGreen)), + ), + ], + ), + ); + } + + Widget _buildDetailSection(String title, String content, IconData icon) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(icon, size: 16, color: AppColors.sageGreen), + const SizedBox(width: 6), + Text( + title, + style: GoogleFonts.outfit( + fontWeight: FontWeight.w600, + fontSize: 14, + ), + ), + ], + ), + const SizedBox(height: 6), + Text( + content, + style: GoogleFonts.outfit( + fontSize: 13, + color: AppColors.charcoal, + ), + ), + ], + ); + } + + String _getTipForPhase(CyclePhase phase, bool isMarried) { + switch (phase) { + case CyclePhase.menstrual: + return 'Focus on iron-rich foods and gentle rest. Your body is working hard; honor it with hydration and Vitamin C.'; + case CyclePhase.follicular: + return 'Energy is rising! Support your cycle with cruciferous vegetables and lean protein as you transition to more active movement.'; + case CyclePhase.ovulation: + if (isMarried) { + return 'Peak energy and connection. Focus on healthy fats for hormonal support and prioritize quality time with your spouse.'; + } + return 'Peak confidence and social energy. Support your peak energy with complex carbs and social engagement.'; + case CyclePhase.luteal: + return 'Nourish your nervous system with magnesium-rich foods and steady mobility. Transition to restorative self-care.'; + } + } + + Map _getDetailsForPhase(CyclePhase phase) { + switch (phase) { + case CyclePhase.menstrual: + return { + 'nutrition': 'Incorporate leafy greens, red meat or lentils for iron. Pair with citrus for better absorption.', + 'movement': 'Gentle walking, restorative yoga, or just deep breathing. Avoid high-intensity stress.', + }; + case CyclePhase.follicular: + return { + 'nutrition': 'Broccoli, cauliflower, and fermented foods help balance rising estrogen. Focus on lean proteins.', + 'movement': 'Strength training and steady cardio. Your body is primed for building and renewal.', + }; + case CyclePhase.ovulation: + return { + 'nutrition': 'Avocados, nuts, and seeds provide healthy fats for peak hormonal health. Keep hydration high.', + 'movement': 'Highest intensity workouts, HIIT, or group sports. You have peak stamina and strength right now.', + }; + case CyclePhase.luteal: + return { + 'nutrition': 'Dark chocolate (70%+), pumpkin seeds, and bananas for magnesium to help with cramps.', + 'movement': 'Pilates, steady-state swimming, or hiking. Focus on persistence rather than peak intensity.', + }; +>>>>>>> 6742220 (Your commit message here) } } } diff --git a/pubspec.lock b/pubspec.lock index 02c17d1..34fceef 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,23 +5,41 @@ packages: dependency: transitive description: name: _fe_analyzer_shared +<<<<<<< HEAD sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted version: "72.0.0" +======= + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + url: "https://pub.dev" + source: hosted + version: "76.0.0" +>>>>>>> 6742220 (Your commit message here) _macros: dependency: transitive description: dart source: sdk +<<<<<<< HEAD version: "0.3.2" +======= + version: "0.3.3" +>>>>>>> 6742220 (Your commit message here) analyzer: dependency: transitive description: name: analyzer +<<<<<<< HEAD sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted version: "6.7.0" +======= + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + url: "https://pub.dev" + source: hosted + version: "6.11.0" +>>>>>>> 6742220 (Your commit message here) args: dependency: transitive description: @@ -146,10 +164,17 @@ packages: dependency: transitive description: name: collection +<<<<<<< HEAD sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted version: "1.18.0" +======= + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + url: "https://pub.dev" + source: hosted + version: "1.19.0" +>>>>>>> 6742220 (Your commit message here) convert: dependency: transitive description: @@ -417,18 +442,32 @@ packages: dependency: transitive description: name: leak_tracker +<<<<<<< HEAD sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted version: "10.0.5" +======= + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + url: "https://pub.dev" + source: hosted + version: "10.0.7" +>>>>>>> 6742220 (Your commit message here) leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing +<<<<<<< HEAD sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted version: "3.0.5" +======= + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + url: "https://pub.dev" + source: hosted + version: "3.0.8" +>>>>>>> 6742220 (Your commit message here) leak_tracker_testing: dependency: transitive description: @@ -457,10 +496,17 @@ packages: dependency: transitive description: name: macros +<<<<<<< HEAD sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" url: "https://pub.dev" source: hosted version: "0.1.2-main.4" +======= + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" + url: "https://pub.dev" + source: hosted + version: "0.1.3-main.0" +>>>>>>> 6742220 (Your commit message here) matcher: dependency: transitive description: @@ -713,7 +759,11 @@ packages: dependency: transitive description: flutter source: sdk +<<<<<<< HEAD version: "0.0.99" +======= + version: "0.0.0" +>>>>>>> 6742220 (Your commit message here) smooth_page_indicator: dependency: "direct main" description: @@ -750,10 +800,17 @@ packages: dependency: transitive description: name: stack_trace +<<<<<<< HEAD sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted version: "1.11.1" +======= + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + url: "https://pub.dev" + source: hosted + version: "1.12.0" +>>>>>>> 6742220 (Your commit message here) state_notifier: dependency: transitive description: @@ -782,10 +839,17 @@ packages: dependency: transitive description: name: string_scanner +<<<<<<< HEAD sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted version: "1.2.0" +======= + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + url: "https://pub.dev" + source: hosted + version: "1.3.0" +>>>>>>> 6742220 (Your commit message here) table_calendar: dependency: "direct main" description: @@ -806,10 +870,17 @@ packages: dependency: transitive description: name: test_api +<<<<<<< HEAD sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted version: "0.7.2" +======= + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + url: "https://pub.dev" + source: hosted + version: "0.7.3" +>>>>>>> 6742220 (Your commit message here) timezone: dependency: transitive description: @@ -878,10 +949,17 @@ packages: dependency: transitive description: name: vm_service +<<<<<<< HEAD sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted version: "14.2.5" +======= + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + url: "https://pub.dev" + source: hosted + version: "14.3.0" +>>>>>>> 6742220 (Your commit message here) watcher: dependency: transitive description: