From 4dcd31cdbb7e007be0795142dab848d0aa3a93ba Mon Sep 17 00:00:00 2001 From: yaso Date: Wed, 12 Mar 2025 13:47:38 +0200 Subject: [PATCH] recreate business prof tools --- .../app_tools/mih_business_profile.dart | 573 ++++++++++++++++++ .../app_tools/mih_business_user_search.dart | 161 +++++ .../app_tools/mih_my_business_team.dart | 124 ++++ 3 files changed, 858 insertions(+) create mode 100644 Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_profile.dart create mode 100644 Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_user_search.dart create mode 100644 Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_my_business_team.dart diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_profile.dart new file mode 100644 index 00000000..eda76b95 --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_profile.dart @@ -0,0 +1,573 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_apis/mih_location_api.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_file_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_body.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:supertokens_flutter/http.dart' as http; +import 'package:http/http.dart' as http2; +import 'package:supertokens_flutter/supertokens.dart'; + +class MihBusinessProfile extends StatefulWidget { + final BusinessArguments arguments; + const MihBusinessProfile({ + super.key, + required this.arguments, + }); + + @override + State createState() => _MihBusinessProfileState(); +} + +class _MihBusinessProfileState extends State { + final FocusNode _focusNode = FocusNode(); + final baseAPI = AppEnviroment.baseApiUrl; + + final nameController = TextEditingController(); + final typeController = TextEditingController(); + final regController = TextEditingController(); + final logonameController = TextEditingController(); + final fnameController = TextEditingController(); + final lnameController = TextEditingController(); + final titleController = TextEditingController(); + final signtureController = TextEditingController(); + final accessController = TextEditingController(); + final contactController = TextEditingController(); + final emailController = TextEditingController(); + final locationController = TextEditingController(); + final practiceNoController = TextEditingController(); + final vatNoController = TextEditingController(); + + late PlatformFile? selectedLogo = null; + late PlatformFile? selectedSignature = null; + + final ValueNotifier busType = ValueNotifier(""); + + late String business_id; + late String oldLogoPath; + late String oldSigPath; + + Future updateBusinessProfileAPICall(String business_id) async { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + var response = await http.put( + Uri.parse("$baseAPI/business/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "business_id": business_id, + "Name": nameController.text, + "type": typeController.text, + "registration_no": regController.text, + "logo_name": logonameController.text, + "logo_path": + "${widget.arguments.signedInUser.app_id}/business_files/${logonameController.text}", + "contact_no": contactController.text, + "bus_email": emailController.text, + "gps_location": locationController.text, + "practice_no": practiceNoController.text, + "vat_no": vatNoController.text, + }), + ); + if (response.statusCode == 200) { + //var businessResponse = jsonDecode(response.body); + //print(selectedLogo != null); + if (selectedLogo != null) { + uploadSelectedFile(selectedLogo, logonameController); + deleteFileApiCall(oldLogoPath); + } + updateBusinessUserAPICall(business_id); + } else { + internetConnectionPopUp(); + } + } + + Future updateBusinessUserAPICall(String business_id) async { + var response = await http.put( + Uri.parse("$baseAPI/business-user/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "business_id": business_id, + "app_id": widget.arguments.signedInUser.app_id, + "signature": signtureController.text, + "sig_path": + "${widget.arguments.signedInUser.app_id}/business_files/${signtureController.text}", + "title": titleController.text, + "access": accessController.text, + }), + ); + if (response.statusCode == 200) { + if (selectedSignature != null) { + uploadSelectedFile(selectedSignature, signtureController); + deleteFileApiCall(oldSigPath); + } + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/business-profile/manage', + arguments: BusinessArguments( + widget.arguments.signedInUser, + widget.arguments.businessUser, + widget.arguments.business, + ), + ); + String message = + "Your business profile is now live! You can now start connecting with customers and growing your business."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } + + Future uploadSelectedFile( + PlatformFile? file, TextEditingController controller) async { + //to-do delete file when changed + var token = await SuperTokens.getAccessToken(); + //print(t); + //print("here1"); + var request = http2.MultipartRequest( + 'POST', Uri.parse("${AppEnviroment.baseApiUrl}/minio/upload/file/")); + request.headers['accept'] = 'application/json'; + request.headers['Authorization'] = 'Bearer $token'; + request.headers['Content-Type'] = 'multipart/form-data'; + request.fields['app_id'] = widget.arguments.signedInUser.app_id; + request.fields['folder'] = "business_files"; + request.files.add(await http2.MultipartFile.fromBytes('file', file!.bytes!, + filename: file.name.replaceAll(RegExp(r' '), '-'))); + var response1 = await request.send(); + if (response1.statusCode == 200) { + } else { + internetConnectionPopUp(); + } + } + + Future deleteFileApiCall(String filePath) async { + // delete file from minio + var response = await http.delete( + Uri.parse("$baseAPI/minio/delete/file/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({"file_path": filePath}), + ); + //print("Here4"); + //print(response.statusCode); + if (response.statusCode == 200) { + //SQL delete + } else { + internetConnectionPopUp(); + } + } + + bool isFullAccess() { + if (widget.arguments.businessUser!.access == "Partial") { + return false; + } else { + return true; + } + } + + bool validEmail() { + String text = emailController.text; + var regex = RegExp(r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'); + return regex.hasMatch(text); + } + + bool isFieldsFilled() { + if (nameController.text.isEmpty || + typeController.text.isEmpty || + regController.text.isEmpty || + logonameController.text.isEmpty || + fnameController.text.isEmpty || + lnameController.text.isEmpty || + titleController.text.isEmpty || + signtureController.text.isEmpty || + accessController.text.isEmpty || + contactController.text.isEmpty || + emailController.text.isEmpty) { + return false; + } else { + return true; + } + } + + void typeSelected() { + if (typeController.text.isNotEmpty) { + busType.value = typeController.text; + } else { + busType.value = ""; + } + } + + void submitForm(String business_id) { + if (!validEmail()) { + emailError(); + } else if (isFieldsFilled()) { + updateBusinessProfileAPICall(business_id); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + } + + void successPopUp(String message) { + showDialog( + context: context, + builder: (context) { + return MIHSuccessMessage( + successType: "Success", + successMessage: message, + ); + }, + ); + } + + void emailError() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Invalid Email"); + }, + ); + } + + void internetConnectionPopUp() { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Internet Connection"); + }, + ); + } + + @override + void dispose() { + nameController.dispose(); + typeController.dispose(); + regController.dispose(); + logonameController.dispose(); + fnameController.dispose(); + lnameController.dispose(); + titleController.dispose(); + signtureController.dispose(); + accessController.dispose(); + contactController.dispose(); + emailController.dispose(); + locationController.dispose(); + practiceNoController.dispose(); + vatNoController.dispose(); + _focusNode.dispose(); + super.dispose(); + } + + @override + void initState() { + typeController.addListener(typeSelected); + setState(() { + titleController.text = widget.arguments.businessUser!.title; + fnameController.text = widget.arguments.signedInUser.fname; + lnameController.text = widget.arguments.signedInUser.lname; + signtureController.text = widget.arguments.businessUser!.signature; + titleController.text = widget.arguments.businessUser!.title; + accessController.text = widget.arguments.businessUser!.access; + oldSigPath = widget.arguments.businessUser!.sig_path; + business_id = widget.arguments.business!.business_id; + regController.text = widget.arguments.business!.registration_no; + nameController.text = widget.arguments.business!.Name; + typeController.text = widget.arguments.business!.type; + logonameController.text = widget.arguments.business!.logo_name; + oldLogoPath = widget.arguments.business!.logo_path; + contactController.text = widget.arguments.business!.contact_no; + emailController.text = widget.arguments.business!.bus_email; + locationController.text = widget.arguments.business!.gps_location; + practiceNoController.text = widget.arguments.business!.practice_no; + vatNoController.text = widget.arguments.business!.vat_no; + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), + child: SingleChildScrollView( + child: SafeArea( + child: KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + //print(business_id); + submitForm(business_id); + } + }, + child: Column( + children: [ + Visibility( + visible: isFullAccess(), + child: Column( + children: [ + const Text( + "Business Profile", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + Divider( + color: MzanziInnovationHub.of(context) + ?.theme + .secondaryColor(), + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: regController, + hintText: "Registration No.", + editable: true, + required: true, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: nameController, + hintText: "Business Name", + editable: true, + required: true, + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: typeController, + hintText: "Business Type", + dropdownOptions: const ["Doctors Office", "Other"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + ValueListenableBuilder( + valueListenable: busType, + builder: (BuildContext context, String value, + Widget? child) { + return Visibility( + visible: value == "Doctors Office", + child: MIHTextField( + controller: practiceNoController, + hintText: "Practice Number", + editable: true, + required: true, + ), + ); + }, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: vatNoController, + hintText: "VAT Number", + editable: true, + required: true, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: contactController, + hintText: "Contact Number", + editable: true, + required: true, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: emailController, + hintText: "Email", + editable: true, + required: true, + ), + const SizedBox(height: 10.0), + MIHFileField( + controller: logonameController, + hintText: "Logo", + editable: false, + required: true, + onPressed: () async { + FilePickerResult? result = + await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['jpg', 'png', 'pdf'], + ); + if (result == null) return; + final selectedFile = result.files.first; + setState(() { + selectedLogo = selectedFile; + }); + setState(() { + logonameController.text = selectedFile.name; + }); + }, + ), + const SizedBox(height: 10.0), + Row( + children: [ + Flexible( + child: MIHTextField( + controller: locationController, + hintText: "Location", + editable: false, + required: false, + ), + ), + const SizedBox(width: 10.0), + SizedBox( + width: 80.0, + height: 50.0, + child: MIHButton( + buttonText: "Set", + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + textColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + onTap: () { + MIHLocationAPI() + .getGPSPosition(context) + .then((position) { + if (position != null) { + setState(() { + locationController.text = + "${position.latitude}, ${position.longitude}"; + }); + } + }); + }, + ), + ), + ], + ), + const SizedBox(height: 15.0), + ], + ), + ), + Column( + children: [ + //const SizedBox(height: 15.0), + const Text( + "My Business User", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + Divider( + color: MzanziInnovationHub.of(context) + ?.theme + .secondaryColor(), + ), + const SizedBox(height: 10.0), + MIHDropdownField( + controller: titleController, + hintText: "Title", + dropdownOptions: const ["Doctor", "Assistant"], + required: true, + editable: true, + enableSearch: false, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: fnameController, + hintText: "Name", + editable: false, + required: true, + ), + const SizedBox(height: 10.0), + MIHTextField( + controller: lnameController, + hintText: "Surname", + editable: false, + required: true, + ), + const SizedBox(height: 10.0), + MIHFileField( + controller: signtureController, + hintText: "Signature", + editable: false, + required: true, + onPressed: () async { + FilePickerResult? result = + await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['jpg', 'png', 'pdf'], + ); + if (result == null) return; + final selectedFile = result.files.first; + setState(() { + selectedSignature = selectedFile; + }); + setState(() { + signtureController.text = selectedFile.name; + }); + }, + ), + const SizedBox(height: 15.0), + MIHDropdownField( + controller: accessController, + hintText: "Access", + dropdownOptions: const ["Full", "Partial"], + required: true, + editable: false, + enableSearch: false, + ), + const SizedBox(height: 30.0), + SizedBox( + width: 500.0, + height: 50.0, + child: MIHButton( + buttonText: "Update", + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + textColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + onTap: () { + //print(business_id); + submitForm(business_id); + }, + ), + ), + ], + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_user_search.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_user_search.dart new file mode 100644 index 00000000..f99285f2 --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_business_user_search.dart @@ -0,0 +1,161 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_body.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_profile/business_profile/builders/build_user_list.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class MihBusinessUserSearch extends StatefulWidget { + final BusinessArguments arguments; + const MihBusinessUserSearch({ + super.key, + required this.arguments, + }); + + @override + State createState() => _MihBusinessUserSearchState(); +} + +class _MihBusinessUserSearchState extends State { + final FocusNode _focusNode = FocusNode(); + final TextEditingController searchController = TextEditingController(); + late Future> userSearchResults; + + String userSearch = ""; + String errorCode = ""; + String errorBody = ""; + + Future> fetchUsers(String search) async { + final response = await http + .get(Uri.parse("${AppEnviroment.baseApiUrl}/users/search/$search")); + errorCode = response.statusCode.toString(); + errorBody = response.body; + if (response.statusCode == 200) { + Iterable l = jsonDecode(response.body); + List users = + List.from(l.map((model) => AppUser.fromJson(model))); + return users; + } else { + throw Exception('failed to load patients'); + } + } + + void submitUserForm() { + if (searchController.text != "") { + setState(() { + userSearch = searchController.text; + userSearchResults = fetchUsers(userSearch); + }); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + } + + Widget displayUserList(List userList) { + if (userList.isNotEmpty) { + return BuildUserList( + users: userList, + arguments: widget.arguments, + ); + } + return Center( + child: Text( + "Enter Username or Email to search", + style: TextStyle( + fontSize: 25, + color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), + textAlign: TextAlign.center, + ), + ); + } + + @override + void initState() { + super.initState(); + userSearchResults = fetchUsers("abc"); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return KeyboardListener( + focusNode: _focusNode, + autofocus: true, + onKeyEvent: (event) async { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + submitUserForm(); + } + }, + child: Column(mainAxisSize: MainAxisSize.max, children: [ + const Text( + "User Search", + style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), + ), + //spacer + Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + MIHSearchField( + controller: searchController, + hintText: "Username or Email Search", + required: true, + editable: true, + onTap: () { + submitUserForm(); + }, + ), + //spacer + const SizedBox(height: 10), + FutureBuilder( + future: userSearchResults, + builder: (context, snapshot) { + //print("patient Liust ${snapshot.data}"); + if (snapshot.connectionState == ConnectionState.waiting) { + return const Mihloadingcircle(); + } else if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + List patientsList; + if (userSearch == "") { + patientsList = []; + } else { + patientsList = snapshot.data!; + //print(patientsList); + } + return displayUserList(patientsList); + } else { + return Center( + child: Text( + "$errorCode: Error pulling Patients Data\n/patients/search/$userSearch\n$errorBody", + style: TextStyle( + fontSize: 25, + color: + MzanziInnovationHub.of(context)!.theme.errorColor()), + textAlign: TextAlign.center, + ), + ); + } + }, + ), + ]), + ); + } +} diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_my_business_team.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_my_business_team.dart new file mode 100644 index 00000000..11b86bbf --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/app_tools/mih_my_business_team.dart @@ -0,0 +1,124 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_body.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/business_employee.dart'; +import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_profile/business_profile/builders/build_employee_list.dart'; +import 'package:flutter/material.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class MihMyBusinessTeam extends StatefulWidget { + final BusinessArguments arguments; + const MihMyBusinessTeam({ + super.key, + required this.arguments, + }); + + @override + State createState() => _MihMyBusinessTeamState(); +} + +class _MihMyBusinessTeamState extends State { + late Future> employeeList; + + String errorCode = ""; + String errorBody = ""; + + Future> fetchEmployees() async { + //print("Patien manager page: $endpoint"); + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/business-user/employees/${widget.arguments.businessUser!.business_id}")); + errorCode = response.statusCode.toString(); + errorBody = response.body; + if (response.statusCode == 200) { + //print("Here1"); + Iterable l = jsonDecode(response.body); + //print("Here2"); + List patientQueue = List.from( + l.map((model) => BusinessEmployee.fromJson(model))); + //print("Here3"); + //print(patientQueue); + return patientQueue; + } else { + throw Exception('failed to load employees'); + } + } + + Widget displayEmployeeList(List employeeList) { + if (employeeList.isNotEmpty) { + return BuildEmployeeList( + employees: employeeList, + arguments: widget.arguments, + ); + } + return Center( + child: Text( + "", + style: TextStyle( + fontSize: 25, + color: MzanziInnovationHub.of(context)!.theme.messageTextColor()), + textAlign: TextAlign.center, + ), + ); + } + + @override + void initState() { + super.initState(); + employeeList = fetchEmployees(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return Column(mainAxisSize: MainAxisSize.max, children: [ + const Text( + "Business Team", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 25, + ), + ), + Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()), + const SizedBox(height: 10), + FutureBuilder( + future: employeeList, + builder: (context, snapshot) { + //print("patient Queue List ${snapshot.hasData}"); + if (snapshot.connectionState == ConnectionState.waiting) { + return const Mihloadingcircle(); + } else if (snapshot.connectionState == ConnectionState.done) { + //List employeeListResults; + // if (searchString == "") { + // patientQueueList = []; + // } else { + + // print(patientQueueList); + // } + + return displayEmployeeList(snapshot.requireData); + } else { + return Center( + child: Text( + "$errorCode: Error pulling Patients Data\n${AppEnviroment.baseApiUrl}/business-user/users/${widget.arguments.businessUser!.business_id}\n$errorBody", + style: TextStyle( + fontSize: 25, + color: MzanziInnovationHub.of(context)!.theme.errorColor()), + textAlign: TextAlign.center, + ), + ); + } + }, + ), + ]); + } +}