Files
pluriwave/lib/widgets/pluri_premium_widgets.dart
FreeTLab e5d461af53 fix(buscar): build the 2x2 "Explorar por" grid, add Novedades
Audit 3.2 (t4 lines 162-171): the prototype groups Países, Géneros,
Tendencias and the entirely-missing Novedades into one 2x2 entry-point
grid. The build had them as three unrelated always-visible widgets
(a Países ListTile, a Géneros FilterChip Wrap, a Tendencias ActionChip
strip) and no Novedades entry at all.

Replaces all three with a single grid section, capability-preserving:
Países still pushes PantallaPaises; Géneros and Tendencias now open
their exact existing content in a picker sheet instead of always-on-
screen (Géneros auto-closes on selection, matching this screen's other
single-choice filter sheets; Tendencias stays open, a browse list, not
a filter). Novedades re-triggers the existing discovery refresh, since
no distinct "new stations" feed exists anywhere in the domain.

New ARB key set (exploreByTitle/exploreTrendingTitle/
exploreTrendingSubtitle/exploreNewTitle/exploreNewSubtitle) translated
across all 13 locales with zero anti-copy allowlist entries needed.

Also fixes a pre-existing PluriEmptyState overflow this restructure
exposed (unrelated to the grid itself, confirmed via isolated repro):
wraps its Column in a SingleChildScrollView so a too-tall title/
subtitle scrolls instead of throwing a hard RenderFlex overflow.
2026-07-30 00:43:27 +02:00

119 lines
3.6 KiB
Dart

import 'package:flutter/material.dart';
import '../tema/pluriwave_theme.dart';
import 'pluri_glass_surface.dart';
import 'pluri_icon.dart';
class PluriStatusPill extends StatelessWidget {
const PluriStatusPill({
super.key,
required this.icon,
required this.label,
this.accent,
});
final IconData icon;
final String label;
final Color? accent;
@override
Widget build(BuildContext context) {
final t = context.pluriTokens;
final color = accent ?? t.electricMagenta;
return Tooltip(
message: label,
child: Container(
constraints: const BoxConstraints(maxWidth: 220),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(999),
color: color.withValues(alpha: 0.13),
border: Border.all(color: color.withValues(alpha: 0.38)),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 16, color: color),
const SizedBox(width: 7),
Flexible(
child: Text(
label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(
context,
).textTheme.labelMedium?.copyWith(fontWeight: FontWeight.w800),
),
),
],
),
),
);
}
}
class PluriEmptyState extends StatelessWidget {
const PluriEmptyState({
super.key,
required this.glyph,
required this.title,
required this.subtitle,
});
final PluriIconGlyph glyph;
final String title;
final String subtitle;
@override
Widget build(BuildContext context) {
final t = context.pluriTokens;
final theme = Theme.of(context);
return Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: PluriGlassSurface(
borderRadius: BorderRadius.circular(t.radiusLg + 10),
padding: const EdgeInsets.all(28),
// Bugfix: every call site constrains this widget to a fixed
// height (`SizedBox(height: 260)`). At a narrow width with
// realistic two-line title/subtitle copy, the icon + gaps +
// wrapped text can exceed what's actually left after this
// surface's own padding — a hard RenderFlex overflow rather
// than a graceful clip. `SingleChildScrollView` is a no-op
// visually whenever the content already fits (the normal
// case, on any real device width this was designed for) and
// only engages scrolling in the rare case it does not.
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
PluriIcon(
glyph: glyph,
variant: PluriIconVariant.activeGlow,
size: 58,
),
const SizedBox(height: 18),
Text(
title,
textAlign: TextAlign.center,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w900,
),
),
const SizedBox(height: 8),
Text(
subtitle,
textAlign: TextAlign.center,
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurface.withValues(alpha: 0.72),
),
),
],
),
),
),
),
);
}
}