import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:go_router/go_router.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../auth/data/services/auth_service.dart'; import '../store/dashboard_store.dart'; import '../widgets/dashboard_app_bar.dart'; import '../widgets/dashboard_metrics_cards.dart'; import '../widgets/quick_actions_dropdown.dart'; import '../widgets/recent_patients_card.dart'; import '../widgets/today_appointments_card.dart'; import '../../../patient_search/presentation/views/patient_search_modal_view.dart'; import '../../../patient/presentation/views/patient_modal_view.dart'; import '../../../config/presentation/views/config_modal_view.dart'; import 'appointments_modal_view.dart'; import '../../../../core/widgets/medical_modal.dart'; class DashboardView extends StatefulWidget { final DashboardStore? store; const DashboardView({super.key, this.store}); @override State createState() => _DashboardViewState(); } class _DashboardViewState extends State { late final DashboardStore _store; bool _isSecretary = false; @override void initState() { super.initState(); _store = widget.store ?? DashboardStore(); _store.loadDashboardData(); _loadUserRole(); } Future _loadUserRole() async { final session = await AuthService().loadSavedSession(); if (mounted && session != null) { setState(() { _isSecretary = session.isSecretary; }); } } void _handleLogout() { showDialog( context: context, barrierDismissible: false, builder: (dialogContext) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), title: const Row( children: [ Icon(Icons.logout_rounded, color: AppColors.error), SizedBox(width: 10), Text('Cerrar Sesión', style: TextStyle(fontWeight: FontWeight.bold)), ], ), content: const Text('¿Está seguro de que desea salir del sistema Hidalyx Med?'), actions: [ TextButton( onPressed: () => Navigator.of(dialogContext).pop(), child: const Text('Cancelar'), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: AppColors.error, foregroundColor: Colors.white, ), onPressed: () async { Navigator.of(dialogContext).pop(); await AuthService().logout(); if (mounted) { context.go('/login'); } }, child: const Text('Salir'), ), ], ), ); } void _handleQuickAction(QuickActionType action) { switch (action) { case QuickActionType.nuevoPaciente: showMedicalModal( context: context, builder: (_) => PatientModalView( isSecretary: _isSecretary, onSaved: (_) { _store.loadDashboardData(); }, ), ); break; case QuickActionType.buscarPaciente: showMedicalModal( context: context, builder: (_) => PatientSearchModalView(isSecretary: _isSecretary), ); break; case QuickActionType.configuracion: showMedicalModal( context: context, builder: (_) => ConfigModalView( onSaved: (updatedConfig) { _store.doctorInfo = updatedConfig; }, ), ); break; } } @override Widget build(BuildContext context) { return Observer( builder: (_) { return Scaffold( backgroundColor: AppColors.background, appBar: DashboardAppBar( doctorName: _store.doctorInfo.nombreDoctor, specialty: _store.doctorInfo.especialidad, isSecretary: _isSecretary, onLogoutPressed: _handleLogout, onQuickActionSelected: _handleQuickAction, ), body: _store.isLoading ? const Center( child: CircularProgressIndicator(color: AppColors.primary), ) : SingleChildScrollView( padding: const EdgeInsets.all(24), child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 1400), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Encabezado de Bienvenida Row( children: [ Container( width: 4, height: 28, decoration: BoxDecoration( color: AppColors.primary, borderRadius: BorderRadius.circular(2), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _isSecretary ? 'Recepción de Pacientes' : 'Panel Central - Consultorio', style: Theme.of(context).textTheme.headlineSmall?.copyWith( fontWeight: FontWeight.w700, color: AppColors.textPrimary, ), ), const SizedBox(height: 2), Text( _isSecretary ? 'Módulo de recepción, registro y sala de espera.' : 'Bienvenido, ${_store.doctorInfo.nombreDoctor}. Sistema clínico listo.', style: const TextStyle( color: AppColors.textSecondary, fontSize: 14, ), ), ], ), ), // Indicador en Vivo de Sala de Espera if (_store.enEsperaCount > 0) Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), decoration: BoxDecoration( color: const Color(0xFFDCFCE7), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFF86EFAC)), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.chair_rounded, size: 18, color: Color(0xFF15803D), ), const SizedBox(width: 8), Text( '${_store.enEsperaCount} en Sala de Espera', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w700, color: Color(0xFF15803D), ), ), ], ), ), ], ), const SizedBox(height: 24), // Mensaje de Error / Reintento si aplica if (_store.errorMessage != null) ...[ Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: AppColors.warning.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColors.warning.withValues(alpha: 0.3)), ), child: Row( children: [ const Icon(Icons.info_outline_rounded, color: AppColors.warning), const SizedBox(width: 12), Expanded( child: Text( 'Aviso de sincronización: ${_store.errorMessage}', style: const TextStyle(color: AppColors.textPrimary, fontSize: 13), ), ), TextButton( onPressed: () => _store.loadDashboardData(), child: const Text('Reintentar'), ), ], ), ), const SizedBox(height: 16), ], // Las 4 Tarjetas de Métricas Solicitadas DashboardMetricsCards(metrics: _store.metrics), const SizedBox(height: 24), // Paneles de Detalle: Pacientes Nuevos y Citas para Hoy LayoutBuilder( builder: (context, constraints) { final recentCard = RecentPatientsCard( patients: _store.recentPatients, ); final appointmentsCard = TodayAppointmentsCard( appointments: _store.todayAppointments, isSecretary: _isSecretary, onStatusChange: (patient, newStatus) async { await _store.changeWaitingStatus(patient.id, newStatus); }, onSchedulePressed: () { showMedicalModal( context: context, builder: (_) => AppointmentsModalView( isSecretary: _isSecretary, onStatusChanged: (patientId, newStatus) { _store.changeWaitingStatus(patientId, newStatus); }, ), ); }, onPatientTap: (patient) { if (patient.id > 0) { showMedicalModal( context: context, builder: (_) => PatientModalView( patientId: patient.id, isSecretary: _isSecretary, onSaved: (_) => _store.loadDashboardData(), ), ); } }, ); if (constraints.maxWidth >= 1000) { return IntrinsicHeight( child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: recentCard), const SizedBox(width: 16), Expanded(child: appointmentsCard), ], ), ); } return Column( children: [ recentCard, const SizedBox(height: 16), appointmentsCard, ], ); }, ), ], ), ), ), ), ); }, ); } }