fix and improve

This commit is contained in:
Tomas Dvorak
2026-01-05 18:23:21 +01:00
parent d712fe1074
commit 2aa4c0721f
18 changed files with 356 additions and 74 deletions
@@ -102,7 +102,7 @@ class _AuthChoiceScreenState extends ConsumerState<AuthChoiceScreen> {
),
const SizedBox(height: 24),
Text(
'LifeTimer',
'1356',
style: Theme.of(context)
.textTheme
.headlineLarge
@@ -64,7 +64,7 @@ class AuthShowcaseScreen extends ConsumerWidget {
),
const SizedBox(height: 16),
Text(
'LifeTimer helps you design a 1356-day experiment, focus on a small set of meaningful goals, and see time as a single bold countdown.',
'1356 helps you design a 1356-day experiment, focus on a small set of meaningful goals, and see time as a single bold countdown.',
style: theme.textTheme.bodyLarge?.copyWith(
color: colorScheme.onSurface.withValues(alpha:0.7),
height: 1.6,
@@ -111,7 +111,7 @@ class _SignInScreenState extends ConsumerState<SignInScreen> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'LifeTimer',
'1356',
style: Theme.of(context)
.textTheme
.titleMedium
@@ -91,7 +91,7 @@ class _SignUpScreenState extends ConsumerState<SignUpScreen> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'LifeTimer',
'1356',
style: Theme.of(context)
.textTheme
.titleMedium
@@ -30,7 +30,9 @@ class _HomeCountdownScreenState extends ConsumerState<HomeCountdownScreen> {
return AppScaffold(
body: SafeArea(
child: countdownState.isLoading
child: Padding(
padding: const EdgeInsets.only(top: 30.0, bottom: 30.0),
child: countdownState.isLoading
? const Center(child: LoadingIndicator())
: countdownState.error != null
? Center(
@@ -156,7 +158,7 @@ class _CountdownActiveScreen extends StatelessWidget {
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Padding(
padding: const EdgeInsets.all(24.0),
padding: const EdgeInsets.only(top: 30.0, left: 24.0, right: 24.0, bottom: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
@@ -17,10 +17,12 @@ class OnboardingHowItWorksScreen extends ConsumerWidget {
return AppScaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(24.0),
padding: const EdgeInsets.only(top: 30.0, left: 24.0, right: 24.0, bottom: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Progress Bar and Navigation
_OnboardingProgress(currentStep: 2, totalSteps: 3),
const SizedBox(height: 24),
Text(
'How It Works',
@@ -50,13 +52,27 @@ class OnboardingHowItWorksScreen extends ConsumerWidget {
description: 'The countdown begins immediately. Track your progress and make every day count.',
icon: Icons.timer,
),
const Spacer(),
PrimaryButton(
onPressed: () {
controller.completeStep('how_it_works');
context.push('/onboarding/motivation');
},
text: 'Continue',
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: TextButton(
onPressed: () => context.pop(),
child: const Text('Back'),
),
),
const SizedBox(width: 16),
Expanded(
flex: 2,
child: PrimaryButton(
onPressed: () {
controller.completeStep('how_it_works');
context.push('/onboarding/motivation');
},
text: 'Continue',
),
),
],
),
const SizedBox(height: 16),
],
@@ -159,3 +175,44 @@ class _StepCard extends StatelessWidget {
);
}
}
class _OnboardingProgress extends StatelessWidget {
final int currentStep;
final int totalSteps;
const _OnboardingProgress({
required this.currentStep,
required this.totalSteps,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Step $currentStep of $totalSteps',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
TextButton(
onPressed: () => context.pop(),
child: const Text('Back'),
),
],
),
const SizedBox(height: 12),
LinearProgressIndicator(
value: currentStep / totalSteps,
backgroundColor: Theme.of(context).colorScheme.primaryContainer.withOpacity(0.3),
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).colorScheme.primary,
),
),
],
);
}
}
@@ -17,10 +17,12 @@ class OnboardingIntroScreen extends ConsumerWidget {
return AppScaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(24.0),
padding: const EdgeInsets.only(top: 30.0, left: 24.0, right: 24.0, bottom: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Progress Bar and Navigation
_OnboardingProgress(currentStep: 1, totalSteps: 3),
const SizedBox(height: 48),
const Icon(
Icons.timer_outlined,
@@ -29,7 +31,7 @@ class OnboardingIntroScreen extends ConsumerWidget {
),
const SizedBox(height: 32),
Text(
'Welcome to LifeTimer',
'Welcome to 1356',
style: Theme.of(context).textTheme.headlineLarge?.copyWith(
fontWeight: FontWeight.bold,
),
@@ -63,22 +65,31 @@ class OnboardingIntroScreen extends ConsumerWidget {
description: 'Watch yourself grow day by day',
),
const Spacer(),
PrimaryButton(
onPressed: () {
controller.completeStep('intro');
context.push('/onboarding/how-it-works');
},
text: 'Get Started',
),
const SizedBox(height: 16),
TextButton(
onPressed: () async {
await controller.skipOnboarding();
if (context.mounted) {
context.push('/home');
}
},
child: const Text('Skip onboarding'),
Row(
children: [
Expanded(
child: TextButton(
onPressed: () async {
await controller.skipOnboarding();
if (context.mounted) {
context.push('/home');
}
},
child: const Text('Skip'),
),
),
const SizedBox(width: 16),
Expanded(
flex: 2,
child: PrimaryButton(
onPressed: () {
controller.completeStep('intro');
context.push('/onboarding/how-it-works');
},
text: 'Get Started',
),
),
],
),
const SizedBox(height: 16),
],
@@ -144,3 +155,44 @@ class _FeatureCard extends StatelessWidget {
);
}
}
class _OnboardingProgress extends StatelessWidget {
final int currentStep;
final int totalSteps;
const _OnboardingProgress({
required this.currentStep,
required this.totalSteps,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Step $currentStep of $totalSteps',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
TextButton(
onPressed: () => context.pop(),
child: const Text('Back'),
),
],
),
const SizedBox(height: 12),
LinearProgressIndicator(
value: currentStep / totalSteps,
backgroundColor: Theme.of(context).colorScheme.primaryContainer.withOpacity(0.3),
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).colorScheme.primary,
),
),
],
);
}
}
@@ -16,11 +16,14 @@ class OnboardingMotivationScreen extends ConsumerWidget {
return AppScaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 30.0, left: 24.0, right: 24.0, bottom: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Progress Bar and Navigation
_OnboardingProgress(currentStep: 3, totalSteps: 3),
const SizedBox(height: 24),
const Icon(
Icons.psychology_outlined,
@@ -65,16 +68,30 @@ class OnboardingMotivationScreen extends ConsumerWidget {
title: 'Celebrate Wins',
description: 'Every achievement is worth celebrating.',
),
const Spacer(),
PrimaryButton(
onPressed: () async {
controller.completeStep('motivation');
await controller.completeOnboarding();
if (context.mounted) {
context.push('/profile/create');
}
},
text: 'Get Started',
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: TextButton(
onPressed: () => context.pop(),
child: const Text('Back'),
),
),
const SizedBox(width: 16),
Expanded(
flex: 2,
child: PrimaryButton(
onPressed: () async {
controller.completeStep('motivation');
await controller.completeOnboarding();
if (context.mounted) {
context.push('/profile/create');
}
},
text: 'Get Started',
),
),
],
),
const SizedBox(height: 16),
],
@@ -140,3 +157,44 @@ class _MotivationCard extends StatelessWidget {
);
}
}
class _OnboardingProgress extends StatelessWidget {
final int currentStep;
final int totalSteps;
const _OnboardingProgress({
required this.currentStep,
required this.totalSteps,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Step $currentStep of $totalSteps',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
),
),
TextButton(
onPressed: () => context.pop(),
child: const Text('Back'),
),
],
),
const SizedBox(height: 12),
LinearProgressIndicator(
value: currentStep / totalSteps,
backgroundColor: Theme.of(context).colorScheme.primaryContainer.withOpacity(0.3),
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).colorScheme.primary,
),
),
],
);
}
}