From 5bea76102cb20a59d854f00deab2e76fdb2344cc Mon Sep 17 00:00:00 2001 From: PGAN-MIS Date: Tue, 7 Mar 2023 15:01:56 +0800 Subject: [PATCH] contact refactor and created its own bloc --- .../contact/contact_bloc.dart | 22 ++ .../contact/contact_event.dart | 16 ++ .../contact/contact_state.dart | 27 ++ .../identification/identification_bloc.dart | 21 ++ .../identification/identification_event.dart | 15 ++ .../identification/identification_state.dart | 28 +++ .../contact_information_screen.dart | 236 +++++++++++++----- .../identification_information_screen.dart | 199 ++++++++++----- lib/screens/profile/profile.dart | 78 +++--- 9 files changed, 480 insertions(+), 162 deletions(-) create mode 100644 lib/bloc/profile/primary_information/contact/contact_bloc.dart create mode 100644 lib/bloc/profile/primary_information/contact/contact_event.dart create mode 100644 lib/bloc/profile/primary_information/contact/contact_state.dart create mode 100644 lib/bloc/profile/primary_information/identification/identification_bloc.dart create mode 100644 lib/bloc/profile/primary_information/identification/identification_event.dart create mode 100644 lib/bloc/profile/primary_information/identification/identification_state.dart diff --git a/lib/bloc/profile/primary_information/contact/contact_bloc.dart b/lib/bloc/profile/primary_information/contact/contact_bloc.dart new file mode 100644 index 0000000..b01bb81 --- /dev/null +++ b/lib/bloc/profile/primary_information/contact/contact_bloc.dart @@ -0,0 +1,22 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; + +import '../../../../model/profile/basic_information/contact_information.dart'; + +part 'contact_event.dart'; +part 'contact_state.dart'; + +class ContactBloc extends Bloc { + ContactBloc() : super(ContactInitial()) { + List contactInformations = []; + on((event, emit) { + emit(ContactLoadingState()); + try { + contactInformations = event.contactInformations; + emit(ContactLoadedState(contactInformation: contactInformations)); + } catch (e) { + emit(ContactErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/primary_information/contact/contact_event.dart b/lib/bloc/profile/primary_information/contact/contact_event.dart new file mode 100644 index 0000000..e2bdc88 --- /dev/null +++ b/lib/bloc/profile/primary_information/contact/contact_event.dart @@ -0,0 +1,16 @@ +part of 'contact_bloc.dart'; + +abstract class ContactEvent extends Equatable { + const ContactEvent(); + + @override + List get props => []; +} + + +class GetContacts extends ContactEvent{ + final List contactInformations; + const GetContacts({required this.contactInformations}); + @override + List get props => []; +} \ No newline at end of file diff --git a/lib/bloc/profile/primary_information/contact/contact_state.dart b/lib/bloc/profile/primary_information/contact/contact_state.dart new file mode 100644 index 0000000..f5a403b --- /dev/null +++ b/lib/bloc/profile/primary_information/contact/contact_state.dart @@ -0,0 +1,27 @@ +part of 'contact_bloc.dart'; + +abstract class ContactState extends Equatable { + const ContactState(); + + @override + List get props => []; +} + +class ContactInitial extends ContactState {} + +class ContactLoadedState extends ContactState{ + final List contactInformation; + const ContactLoadedState({required this.contactInformation}); + @override + List get props => []; +} + +class ContactLoadingState extends ContactState{ + +} +class ContactErrorState extends ContactState{ + final String message; + const ContactErrorState({required this.message}); + @override + List get props => [message]; +} \ No newline at end of file diff --git a/lib/bloc/profile/primary_information/identification/identification_bloc.dart b/lib/bloc/profile/primary_information/identification/identification_bloc.dart new file mode 100644 index 0000000..2ea178d --- /dev/null +++ b/lib/bloc/profile/primary_information/identification/identification_bloc.dart @@ -0,0 +1,21 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; + +import '../../../../model/profile/basic_information/identification_information.dart'; + +part 'identification_event.dart'; +part 'identification_state.dart'; + +class IdentificationBloc extends Bloc { + IdentificationBloc() : super(IdentificationInitial()) { + List identificationInformations = []; + on((event, emit) { + try{ + identificationInformations = event.identificationInformation; + emit(IdentificationLoadedState(identificationInformation: identificationInformations)); + }catch(e){ + emit(IdenficationErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/primary_information/identification/identification_event.dart b/lib/bloc/profile/primary_information/identification/identification_event.dart new file mode 100644 index 0000000..03bbc09 --- /dev/null +++ b/lib/bloc/profile/primary_information/identification/identification_event.dart @@ -0,0 +1,15 @@ +part of 'identification_bloc.dart'; + +abstract class IdentificationEvent extends Equatable { + const IdentificationEvent(); + + @override + List get props => []; +} + +class GetIdentifications extends IdentificationEvent{ + final List identificationInformation; + const GetIdentifications({required this.identificationInformation}); + @override + List get props => [identificationInformation]; +} diff --git a/lib/bloc/profile/primary_information/identification/identification_state.dart b/lib/bloc/profile/primary_information/identification/identification_state.dart new file mode 100644 index 0000000..0cae35d --- /dev/null +++ b/lib/bloc/profile/primary_information/identification/identification_state.dart @@ -0,0 +1,28 @@ +part of 'identification_bloc.dart'; + +abstract class IdentificationState extends Equatable { + const IdentificationState(); + + @override + List get props => []; +} + +class IdentificationInitial extends IdentificationState {} + +class IdentificationLoadedState extends IdentificationState{ + final List identificationInformation; + const IdentificationLoadedState({required this.identificationInformation}); + @override + List get props => [identificationInformation]; +} + +class IdenficationErrorState extends IdentificationState{ + final String message; + const IdenficationErrorState({required this.message}); + @override + List get props => [message]; +} + +class IdentificationLoadingState extends IdentificationState{ + +} diff --git a/lib/screens/profile/components/basic_information/contact_information_screen.dart b/lib/screens/profile/components/basic_information/contact_information_screen.dart index 43edb28..e7601a1 100644 --- a/lib/screens/profile/components/basic_information/contact_information_screen.dart +++ b/lib/screens/profile/components/basic_information/contact_information_screen.dart @@ -1,5 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:unit2/model/profile/basic_information/contact_information.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:unit2/bloc/profile/primary_information/contact/contact_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/text_container.dart'; @@ -7,73 +12,178 @@ import 'package:unit2/widgets/Leadings/add_leading.dart'; import 'package:unit2/widgets/empty_data.dart'; class ContactInformationScreen extends StatelessWidget { - final List contacts; - const ContactInformationScreen({super.key, required this.contacts}); + const ContactInformationScreen({ + super.key, + }); @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( - appBar: AppBar( - title: const Text(contactScreenTitle), - centerTitle: true, - backgroundColor: primary, - actions: [AddLeading(onPressed: (){})], - ), - body: contacts.isNotEmpty? ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 10), - itemCount: contacts.length, - itemBuilder: (BuildContext context, int index) { - String numberMail = contacts[index].numbermail!; - String commService = contacts[index].commService!.serviceProvider!.alias!; - return Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - decoration: box1(), - padding: const EdgeInsets.symmetric(horizontal: 12,vertical: 8), - child: Row( - children: [ - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(numberMail,style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500)), - const Divider(), - const SizedBox(height: 5,), - Row( - children: [ - Expanded( - child: Text(commService - .toString(),style: Theme.of(context).textTheme.titleSmall,), - ), - - contacts[index].active==true? const Badge(backgroundColor: Colors.green, label: Text("Active",),):const SizedBox(), - const SizedBox(width: 5), - contacts[index].primary==true? const Badge(backgroundColor: Colors.blue, label: Text("Primary"),):const SizedBox() - ], - ), - const SizedBox(height: 5,), - Text(contacts[index].commService! - .serviceProvider!.agency!.name - .toString()), - - ]), - ), - IconButton(onPressed: (){}, icon: const Icon(Icons.more_vert,color: Colors.grey,)) - ], - ), - ), - const SizedBox(height: 5,), - - - - ], - ); - }):const EmptyData(message: "You don't have contact information added. Please click + to add"), - ), + appBar: AppBar( + title: const Text(contactScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: [AddLeading(onPressed: () {})], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is ContactLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is ContactLoadedState || + state is ContactErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, + builder: (context, state) { + if (state is ContactLoadedState) { + if (state.contactInformation.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.contactInformation.length, + itemBuilder: + (BuildContext context, int index) { + String numberMail = state + .contactInformation[index] + .numbermail!; + String commService = state + .contactInformation[index] + .commService! + .serviceProvider! + .alias!; + return Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text(numberMail, + style: Theme.of( + context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500)), + const Divider(), + const SizedBox( + height: 5, + ), + Row( + children: [ + Expanded( + child: Text( + commService + .toString(), + style: Theme.of( + context) + .textTheme + .titleSmall, + ), + ), + state.contactInformation[index] + .active == + true + ? const Badge( + backgroundColor: + Colors + .green, + label: Text( + "Active", + ), + ) + : const SizedBox(), + const SizedBox( + width: 5), + state.contactInformation[index] + .primary == + true + ? const Badge( + backgroundColor: + Colors + .blue, + label: Text( + "Primary"), + ) + : const SizedBox() + ], + ), + const SizedBox( + height: 5, + ), + Text(state + .contactInformation[ + index] + .commService! + .serviceProvider! + .agency! + .name + .toString()), + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have contact information added. Please click + to add"); + } + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )), ); } } diff --git a/lib/screens/profile/components/basic_information/identification_information_screen.dart b/lib/screens/profile/components/basic_information/identification_information_screen.dart index 2eba37e..2d59569 100644 --- a/lib/screens/profile/components/basic_information/identification_information_screen.dart +++ b/lib/screens/profile/components/basic_information/identification_information_screen.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:unit2/bloc/profile/primary_information/identification/identification_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/model/profile/basic_information/identification_information.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/colors.dart'; @@ -7,76 +10,140 @@ import 'package:unit2/utils/text_container.dart'; import 'package:unit2/widgets/Leadings/add_leading.dart'; import 'package:unit2/widgets/empty_data.dart'; +import '../../../../bloc/user/user_bloc.dart'; + class IdentificationsScreen extends StatelessWidget { - final List identities; - const IdentificationsScreen({super.key, required this.identities}); + const IdentificationsScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: const Text(identificationScreenTitle), - centerTitle: true, - backgroundColor: primary, - actions: [AddLeading(onPressed: (){})], - ), - body:identities.isNotEmpty? ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10), - itemCount: identities.length, - itemBuilder: (BuildContext context, int index) { - String agency = identities[index].agency!.name!; - String idNumber = identities[index].identificationNumber!; - bool government = identities[index].agency!.privateEntity!; - String issuedAt = "${identities[index].issuedAt!.cityMunicipality!.description!} ${identities[index].issuedAt!.cityMunicipality!.province!.description}"; - return Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: screenWidth, - decoration: box1(), - padding: - const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - child: Row( - children: [ - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded(child: Text(agency,style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w400))), - const Divider(), - const SizedBox(height: 5,), - Expanded( - child: Text( - "$idNumberText : $idNumber",style: Theme.of(context).textTheme.titleSmall, - ), - ), - - Badge( - - backgroundColor: success2, - label: Text( - government == - true - ? privateText.toUpperCase() - :governmentText.toUpperCase(), - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.white),)), - const SizedBox(height: 5,), - Text(issuedAt), - ]), - ), - IconButton( - onPressed: () {}, icon: const Icon(Icons.more_vert,color: Colors.grey,)) - ], - ), - ), - const SizedBox( - height: 5, - ), - ], - ); - }):const EmptyData(message: "You don't have identifications added. Please click + to add."), - ); + appBar: AppBar( + title: const Text(identificationScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: [AddLeading(onPressed: () {})], + ), + body: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) {}, + builder: (context, state) { + if (state is IdentificationLoadedState) { + if (state.identificationInformation.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.identificationInformation.length, + itemBuilder: (BuildContext context, int index) { + String agency = + state.identificationInformation[index].agency!.name!; + String idNumber = + state.identificationInformation[index].identificationNumber!; + bool government = + state.identificationInformation[index].agency!.privateEntity!; + String issuedAt = + "${state.identificationInformation[index].issuedAt!.cityMunicipality!.description!} ${state.identificationInformation[index].issuedAt!.cityMunicipality!.province!.description}"; + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text(agency, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w400)), + const Divider(), + const SizedBox( + height: 5, + ), + Row(children: [ + Expanded( + child: Text( + "$idNumberText : $idNumber", + style: + Theme.of(context) + .textTheme + .titleSmall, + ), + ), + Badge( + backgroundColor: + success2, + label: Text( + government == true + ? privateText + .toUpperCase() + : governmentText + .toUpperCase(), + style: Theme.of( + context) + .textTheme + .bodySmall! + .copyWith( + color: Colors + .white), + )) + ]), + const SizedBox( + height: 5, + ), + Text(issuedAt), + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have identifications added. Please click + to add."); + } + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + )); } } diff --git a/lib/screens/profile/profile.dart b/lib/screens/profile/profile.dart index b9f3da9..7d444dc 100644 --- a/lib/screens/profile/profile.dart +++ b/lib/screens/profile/profile.dart @@ -9,6 +9,8 @@ import 'package:fluttericon/entypo_icons.dart'; import 'package:fluttericon/font_awesome5_icons.dart'; import 'package:fluttericon/modern_pictograms_icons.dart'; import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart'; +import 'package:unit2/bloc/profile/primary_information/contact/contact_bloc.dart'; +import 'package:unit2/bloc/profile/primary_information/identification/identification_bloc.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/screens/profile/components/basic_information/address_screen.dart'; import 'package:unit2/screens/profile/components/basic_information/citizenship_screen.dart'; @@ -117,35 +119,43 @@ class _ProfileInfoState extends State { })); }), subMenu(Icons.home, "Home Addresses", () { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) { - return BlocProvider( - create: (context) => AddressBloc() - ..add(GetAddress( - addresses: state.profileInformation.basicInfo.addresses)), - child: const AddressScreen(), - ); - })); - + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => AddressBloc() + ..add(GetAddress( + addresses: state.profileInformation + .basicInfo.addresses)), + child: const AddressScreen(), + ); + })); }), subMenu(Icons.contact_mail, "Identifications", () { Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) { - return IdentificationsScreen( - identities: state.profileInformation - .basicInfo.identifications); + return BlocProvider( + create: (context) => IdentificationBloc() + ..add(GetIdentifications( + identificationInformation: state + .profileInformation + .basicInfo + .identifications)), + child: const IdentificationsScreen(), + ); })); }), subMenu(Icons.contact_phone, "Contact Info", () { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) { - return ContactInformationScreen( - contacts: state.profileInformation - .basicInfo.contactInformation, - ); - })); + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => ContactBloc() + ..add(GetContacts( + contactInformations: state.profileInformation.basicInfo.contactInformation)), + child: ContactInformationScreen(), + ); + })); }), subMenu(Icons.flag, "Citizenships", () { Navigator.push(context, MaterialPageRoute( @@ -162,7 +172,7 @@ class _ProfileInfoState extends State { icon: Elusive.group, title: "Family", onTap: () { - Navigator.push(context, MaterialPageRoute( + Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) { return BlocProvider( create: (context) => FamilyBloc() @@ -300,28 +310,30 @@ class _ProfileInfoState extends State { }), subMenu(FontAwesome5.certificate, "Organization Memberships", () { - Navigator.push(context, MaterialPageRoute( + Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) { return BlocProvider( - create: (context) => OrganizationMembershipBloc() - ..add(GetOrganizationMembership( - profileId: profileId!, - token: token!)), + create: (context) => + OrganizationMembershipBloc() + ..add(GetOrganizationMembership( + profileId: profileId!, + token: token!)), child: const OrgMembershipsScreen(), ); })); }), subMenu(Entypo.doc_text, "Non-Academic Recognitions", () { - - Navigator.push(context, MaterialPageRoute( + Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) { return BlocProvider( - create: (context) => NonAcademicRecognitionBloc() - ..add(GetNonAcademicRecognition( - profileId: profileId!, - token: token!)), - child: const NonAcademicRecognitionScreen(), + create: (context) => + NonAcademicRecognitionBloc() + ..add(GetNonAcademicRecognition( + profileId: profileId!, + token: token!)), + child: + const NonAcademicRecognitionScreen(), ); })); }),