// onboarding_screen.dart — 首次引导页(3 屏可滑动,文案经 AppText 单显) import 'package:flutter/material.dart'; import '../l10n/app_text.dart'; import '../pangolin_theme.dart'; import 'pangolin_icons.dart'; import 'pangolin_button.dart'; class OnboardingStep { const OnboardingStep({required this.icon, required this.title, required this.body, required this.cta, this.tint, this.tintBg}); final IconData icon; final String title, body, cta; final Color? tint, tintBg; } class OnboardingScreen extends StatefulWidget { const OnboardingScreen({super.key, required this.onDone, required this.t, this.steps}); final VoidCallback onDone; final AppText t; final List? steps; @override State createState() => _OnboardingScreenState(); } class _OnboardingScreenState extends State { int _i = 0; final _pager = PageController(); List _defaults(PangolinScheme c) { final t = widget.t; return [ OnboardingStep(icon: PangolinIcons.globe, title: t.ob1Title, body: t.ob1Sub, cta: t.obNext), OnboardingStep(icon: PangolinIcons.shield, title: t.ob2Title, body: t.ob2Sub, cta: t.obAllow), OnboardingStep(icon: PangolinIcons.shieldCheck, title: t.ob3Title, body: t.ob3Sub, cta: t.obStart, tint: c.success, tintBg: c.successSubtle), ]; } @override void dispose() { _pager.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final c = context.pangolin; final steps = widget.steps ?? _defaults(c); final last = _i == steps.length - 1; return Scaffold( backgroundColor: c.bg, body: SafeArea( child: Column(children: [ Align( alignment: Alignment.centerRight, child: Padding( padding: const EdgeInsets.all(8), child: TextButton(onPressed: widget.onDone, child: Text(widget.t.obSkip, style: PangolinText.sm.copyWith(color: c.fg3, fontWeight: FontWeight.w600))), ), ), Expanded( child: PageView.builder( controller: _pager, itemCount: steps.length, onPageChanged: (v) => setState(() => _i = v), itemBuilder: (_, idx) { final s = steps[idx]; return Padding( padding: const EdgeInsets.symmetric(horizontal: 32), child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 120, height: 120, decoration: BoxDecoration(color: s.tintBg ?? c.accentSubtle, shape: BoxShape.circle), child: Icon(s.icon, size: 52, color: s.tint ?? c.accent), ), const SizedBox(height: 28), Text(s.title, textAlign: TextAlign.center, style: PangolinText.h1.copyWith(color: c.fg1, fontSize: 26)), const SizedBox(height: 12), Text(s.body, textAlign: TextAlign.center, style: PangolinText.body.copyWith(color: c.fg2, height: 1.6)), ]), ); }, ), ), Row(mainAxisAlignment: MainAxisAlignment.center, children: List.generate(steps.length, (k) { final on = k == _i; return AnimatedContainer( duration: PangolinMotion.base, curve: PangolinMotion.easeOut, width: on ? 22 : 7, height: 7, margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration(color: on ? c.accent : c.borderStrong, borderRadius: BorderRadius.circular(PangolinRadius.full)), ); })), Padding( padding: const EdgeInsets.fromLTRB(28, 22, 28, 26), child: PangolinButton( label: steps[_i].cta, expand: true, onPressed: () { if (last) { widget.onDone(); } else { _pager.nextPage(duration: PangolinMotion.base, curve: PangolinMotion.easeOut); } }, ), ), ]), ), ); } }