import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:medora/data/models/consultation_booking.dart'; import 'package:medora/data/services/consultation_booking_service.dart'; import 'package:medora/route/route_names.dart'; import 'package:medora/screens/patientScreens/appoinmentBooking/speciality_screen.dart'; class PatientHomeScreen extends StatefulWidget { const PatientHomeScreen({super.key}); @override State createState() => _PatientHomeScreenState(); } class _PatientHomeScreenState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; final BookingService _bookingService = BookingService(); late Stream> _bookingsStream; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 300), ); _animationController.forward(); final User? user = FirebaseAuth.instance.currentUser; if (user != null) { final String userId = user.uid; _bookingsStream = _bookingService.getPatientBookings(userId); } else { _bookingsStream = const Stream.empty(); } } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( children: [ _buildSearchBar(), Expanded( child: ListView( padding: const EdgeInsets.all(16), children: [ _buildRealTimeCard(), const SizedBox(height: 20), _buildConsultationsSection(), const SizedBox(height: 20), _buildFindDoctorSection(), ], ), ), ], ), ), ); } Widget _buildSearchBar() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.blue, borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(30.0), bottomRight: Radius.circular(30.0), ), boxShadow: [ BoxShadow( color: Colors.blue.withOpacity(0.3), blurRadius: 10, offset: const Offset(0, 5), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(30), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 5), ), ], ), child: TextField( decoration: InputDecoration( hintText: 'Search Doctor/Hospital/Symptoms', hintStyle: GoogleFonts.poppins( color: Colors.grey[400], ), prefixIcon: const Icon(Icons.search, color: Colors.blue), border: OutlineInputBorder( borderRadius: BorderRadius.circular(30), borderSide: BorderSide.none, ), contentPadding: const EdgeInsets.symmetric(horizontal: 20), ), ), ), ], ), ); } Widget _buildRealTimeCard() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.blue[400]!, Colors.white], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.blue.withOpacity(0.3), blurRadius: 10, offset: const Offset(0, 5), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Real-time care\nat your fingertips.', style: GoogleFonts.poppins( fontSize: 30, fontWeight: FontWeight.bold, color: const Color.fromARGB(221, 67, 67, 67), ), ), const SizedBox(height: 12), ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SpecialtyScreen()), ); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.blue[700], padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 7), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), elevation: 5, ), child: Text( 'Start Consultation', style: GoogleFonts.poppins( fontWeight: FontWeight.bold, ), ), ), ], ), ); } Widget _buildConsultationsSection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Upcoming Consultations', style: GoogleFonts.poppins( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.grey[800], ), ), ], ), ), const SizedBox(height: 20), SizedBox( height: 201, child: StreamBuilder>( stream: _bookingsStream, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const CircularProgressIndicator(), const SizedBox(height: 12), Text( 'Loading consultations...', style: GoogleFonts.poppins( color: Colors.grey[600], ), ), ], ), ); } if (snapshot.hasError) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.error_outline, color: Colors.red[400], size: 48), const SizedBox(height: 12), Text( 'Error loading consultations', style: GoogleFonts.poppins( color: Colors.red[400], fontWeight: FontWeight.w500, ), ), TextButton( onPressed: () { // Implement refresh logic }, child: Text( 'Try Again', style: GoogleFonts.poppins( color: Colors.blue[700], ), ), ), ], ), ); } final bookings = snapshot.data ?? []; if (bookings.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.calendar_today, color: Colors.grey[400], size: 48), const SizedBox(height: 12), Text( 'No upcoming consultations', style: GoogleFonts.poppins( color: Colors.grey[600], fontSize: 16, ), ), TextButton( onPressed: () { // Navigate to book consultation }, child: Text( 'Book a Consultation', style: GoogleFonts.poppins( color: Colors.blue[700], fontWeight: FontWeight.w600, ), ), ), ], ), ); } return ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 20), scrollDirection: Axis.horizontal, itemCount: bookings.length, itemBuilder: (context, index) { final booking = bookings[index]; return Padding( padding: const EdgeInsets.only(right: 16), child: Hero( tag: 'consultation_${booking.id}', child: Material( child: _consultationCard( booking.doctorName, '${DateFormat('EEE, MMM d, yyyy').format(booking.appointmentDate)}\n${booking.appointmentTime}', booking.specialization, booking.paymentStatus, ), ), ), ); }, ); }, ), ), ], ); } Widget _consultationCard( String name, String schedule, String speciality, PaymentStatus paymentStatus, ) { return Container( width: 300, padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.white, Colors.grey[50]!], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(24), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.1), blurRadius: 20, offset: const Offset(0, 8), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 64, height: 64, decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.blue[400]!, Colors.blue[600]!], begin: Alignment.topLeft, end: Alignment.bottomRight, ), shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.blue[300]!.withOpacity(0.3), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: const Icon( Icons.person, size: 36, color: Colors.white, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, style: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.grey[800], ), ), Text( speciality, style: GoogleFonts.poppins( color: Colors.grey[600], fontSize: 14, ), ), const SizedBox(height: 8), Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 4, ), decoration: BoxDecoration( color: _getStatusColor(paymentStatus).withOpacity(0.1), borderRadius: BorderRadius.circular(20), border: Border.all( color: _getStatusColor(paymentStatus).withOpacity(0.2), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( _getStatusIcon(paymentStatus), size: 14, color: _getStatusColor(paymentStatus), ), const SizedBox(width: 4), Text( _getStatusText(paymentStatus), style: GoogleFonts.poppins( fontSize: 12, color: _getStatusColor(paymentStatus), fontWeight: FontWeight.w600, ), ), ], ), ), ], ), ), ], ), const SizedBox(height: 16), Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: Colors.blue[50], borderRadius: BorderRadius.circular(16), border: Border.all( color: Colors.blue[100]!, ), ), child: Row( children: [ Icon( Icons.calendar_today, size: 18, color: Colors.blue[700], ), const SizedBox(width: 8), Text( schedule, style: GoogleFonts.poppins( color: Colors.blue[700], fontSize: 13, fontWeight: FontWeight.w500, ), ), ], ), ), ], ), ); } IconData _getStatusIcon(PaymentStatus status) { switch (status) { case PaymentStatus.completed: return Icons.check_circle; case PaymentStatus.pending: return Icons.access_time; case PaymentStatus.failed: return Icons.error; default: return Icons.info; } } Color _getStatusColor(PaymentStatus status) { switch (status) { case PaymentStatus.pending: return Colors.orange; case PaymentStatus.completed: return Colors.green; case PaymentStatus.failed: return Colors.red; default: return Colors.grey; } } String _getStatusText(PaymentStatus status) { switch (status) { case PaymentStatus.pending: return 'Payment Pending'; case PaymentStatus.completed: return 'Confirmed'; case PaymentStatus.failed: return 'Payment Failed'; default: return 'Unknown'; } } Widget _buildFindDoctorSection() { final specialistData = [ { 'icon': Icons.local_hospital, 'label': 'General', 'color': Colors.blue, 'description': 'Primary Healthcare' }, { 'icon': Icons.remove_red_eye, 'label': 'Eye', 'color': Colors.indigo, 'description': 'Vision Care' }, { 'icon': Icons.medical_services, 'label': 'Dental', 'color': Colors.amber, 'description': 'Oral Health' }, { 'icon': Icons.favorite, 'label': 'Cardio', 'color': Colors.red, 'description': 'Heart Specialist' }, { 'icon': Icons.psychology, 'label': 'Mental', 'color': Colors.green, 'description': 'Mental Health' }, { 'icon': Icons.child_care, 'label': 'Pediatric', 'color': Colors.purple, 'description': 'Child Care' }, { 'icon': Icons.elderly, 'label': 'Geriatric', 'color': Colors.teal, 'description': 'Senior Care' }, { 'icon': Icons.fitness_center, 'label': 'Physio', 'color': Colors.orange, 'description': 'Physical Therapy' }, ]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: Text( 'Find Specialists', style: GoogleFonts.poppins( fontSize: 20, fontWeight: FontWeight.bold, ), ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ for (final data in specialistData) Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: _specialistCard( icon: data['icon'] as IconData, label: data['label'] as String, color: data['color'] as Color, description: data['description'] as String, ), ), const SizedBox(width: 8), ], ), ), ), IconButton( icon: const Icon(Icons.arrow_forward, color: Colors.blue), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SpecialtyScreen()), ); }, ), ], ), ], ); } Widget _specialistCard({ required IconData icon, required String label, required Color color, required String description, }) { return GestureDetector( onTap: () { Navigator.pushNamed( context, RouteNames.doctorListScreen, arguments: { 'specialty': label, }, ); }, child: Container( width: 140, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: color.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Icon(icon, color: color, size: 24), ), const SizedBox(height: 8), Text( label, style: GoogleFonts.poppins( color: Colors.black87, fontSize: 16, fontWeight: FontWeight.bold, ), ), Text( description, style: GoogleFonts.poppins( color: Colors.grey[600], fontSize: 12, ), ), ], ), ), ); } }