import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:prosapp_web_app/models/schedules_entity.dart'; import 'package:prosapp_web_app/models/service.dart'; import 'package:prosapp_web_app/models/service_status.dart'; import 'package:prosapp_web_app/models/servicio_profesional.dart'; import 'package:prosapp_web_app/services/navigation_service.dart'; import 'package:provider/provider.dart'; import 'package:prosapp_web_app/providers/auth_provider.dart'; import 'package:prosapp_web_app/providers/services_provider.dart'; const _kPrimary = Color(0xFF1565C0); const _kBg = Color(0xFFF4F6FA); const _kCard = Colors.white; class ServicesRequestsView extends StatelessWidget { const ServicesRequestsView({super.key}); @override Widget build(BuildContext context) { final sp = Provider.of(context, listen: false); sp.getServicesRequestsForProfessional( Provider.of(context, listen: false).user!.id); return Container( color: _kBg, child: Consumer( builder: (context, sp, _) { if (sp.isLoading) { return const Center( child: CircularProgressIndicator(color: _kPrimary), ); } return ListView( physics: const ClampingScrollPhysics(), padding: const EdgeInsets.only(bottom: 32), children: [ // Header Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 720), child: Padding( padding: const EdgeInsets.fromLTRB(16, 20, 16, 4), child: Row( children: [ Container( width: 36, height: 36, decoration: BoxDecoration( color: _kPrimary.withOpacity(0.08), borderRadius: BorderRadius.circular(10), ), child: const Icon(Icons.inbox_outlined, size: 19, color: _kPrimary), ), const SizedBox(width: 10), const Text( 'Solicitudes', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w800, color: Color(0xFF1E293B), ), ), const Spacer(), if (sp.services.isNotEmpty) Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 4), decoration: BoxDecoration( color: _kPrimary.withOpacity(0.1), borderRadius: BorderRadius.circular(20), ), child: Text( '${sp.services.length}', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w700, color: _kPrimary, ), ), ), ], ), ), ), ), if (sp.services.isEmpty) _emptyState() else ...sp.services.map((data) => _RequestCard(data: data)), ], ); }, ), ); } Widget _emptyState() { return Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 720), child: Container( margin: const EdgeInsets.fromLTRB(16, 12, 16, 0), padding: const EdgeInsets.symmetric(vertical: 56, horizontal: 24), decoration: BoxDecoration( color: _kCard, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 12, offset: const Offset(0, 2), ) ], ), child: Column( children: [ Container( width: 64, height: 64, decoration: BoxDecoration( color: const Color(0xFF94A3B8).withOpacity(0.1), shape: BoxShape.circle, ), child: const Icon(Icons.inbox_outlined, size: 32, color: Color(0xFF94A3B8)), ), const SizedBox(height: 16), const Text( 'Sin solicitudes pendientes', style: TextStyle( fontSize: 15, fontWeight: FontWeight.w700, color: Color(0xFF475569), ), ), const SizedBox(height: 6), const Text( 'Cuando un cliente solicite tus servicios\naparecerá aquí.', textAlign: TextAlign.center, style: TextStyle( fontSize: 13, color: Color(0xFF94A3B8), height: 1.5, ), ), ], ), ), ), ); } } class _RequestCard extends StatelessWidget { final ServicioProfesional data; const _RequestCard({required this.data}); @override Widget build(BuildContext context) { final service = data.service; final user = data.user; final statusInfo = _statusInfo(service.status); final dateStr = DateFormat('dd MMM yyyy', 'es') .format(DateTime.parse(service.day)); final timeStr = ScheduleEntity.getFormatTime(service.range1Hour1) ?? ''; return Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 720), child: Container( margin: const EdgeInsets.fromLTRB(16, 8, 16, 0), decoration: BoxDecoration( color: _kCard, borderRadius: BorderRadius.circular(14), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ) ], ), child: ClipRRect( borderRadius: BorderRadius.circular(14), child: MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( onTap: () => NavigationService.replaceTo( '/dashboard/professional/service/${service.id}'), child: IntrinsicHeight( child: Row( children: [ // Status accent strip Container(width: 4, color: statusInfo.color), // Avatar Padding( padding: const EdgeInsets.all(14), child: Stack( children: [ Container( width: 52, height: 52, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: statusInfo.color.withOpacity(0.3), width: 2, ), ), child: ClipOval( child: (user.picture == null || user.picture!.isEmpty) ? Container( color: _kPrimary.withOpacity(0.1), child: Center( child: Text( user.name.isNotEmpty ? user.name[0].toUpperCase() : '?', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.w700, color: _kPrimary, ), ), ), ) : FadeInImage.assetNetwork( placeholder: 'loader.gif', image: user.picture!, fit: BoxFit.cover, ), ), ), ], ), ), // Content Expanded( child: Padding( padding: const EdgeInsets.symmetric(vertical: 14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( user.name, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Color(0xFF1E293B), ), ), if (service.description.isNotEmpty) ...[ const SizedBox(height: 2), Text( '"${service.description}"', style: const TextStyle( fontSize: 12, color: Color(0xFF64748B), fontStyle: FontStyle.italic, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], const SizedBox(height: 6), Row( children: [ const Icon(Icons.calendar_today_outlined, size: 12, color: Color(0xFF94A3B8)), const SizedBox(width: 4), Text( '$dateStr · $timeStr', style: const TextStyle( fontSize: 12, color: Color(0xFF64748B), fontWeight: FontWeight.w500, ), ), ], ), ], ), ), ), // Status + arrow Padding( padding: const EdgeInsets.fromLTRB(8, 14, 12, 14), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ _StatusBadge(info: statusInfo), const SizedBox(height: 8), Icon(Icons.chevron_right, size: 18, color: Colors.grey.shade400), ], ), ), ], ), ), ), ), ), ), ), ); } } class _StatusBadge extends StatelessWidget { final _StatusInfo info; const _StatusBadge({required this.info}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 4), decoration: BoxDecoration( color: info.color.withOpacity(0.1), borderRadius: BorderRadius.circular(20), border: Border.all(color: info.color.withOpacity(0.3)), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(info.icon, size: 11, color: info.color), const SizedBox(width: 4), Text( info.label, style: TextStyle( fontSize: 11, fontWeight: FontWeight.w700, color: info.color, ), ), ], ), ); } } class _StatusInfo { final String label; final Color color; final IconData icon; const _StatusInfo(this.label, this.color, this.icon); } _StatusInfo _statusInfo(ServiceStatus status) { return switch (status) { ServiceStatus.pending => const _StatusInfo('Pendiente', Color(0xFFD97706), Icons.hourglass_top_outlined), ServiceStatus.acepted => const _StatusInfo('Aceptado', Color(0xFF1565C0), Icons.check_circle_outline), ServiceStatus.active => const _StatusInfo('En curso', Color(0xFF16A34A), Icons.play_circle_outline), ServiceStatus.completed => const _StatusInfo('Completado', Color(0xFF64748B), Icons.task_alt_outlined), ServiceStatus.denied => const _StatusInfo('Rechazado', Color(0xFFDC2626), Icons.cancel_outlined), ServiceStatus.cancelled => const _StatusInfo('Cancelado', Color(0xFF9CA3AF), Icons.remove_circle_outline), ServiceStatus.selfBooked => const _StatusInfo('Reservado', Color(0xFF7C3AED), Icons.bookmark_outline), }; }