When tapping Start with existing saved runs, shows dialog asking whether to continue from last run or start fresh. Continuing pre-fills all profile and behavior inputs from the saved run. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
192 lines
5.8 KiB
Dart
192 lines
5.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../models/models.dart';
|
|
import '../storage/local_storage.dart';
|
|
import '../theme.dart';
|
|
import 'about_screen.dart';
|
|
import 'baseline_screen.dart';
|
|
|
|
class WelcomeScreen extends StatelessWidget {
|
|
const WelcomeScreen({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: SafeArea(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
|
child: Column(
|
|
children: [
|
|
const Spacer(flex: 1),
|
|
// Main question - large and centered
|
|
Text(
|
|
'Simple questions.\nHonest answers.',
|
|
style: Theme.of(context).textTheme.headlineLarge?.copyWith(
|
|
fontSize: 32,
|
|
height: 1.3,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 40),
|
|
Text(
|
|
"What's the single biggest change I can make to live a longer, healthier life?",
|
|
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
|
|
fontWeight: FontWeight.w400,
|
|
color: AppColors.textSecondary,
|
|
height: 1.4,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const Spacer(flex: 2),
|
|
// Privacy note
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
Icons.lock_outline,
|
|
size: 16,
|
|
color: AppColors.textSecondary,
|
|
),
|
|
const SizedBox(width: 8),
|
|
Text(
|
|
'All data stays on your device',
|
|
style: Theme.of(context).textTheme.bodySmall,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 24),
|
|
// Start button
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: ElevatedButton(
|
|
onPressed: () => _handleStart(context),
|
|
child: const Text('Start'),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
// Skip Forever and About links
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
TextButton(
|
|
onPressed: () => _showSkipForeverConfirmation(context),
|
|
child: const Text('Skip Forever'),
|
|
),
|
|
const SizedBox(width: 24),
|
|
TextButton(
|
|
onPressed: () => Navigator.push(
|
|
context,
|
|
MaterialPageRoute(builder: (_) => const AboutScreen()),
|
|
),
|
|
child: const Text('About'),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _handleStart(BuildContext context) async {
|
|
final recentRun = await LocalStorage.getMostRecentSavedRun();
|
|
|
|
if (recentRun == null) {
|
|
// No saved runs, start fresh
|
|
if (context.mounted) {
|
|
_navigateToBaseline(context, null, null);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Show dialog to choose between continuing or starting fresh
|
|
if (context.mounted) {
|
|
_showContinueDialog(context, recentRun);
|
|
}
|
|
}
|
|
|
|
void _showContinueDialog(BuildContext context, SavedRun recentRun) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (dialogContext) => AlertDialog(
|
|
title: const Text('Continue from last run?'),
|
|
content: Text(
|
|
'You have a saved run from ${recentRun.displayDate}. '
|
|
'Would you like to start with those inputs and make adjustments?',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.pop(dialogContext);
|
|
_navigateToBaseline(context, null, null);
|
|
},
|
|
child: const Text('Start Fresh'),
|
|
),
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.pop(dialogContext);
|
|
_navigateToBaseline(
|
|
context,
|
|
recentRun.profile,
|
|
recentRun.behaviors,
|
|
);
|
|
},
|
|
child: const Text('Continue'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
void _navigateToBaseline(
|
|
BuildContext context,
|
|
UserProfile? profile,
|
|
BehavioralInputs? behaviors,
|
|
) {
|
|
if (!context.mounted) return;
|
|
|
|
Navigator.of(context).push(
|
|
MaterialPageRoute(
|
|
builder: (_) => BaselineScreen(
|
|
initialProfile: profile,
|
|
initialBehaviors: behaviors,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _showSkipForeverConfirmation(BuildContext context) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (dialogContext) => AlertDialog(
|
|
title: const Text('Skip Forever?'),
|
|
content: const Text(
|
|
'You won\'t be asked to complete the questionnaire again. '
|
|
'You can still access the app from the About screen.',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.pop(dialogContext),
|
|
child: const Text('Cancel'),
|
|
),
|
|
TextButton(
|
|
onPressed: () async {
|
|
await LocalStorage.setSkipForever(true);
|
|
Navigator.pop(dialogContext);
|
|
if (context.mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content: Text('Questionnaire skipped'),
|
|
duration: Duration(seconds: 2),
|
|
),
|
|
);
|
|
}
|
|
},
|
|
child: const Text('Skip Forever'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|