feat: Implement husband features and fix iOS Safari web startup
Implement initial features for husband's companion app, including mock data service and husband notes screen. Refactor scripture and cycle services for improved stability and testability. Address iOS Safari web app startup issue by removing deprecated initialization. - Implemented MockDataService and HusbandNotesScreen. - Converted _DashboardTab and DevotionalScreen to StatefulWidgets for robust scripture provider initialization. - Refactored CycleService to use immutable CycleInfo class, reducing UI rebuilds. - Removed deprecated window.flutterConfiguration from index.html, resolving Flutter web app startup failure on iOS Safari. - Updated and fixed related tests.
This commit is contained in:
@@ -10,25 +10,25 @@ class AppColors {
|
||||
static const Color lavender = Color(0xFFD4C4E8);
|
||||
static const Color cream = Color(0xFFFDF8F5);
|
||||
static const Color softGold = Color(0xFFD4A574);
|
||||
|
||||
|
||||
// Text Colors
|
||||
static const Color charcoal = Color(0xFF3D3D3D);
|
||||
static const Color warmGray = Color(0xFF7A7A7A);
|
||||
static const Color lightGray = Color(0xFFB8B8B8);
|
||||
|
||||
|
||||
// Husband's App Colors
|
||||
static const Color navyBlue = Color(0xFF2C3E50);
|
||||
static const Color steelBlue = Color(0xFF5D7B93);
|
||||
static const Color warmCream = Color(0xFFF5F0E8);
|
||||
static const Color gold = Color(0xFFC9A961);
|
||||
static const Color softCoral = Color(0xFFE8B4A8);
|
||||
|
||||
|
||||
// Phase Colors
|
||||
static const Color menstrualPhase = Color(0xFFE88A9E);
|
||||
static const Color follicularPhase = Color(0xFF8BC5A3);
|
||||
static const Color ovulationPhase = Color(0xFFB8A5D4);
|
||||
static const Color lutealPhase = Color(0xFF8BA5C5);
|
||||
|
||||
|
||||
// Semantic Colors
|
||||
static const Color success = Color(0xFF7AB98A);
|
||||
static const Color warning = Color(0xFFE8C567);
|
||||
@@ -42,7 +42,7 @@ class AppTheme {
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: Brightness.light,
|
||||
|
||||
|
||||
// Color Scheme
|
||||
colorScheme: const ColorScheme.light(
|
||||
primary: AppColors.sageGreen,
|
||||
@@ -54,10 +54,10 @@ class AppTheme {
|
||||
onSecondary: Colors.white,
|
||||
onSurface: AppColors.charcoal,
|
||||
),
|
||||
|
||||
|
||||
// Scaffold
|
||||
scaffoldBackgroundColor: AppColors.cream,
|
||||
|
||||
|
||||
// AppBar
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: AppColors.cream,
|
||||
@@ -70,7 +70,7 @@ class AppTheme {
|
||||
color: AppColors.charcoal,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Text Theme
|
||||
textTheme: TextTheme(
|
||||
displayLarge: GoogleFonts.outfit(
|
||||
@@ -124,9 +124,9 @@ class AppTheme {
|
||||
color: AppColors.charcoal,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Card Theme
|
||||
cardTheme: CardTheme(
|
||||
cardTheme: CardThemeData(
|
||||
color: Colors.white,
|
||||
elevation: 2,
|
||||
shadowColor: AppColors.charcoal.withOpacity(0.1),
|
||||
@@ -135,7 +135,7 @@ class AppTheme {
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
),
|
||||
|
||||
|
||||
// Button Themes
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
@@ -152,7 +152,7 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: AppColors.sageGreen,
|
||||
@@ -167,7 +167,7 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: AppColors.rose,
|
||||
@@ -177,7 +177,7 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Input Decoration
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
@@ -194,13 +194,14 @@ class AppTheme {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: const BorderSide(color: AppColors.sageGreen, width: 2),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
hintStyle: GoogleFonts.outfit(
|
||||
color: AppColors.lightGray,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Bottom Navigation
|
||||
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
||||
backgroundColor: Colors.white,
|
||||
@@ -217,14 +218,14 @@ class AppTheme {
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Floating Action Button
|
||||
floatingActionButtonTheme: const FloatingActionButtonThemeData(
|
||||
backgroundColor: AppColors.sageGreen,
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
),
|
||||
|
||||
|
||||
// Slider Theme
|
||||
sliderTheme: SliderThemeData(
|
||||
activeTrackColor: AppColors.sageGreen,
|
||||
@@ -233,7 +234,7 @@ class AppTheme {
|
||||
overlayColor: AppColors.sageGreen.withOpacity(0.2),
|
||||
trackHeight: 4,
|
||||
),
|
||||
|
||||
|
||||
// Divider
|
||||
dividerTheme: DividerThemeData(
|
||||
color: AppColors.lightGray.withOpacity(0.3),
|
||||
@@ -242,24 +243,12 @@ class AppTheme {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static ThemeData get darkTheme {
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: Brightness.dark,
|
||||
|
||||
<<<<<<< HEAD
|
||||
colorScheme: const ColorScheme.dark(
|
||||
primary: AppColors.sageGreen,
|
||||
secondary: AppColors.rose,
|
||||
tertiary: AppColors.lavender,
|
||||
surface: Color(0xFF1E1E1E),
|
||||
error: AppColors.error,
|
||||
),
|
||||
|
||||
scaffoldBackgroundColor: const Color(0xFF121212),
|
||||
|
||||
=======
|
||||
|
||||
// Color Scheme
|
||||
colorScheme: ColorScheme.dark(
|
||||
primary: AppColors.sageGreen,
|
||||
@@ -273,10 +262,10 @@ class AppTheme {
|
||||
onSurfaceVariant: Colors.white70,
|
||||
outline: Colors.white.withOpacity(0.1),
|
||||
),
|
||||
|
||||
|
||||
// Scaffold
|
||||
scaffoldBackgroundColor: const Color(0xFF121212),
|
||||
|
||||
|
||||
// AppBar
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: const Color(0xFF121212),
|
||||
@@ -289,17 +278,14 @@ class AppTheme {
|
||||
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,
|
||||
@@ -325,7 +311,6 @@ class AppTheme {
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
bodyLarge: GoogleFonts.outfit(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
@@ -336,16 +321,6 @@ class AppTheme {
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.white70,
|
||||
),
|
||||
<<<<<<< HEAD
|
||||
),
|
||||
|
||||
cardTheme: CardTheme(
|
||||
color: const Color(0xFF1E1E1E),
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
=======
|
||||
bodySmall: GoogleFonts.outfit(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
@@ -357,9 +332,9 @@ class AppTheme {
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Card Theme
|
||||
cardTheme: CardTheme(
|
||||
cardTheme: CardThemeData(
|
||||
color: const Color(0xFF1E1E1E),
|
||||
elevation: 0, // Material 3 uses color/opacity for elevation in dark mode
|
||||
shadowColor: Colors.transparent,
|
||||
@@ -418,13 +393,14 @@ class AppTheme {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: const BorderSide(color: AppColors.sageGreen, width: 2),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
hintStyle: GoogleFonts.outfit(
|
||||
color: Colors.white38,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// Bottom Navigation
|
||||
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
||||
backgroundColor: const Color(0xFF1E1E1E),
|
||||
@@ -459,7 +435,6 @@ class AppTheme {
|
||||
color: Colors.white.withOpacity(0.05),
|
||||
thickness: 1,
|
||||
space: 24,
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -467,35 +442,21 @@ 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)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user