import 'dart:typed_data'; import 'package:file_picker/file_picker.dart'; import 'package:prosapp_web_app/models/pro_state.dart'; import 'package:prosapp_web_app/models/profession.dart'; import 'package:prosapp_web_app/models/usuario.dart'; import 'package:prosapp_web_app/providers/auth_provider.dart'; import 'package:prosapp_web_app/providers/professional_form_provider.dart'; import 'package:prosapp_web_app/providers/professional_provider.dart'; import 'package:prosapp_web_app/providers/professions_provider.dart'; import 'package:prosapp_web_app/providers/profile_form_provider.dart'; import 'package:prosapp_web_app/services/notifications_service.dart'; import 'package:prosapp_web_app/ui/cards/white_card.dart'; import 'package:prosapp_web_app/ui/inputs/custom_inputs.dart'; import 'package:flutter/material.dart'; import 'package:prosapp_web_app/ui/views/no_page_found_view.dart'; import 'package:provider/provider.dart'; class RequestProfessionalView extends StatefulWidget { const RequestProfessionalView({super.key}); @override State createState() => _RequestProfessionalViewState(); } class _RequestProfessionalViewState extends State { Usuario? user; List professions = []; late ProfessionalFormProvider professionalFormProvider; @override void initState() { super.initState(); final authProvider = Provider.of(context, listen: false); final profileFormProvider = Provider.of(context, listen: false); professionalFormProvider = Provider.of(context, listen: false); final professionsProvider = Provider.of(context, listen: false); final proProvider = Provider.of(context, listen: false); profileFormProvider.user = authProvider.user; proProvider.getProfessional(authProvider.user!.id).then((value) { professionalFormProvider.setProfesional(value); }); setState(() { professions = professionsProvider.professions; user = authProvider.user; }); } @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { if (constraints.maxWidth < 900) { return ListView( physics: const ClampingScrollPhysics(), children: const [SizedBox(height: 10), _ProfileViewForm()], ); } else { return Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: ListView( physics: const ClampingScrollPhysics(), children: const [SizedBox(height: 10), _ProfileViewForm()], ), ); } }); } } class _ProfileViewForm extends StatefulWidget { const _ProfileViewForm(); @override State<_ProfileViewForm> createState() => _ProfileViewFormState(); } class _ProfileViewFormState extends State<_ProfileViewForm> { final TextEditingController _specialityController = TextEditingController(); List specializations = []; void _addItemToList() { setState(() { String newItem = _specialityController.text.trim(); if (newItem.isNotEmpty) { specializations.add(newItem); _specialityController.clear(); } }); } void _removeItemFromList(String item) { setState(() { specializations.remove(item); }); } @override Widget build(BuildContext context) { final authProvider = Provider.of(context); final professionsProvider = Provider.of(context); final professions = professionsProvider.professions; final user = authProvider.user!; return Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 900), child: Consumer( builder: (context, professionalFormProvider, child) { if (professionalFormProvider.profesional == null) { return const Center( child: CircularProgressIndicator(), ); } final professional = professionalFormProvider.profesional; switch (enumToInt(user.proState)) { case 0: return WhiteCard( title: 'Información profesional', child: Form( key: professionalFormProvider.formKey, autovalidateMode: AutovalidateMode.always, child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ const SizedBox(height: 10), TextFormField( initialValue: professional!.identification, validator: (value) { if (value == null || value.isEmpty) { return 'La cedula es obligatoria'; } if (value.trim().length < 6) { return 'La cedula debe tener al menos 6 caracteres'; } return null; }, onChanged: (value) { professionalFormProvider.copyProfesionalWith( identification: value); }, decoration: CustomInputs.formInputDecoration( hint: 'Ingresa tu cedula', label: 'Cedula', icon: Icons.badge_outlined, ), ), const SizedBox(height: 10), ElevatedButton.icon( onPressed: () async { try { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['pdf'], withData: true, ); if (result != null) { PlatformFile file = result.files.first; Uint8List? fileBytes = file.bytes; if (fileBytes != null) { NotificationsService.showBusyIndicator(context); final provider = Provider.of( context, listen: false); await provider.uploadPdfIdentification( fileBytes, user.id); Navigator.pop(context); } } } catch (e) { print('debugeando $e'); } }, icon: const Icon(Icons.upload_file), label: const Text('Cargar pdf de la cedula'), ), const SizedBox(height: 20), DropdownButtonFormField( validator: (value) { if (value == null) { return 'La profesión es obligatoria'; } return null; }, value: professional.profession == '' ? null : professional.profession, decoration: CustomInputs.formInputDecoration( hint: 'Selecciona tu profesión', label: 'Profesión', icon: Icons.work_outline_outlined, ), items: professions.map((Profession profession) { return DropdownMenuItem( value: profession.name, child: Text( profession.name, style: const TextStyle( color: Colors.black, fontWeight: FontWeight.normal, ), ), ); }).toList(), onChanged: (value) { professionalFormProvider.copyProfesionalWith( profession: value); }), const SizedBox(height: 10), ElevatedButton.icon( onPressed: () async { try { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['pdf'], withData: true, ); if (result != null) { PlatformFile file = result.files.first; Uint8List? fileBytes = file.bytes; if (fileBytes != null) { NotificationsService.showBusyIndicator(context); final provider = Provider.of( context, listen: false); await provider.uploadPdfCertificate( fileBytes, user.id); Navigator.pop(context); } } } catch (e) { print('debugeando $e'); } }, icon: const Icon(Icons.upload_file), label: const Text('Cargar pdf del certificado'), ), const SizedBox(height: 20), TextFormField( validator: (value) { if (RegExp(r'\s{2,}').hasMatch(value!)) { return 'La especialización no es valida'; } return null; }, onFieldSubmitted: (_) { _addItemToList(); }, controller: _specialityController, decoration: CustomInputs.formInputDecoration( hint: 'Ingresa tus especializaciones y agregalas (+)', label: 'Especializaciones', icon: Icons.assignment_outlined, iconButton: IconButton( onPressed: () { _addItemToList(); }, icon: const Icon(Icons.add), ), ), ), const SizedBox(height: 10), ElevatedButton.icon( onPressed: () async { try { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowMultiple: true, allowedExtensions: ['pdf'], withData: true, ); if (result != null) { List filesBytes = result.files .where((file) => file.bytes != null) .map((file) => file.bytes!) .toList(); if (filesBytes.isNotEmpty) { NotificationsService.showBusyIndicator(context); final provider = Provider.of( context, listen: false); await provider.uploadPdfSpecializations( filesBytes, user.id); Navigator.pop(context); } } } catch (e) { print('debugeando $e'); } }, icon: const Icon(Icons.upload_file), label: const Text('Cargar pdfs de las especializaciones'), ), const SizedBox(height: 10), Wrap( spacing: 8.0, runSpacing: 4.0, children: specializations .map((item) => Chip( label: Text(item), backgroundColor: Colors.blue.withOpacity(0.3), labelStyle: const TextStyle(color: Colors.blue), deleteIconColor: Colors.blue, onDeleted: () { _removeItemFromList(item); }, shape: RoundedRectangleBorder( side: const BorderSide( color: Colors.blue, width: 0.3), borderRadius: BorderRadius.circular(8), ), )) .toList(), ), const SizedBox(height: 20), Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 180), child: ElevatedButton( onPressed: () async { professionalFormProvider.copyProfesionalWith( specializations: specializations); final res = await professionalFormProvider .updateProfesionalInfo(user.id); if (res) { Provider.of(context, listen: false) .refreshUser(); final profileFormProvider = Provider.of(context, listen: false); profileFormProvider.copyUserWith( proState: ProState.pending); profileFormProvider.updateUserInfoNoValid(); } }, style: ButtonStyle( backgroundColor: WidgetStateProperty.all( Colors.blue.shade400, ), shape: WidgetStateProperty.all( const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(5)), ), ), shadowColor: WidgetStateProperty.all(Colors.transparent), ), child: const Text( 'Enviar a revisión', style: TextStyle( color: Colors.white, fontSize: 15, ), ), ), ), ), const SizedBox(height: 15), ], ), ), ); case 1: return LayoutBuilder( builder: (context, constraints) { double screenWidth = constraints.maxWidth; double baseFontSize = 18; double responsiveFontSize = screenWidth < 600 ? baseFontSize * 0.8 : baseFontSize; return WhiteCard( child: Column( children: [ const Center( child: Image( image: AssetImage('checklist.gif'), width: 320, ), ), ConstrainedBox( constraints: const BoxConstraints(maxWidth: 1020), child: Container( margin: const EdgeInsets.symmetric(horizontal: 8), child: Text( 'Gracias por proporcionar tu información. Actualmente, estamos revisando tus datos y una vez aprobados, podrás acceder al perfil profesional sin problemas. Te notificaremos tan pronto como tu cuenta esté lista.', style: TextStyle(fontSize: responsiveFontSize), textAlign: TextAlign.center, ), ), ), const SizedBox(height: 20), Text( '¡Gracias por tu paciencia!', style: TextStyle(fontSize: responsiveFontSize), textAlign: TextAlign.center, ), const SizedBox(height: 30), ], ), ); }, ); case 3: return LayoutBuilder( builder: (context, constraints) { double screenWidth = constraints.maxWidth; double baseFontSize = 18; double responsiveFontSize = screenWidth < 600 ? baseFontSize * 0.8 : baseFontSize; return WhiteCard( child: Column( children: [ Container( margin: const EdgeInsets.symmetric(vertical: 25), child: const Center( child: Icon( Icons.sentiment_dissatisfied_outlined, size: 100, color: Colors.red, ), ), ), ConstrainedBox( constraints: const BoxConstraints(maxWidth: 1020), child: Container( margin: const EdgeInsets.only( left: 8, right: 8, bottom: 10), child: Text( 'Lamentablemente, tu solicitud no ha sido aceptada en esta ocasión. Por favor, revisa tus datos y vuelve a intentarlo más tarde.', style: TextStyle(fontSize: responsiveFontSize), textAlign: TextAlign.center, ), ), ), const SizedBox(height: 20), Text( '¡Gracias por tu paciencia!', style: TextStyle(fontSize: responsiveFontSize), textAlign: TextAlign.center, ), const SizedBox(height: 30), ], ), ); }, ); } return Center(child: Text('No se encontró la sección.')); // return const NoPageFoundView(); }), ), ); } }