feat(ui): implement award mockup redesign
Build & Deploy Pluriwave / Análisis de código (push) Successful in 10s
Build & Deploy Pluriwave / Build APK + AAB release (push) Successful in 1m19s

This commit is contained in:
2026-05-20 21:29:36 +02:00
parent eb0ef37c76
commit d8acf74771
14 changed files with 621 additions and 211 deletions
+36 -43
View File
@@ -7,6 +7,7 @@ import '../estado/estado_radio.dart';
import '../tema/pluriwave_theme.dart';
import '../widgets/pluri_glass_surface.dart';
import '../widgets/pluri_icon.dart';
import '../widgets/pluri_premium_widgets.dart';
import 'package:pluriwave/widgets/tarjeta_emisora.dart';
/// Pantalla principal: emisoras populares y por género.
@@ -44,13 +45,13 @@ class _PantallaInicioState extends State<PantallaInicio> {
onRefresh: estado.cargarPopulares,
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(child: _heroHeader(context)),
SliverToBoxAdapter(child: _heroHeader(context, estado)),
SliverToBoxAdapter(child: _seccionTendencias(estado, theme)),
SliverToBoxAdapter(child: _chipGeneros(context, theme)),
if (estado.error != null)
SliverToBoxAdapter(child: _errorBanner(estado, theme)),
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: t.spacingMd),
padding: EdgeInsets.fromLTRB(t.spacingMd, 0, t.spacingMd, 124),
sliver: _gridEmisoras(estado),
),
],
@@ -58,39 +59,27 @@ class _PantallaInicioState extends State<PantallaInicio> {
);
}
Widget _heroHeader(BuildContext context) {
final t = context.pluriTokens;
final theme = Theme.of(context);
return Padding(
padding: EdgeInsets.fromLTRB(
t.spacingMd,
t.spacingSm,
t.spacingMd,
t.spacingSm,
),
child: PluriGlassSurface(
borderRadius: BorderRadius.circular(t.radiusLg),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const PluriIcon(
glyph: PluriIconGlyph.home,
variant: PluriIconVariant.activeGlow,
size: 30,
),
const SizedBox(height: 10),
Text(
'PluriWave',
style: theme.textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.w700,
),
),
Text(
'Ondas vivas globales',
style: theme.textTheme.titleMedium?.copyWith(color: t.warmCoral),
),
],
),
Widget _heroHeader(BuildContext context, EstadoRadio estado) {
return PluriScreenHeader(
title: 'PluriWave',
subtitle: 'Radio global en vivo con senales limpias, favoritos inteligentes y una experiencia visual de concurso.',
glyph: PluriIconGlyph.home,
primaryActionLabel: 'Explorar emisoras',
onPrimaryAction: estado.cargarPopulares,
trailing: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
PluriStatusPill(
icon: Icons.public_rounded,
label: '${estado.emisorasInicio.length} radios',
accent: Theme.of(context).colorScheme.secondary,
),
const SizedBox(height: 8),
const PluriStatusPill(
icon: Icons.hd_rounded,
label: 'Calidad HD',
),
],
),
);
}
@@ -103,7 +92,7 @@ class _PantallaInicioState extends State<PantallaInicio> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Tendencias premium', style: theme.textTheme.titleMedium),
Text('Radar en directo', style: theme.textTheme.titleMedium),
const SizedBox(height: 8),
SizedBox(
height: 56,
@@ -214,16 +203,20 @@ class _PantallaInicioState extends State<PantallaInicio> {
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.85,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
childAspectRatio: 0.78,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
);
}
if (emisoras.isEmpty) {
return const SliverFillRemaining(
child: Center(child: Text('No hay emisoras disponibles')),
child: PluriEmptyState(
glyph: PluriIconGlyph.home,
title: 'No hay emisoras disponibles',
subtitle: 'Proba refrescar o elegir otro g?nero para volver a capturar se?al.',
),
);
}
@@ -237,9 +230,9 @@ class _PantallaInicioState extends State<PantallaInicio> {
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.85,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
childAspectRatio: 0.78,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
);
}