Files
shaynee-flutter/lib/screens/onboarding/s20_welcome.dart
mav 93042cbb4c feat: complete 20-screen onboarding flow
Full quiz flow s01-s20: splash, intro, value prop, social proof,
name/skin-type/age/concerns/goal quiz with insights, analysing loader,
result with skin score, AM/PM routines, ingredient science, signup, welcome.

Duolingo-style design: flat cards, pressable SButton (Stack trick),
4px progress bar, mascot moods (wave/think/analyze/celebrate),
confetti on result+welcome, personalized content throughout.
2026-05-28 17:11:27 +02:00

71 lines
2.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import '../../theme.dart';
import '../../widgets/mascot.dart';
import '../../widgets/s_button.dart';
import '../../widgets/confetti.dart';
import '../../model/quiz_state.dart';
class WelcomeScreen extends StatefulWidget {
final QuizState state;
const WelcomeScreen({super.key, required this.state});
@override
State<WelcomeScreen> createState() => _State();
}
class _State extends State<WelcomeScreen> {
bool _showConfetti = true;
@override
void initState() {
super.initState();
Future.delayed(const Duration(milliseconds: 2800), () {
if (mounted) setState(() => _showConfetti = false);
});
}
@override
Widget build(BuildContext context) {
final name = widget.state.name.split(' ').first;
return Scaffold(
backgroundColor: SColors.bgSurface,
body: Stack(
children: [
SafeArea(
child: Column(
children: [
const Spacer(flex: 2),
Mascot(mood: MascotMood.celebrate, size: 200)
.animate()
.fadeIn(duration: 700.ms, delay: 300.ms)
.slideY(begin: 0.08, end: 0),
const SizedBox(height: 32),
Text('Welcome to\nShaynee, $name! 🎉',
textAlign: TextAlign.center,
style: SText.headline2(SColors.textHead))
.animate().fadeIn(duration: 500.ms, delay: 600.ms)
.slideY(begin: 0.06, end: 0),
const SizedBox(height: 10),
Text("Your routine is ready.\nLet's get glowing ✨",
textAlign: TextAlign.center,
style: SText.subtitle(SColors.textSub))
.animate().fadeIn(duration: 500.ms, delay: 750.ms),
const Spacer(flex: 3),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: SButton(
label: "LET'S START",
onTap: () {},
).animate().fadeIn(duration: 400.ms, delay: 1000.ms),
),
const SizedBox(height: 24),
],
),
),
if (_showConfetti) const Positioned.fill(child: IgnorePointer(child: ConfettiOverlay())),
],
),
);
}
}