import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:injector/injector.dart'; import 'package:intl/intl.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; import 'package:prosappco/components/general_secondary_button.dart'; import 'package:service_repository/service_repository.dart'; import 'package:setting_repository/setting_repository.dart'; import 'package:user_repository/user_repository.dart'; class ProfessionalServiceScreen extends StatefulWidget { final String serviceId; const ProfessionalServiceScreen({super.key, required this.serviceId}); @override State createState() => _ProfessionalServiceScreenState(); } class _ProfessionalServiceScreenState extends State { final settingRepository = Injector.appInstance.get(); SettingEntity? settings; @override void initState() { super.initState(); _loadSettings(); } void _loadSettings() { settingRepository.getSettings().then( (value) => setState(() { settings = value; }), ); } @override Widget build(BuildContext context) { return BlocProvider( create: (context) => Injector.appInstance.get(), child: Scaffold( appBar: AppBar( title: const Text('Servicio'), ), body: BlocBuilder( builder: (context, state) { if (state is ServiceLoaded) { final service = state.service; return FutureBuilder( future: _getUserAndProfessionalInfo(service), builder: (BuildContext context, AsyncSnapshot> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else { if (snapshot.hasError) { return Center( child: Text('Error inesperado: ${snapshot.error}'), ); } else { final userInfo = snapshot.data![0] as MyUser; return Column( children: [ Expanded( child: SingleChildScrollView( child: Column( children: [ ListTile( leading: Container( width: 60, height: 60, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, image: userInfo.picture == null ? null : DecorationImage( image: NetworkImage( userInfo.picture!, ), fit: BoxFit.contain, ), ), child: userInfo.picture == null ? Icon( CupertinoIcons.person, color: Colors.grey.shade400, size: 40, ) : null, ), title: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${userInfo.name}', style: const TextStyle( fontWeight: FontWeight.bold), ), const SizedBox(width: 5), Text( '${DateFormat('dd MMMM', 'es').format(DateTime.parse(service.day))} - ${ScheduleEntity.getFormatTime(service.range1Hour1)}', style: TextStyle( color: Colors.grey[600], ), ), ], ), subtitle: const Text('Rating: 5.0'), ), Container( margin: const EdgeInsets.only( left: 40, right: 40, top: 20, bottom: 20, ), padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 15, ), decoration: BoxDecoration( color: const Color(0xFFD6F4FF), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.5), spreadRadius: 1, blurRadius: 5, offset: const Offset(1, 3), ), ], ), child: Row( children: [ const Icon( Icons.error_outline, size: 27, color: Colors.black54, ), const SizedBox(width: 15), service.location == ServiceLocationPreferences .delivery ? const Text( 'Servicio a domicilio.', style: TextStyle( color: Colors.black, fontSize: 14, ), ) : const Text( 'Servicio en tu consultorio', style: TextStyle( color: Colors.black, fontSize: 14, ), ), ], ), ), ListTile( leading: const Icon(Icons.near_me), title: Text( service.address, style: TextStyle( fontSize: 15, color: Colors.grey[600], ), ), subtitle: service.aditionalAddress.isEmpty ? null : Text( service.aditionalAddress, style: TextStyle( fontSize: 15, color: Colors.grey[600], ), ), ), service.description.isEmpty ? const SizedBox() : Container( alignment: Alignment.center, width: MediaQuery.of(context) .size .width * 0.8, child: Text( '"${service.description.trim()}"', style: TextStyle( color: Colors.grey[600], fontStyle: FontStyle.italic, ), ), ), const SizedBox(height: 65), customMessageStatus(service), const SizedBox(height: 20), ], ), ), ), const Divider( height: 1, thickness: 0.5, ), Padding( padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 15, ), child: customButton(service, context), ), ], ); } } }, ); } else { BlocProvider.of(context) .add(LoadService(widget.serviceId)); return const Center(child: CircularProgressIndicator()); } }, ), ), ); } Widget customMessageStatus(ServiceEntity service) { if (service.status == ServiceStatus.acepted) { return Stack( alignment: AlignmentDirectional.topCenter, clipBehavior: Clip.none, children: [ Card( color: Colors.green.shade50, child: const Padding( padding: EdgeInsets.fromLTRB(32, 56, 32, 32), child: Text( 'Aceptado', style: TextStyle(fontSize: 32, color: Colors.green), ), ), ), Positioned( top: -40, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.green.shade50, width: 4), shape: BoxShape.circle, ), child: const Icon(Icons.check, color: Colors.green, size: 48), ), ) ], ); } if (service.status == ServiceStatus.cancelled) { return Stack( alignment: AlignmentDirectional.topCenter, clipBehavior: Clip.none, children: [ Card( color: Colors.red.shade100, child: const Padding( padding: EdgeInsets.fromLTRB(32, 56, 32, 32), child: Text( 'Cancelado', style: TextStyle(fontSize: 32, color: Colors.red), ), ), ), Positioned( top: -40, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.red.shade100, width: 4), shape: BoxShape.circle, ), child: const Icon(Icons.close_rounded, color: Colors.red, size: 48), ), ) ], ); } if (service.status == ServiceStatus.denied) { return Stack( alignment: AlignmentDirectional.topCenter, clipBehavior: Clip.none, children: [ Card( color: Colors.red.shade100, child: const Padding( padding: EdgeInsets.fromLTRB(32, 56, 32, 32), child: Text( 'Rechazado', style: TextStyle(fontSize: 32, color: Colors.red), ), ), ), Positioned( top: -40, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.red.shade100, width: 4), shape: BoxShape.circle, ), child: const Icon(Icons.close_rounded, color: Colors.red, size: 48), ), ) ], ); } if (service.status == ServiceStatus.active) { return Stack( alignment: AlignmentDirectional.topCenter, clipBehavior: Clip.none, children: [ Card( color: Colors.green.shade50, child: const Padding( padding: EdgeInsets.fromLTRB(32, 56, 32, 32), child: Text( 'En proceso...', style: TextStyle(fontSize: 32, color: Colors.green), ), ), ), Positioned( top: -40, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.green.shade50, width: 4), shape: BoxShape.circle, ), child: const Icon( Icons.access_time_rounded, color: Colors.green, size: 48, ), ), ) ], ); } if (service.status == ServiceStatus.completed) { return Stack( alignment: AlignmentDirectional.topCenter, clipBehavior: Clip.none, children: [ Card( color: Colors.green.shade50, child: const Padding( padding: EdgeInsets.fromLTRB(32, 56, 32, 32), child: Text( 'Completado', style: TextStyle(fontSize: 32, color: Colors.green), ), ), ), Positioned( top: -40, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.green.shade50, width: 4), shape: BoxShape.circle, ), child: const Icon( Icons.star, color: Colors.green, size: 48, ), ), ) ], ); } return const SizedBox(); } Widget customButton(ServiceEntity service, BuildContext context) { if (service.status == ServiceStatus.pending) { return Column( children: [ GeneralSecondaryButton( label: 'Rechazar servicio', color: Theme.of(context).colorScheme.error, onPressed: () { final currentState = context.read().state; if (currentState is ServiceLoaded) { context.read().add(UpdateServiceStatus( widget.serviceId, ServiceStatus.denied)); } }, ), const SizedBox(height: 10), GeneralSecondaryButton( label: 'Aceptar servicio', onPressed: () { final currentState = context.read().state; if (currentState is ServiceLoaded) { context.read().add(UpdateServiceStatus( widget.serviceId, ServiceStatus.acepted)); } }, ), ], ); } if (service.status == ServiceStatus.acepted) { return GeneralSecondaryButton( label: 'Iniciar servicio', onPressed: () { final currentState = context.read().state; if (currentState is ServiceLoaded) { context.read().add( UpdateServiceStatus(widget.serviceId, ServiceStatus.active)); } }, ); // customStatusButton( // label: 'Iniciar servicio', // onPressed: () { // final currentState = context.read().state; // if (currentState is ServiceLoaded) { // context.read().add( // UpdateServiceStatus(widget.serviceId, ServiceStatus.active)); // } // }, // ); } if (service.status == ServiceStatus.active) { return GeneralSecondaryButton( label: 'Terminar servicio', onPressed: () { final currentState = context.read().state; if (currentState is ServiceLoaded) { context.read().add(UpdateServiceStatus( widget.serviceId, ServiceStatus.completed)); } }); } return GeneralSecondaryButton( label: 'Volver', onPressed: () { Navigator.pop(context); }); // customStatusButton( // label: 'Volver', // onPressed: () { // Navigator.pop(context); // }, // ); } String formatCurrency(int number) { final formatter = NumberFormat.currency(locale: 'es_CO', decimalDigits: 0, symbol: ''); return '\$${formatter.format(number)}'; } Future> _getUserAndProfessionalInfo( ServiceEntity service) async { final userRepo = FirebaseUserRepository(FirebaseAuth.instance); final userInfo = await userRepo.getMyUser(service.userId); return [userInfo]; } }