import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:diacritic/diacritic.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/photo_view.dart'; import 'package:prosappco/src/components/pop_appbar.dart'; import 'package:prosappco/src/models/setting_model.dart'; import 'package:prosappco/src/models/user_model.dart'; import 'package:prosappco/src/presentation/screens/professional_info.dart'; import '../../models/scores_model.dart'; class ProfessionalScreen extends StatefulWidget { final String profession; const ProfessionalScreen({super.key, required this.profession}); @override State createState() => _ProfessionalScreenState(); } final FirebaseStorage storage = FirebaseStorage.instance; final CollectionReference usersCollection = FirebaseFirestore.instance.collection('users'); var _photo = '...'; class Professional { final String id; final Reference professionalRef; final String name; final String professionName; final String cityName; final String ubicacion; final String realAddress; final double latitude; final double longitude; final List professionalEspecializado; final ScoresModel scores; final int? tarifa; final String? token; Professional({ required this.id, required this.professionalRef, required this.name, required this.professionName, required this.cityName, required this.ubicacion, required this.professionalEspecializado, required this.scores, required this.realAddress, required this.latitude, required this.longitude, this.tarifa, this.token, }); String getEspecializaciones() { return professionalEspecializado.join(',\n'); } @override String toString() { return 'Professional {\n' ' professionalRef: $professionalRef,\n' ' name: $name,\n' ' professionName: $professionName,\n' ' cityName: $cityName,\n' ' ubicacion: $ubicacion,\n' ' realAddress: $realAddress,\n' ' latitude: $latitude,\n' ' longitude: $longitude,\n' ' professionalEspecializado: ${getEspecializaciones()}\n' ' tarifa: $tarifa,\n' ' token: $token,\n' '}'; } static Future getProfessional(String uid) async { var photo = '...'; final FirebaseStorage storage = FirebaseStorage.instance; try { DocumentSnapshot user = await FirebaseFirestore.instance.collection('users').doc(uid).get(); Map data = user.data() as Map; photo = await AuthenticationRepository.instance.getPhoto(user.id); if (data['estado'] == 'activo') { List especializaciones; especializaciones = (data['especializaciones'] as List) .map((e) => e.toString()) .toList(); Professional professional = Professional( id: user.id, name: data['name'], professionName: data['profesion'], cityName: data['city'], professionalRef: storage.ref().child(photo), professionalEspecializado: especializaciones, ubicacion: data['ubicacion'] ?? '', realAddress: data['address'] ?? '', latitude: data['latitude'] ?? 0, longitude: data['longitude'] ?? 0, scores: await ScoresModel.scoreFrom(uid, true, true), tarifa: data['tarifa'] ?? 0, token: data['token'] ?? '', ); return professional; } } catch (e) { print('Error al obtener profesionales: $e'); } return null; } } class _ProfessionalScreenState extends State { UserModel? userme; SettingModel? settings; @override void initState() { super.initState(); if (userme == null) { UserModel.getUser(uid.toString()).then( (UserModel s) => setState(() => userme = s), ); } if (settings == null) { SettingModel.getSettings().then( (SettingModel value) => setState(() { settings = value; }), ); } searchController.addListener(() { setState(() { if (_professionals != null) { if (searchController.text.isEmpty) { filteredProfessionals = _professionals! .where((professional) => professional.id != uid) .toList(); } else { filteredProfessionals = _professionals! .where((professional) => removeDiacritics(professional.name).toLowerCase().contains( removeDiacritics( searchController.text.toLowerCase())) && professional.id != uid) .toList(); } } }); }); if (_professionals == null) { getProfessionals().then((List element) => setState(() { _professionals = element; filteredProfessionals = element; })); } } String formatCurrency(int number) { final formatter = NumberFormat.currency(locale: 'es_CO', decimalDigits: 0, symbol: ''); return '\$${formatter.format(number)}'; } Future _showChoiceDialog(BuildContext context) async { String? selectedOption = await showDialog( context: context, builder: (BuildContext context) { return AlertDialog( content: SingleChildScrollView( child: ListBody( children: [ GestureDetector( child: const Text( textAlign: TextAlign.center, "A domicilio", style: TextStyle(color: Color(0xFF2BA4EC)), ), onTap: () { Navigator.of(context).pop("domicilio"); }, ), const Divider(color: Colors.black54), GestureDetector( child: const Text( textAlign: TextAlign.center, "En sitio", style: TextStyle(color: Color(0xFF2BA4EC)), ), onTap: () { Navigator.of(context).pop("sitio"); }, ), ], ), ), ); }, ); return selectedOption; } List? filteredProfessionals; TextEditingController searchController = TextEditingController(); final uid = AuthenticationRepository.instance.getCurrentUserUid(); List? _professionals; Future> getProfessionals() async { List professionals = []; try { QuerySnapshot users = await usersCollection.get(); for (DocumentSnapshot user in users.docs) { Map data = user.data() as Map; _photo = await AuthenticationRepository.instance.getPhoto(user.id); if (data['estado'] == 'activo') { if (user.id != uid) { List especializaciones; especializaciones = (data['especializaciones'] as List) .map((e) => e.toString()) .toList(); if (widget.profession == data['profesion'] || widget.profession == '' && userme?.city == data['city'] && data['ubicacion'] != null) { Professional professional = Professional( id: user.id, name: data['name'], professionName: data['profesion'], cityName: data['city'], professionalRef: storage.ref().child(_photo), professionalEspecializado: especializaciones, ubicacion: data['ubicacion'] ?? '', realAddress: data['address'] ?? '', latitude: data['latitude'] ?? 0, longitude: data['longitude'] ?? 0, scores: await ScoresModel.scoreTo(user.id, true, true), tarifa: data['tarifa'] ?? 0, token: data['token'] ?? '', ); professionals.add(professional); } } } } } catch (e) { print('Error al obtener profesionales: $e'); } return professionals; } @override Widget build(BuildContext context) { if (filteredProfessionals == null) { return const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Color(0xFF2BA4EC)), ), ); } var professionals = filteredProfessionals!; return SafeArea( child: Scaffold( appBar: PopAppbar( onPressed: () { Navigator.pop(context); }, label: 'Seleccione un profesional'), body: Column( children: [ Padding( padding: const EdgeInsets.all(10), child: TextField( controller: searchController, decoration: const InputDecoration( hintText: 'Escriba un nombre', prefixIcon: Icon(Icons.assignment_ind_rounded), ), ), ), professionals.isEmpty ? Expanded( child: Padding( padding: const EdgeInsets.only(left: 20, right: 20, top: 50), child: Text('Aún no tenemos ningun(a) ${widget.profession}'), )) : Expanded( child: ListView.builder( itemCount: professionals.length, itemBuilder: (BuildContext context, int index) { return ListTile( leading: GestureDetector( onTap: () { Navigator.of(context).push( CupertinoPageRoute( builder: (BuildContext context) { return ProfessionalInfoScreen( professional: professionals[index], ); }, ), ); }, child: ReferencePhoto( ref: professionals[index].professionalRef, sizeCircle: 50, size: 50, sizeIcon: 35, ), ), trailing: GestureDetector( child: const Icon(Icons.keyboard_arrow_right), onTap: () { Navigator.of(context).push( CupertinoPageRoute( builder: (BuildContext context) { return ProfessionalInfoScreen( professional: professionals[index], ); }, ), ); }, ), title: RichText( text: TextSpan( style: const TextStyle( fontSize: 15.0, color: Colors.black, ), children: [ TextSpan( text: '${professionals[index].name}, ', style: const TextStyle( fontWeight: FontWeight.bold), ), TextSpan( text: "${professionals[index].professionName}, ${professionals[index].cityName}", style: TextStyle(color: Colors.grey[600]), ), ], ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ settings?.tarifas == true ? professionals[index].tarifa == 0 ? const SizedBox() : Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 5), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.0), color: const Color(0xFFD6F4FF), ), child: Text( formatCurrency( professionals[index].tarifa ?? 0), style: TextStyle( color: Colors.grey[850], fontWeight: FontWeight.w600, ), ), ) : const SizedBox(), professionals[index].ubicacion == 'ambos' ? Text( 'Disponibilidad a domicilio y en sitio ${professionals[index].tarifa}', style: const TextStyle( color: Colors.blue, ), ) : professionals[index].ubicacion == 'sitio' ? Text( 'Disponibilidad en ${professionals[index].ubicacion} ', style: const TextStyle( color: Colors.blue, ), ) : Text( 'Disponibilidad a ${professionals[index].ubicacion}', style: const TextStyle( color: Colors.blue, ), ), ], ), onTap: () { if (professionals[index].ubicacion == 'ambos') { _showChoiceDialog(context).then((String? value) { if (value != null) { Navigator.pop( context, [professionals[index], value]); } }); } else if (professionals[index].ubicacion == 'sitio') { Navigator.pop( context, [professionals[index], 'sitio']); } else { Navigator.pop( context, [professionals[index], 'domicilio']); } }, ); }, ), ), ], ), ), ); } }