import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../estado/estado_navegacion.dart'; import '../l10n/gen/app_localizations.dart'; import '../servicios/servicio_bienvenida.dart'; import '../tema/pluriwave_theme.dart'; /// WU17: first-run welcome surface (`onboarding-welcome` spec, mockup /// screen 14) rebuilt WITHOUT its monetization content — no "PRO" pill, no /// "14 días" trial line, no pricing card, and no secondary "free version" /// link (binding no-monetization requirement). Content only: logo, /// headline, body copy, exactly 3 feature bullets, and the single /// "Empezar a escuchar" CTA. /// /// A full-screen ROUTE, not a modal `Dialog` — deliberately distinct from /// the pre-existing `PluriOnboardingDialog` (an unrelated "what's new" /// help-content modal already shown from `app.dart`'s launch flow). Both /// surfaces coexist: [mostrarSiProcede] (WU17b) is what actually wires this /// screen into the genuine first-launch flow, called from `app.dart` BEFORE /// `PluriOnboardingDialog.mostrarSiProcede` on every cold start, so the two /// never race — the once-ever welcome resolves first, then the recurring /// what's-new dialog runs its own unrelated per-version check exactly as /// before. class PantallaBienvenida extends StatelessWidget { const PantallaBienvenida({super.key}); static final ServicioBienvenida _servicio = ServicioBienvenida(); /// WU17b: shows this screen once, on the genuine first launch, then never /// again. Mirrors `PluriOnboardingDialog.mostrarSiProcede`'s shape /// (check-then-show-then-mark-seen) so both first-launch surfaces share /// the same call convention from `app.dart`. static Future mostrarSiProcede(BuildContext context) async { if (!await _servicio.debeMostrarBienvenida()) return; if (!context.mounted) return; await Navigator.of( context, ).push(MaterialPageRoute(builder: (_) => const PantallaBienvenida())); await _servicio.marcarBienvenidaVista(); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); final t = context.pluriTokens; final theme = Theme.of(context); return Scaffold( body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(24, 48, 24, 28), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Image.asset( 'assets/icons/pluriwave_app_mark.png', width: 76, height: 76, errorBuilder: (_, __, ___) => Icon( Icons.graphic_eq_rounded, size: 76, color: t.electricMagenta, ), ), const SizedBox(height: 22), Text( l10n.welcomeHeadline, style: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.w800, height: 1.05, letterSpacing: -1.0, ), ), const SizedBox(height: 12), Text( l10n.welcomeBody, style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurface.withValues(alpha: 0.72), height: 1.5, ), ), const SizedBox(height: 28), FilaCaracteristicaBienvenida( icon: Icons.equalizer_rounded, iconColor: t.electricMagenta, titulo: l10n.welcomeBullet1Title, subtitulo: l10n.welcomeBullet1Subtitle, ), const SizedBox(height: 16), FilaCaracteristicaBienvenida( icon: Icons.directions_car_rounded, iconColor: t.liveGreen, titulo: l10n.welcomeBullet2Title, subtitulo: l10n.welcomeBullet2Subtitle, ), const SizedBox(height: 16), FilaCaracteristicaBienvenida( icon: Icons.alarm_rounded, iconColor: t.warmCoral, titulo: l10n.welcomeBullet3Title, subtitulo: l10n.welcomeBullet3Subtitle, ), const SizedBox(height: 32), SizedBox( height: 58, child: FilledButton( onPressed: () => _empezar(context), child: Text( l10n.welcomeCtaLabel, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w800, ), ), ), ), ], ), ), ), ); } void _empezar(BuildContext context) { context.read().irA(RaizPluriWave.escuchar); Navigator.of(context).pop(); } } /// One icon-badge + title/subtitle row. Public (not `_FilaCaracteristica`) /// so the structural "exactly 3 feature bullets" guard in /// `pantalla_bienvenida_test.dart` can target it via `find.byType` — the /// same reason WU4 made `FormularioEmisoraPersonalizada` public. class FilaCaracteristicaBienvenida extends StatelessWidget { const FilaCaracteristicaBienvenida({ super.key, required this.icon, required this.iconColor, required this.titulo, required this.subtitulo, }); final IconData icon; final Color iconColor; final String titulo; final String subtitulo; @override Widget build(BuildContext context) { final theme = Theme.of(context); return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 38, height: 38, decoration: BoxDecoration( color: iconColor.withValues(alpha: 0.16), borderRadius: BorderRadius.circular(11), ), child: Icon(icon, size: 20, color: iconColor), ), const SizedBox(width: 13), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( titulo, style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w800, ), ), Text( subtitulo, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurface.withValues(alpha: 0.58), ), ), ], ), ), ], ); } }