import 'package:flutter/material.dart'; import 'package:prosapp_web_app/providers/auth_provider.dart'; import 'package:prosapp_web_app/providers/professional_provider.dart'; import 'package:prosapp_web_app/providers/score_provider.dart'; import 'package:prosapp_web_app/providers/services_provider.dart'; import 'package:prosapp_web_app/providers/sidemenu_provider.dart'; import 'package:prosapp_web_app/providers/theme_provider.dart'; import 'package:prosapp_web_app/ui/shared/widgets/navbar_avatar.dart'; import 'package:provider/provider.dart'; class Navbar extends StatelessWidget { const Navbar({super.key}); @override Widget build(BuildContext context) { final size = MediaQuery.of(context).size; return Consumer(builder: (context, themeProvider, _) { final isDark = themeProvider.isDark; final iconColor = isDark ? Colors.white70 : const Color(0xFF475569); final bgColor = isDark ? const Color(0xFF1E293B) : Colors.white; final shadowColor = isDark ? Colors.black54 : Colors.black12; return Consumer(builder: (context, scoreProvider, _) { final professionalProvider = Provider.of(context, listen: false); WidgetsBinding.instance.addPostFrameCallback((_) { scoreProvider.loadReputation( context.read().user!.id); }); final reputation = scoreProvider.reputation; return Container( width: double.infinity, height: 56, decoration: BoxDecoration( color: bgColor, boxShadow: [BoxShadow(color: shadowColor, blurRadius: 6)], ), child: Row( children: [ // Menú hamburguesa (móvil) if (size.width <= 700) IconButton( icon: Icon(Icons.menu, color: iconColor), onPressed: () => SideMenuProvider.openMenu(), ), const Spacer(), // Puntuación Icon(Icons.star_rounded, color: Colors.amber, size: 17), const SizedBox(width: 3), Text( professionalProvider.isProModeActive ? reputation.averagePro.toStringAsFixed(1) : reputation.average.toStringAsFixed(1), style: TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: isDark ? Colors.white70 : const Color(0xFF1E293B), ), ), const SizedBox(width: 8), // Toggle día / noche Tooltip( message: isDark ? 'Cambiar a modo día' : 'Cambiar a modo noche', child: InkWell( borderRadius: BorderRadius.circular(20), onTap: themeProvider.toggle, child: Padding( padding: const EdgeInsets.all(8), child: Icon( isDark ? Icons.light_mode : Icons.dark_mode, color: isDark ? Colors.amber : iconColor, size: 22, ), ), ), ), // Campana de notificaciones _NotificationBell(isDark: isDark, iconColor: iconColor), const SizedBox(width: 4), // Avatar const NavbarAvatar(), const SizedBox(width: 14), ], ), ); }); }); } } class _NotificationBell extends StatelessWidget { final bool isDark; final Color iconColor; const _NotificationBell({required this.isDark, required this.iconColor}); @override Widget build(BuildContext context) { return Consumer(builder: (context, sp, _) { final pendingCount = sp.services.where((s) => s.service.status.index == 0).length; return Tooltip( message: 'Notificaciones', child: Stack( clipBehavior: Clip.none, children: [ InkWell( borderRadius: BorderRadius.circular(20), onTap: () => _showSheet(context, sp), child: Padding( padding: const EdgeInsets.all(8), child: Icon( pendingCount > 0 ? Icons.notifications_active : Icons.notifications_outlined, color: pendingCount > 0 ? const Color(0xFF42A4EF) : iconColor, size: 22, ), ), ), if (pendingCount > 0) Positioned( top: 4, right: 4, child: Container( width: 15, height: 15, decoration: const BoxDecoration( color: Color(0xFFEF4444), shape: BoxShape.circle, ), child: Center( child: Text( pendingCount > 9 ? '9+' : '$pendingCount', style: const TextStyle( color: Colors.white, fontSize: 8, fontWeight: FontWeight.bold, ), ), ), ), ), ], ), ); }); } void _showSheet(BuildContext context, ServicesProvider sp) { final isDark = Theme.of(context).brightness == Brightness.dark; final pending = sp.services.where((s) => s.service.status.index == 0).toList(); final isPro = Provider.of(context, listen: false) .isProModeActive; showModalBottomSheet( context: context, backgroundColor: isDark ? const Color(0xFF1E293B) : Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), builder: (_) => Padding( padding: const EdgeInsets.fromLTRB(20, 12, 20, 32), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: Container( width: 36, height: 4, decoration: BoxDecoration( color: Colors.grey[400], borderRadius: BorderRadius.circular(2), ), ), ), const SizedBox(height: 16), Row( children: [ const Icon(Icons.notifications_outlined, size: 20), const SizedBox(width: 8), const Text('Notificaciones', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold)), const Spacer(), if (pending.isNotEmpty) Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 3), decoration: BoxDecoration( color: const Color(0xFF42A4EF), borderRadius: BorderRadius.circular(10), ), child: Text('${pending.length} nuevas', style: const TextStyle( color: Colors.white, fontSize: 11)), ), ], ), const SizedBox(height: 12), if (pending.isEmpty) Padding( padding: const EdgeInsets.symmetric(vertical: 28), child: Center( child: Column(children: [ Icon(Icons.notifications_none, size: 48, color: Colors.grey[400]), const SizedBox(height: 8), Text('Sin notificaciones pendientes', style: TextStyle(color: Colors.grey[500])), ]), ), ) else ...pending.take(5).map((s) => ListTile( contentPadding: EdgeInsets.zero, leading: Container( width: 40, height: 40, decoration: BoxDecoration( color: const Color(0xFF42A4EF).withOpacity(0.12), shape: BoxShape.circle, ), child: const Icon( Icons.room_service_outlined, color: Color(0xFF42A4EF), size: 20), ), title: Text( isPro ? 'Nueva solicitud de servicio' : 'Servicio pendiente', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w600), ), subtitle: Text( s.service.address.isNotEmpty ? s.service.address : 'Sin dirección', style: const TextStyle(fontSize: 12), maxLines: 1, overflow: TextOverflow.ellipsis, ), trailing: const Icon(Icons.circle, color: Color(0xFF42A4EF), size: 8), )), ], ), ), ); } }