import 'dart:io'; import 'package:flutter/material.dart'; import 'package:injector/injector.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:image_picker/image_picker.dart'; import 'package:prosappco/blocs/auth_bloc/auth_bloc.dart'; import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart'; import 'package:prosappco/blocs/professional_bloc/professional_bloc.dart'; import 'package:prosappco/blocs/profile_bloc/profile_bloc.dart'; import 'package:prosappco/screens/lists/profession_list_screen.dart'; import 'package:user_repository/user_repository.dart'; import 'package:file_picker/file_picker.dart'; class ProfessionalFormScreen extends StatefulWidget { const ProfessionalFormScreen({super.key}); @override State createState() => _ProfessionalFormScreenState(); } class _ProfessionalFormScreenState extends State { final TextEditingController _cedulaController = TextEditingController(); final TextEditingController _professionController = TextEditingController(); final TextEditingController _specialityController = TextEditingController(); final List _items = []; XFile? _imageFile; PlatformFile? _cedulaPdfFile; PlatformFile? _certificadoPdfFile; List? _especializacionesPdfFiles = []; late final AuthBloc authBloc; @override void initState() { super.initState(); authBloc = Injector.appInstance.get(); } @override void dispose() { _cedulaController.dispose(); _professionController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return BlocProvider( create: (context) => authBloc, child: Scaffold( appBar: AppBar( title: const Text('Perfil profesional'), ), body: BlocBuilder( builder: (context, state) { return Column( children: [ Expanded( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric( horizontal: 40, vertical: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ pictureWidget(state, context), const SizedBox(height: 30), TextFormField( controller: _cedulaController, decoration: const InputDecoration( labelText: 'Cedula', prefixIcon: Icon(Icons.assignment_ind), hintText: 'Ingresa tu cedula', border: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(10.0), )), errorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.red), ), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.red, width: 2.0), ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Por favor, ingrese su nombre'; } return null; }, ), const SizedBox(height: 10.0), ElevatedButton( onPressed: _pickCedulaPDF, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('Cargar pdf de la cedula'), _cedulaPdfFile != null ? const Icon(Icons.check) : const Icon(Icons.file_upload_outlined), ], ), ), const SizedBox(height: 20.0), TextFormField( controller: _professionController, readOnly: true, onTap: () async { final professionName = await Navigator.push( context, CupertinoPageRoute( builder: (BuildContext context) { return const ProfessionListScreen(); }, ), ); if (professionName != null) { _professionController.text = professionName; } }, decoration: const InputDecoration( labelText: 'Profesión', prefixIcon: Icon(Icons.work_rounded), hintText: 'Selecciona tu profesión', border: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(10.0), )), errorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.red), ), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.red, width: 2.0), ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Por favor, ingrese su nombre'; } return null; }, ), const SizedBox(height: 10.0), ElevatedButton( onPressed: _pickCertificadoPDF, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('Cargar pdf del certificado'), _certificadoPdfFile != null ? const Icon(Icons.check) : const Icon(Icons.file_upload_outlined), ], ), ), const SizedBox(height: 20.0), TextField( controller: _specialityController, onSubmitted: (value) { _addItemToList(); }, decoration: InputDecoration( labelText: 'Especializaciones', prefixIcon: const Icon(Icons.assignment_rounded), suffixIcon: IconButton( onPressed: () { _addItemToList(); }, icon: const Icon(Icons.add)), hintText: 'Ingresa tus especializaciones', border: const OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(10.0), )), errorBorder: const OutlineInputBorder( borderSide: BorderSide(color: Colors.red), ), focusedErrorBorder: const OutlineInputBorder( borderSide: BorderSide(color: Colors.red, width: 2.0), ), ), ), const SizedBox(height: 10.0), ElevatedButton( onPressed: _pickEspecializacionesPDF, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Expanded( child: Text( 'Cargar pdfs de tus especializaciones', overflow: TextOverflow.ellipsis, maxLines: 2, ), ), _especializacionesPdfFiles?.isNotEmpty == true ? const Icon(Icons.check) : const Icon(Icons.file_upload_outlined), ], ), ), const SizedBox(height: 10.0), Wrap( spacing: 8.0, runSpacing: 4.0, children: _items .map((item) => Chip( label: Text(item), backgroundColor: Theme.of(context) .colorScheme .tertiary, 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), ], ), ), ), ), const Divider( height: 1, thickness: 0.5, ), Padding( padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 15, ), child: FilledButton( onPressed: () { final userId = context.read().state.user!.id; final String? cedulaPdfPath = _cedulaPdfFile?.path; final String? certificadoPdfPath = _certificadoPdfFile?.path; final List especializacionesPdfPaths = _especializacionesPdfFiles ?.map((file) => file.path) .where((file) => file != null) .map((e) => e!) .toList() ?? []; if (_cedulaController.text.isEmpty || _professionController.text.isEmpty) { ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( 'Llena los campos de cedula y profesión'))); return; } if (cedulaPdfPath == null) { ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Carga el pdf de tu cedula'))); return; } if (certificadoPdfPath == null) { ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( 'Carga el pdf de tu certificado profesional'))); return; } context .read() .add(SendProfessionalToReviewEvent( id: userId, identification: _cedulaController.text, identificationPicture: cedulaPdfPath, profession: _professionController.text, certificatePicture: certificadoPdfPath, specializations: _items, specializationsPictures: especializacionesPdfPaths, )); final myUser = state.user!.copyWith(proState: ProState.pending); context.read().add(UpdateUserInfo( myUser: myUser, filePicture: _imageFile?.path)); ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Información enviada a revisión')), ); Navigator.pop(context); }, style: FilledButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, padding: const EdgeInsets.symmetric(vertical: 15), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), child: Container( alignment: Alignment.center, width: double.infinity, child: const Text( 'Enviar a revisión', style: TextStyle( color: Colors.white, fontSize: 18, ), ), ), )), ], ); }, ), ), ); } void _addItemToList() { setState(() { String newItem = _specialityController.text.trim(); if (newItem.isNotEmpty) { _items.add(newItem); _specialityController.clear(); } }); } void _removeItemFromList(String item) { setState(() { _items.remove(item); }); } Future _pickCedulaPDF() async { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['pdf'], ); if (result != null) { setState(() { _cedulaPdfFile = result.files.first; }); } } Future _pickCertificadoPDF() async { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['pdf'], ); if (result != null) { setState(() { _certificadoPdfFile = result.files.first; }); } } Future _pickEspecializacionesPDF() async { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['pdf'], allowMultiple: true, ); if (result != null) { setState(() { _especializacionesPdfFiles = result.files; }); } } Widget pictureWidget(MyUserState state, BuildContext context) { final pictureUrl = state.user?.picture; final pathImageFile = _imageFile?.path; ImageProvider? imageProvider; if (pathImageFile != null && pathImageFile.isNotEmpty) { imageProvider = FileImage(File(pathImageFile)); } else if (pictureUrl != null && pictureUrl.isNotEmpty) { imageProvider = NetworkImage(pictureUrl); } return GestureDetector( onTap: () async { final ImagePicker picker = ImagePicker(); final XFile? image = await picker.pickImage( source: ImageSource.gallery, maxHeight: 500, maxWidth: 500, imageQuality: 40, ); if (image != null) { setState(() { _imageFile = image; }); } }, child: Hero( tag: 'picture-profile', child: pictureContainerWidget(imageProvider), ), ); } Widget pictureContainerWidget(ImageProvider? imageProvider) { final image = imageProvider == null ? null : DecorationImage( image: imageProvider, fit: BoxFit.contain, ); final widget = image == null ? Icon( CupertinoIcons.person, color: Colors.grey.shade400, size: 40, ) : null; return Container( width: 120, height: 120, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, image: image, ), child: widget, ); } }