app/lib/main.dart
John Mizerek 151106aa8e Initial commit: Add Months MVP
Local-first Flutter app that identifies the single behavioral change
most likely to extend lifespan using hazard-based modeling.

Features:
- Risk engine with hazard ratios from meta-analyses
- 50 countries mapped to 4 mortality groups
- 6 modifiable factors: smoking, alcohol, sleep, activity, driving, work hours
- SQLite local storage (no cloud, no accounts)
- Muted clinical UI theme
- 23 unit tests for risk engine

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-20 21:25:00 -08:00

107 lines
2.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'screens/screens.dart';
import 'storage/local_storage.dart';
import 'theme.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize database
await LocalStorage.database;
// Set preferred orientations
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
runApp(const AddMonthsApp());
}
class AddMonthsApp extends StatelessWidget {
const AddMonthsApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Add Months',
debugShowCheckedModeBanner: false,
theme: buildAppTheme(),
home: const AppRouter(),
);
}
}
class AppRouter extends StatefulWidget {
const AppRouter({super.key});
@override
State<AppRouter> createState() => _AppRouterState();
}
class _AppRouterState extends State<AppRouter> {
bool _loading = true;
bool _hasData = false;
@override
void initState() {
super.initState();
_checkExistingData();
}
Future<void> _checkExistingData() async {
final hasData = await LocalStorage.hasCompletedSetup();
setState(() {
_hasData = hasData;
_loading = false;
});
}
@override
Widget build(BuildContext context) {
if (_loading) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
// If user has existing data, go straight to results
if (_hasData) {
return FutureBuilder(
future: _loadExistingData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
if (snapshot.hasData) {
final data = snapshot.data!;
return ResultsScreen(
profile: data.$1,
behaviors: data.$2,
);
}
return const WelcomeScreen();
},
);
}
return const WelcomeScreen();
}
Future<(dynamic, dynamic)?> _loadExistingData() async {
final profile = await LocalStorage.getProfile();
final behaviors = await LocalStorage.getBehaviors();
if (profile != null && behaviors != null) {
return (profile, behaviors);
}
return null;
}
}