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_phone_field/helpers.dart'; import 'package:profession_repository/profession_repository.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/professional_list_bloc/professional_list_bloc.dart'; import 'package:prosappco/screens/lists/city_list_screen.dart'; import 'package:prosappco/screens/user/user_calendar_screen.dart'; import 'package:prosappco/screens/user/user_view_profile_screen.dart'; import 'package:setting_repository/setting_repository.dart'; import 'package:shimmer/shimmer.dart'; class ProfessionalListScreen extends StatefulWidget { const ProfessionalListScreen({super.key}); @override State createState() => _ProfessionalListScreenState(); } class _ProfessionalListScreenState extends State { final _searchController = TextEditingController(); final professionRepository = Injector.appInstance.get(); final settingRepository = Injector.appInstance.get(); SettingEntity? settings; List? _professions; List? _filteredProfessions; String? _selectedProfession; bool _isLoading = true; late final ProfessionalListBloc bloc; @override void initState() { super.initState(); bloc = Injector.appInstance.get(); bloc.add(const ProfessionalListFetch()); _loadSettings(); _loadProfessions(); } void _loadSettings() { settingRepository.getSettings().then( (value) => setState(() { settings = value; }), ); } void _loadProfessions() { professionRepository.getProfessions().then((Professions element) { setState(() { _professions = element.professions; _filteredProfessions = _professions; _isLoading = false; }); }); } @override Widget build(BuildContext context) { return BlocProvider( create: (context) => bloc, child: BlocBuilder( builder: (context, state) { return Scaffold( appBar: AppBar( actions: [ _selectedProfession != null ? IconButton( icon: const Icon( Icons.clear, color: Colors.red, size: 32, ), onPressed: () { setState(() { _selectedProfession = null; }); }, ) : Container() ], title: _selectedProfession != null ? Text(_selectedProfession!) : const Text('Selecciona un profesional'), ), body: Column( children: [ _isLoading ? _buildShimmerEffect() : _selectedProfession == null ? Container( padding: const EdgeInsets.symmetric(horizontal: 20), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.grey[400]!, ), ), ), child: DropdownButtonHideUnderline( child: DropdownButton( isExpanded: true, value: _selectedProfession, hint: const Text('Seleccione una profesión'), items: _filteredProfessions ?.map((String profession) { return DropdownMenuItem( value: profession, child: Text(profession), ); }).toList(), onChanged: (String? newValue) { setState(() { _selectedProfession = newValue; }); }, ), ), ) : Container(), _selectedProfession != null ? TextField( controller: _searchController, onChanged: (value) { setState(() { _searchController.text = value; }); }, decoration: const InputDecoration( hintText: 'Busca un profesional', prefixIcon: Icon(Icons.search), enabledBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey), ), focusedBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey), ), ), ) : Container(), Expanded( child: _selectedProfession != null ? _body(state) : const Center( child: Text( 'Agrega los filtros para ver los profesionales'), ), ), ], ), ); }, ), ); } _body(ProfessionalListState state) { if (state is ProfessionalListSuccess) { final List filteredUsers; // TODO: encaso de filtro dañado // if (_searchController.text.isNotEmpty) { filteredUsers = state.users .where((element) => removeDiacritics(element.myUser.name!) .toLowerCase() .contains(removeDiacritics(_searchController.text.toLowerCase()))) .where((user) => user.myUser.id != FirebaseAuth.instance.currentUser!.uid) .where( (user) => user.professionalInfo.profession == _selectedProfession) .toList(); // } else { // filteredUsers = state.users // // .where((user) => user.myUser.id != FirebaseAuth.instance.currentUser!.uid) // .toList(); // } if (filteredUsers.isEmpty) { return const Center( child: Text('Ningun profesional coincide con la busqueda'), ); } return ListView.builder( itemCount: filteredUsers.length, itemBuilder: (BuildContext context, int index) { return Container( decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey.withOpacity(0.2)), ), ), child: ListTile( onTap: () async { var datos = await Navigator.push( context, CupertinoPageRoute( builder: (context) => UserCalendarScreen( userProfessional: filteredUsers[index], ), ), ); if (datos != null) { Navigator.pop(context, datos); } }, trailing: GestureDetector( onTap: () { Navigator.push( context, CupertinoPageRoute( builder: (context) => UserViewProfileScreen( userProfessional: filteredUsers[index], ), ), ); }, child: filteredUsers[index].professionalInfo.rate.isEmpty || settings?.tarifas == false ? const Icon( Icons.keyboard_arrow_right, color: Colors.black, ) : Column( children: [ const SizedBox(height: 5), const Icon( Icons.keyboard_arrow_right, color: Colors.black, ), Container( //fondo azul decoration: BoxDecoration( color: Colors.blue[200], borderRadius: BorderRadius.circular(50), ), child: Padding( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2), child: Text( '\$${filteredUsers[index].professionalInfo.rate}', style: const TextStyle( fontSize: 13, ), ), ), ), ], ), ), leading: Container( width: 60, height: 60, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, image: filteredUsers[index].myUser.picture == null ? null : DecorationImage( image: NetworkImage( filteredUsers[index].myUser.picture ?? ''), fit: BoxFit.contain, ), ), child: filteredUsers[index].myUser.picture == null ? Icon( CupertinoIcons.person, color: Colors.grey.shade400, size: 40, ) : null, ), title: Row( children: [ Flexible( child: Text( '${filteredUsers[index].myUser.name ?? ''}, ', overflow: TextOverflow.ellipsis, ), ), Text( filteredUsers[index].professionalInfo.profession, overflow: TextOverflow.ellipsis, ), ], ), subtitle: Text( _disponibilidad(filteredUsers[index].professionalInfo), style: const TextStyle( fontSize: 13, color: Colors.blue, ), ), ), ); }, ); } return Shimmer.fromColors( baseColor: Colors.grey[300]!, highlightColor: Colors.grey[100]!, child: ListView.builder( itemCount: 8, itemBuilder: (_, __) => Container( decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey.withOpacity(0.4)), ), ), child: ListTile( trailing: const Icon( Icons.keyboard_arrow_right, color: Colors.black, ), leading: Container( width: 60, height: 60, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), title: Container( width: MediaQuery.of(context).size.width * 0.8, height: 20.0, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), ), subtitle: Container( width: MediaQuery.of(context).size.width * 0.3, height: 15.0, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), ), ), ), ), ); } String _disponibilidad(ProfessionalEntity professionalInfo) { if (professionalInfo.locationPreferences == LocationPreferences.office) { return 'Disponibilidad: en sitio.'; } if (professionalInfo.locationPreferences == LocationPreferences.delivery) { return 'Disponibilidad: domicilio.'; } return 'Disponibilidad: domicilio, en sitio.'; } Widget _buildShimmerEffect() { return Expanded( child: Shimmer.fromColors( baseColor: Colors.grey[300]!, highlightColor: Colors.grey[100]!, child: ListView.builder( itemCount: 8, itemBuilder: (_, __) => const ListTileShimmer(), ), ), ); } }