Files
Tracker/lib/screens/splash_screen.dart
Sterlen b4b2bfe749 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.
2025-12-26 22:40:52 -06:00

184 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../theme/app_theme.dart';
import 'onboarding/onboarding_screen.dart';
import 'home/home_screen.dart';
import '../models/user_profile.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/user_provider.dart';
import 'husband/husband_home_screen.dart';
class SplashScreen extends ConsumerStatefulWidget {
const SplashScreen({super.key});
@override
ConsumerState<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends ConsumerState<SplashScreen> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _fadeAnimation;
late Animation<double> _scaleAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 1500),
vsync: this,
);
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: const Interval(0.0, 0.5, curve: Curves.easeIn),
),
);
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: const Interval(0.0, 0.5, curve: Curves.easeOutBack),
),
);
_controller.forward();
// Navigate after splash
Future.delayed(const Duration(milliseconds: 1200), () {
_navigateToNextScreen();
});
}
void _navigateToNextScreen() {
final user = ref.read(userProfileProvider);
final hasProfile = user != null;
Widget nextScreen;
if (!hasProfile) {
nextScreen = const OnboardingScreen();
} else if (user.role == UserRole.husband) {
nextScreen = const HusbandHomeScreen();
} else {
nextScreen = const HomeScreen();
}
Navigator.of(context).pushReplacement(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => nextScreen,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(opacity: animation, child: child);
},
transitionDuration: const Duration(milliseconds: 500),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.cream,
body: Center(
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return FadeTransition(
opacity: _fadeAnimation,
child: ScaleTransition(
scale: _scaleAnimation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// App Icon/Logo
Container(
width: 120,
height: 120,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColors.blushPink,
AppColors.rose.withOpacity(0.8),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(30),
boxShadow: [
BoxShadow(
color: AppColors.rose.withOpacity(0.3),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
child: const Icon(
Icons.favorite_rounded,
size: 60,
color: Colors.white,
),
),
const SizedBox(height: 24),
// App Name placeholder
Text(
'Period Tracker',
style: GoogleFonts.outfit(
fontSize: 28,
fontWeight: FontWeight.w600,
color: AppColors.charcoal,
),
),
const SizedBox(height: 8),
// Tagline
Text(
'Faith-Centered Wellness',
style: GoogleFonts.outfit(
fontSize: 14,
fontWeight: FontWeight.w400,
color: AppColors.warmGray,
letterSpacing: 1.2,
),
),
const SizedBox(height: 48),
// Scripture
Padding(
padding: const EdgeInsets.symmetric(horizontal: 48),
child: Text(
'"I praise you because I am\nfearfully and wonderfully made."',
textAlign: TextAlign.center,
style: GoogleFonts.lora(
fontSize: 16,
fontStyle: FontStyle.italic,
color: AppColors.charcoal,
height: 1.5,
),
),
),
const SizedBox(height: 8),
Text(
'— Psalm 139:14',
style: GoogleFonts.outfit(
fontSize: 12,
fontWeight: FontWeight.w500,
color: AppColors.warmGray,
),
),
],
),
),
);
},
),
),
);
}
}