import 'dart:io'; import 'package:app_popup_menu/app_popup_menu.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_svg/svg.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:unit2/bloc/profile/education/education_bloc.dart'; import 'package:unit2/bloc/profile/learningDevelopment/learning_development_bloc.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/model/profile/attachment.dart'; import 'package:unit2/model/profile/eligibility.dart'; import 'package:unit2/screens/profile/components/eligibility/add_modal.dart'; import 'package:unit2/screens/profile/components/eligibility/edit_modal.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/btn-style.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/theme-data.dart/form-style.dart'; import 'package:unit2/utils/global.dart'; import 'package:unit2/utils/text_container.dart'; import 'package:unit2/widgets/Leadings/add_leading.dart'; import 'package:unit2/widgets/Leadings/close_leading.dart'; import 'package:unit2/widgets/empty_data.dart'; import 'package:unit2/widgets/error_state.dart'; import '../../../bloc/profile/eligibility/eligibility_bloc.dart'; import '../../../utils/alerts.dart'; import '../shared/multiple_attachment.dart'; import '../shared/single_attachment.dart'; class EligibiltyScreen extends StatelessWidget { const EligibiltyScreen({super.key}); @override Widget build(BuildContext context) { BuildContext parent = context; String? token; int? profileId; List? results = []; AttachmentCategory? selectedAttachmentCategory; List attachmentCategories = []; return WillPopScope( onWillPop: () async { return true; }, child: Scaffold( resizeToAvoidBottomInset: true, appBar: AppBar( title: context.watch().state is AddEligibilityState ? const Text("Add Eligiblity") : context.watch().state is EditEligibilityState ? const Text("Edit Eligibilty") : const Text(elibilityScreenTitle), centerTitle: true, backgroundColor: primary, actions: (context.watch().state is EligibilityLoaded) ? [ AddLeading(onPressed: () { context .read() .add(ShowAddEligibilityForm()); }) ] : (context.watch().state is AddEligibilityState || context.watch().state is EditEligibilityState) ? [ CloseLeading(onPressed: () { context .read() .add(const LoadEligibility()); }) ] : [], ), body: BlocBuilder( builder: (context, state) { if (state is UserLoggedIn) { token = state.userData!.user!.login!.token; profileId = state.userData!.user!.login!.user!.profileId; return BlocBuilder( builder: (context, state) { if (state is ProfileLoaded) { return ProgressHUD( padding: const EdgeInsets.all(24), indicatorWidget: const SpinKitFadingCircle( color: Colors.white, ), backgroundColor: Colors.black87, child: BlocConsumer( listener: (context, state) { if (state is EligibilityLoadingState) { final progress = ProgressHUD.of(context); progress!.showWithText("Please wait..."); } if (state is EligibilityLoaded || state is AddEligibilityState || state is EditEligibilityState || state is EligibilityDeletedState || state is EligibilityAddedState || state is EligibilityEditedState || state is EligibilityErrorState) { final progress = ProgressHUD.of(context); progress!.dismiss(); } ////DELETED STATE if (state is EligibilityDeletedState) { if (state.success) { successAlert(context, "Deletion Successfull", "Eligibility has been deleted successfully", () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } else { errorAlert(context, "Deletion Failed", "Error deleting eligibility", () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } } ////ATTACHMENT ADDED STATE if (state is EligibilityAttachmentAddedState) { if (state.response['success']) { successAlert(context, "Adding Successfull!", state.response['message'], () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } else { errorAlert(context, "Adding Failed", "Something went wrong. Please try again.", () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } } ////ADDED STATE if (state is EligibilityAddedState) { if (state.response['success']) { successAlert(context, "Adding Successfull!", state.response['message'], () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } else { errorAlert(context, "Adding Failed", "Something went wrong. Please try again.", () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } } ////UPDATED STATE if (state is EligibilityEditedState) { if (state.response['success']) { successAlert(context, "Update Successfull!", state.response['message'], () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } else { errorAlert(context, "Update Failed", "Something went wrong. Please try again.", () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } } ////ATTACHMENT DELETED STATE if (state is EligibilitytAttachmentDeletedState) { if (state.success) { successAlert(context, "Deletion Successfull", "Attachment has been deleted successfully", () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } else { errorAlert(context, "Deletion Failed", "Error deleting Attachment", () { Navigator.of(context).pop(); context .read() .add(const LoadEligibility()); }); } } }, builder: (context, state) { return BlocBuilder( builder: (context, state) { if (state is EligibilityLoaded) { for (var cat in state.attachmentCategory) { if (cat.subclass!.id == 3) { attachmentCategories.add(cat); } } if (state.eligibilities.isNotEmpty) { return ListView.builder( padding: const EdgeInsets.symmetric( vertical: 8, horizontal: 10), itemCount: state.eligibilities.length, itemBuilder: (BuildContext context, int index) { String title = state .eligibilities[index] .eligibility! .title; return Column( children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8), decoration: box1(), child: Column( children: [ Row( children: [ Expanded( child: Column( mainAxisAlignment: MainAxisAlignment .start, crossAxisAlignment: CrossAxisAlignment .start, children: [ Text( title, style: Theme.of( context) .textTheme .titleMedium! .copyWith( fontWeight: FontWeight .w500, color: primary), ), const SizedBox( height: 5, ), Text( "$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}", style: Theme.of( context) .textTheme .titleSmall), const SizedBox( height: 3, ), Text( "Rating : ${state.eligibilities[index].rating ?? 'N/A'}", style: Theme.of( context) .textTheme .titleSmall), ]), ), AppPopupMenu( offset: const Offset( -10, -10), elevation: 3, onSelected: (value) { ////delete eligibilty-= = = = = = = = =>> if (value == 2) { confirmAlert( context, () { final progress = ProgressHUD.of( context); progress! .showWithText( "Loading..."); BlocProvider .of( context) .add(DeleteEligibility( eligibilityId: state .eligibilities[ index] .id!, profileId: profileId .toString(), token: token!)); }, "Delete?", "Confirm Delete?"); } if (value == 1) { ////edit eligibilty-= = = = = = = = =>> final progress = ProgressHUD.of( context); progress! .showWithText( "Loading..."); EligibityCert eligibityCert = state.eligibilities[ index]; bool overseas = eligibityCert .examAddress! .country! .id .toString() == '175' ? false : true; eligibityCert .overseas = overseas; eligibityCert .overseas = overseas; context .read< EligibilityBloc>() .add(ShowEditEligibilityForm( eligibityCert: eligibityCert)); } ////Attachment if (value == 3) { results.clear(); showDialog( context: context, builder: (BuildContext context) { return AlertDialog( contentPadding: const EdgeInsets .all(0), backgroundColor: Colors .grey .shade100, icon: const Icon( Icons .file_copy, size: 32, color: primary, ), title: const Text( "File Attachment:"), content: StatefulBuilder(builder: (context, setState) { return Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Divider(), Text( title, style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary), ), const SizedBox( height: 5, ), Text("$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}", style: Theme.of(context).textTheme.titleSmall), const SizedBox( height: 3, ), Text("Rating : ${state.eligibilities[index].rating ?? 'N/A'}", style: Theme.of(context).textTheme.titleSmall), const Divider(), FormBuilderDropdown( autovalidateMode: AutovalidateMode.always, decoration: normalTextFieldStyle("attachment category", "attachment category"), name: 'attachments_categorues', validator: FormBuilderValidators.required(errorText: "This field is required"), onChanged: (value) { selectedAttachmentCategory = value; }, items: attachmentCategories.map((e) { return DropdownMenuItem(value: e, child: Text(e.description!)); }).toList()), const SizedBox( height: 8, ), Text( "You may attach necessary documents such as Transcript of Records (TOR), diploma, and the likes.", style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black), ), const SizedBox( height: 5, ), Text( "Acceptable Files: PDF, JPEG, PNG", style: Theme.of(context).textTheme.bodySmall, ), Text( "Max File Size (per attachment): 1MB", style: Theme.of(context).textTheme.bodySmall, ), const Divider(), ElevatedButton( style: ButtonStyle( elevation: MaterialStateProperty.all(0), backgroundColor: MaterialStateProperty.all(Colors.white), ), onPressed: () async { FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [ 'jpg', 'png', 'jpeg', 'pdf' ]); setState(() { FilePickerResult? x; if (newResult != null) { newResult.files.forEach((element) { results.add(element); }); } }); }, child: const Center( child: Text( "Select Files", textAlign: TextAlign.center, style: TextStyle(color: Colors.black), ))), const Divider(), SingleChildScrollView( child: SizedBox( height: 100, width: double.maxFinite, child: results.isEmpty ? const SizedBox() : Expanded( child: ListView.builder( itemCount: results.length, itemBuilder: (BuildContext context, index) { final kb = results[index].size / 1024; final mb = kb / 1024; final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB'; return Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: double.infinity, child: Row( children: [ Flexible( child: SizedBox( child: results[index].extension!.toLowerCase() == 'pdf' ? SvgPicture.asset( 'assets/svgs/pdf.svg', height: blockSizeVertical * 3, allowDrawingOutsideViewBox: true, ) : results[index].extension!.toLowerCase() == 'png' ? SvgPicture.asset( 'assets/svgs/png.svg', height: blockSizeVertical * 3, allowDrawingOutsideViewBox: true, ) : results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg' ? SvgPicture.asset( 'assets/svgs/jpg.svg', height: blockSizeVertical * 3, allowDrawingOutsideViewBox: true, ) : const SizedBox())), const SizedBox( width: 12, ), Flexible( flex: 6, child: Text( results[index].name, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2), ), ), const SizedBox( width: 8, ), Flexible( flex: 2, child: Text( size, style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey), )), Flexible( flex: 1, child: IconButton( icon: const Icon( Icons.close, color: Colors.grey, ), onPressed: () { setState(() { results.removeAt(index); }); }, )) ], )), const Divider() ], ); }), ), ), ), const SizedBox( height: 12, ), SizedBox( width: double.maxFinite, height: 50, child: ElevatedButton( style: mainBtnStyle(primary, Colors.transparent, second), onPressed: () { List paths = []; if (selectedAttachmentCategory != null && results.isNotEmpty) { for (var res in results) { paths.add(res.path!); } setState(() { results.clear(); }); Navigator.pop(context); parent.read().add(AddEligibiltyAttachment(attachmentModule: state.eligibilities[index].id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString())); } }, child: const Text("Submit")), ) ]), ); }), ); }); } }, menuItems: [ popMenuItem( text: "Update", value: 1, icon: Icons.edit), popMenuItem( text: "Remove", value: 2, icon: Icons.delete), popMenuItem( text: "Attach", value: 3, icon: Icons .attach_file), ], icon: const Icon( Icons.more_vert, color: Colors.grey, ), tooltip: "Options", ) ], ), const Divider(), ////Show Attachments SizedBox( width: screenWidth, child: state .eligibilities[ index] .attachments == null || state .eligibilities[ index] .attachments! .isEmpty ? const SizedBox() : state.eligibilities[index].attachments != null && state .eligibilities[ index] .attachments! .length == 1 ? ////Single Attachment view SingleAttachment( onpressed: () { confirmAlert( context, () { parent.read().add(DeleteEligibyAttachment( attachment: state .eligibilities[ index] .attachments! .first, moduleId: state .eligibilities[ index] .id .toString(), profileId: profileId .toString(), token: token!)); }, "Delete?", "Confirm Delete?"); }, attachment: state .eligibilities[ index] .attachments! .first, ) ////Multiple Attachments View : MultipleAttachments( profileId: profileId!, token: token!, moduleId: state .eligibilities[ index] .eligibility! .id, educationBloc: null, learningDevelopmentBloc: null, workHistoryBloc: null, eligibilityBloc: BlocProvider.of< EligibilityBloc>( context), blocId: 2, eligibilityName: state .eligibilities[ index] .eligibility! .title, attachments: state .eligibilities[ index] .attachments!, )) ], ), ), const SizedBox( height: 5, ), ], ); }); } else { return const EmptyData( message: "You don't have any eligibilities added. Please click + to add"); } } if (state is EditEligibilityState) { return EditEligibilityScreen( profileId: profileId!, token: token!, eligibityCert: state.eligibityCert); } if (state is AddEligibilityState) { return AddEligibilityScreen( token: token!, profileId: profileId!, ); } if (state is EligibilityErrorState) { return SomethingWentWrong( message: state.message, onpressed: () { context.read().add( GetEligibilities( token: token!, profileId: profileId!)); }); } return Container( color: Colors.grey.shade200, ); }, ); }, ), ); } return Container(); }); } return Container(); }, )), ); } PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { return PopupMenuItem( value: value, child: Row( children: [ Icon( icon, ), const SizedBox( width: 10, ), Text( text!, ), ], ), ); } }