import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; class DashboardScreen extends StatelessWidget { const DashboardScreen({super.key}); @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; final tt = Theme.of(context).textTheme; return SingleChildScrollView( padding: const EdgeInsets.all(32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Inicio', style: tt.headlineMedium?.copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 4), Text( 'Accesos rápidos', style: tt.bodyLarge?.copyWith(color: cs.onSurfaceVariant), ), const SizedBox(height: 32), _QuickAccessGrid(), ], ), ); } } // ── Grid de accesos rápidos ─────────────────────────────────────────────── class _QuickAccessGrid extends StatelessWidget { @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { final columns = constraints.maxWidth >= 900 ? 4 : 2; final spacing = 16.0; final cardWidth = (constraints.maxWidth - spacing * (columns - 1)) / columns; return Wrap( spacing: spacing, runSpacing: spacing, children: _kShortcuts .map((s) => SizedBox( width: cardWidth, child: _ShortcutCard(shortcut: s), )) .toList(), ); }, ); } } // ── Tarjeta individual ──────────────────────────────────────────────────── class _ShortcutCard extends StatelessWidget { final _Shortcut shortcut; const _ShortcutCard({required this.shortcut}); @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; final tt = Theme.of(context).textTheme; final bgColor = shortcut.color.resolve(cs); final fgColor = shortcut.foreground.resolve(cs); return Card( elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), side: BorderSide(color: cs.outlineVariant), ), clipBehavior: Clip.antiAlias, child: InkWell( onTap: () => context.go(shortcut.route), child: Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 52, height: 52, decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(14), ), child: Icon(shortcut.icon, color: fgColor, size: 26), ), const SizedBox(height: 20), Text( shortcut.title, style: tt.titleMedium?.copyWith(fontWeight: FontWeight.w600), ), const SizedBox(height: 4), Text( shortcut.subtitle, style: tt.bodySmall?.copyWith(color: cs.onSurfaceVariant), ), ], ), ), ), ); } } // ── Datos ───────────────────────────────────────────────────────────────── class _Shortcut { final String title; final String subtitle; final IconData icon; final String route; final _SchemeColor color; final _SchemeColor foreground; const _Shortcut({ required this.title, required this.subtitle, required this.icon, required this.route, required this.color, required this.foreground, }); } /// Referencia indirecta a un color del ColorScheme para evitar context en const. class _SchemeColor { final Color Function(ColorScheme) resolve; const _SchemeColor(this.resolve); } const _kShortcuts = [ _Shortcut( title: 'Abonados', subtitle: 'Gestionar abonados del club', icon: Icons.people_outlined, route: '/abonados', color: _SchemeColor(_primary), foreground: _SchemeColor(_onPrimary), ), _Shortcut( title: 'Reservas', subtitle: 'Reservas de pistas', icon: Icons.sports_tennis_outlined, route: '/reservas', color: _SchemeColor(_secondary), foreground: _SchemeColor(_onSecondary), ), _Shortcut( title: 'Recibos', subtitle: 'Recibos por abonado', icon: Icons.receipt_long_outlined, route: '/recibos/abonado', color: _SchemeColor(_tertiary), foreground: _SchemeColor(_onTertiary), ), _Shortcut( title: 'Caja', subtitle: 'Movimientos y cobros', icon: Icons.point_of_sale_outlined, route: '/caja', color: _SchemeColor(_error), foreground: _SchemeColor(_onError), ), ]; // Funciones top-level para poder usarlas en const Color _primary(ColorScheme cs) => cs.primaryContainer; Color _onPrimary(ColorScheme cs) => cs.onPrimaryContainer; Color _secondary(ColorScheme cs) => cs.secondaryContainer; Color _onSecondary(ColorScheme cs) => cs.onSecondaryContainer; Color _tertiary(ColorScheme cs) => cs.tertiaryContainer; Color _onTertiary(ColorScheme cs) => cs.onTertiaryContainer; Color _error(ColorScheme cs) => cs.errorContainer; Color _onError(ColorScheme cs) => cs.onErrorContainer;