diff --git a/.DS_Store b/.DS_Store index ecfa0db1..194e7e80 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart index ebc87c96..351c9e83 100644 --- a/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart +++ b/Frontend/lib/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_banner_ad.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_business_card.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; @@ -165,6 +166,21 @@ class _PackageToolOneState extends State { ], ), const SizedBox(height: 20), + MihBusinessCard( + businessName: "Mzansi Innovation Hub", + cellNumber: "0788300006", + email: "yasien.meth@mzansi-innovation-hub.co.za", + gpsLocation: "-26.1853611, 28.134664", + website: + "https://app.mzansi-innovation-hub.co.za/privacy.html", + ), + const SizedBox(height: 10), + Divider( + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + thickness: 2, + ), + const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart b/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart index b2cb8d47..811dd798 100644 --- a/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart +++ b/Frontend/lib/mih_packages/mih_home/mih_profile_getter.dart @@ -218,7 +218,6 @@ class _MIHProfileGetterState extends State { // ); } -// Dont know icons created by Freepik - Flaticon @override void dispose() { // TODO: implement dispose diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_business_card.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_business_card.dart new file mode 100644 index 00000000..32316654 --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/components/mih_business_card.dart @@ -0,0 +1,425 @@ +import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class MihBusinessCard extends StatefulWidget { + final String businessName; + final String cellNumber; + final String email; + final String gpsLocation; + final String website; + const MihBusinessCard({ + super.key, + required this.businessName, + required this.cellNumber, + required this.email, + required this.gpsLocation, + required this.website, + }); + + @override + State createState() => _MihBusinessCardState(); +} + +class _MihBusinessCardState extends State { + Future _makePhoneCall(String phoneNumber) async { + final Uri url = Uri(scheme: 'tel', path: phoneNumber); + if (await canLaunchUrl(url)) { + await launchUrl(url); + } else { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_rounded, + size: 100, + ), + alertTitle: "Error Making Call", + alertBody: Column( + children: [ + Text( + "Unable to lauch phone to call ${widget.cellNumber}", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.errorColor(), + fontSize: 15, + ), + ), + ], + ), + alertColour: MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }); + } + } + + String? _encodeQueryParameters(Map params) { + return params.entries + .map((MapEntry e) => + '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}') + .join('&'); + } + + Future _launchEmail( + String recipient, String subject, String body) async { + final Uri emailLaunchUri = Uri( + scheme: 'mailto', + path: recipient, + query: _encodeQueryParameters({ + 'subject': subject, + 'body': body, + }), + ); + + if (await canLaunchUrl(emailLaunchUri)) { + await launchUrl(emailLaunchUri); + } else { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_rounded, + size: 100, + ), + alertTitle: "Error Creating Email", + alertBody: Column( + children: [ + Text( + "Unable to lauch email to ${widget.email}", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.errorColor(), + fontSize: 15, + ), + ), + ], + ), + alertColour: MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }); + } + } + + Future _launchGoogleMapsWithUrl({ + required double latitude, + required double longitude, + String? label, + }) async { + final Uri googleMapsUrl = Uri.parse( + 'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude${label != null ? '&query_place_id=' : ''}', + ); + try { + if (await canLaunchUrl(googleMapsUrl)) { + await launchUrl(googleMapsUrl); + } else { + print( + 'Could not launch Google Maps. Make sure the Google Maps app is installed or an internet connection is available.'); + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_rounded, + size: 100, + ), + alertTitle: "Error Creating Maps", + alertBody: Column( + children: [ + Text( + "Unable to lauch maps to ${widget.businessName}", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.errorColor(), + fontSize: 15, + ), + ), + ], + ), + alertColour: + MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }); + } + } catch (e) { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_rounded, + size: 100, + ), + alertTitle: "Error Creating Maps", + alertBody: Column( + children: [ + Text( + "Unable to lauch maps to ${widget.businessName}", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.errorColor(), + fontSize: 15, + ), + ), + ], + ), + alertColour: MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }); + } + } + + Future _launchWebsite(String urlString) async { + final Uri url = Uri.parse(urlString); + try { + if (await canLaunchUrl(url)) { + await launchUrl(url); + } else { + print('Could not launch $urlString'); + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_rounded, + size: 100, + ), + alertTitle: "Error Opening Website", + alertBody: Column( + children: [ + Text( + "Unable to lauch ${widget.businessName}", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.errorColor(), + fontSize: 15, + ), + ), + ], + ), + alertColour: + MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }); + } + } catch (e) { + showDialog( + context: context, + builder: (context) { + return MihPackageAlert( + alertIcon: Icon( + Icons.warning_rounded, + size: 100, + ), + alertTitle: "Error Opening Website", + alertBody: Column( + children: [ + Text( + "Unable to lauch ${widget.businessName}", + style: TextStyle( + color: + MzanziInnovationHub.of(context)!.theme.errorColor(), + fontSize: 15, + ), + ), + ], + ), + alertColour: MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }); + } + } + + Widget _buildContactInfo( + String label, + String subLabel, + IconData icon, + Color? iconColor, + Function()? ontap, + ) { + return Material( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + child: InkWell( + onTap: ontap, + splashColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor() + .withOpacity(0.2), + borderRadius: BorderRadius.circular(15), + child: Padding( + padding: EdgeInsetsGeometry.symmetric( + horizontal: 25, + ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: iconColor, + borderRadius: BorderRadius.circular(15), + ), + padding: const EdgeInsets.all(5.0), + child: Icon( + icon, + size: 35, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + SizedBox(width: 20), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + label, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + height: 1.0, + ), + ), + Text( + subLabel, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w700, + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + borderRadius: BorderRadius.circular(10), + ), + child: Column( + children: [ + const SizedBox(height: 10), + _buildContactInfo( + "Call", + "Give us a quick call.", + Icons.phone, + const Color(0xffaff0b3), + () { + // print("Calling ${widget.cellNumber}"); + _makePhoneCall(widget.cellNumber); + }, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Divider( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + _buildContactInfo( + "Email", + "Send us an email.", + Icons.email, + const Color(0xffdaa2e9), + () { + // print("Emailing ${widget.email}"); + _launchEmail( + widget.email, + "Inquiery about ${widget.businessName}", + "Dear ${widget.businessName},\n\nI would like to inquire about your services.\n\nBest regards,\n", + ); + }, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Divider( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + _buildContactInfo( + "Location", + "Come visit us.", + Icons.location_on, + const Color(0xffe9e8a1), + () { + final latitude = double.parse(widget.gpsLocation.split(',')[0]); + final longitude = double.parse(widget.gpsLocation.split(',')[1]); + _launchGoogleMapsWithUrl( + latitude: latitude, + longitude: longitude, + ); + }, + ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 10.0), + // child: Divider( + // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // ), + // _buildContactInfo( + // "Website", + // "Find out more about us.", + // Icons.vpn_lock, + // const Color(0xffd67d8a), + // () { + // _launchWebsite(widget.website); + // }, + // ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 10.0), + // child: Divider( + // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // ), + // _buildContactInfo( + // "Rate Us", + // "Let us know how we are doing.", + // Icons.star_rate_rounded, + // const Color(0xffd69d7d), + // () { + // print("Opeining rating dialog"); + // // _launchWebsite(widget.website); + // }, + // ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 10.0), + // child: Divider( + // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // ), + // _buildContactInfo( + // "Bookmark", + // "Save us for later.", + // Icons.bookmark_add_rounded, + // const Color(0xff6e7dcc), + // () { + // // _launchWebsite(widget.website); + // print("Saving ${widget.businessName} to Directory"); + // }, + // ), + const SizedBox(height: 10), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 10.0), + // child: Divider( + // color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // ), + ], + ), + ); + } +} diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart index 0968ce61..a0e0bcf2 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart @@ -1,6 +1,10 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_business_card.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; @@ -49,7 +53,7 @@ class _MihBusinessDetailsState extends State { Future submitForm() async { if (isFormFilled()) { int statusCode = 0; - statusCode = await MihBusinessDetailsApi().updateBusinessDetails( + statusCode = await MihBusinessDetailsServices().updateBusinessDetails( widget.arguments.business!.business_id, nameController.text, typeController.text, @@ -185,6 +189,259 @@ class _MihBusinessDetailsState extends State { } } + void editBizProfileWindow(double width) { + showDialog( + context: context, + builder: (context) => MihPackageWindow( + fullscreen: false, + windowTitle: 'Edit Profile', + onWindowTapClose: () { + Navigator.of(context).pop(); + }, + windowBody: MihSingleChildScroll( + child: Padding( + padding: MzanziInnovationHub.of(context)!.theme.screenType == + "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : EdgeInsets.symmetric(horizontal: width * 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: widget.logoImage, + width: 150, + editable: true, + fileNameController: fileNameController, + userSelectedfile: imageFile, + frameColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + backgroundColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + onChange: (selectedfile) { + setState(() { + imageFile = selectedfile; + }); + }, + ), + ), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: fileNameController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 20), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: regController, + multiLineInput: false, + requiredText: true, + hintText: "Registration No.", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: nameController, + multiLineInput: false, + requiredText: true, + hintText: "Business Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 15), + MihDropdownField( + controller: typeController, + hintText: "Business Type", + dropdownOptions: const ["Doctors Office", "Other"], + editable: true, + enableSearch: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + requiredText: true, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: practiceNoController, + multiLineInput: false, + requiredText: + typeController.text == "Doctors Office", + hintText: "Practice Number", + validator: (validateValue) { + return MihValidationServices() + .isEmpty(validateValue); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: vatNoController, + multiLineInput: false, + requiredText: true, + hintText: "VAT Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: contactController, + multiLineInput: false, + requiredText: true, + hintText: "Contact Number", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: emailController, + multiLineInput: false, + requiredText: true, + hintText: "Business Email", + validator: (value) { + return MihValidationServices() + .validateEmail(value); + }, + ), + const SizedBox(height: 10), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + controller: locationController, + multiLineInput: false, + requiredText: true, + hintText: "GPS Location", + ), + ), + const SizedBox(width: 10.0), + MihButton( + onPressed: () { + MIHLocationAPI() + .getGPSPosition(context) + .then((position) { + if (position != null) { + setState(() { + locationController.text = + "${position.latitude}, ${position.longitude}"; + }); + } + }); + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + width: 100, + child: Text( + "Set", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 25), + Center( + child: MihButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + submitForm(); + } else { + MihAlertServices() + .formNotFilledCompletely(context); + } + }, + buttonColor: MzanziInnovationHub.of(context)! + .theme + .successColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(height: 20), + ], + ), + ], + ), + ), + ), + )); + } + @override void dispose() { super.dispose(); @@ -233,178 +490,84 @@ class _MihBusinessDetailsState extends State { } Widget getBody(double width, BuildContext context) { - return MihSingleChildScroll( - child: Padding( - padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" - ? EdgeInsets.symmetric(horizontal: width * 0.2) - : EdgeInsets.symmetric(horizontal: width * 0.075), - child: Column( - children: [ - MihForm( - formKey: _formKey, - formFields: [ - Center( - child: MihCircleAvatar( - imageFile: widget.logoImage, - width: 150, - editable: true, - fileNameController: fileNameController, - userSelectedfile: imageFile, - frameColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - backgroundColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (selectedfile) { - setState(() { - imageFile = selectedfile; - }); - }, - ), - ), - Visibility( - visible: false, - child: MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fileNameController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Selected File Name", - ), - ), - const SizedBox(height: 20), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: regController, - multiLineInput: false, - requiredText: true, - hintText: "Registration No.", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: nameController, - multiLineInput: false, - requiredText: true, - hintText: "Business Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 15), - MihDropdownField( - controller: typeController, - hintText: "Business Type", - dropdownOptions: const ["Doctors Office", "Other"], - editable: true, - enableSearch: true, - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - requiredText: true, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: practiceNoController, - multiLineInput: false, - requiredText: typeController.text == "Doctors Office", - hintText: "Practice Number", - validator: (validateValue) { - return MihValidationServices().isEmpty(validateValue); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: vatNoController, - multiLineInput: false, - requiredText: true, - hintText: "VAT Number", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: contactController, - multiLineInput: false, - requiredText: true, - hintText: "Contact Number", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: emailController, - multiLineInput: false, - requiredText: true, - hintText: "Business Email", - validator: (value) { - return MihValidationServices().validateEmail(value); - }, - ), - const SizedBox(height: 10), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Flexible( - child: MihTextFormField( - fillColor: MzanziInnovationHub.of(context)! - .theme - .secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: locationController, - multiLineInput: false, - requiredText: true, - hintText: "GPS Location", - ), - ), - const SizedBox(width: 10.0), - MihButton( - onPressed: () { - MIHLocationAPI().getGPSPosition(context).then((position) { - if (position != null) { - setState(() { - locationController.text = - "${position.latitude}, ${position.longitude}"; - }); - } + return Stack( + children: [ + MihSingleChildScroll( + child: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + children: [ + Center( + child: MihCircleAvatar( + imageFile: widget.logoImage, + width: 150, + editable: false, + fileNameController: fileNameController, + userSelectedfile: imageFile, + frameColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (selectedfile) { + setState(() { + imageFile = selectedfile; }); }, + ), + ), + FittedBox( + child: Text( + widget.arguments.business!.Name, + style: TextStyle( + fontSize: 35, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ), + // Center( + // child: Text( + // "*DEMO TEXT* This would be the bio of the user telling us a bit about themself and let. This would be the bio of the user telling us a bit about themself and let. This would be the bio of the user telling us a bit about themself", + // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 15, + // fontWeight: FontWeight.bold, + // color: MzanziInnovationHub.of(context)! + // .theme + // .secondaryColor(), + // ), + // ), + // ), + const SizedBox(height: 20), + SizedBox( + width: 700, + child: MihBusinessCard( + businessName: widget.arguments.business!.Name, + cellNumber: widget.arguments.business!.contact_no, + email: widget.arguments.business!.bus_email, + gpsLocation: widget.arguments.business!.gps_location, + //To-Do: Add the business Website + website: + "https://app.mzansi-innovation-hub.co.za/privacy.html", + ), + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + // Connect with the user + editBizProfileWindow(width); + }, buttonColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - width: 100, + MzanziInnovationHub.of(context)!.theme.successColor(), + width: 300, child: Text( - "Set", + "Edit Profile", style: TextStyle( color: MzanziInnovationHub.of(context)! .theme @@ -414,37 +577,39 @@ class _MihBusinessDetailsState extends State { ), ), ), - ], - ), - const SizedBox(height: 25), - Center( - child: MihButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - submitForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } - }, - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - width: 300, - child: Text( - "Update", - style: TextStyle( - color: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), ), - ), - const SizedBox(height: 20), + ], + ), + ), + ), + Positioned( + right: 5, + bottom: 10, + child: MihFloatingMenu( + animatedIcon: AnimatedIcons.menu_close, + children: [ + SpeedDialChild( + child: Icon( + Icons.edit, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + label: "Edit Profile", + labelBackgroundColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + labelStyle: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontWeight: FontWeight.bold, + ), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + onTap: () { + editBizProfileWindow(width); + }, + ) ], ), - ], - ), - )); + ), + ], + ); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart index c3202f75..3116a16c 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart @@ -90,7 +90,7 @@ class _MihMyBusinessUserState extends State { Future submitForm() async { if (isFormFilled()) { - int statusCode = await MihMyBusinessUserApi().updateBusinessUser( + int statusCode = await MihMyBusinessUserServices().updateBusinessUser( widget.arguments.signedInUser.app_id, widget.arguments.businessUser!.business_id, titleDropdownController.text, diff --git a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart index fd0840d8..bea0eeff 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/business_profile/profile_business_add.dart @@ -86,7 +86,7 @@ class _ProfileBusinessAddState extends State { Future createBusinessUserAPICall(String business_id) async { print("Inside create bus user method"); - int statusCode = await MihMyBusinessUserApi().createBusinessUser( + int statusCode = await MihMyBusinessUserServices().createBusinessUser( business_id, widget.signedInUser.app_id, signtureController.text, @@ -111,7 +111,8 @@ class _ProfileBusinessAddState extends State { Future createBusinessProfileAPICall() async { print("Inside create business profile method"); - Response response = await MihBusinessDetailsApi().createBusinessDetails( + Response response = + await MihBusinessDetailsServices().createBusinessDetails( widget.signedInUser.app_id, nameController.text, typeController.text, diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index 5ef3261b..bbff0a47 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -1,6 +1,7 @@ -import 'dart:convert'; - +import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart'; @@ -19,7 +20,6 @@ import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/http.dart' as http; class MihPersonalProfile extends StatefulWidget { final AppProfileUpdateArguments arguments; @@ -70,8 +70,8 @@ class _MihPersonalProfileState extends State { Future submitForm() async { // print("============\nsubmiit form\n================="); if (widget.arguments.signedInUser.username != usernameController.text) { - bool isUsernameUnique = - await MihUserApis.isUsernameUnique(usernameController.text, context); + bool isUsernameUnique = await MihUserServices.isUsernameUnique( + usernameController.text, context); print("isUsernameUnique: $isUsernameUnique"); if (isUsernameUnique == false) { notUniqueAlert(); @@ -112,49 +112,30 @@ class _MihPersonalProfileState extends State { } Future updateUserApiCall() async { - var fname = proPicController.text.replaceAll(RegExp(r' '), '-'); - var filePath = - "${widget.arguments.signedInUser.app_id}/profile_files/$fname"; - var profileType; - if (businessUser) { - profileType = "business"; - } else { - profileType = "personal"; - } - if (isUsernameValid(usernameController.text) == false) { - usernamePopUp(); - } else { - var response = await http.put( - Uri.parse("${AppEnviroment.baseApiUrl}/user/update/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "idusers": widget.arguments.signedInUser.idUser, - "username": usernameController.text, - "fnam": fnameController.text, - "lname": lnameController.text, - "type": profileType, - "pro_pic_path": filePath, - }), + int responseCode = await MihUserServices().updateUser( + widget.arguments.signedInUser, + fnameController.text, + lnameController.text, + usernameController.text, + proPicController.text, + businessUser, + context, + ); + if (responseCode == 200) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/', + arguments: AuthArguments( + true, + false, + ), ); - //print("Here4"); - //print(response.statusCode); - if (response.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - '/', - arguments: AuthArguments( - true, - false, - ), - ); - String message = "Your information has been updated successfully!"; - successPopUp(message); - } else { - internetConnectionPopUp(); - } + String message = "Your information has been updated successfully!"; + successPopUp(message); + } else { + internetConnectionPopUp(); } } @@ -203,6 +184,152 @@ class _MihPersonalProfileState extends State { ); } + void editProfileWindow(double width) { + showDialog( + context: context, + builder: (context) => MihPackageWindow( + fullscreen: false, + windowTitle: "Edit Profile", + onWindowTapClose: () { + Navigator.of(context).pop(); + }, + windowBody: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.05) + : EdgeInsets.symmetric(horizontal: width * 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + MihForm( + formKey: _formKey, + formFields: [ + Center( + child: MihCircleAvatar( + imageFile: propicPreview, + width: 150, + editable: true, + fileNameController: proPicController, + userSelectedfile: proPic, + frameColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (selectedImage) { + setState(() { + proPic = selectedImage; + }); + }, + ), + ), + // const SizedBox(height: 25.0), + Visibility( + visible: false, + child: MihTextFormField( + fillColor: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: proPicController, + multiLineInput: false, + requiredText: true, + readOnly: true, + hintText: "Selected File Name", + ), + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: usernameController, + multiLineInput: false, + requiredText: true, + hintText: "Username", + validator: (value) { + return MihValidationServices().validateUsername(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: fnameController, + multiLineInput: false, + requiredText: true, + hintText: "First Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihTextFormField( + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + controller: lnameController, + multiLineInput: false, + requiredText: true, + hintText: "Last Name", + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 10.0), + MihToggle( + hintText: "Activate Business Account", + initialPostion: businessUser, + fillColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + secondaryFillColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onChange: (value) { + setState(() { + businessUser = value; + }); + }, + ), + const SizedBox(height: 30.0), + Center( + child: MihButton( + onPressed: () { + //Add validation here + if (_formKey.currentState!.validate()) { + submitForm(); + } else { + MihAlertServices().formNotFilledCompletely(context); + } + }, + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MzanziInnovationHub.of(context)! + .theme + .primaryColor(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ], + ), + ), + ), + ); + } + @override void dispose() { proPicController.dispose(); @@ -246,22 +373,22 @@ class _MihPersonalProfileState extends State { } Widget getBody(double width) { - return MihSingleChildScroll( - child: Padding( - padding: MzanziInnovationHub.of(context)!.theme.screenType == "desktop" - ? EdgeInsets.symmetric(horizontal: width * 0.2) - : EdgeInsets.symmetric(horizontal: width * 0.075), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - MihForm( - formKey: _formKey, - formFields: [ + return Stack( + children: [ + MihSingleChildScroll( + child: Padding( + padding: + MzanziInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0.075), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ Center( child: MihCircleAvatar( imageFile: propicPreview, width: 150, - editable: true, + editable: false, fileNameController: proPicController, userSelectedfile: proPic, frameColor: @@ -275,117 +402,68 @@ class _MihPersonalProfileState extends State { }, ), ), - const SizedBox(height: 25.0), - Visibility( - visible: false, - child: MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: proPicController, - multiLineInput: false, - requiredText: true, - readOnly: true, - hintText: "Selected File Name", + FittedBox( + child: Text( + "@${widget.arguments.signedInUser.username}", + style: TextStyle( + fontSize: 35, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), ), ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: usernameController, - multiLineInput: false, - requiredText: true, - hintText: "Username", - validator: (value) { - return MihValidationServices().validateUsername(value); - }, + FittedBox( + child: Text( + "${widget.arguments.signedInUser.fname} ${widget.arguments.signedInUser.lname}", + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: fnameController, - multiLineInput: false, - requiredText: true, - hintText: "First Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, + FittedBox( + child: Text( + businessUser ? "Business" : "Personal", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), ), - const SizedBox(height: 10.0), - MihTextFormField( - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - inputColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - controller: lnameController, - multiLineInput: false, - requiredText: true, - hintText: "Last Name", - validator: (value) { - return MihValidationServices().isEmpty(value); - }, - ), - const SizedBox(height: 10.0), - MihToggle( - hintText: "Activate Business Account", - initialPostion: businessUser, - fillColor: - MzanziInnovationHub.of(context)!.theme.secondaryColor(), - secondaryFillColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - onChange: (value) { - setState(() { - businessUser = value; - }); - }, - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.start, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // const Text( - // "Activate Business Account", - // style: TextStyle( - // fontWeight: FontWeight.bold, - // fontSize: 20, - // ), + // const SizedBox(height: 10.0), + // Center( + // child: Text( + // "*DEMO TEXT* This would be the bio of the user telling us a bit about themself and let. This would be the bio of the user telling us a bit about themself and let. This would be the bio of the user telling us a bit about themself", + // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 15, + // fontWeight: FontWeight.bold, + // color: MzanziInnovationHub.of(context)! + // .theme + // .secondaryColor(), // ), - // const SizedBox( - // width: 10, - // ), - // Switch( - // value: businessUser, - // onChanged: (bool value) { - // setState(() { - // businessUser = value; - // }); - // }, - // ), - // ], + // ), // ), const SizedBox(height: 30.0), Center( child: MihButton( onPressed: () { - //Add validation here - if (_formKey.currentState!.validate()) { - submitForm(); - } else { - MihAlertServices().formNotFilledCompletely(context); - } + // Connect with the user + editProfileWindow(width); }, buttonColor: MzanziInnovationHub.of(context)!.theme.successColor(), width: 300, child: Text( - "Update", + "Edit Profile", style: TextStyle( color: MzanziInnovationHub.of(context)! .theme @@ -398,9 +476,36 @@ class _MihPersonalProfileState extends State { ), ], ), - ], + ), ), - ), + Positioned( + right: 5, + bottom: 10, + child: MihFloatingMenu( + animatedIcon: AnimatedIcons.menu_close, + children: [ + SpeedDialChild( + child: Icon( + Icons.edit, + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + label: "Edit Profile", + labelBackgroundColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + labelStyle: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontWeight: FontWeight.bold, + ), + backgroundColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + onTap: () { + editProfileWindow(width); + }, + ) + ], + ), + ), + ], ); } } diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart index c1956931..5b07cc0a 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_settings.dart @@ -61,7 +61,7 @@ class _MihPersonalSettingsState extends State { children: [ MihButton( onPressed: () { - MihUserApis.deleteAccount( + MihUserServices.deleteAccount( widget.signedInUser.app_id, context); }, buttonColor: diff --git a/Frontend/lib/mih_services/mih_business_details_services.dart b/Frontend/lib/mih_services/mih_business_details_services.dart index 0281bdfb..2ca27ed4 100644 --- a/Frontend/lib/mih_services/mih_business_details_services.dart +++ b/Frontend/lib/mih_services/mih_business_details_services.dart @@ -1,13 +1,32 @@ import 'dart:convert'; import 'package:http/http.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:flutter/material.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:supertokens_flutter/http.dart' as http; -class MihBusinessDetailsApi { +class MihBusinessDetailsServices { + Future getBusinessDetails( + String app_id, + ) async { + var response = await http.get( + Uri.parse("${AppEnviroment.baseApiUrl}/business/app_id/$app_id"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + ); + if (response.statusCode == 200) { + String body = response.body; + var jsonBody = jsonDecode(body); + return Business.fromJson(jsonBody); + } else { + return null; + } + } + Future createBusinessDetails( String appId, String busineName, diff --git a/Frontend/lib/mih_services/mih_my_business_user_services.dart b/Frontend/lib/mih_services/mih_my_business_user_services.dart index 9d758bed..e1481493 100644 --- a/Frontend/lib/mih_services/mih_my_business_user_services.dart +++ b/Frontend/lib/mih_services/mih_my_business_user_services.dart @@ -1,12 +1,28 @@ import 'dart:convert'; - +import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:flutter/material.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:supertokens_flutter/http.dart' as http; -class MihMyBusinessUserApi { +class MihMyBusinessUserServices { + Future getBusinessUser( + String app_id, + ) async { + var response = await http.get( + Uri.parse("${AppEnviroment.baseApiUrl}/business-user/$app_id"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + ); + if (response.statusCode == 200) { + return BusinessUser.fromJson(jsonDecode(response.body)); + } else { + return null; + } + } + Future createBusinessUser( String business_id, String app_id, diff --git a/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart b/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart index dad3dbb3..acbdf2a1 100644 --- a/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart +++ b/Frontend/lib/mih_services/mih_mzansi_wallet_services.dart @@ -5,17 +5,6 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart' import 'package:mzansi_innovation_hub/mih_components/mih_objects/loyalty_card.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:flutter/material.dart'; -// import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; -// import '../mih_components/mih_pop_up_messages/mih_success_message.dart'; -// import '../mih_env/mih_env.dart'; -// import '../mih_objects/app_user.dart'; -// import '../mih_objects/arguments.dart'; -// import '../mih_objects/business.dart'; -// import '../mih_objects/business_user.dart'; -// import '../mih_objects/notification.dart'; -// import '../mih_objects/patient_access.dart'; -// import '../mih_objects/patient_queue.dart'; -// import '../mih_objects/patients.dart'; import 'package:supertokens_flutter/http.dart' as http; import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; diff --git a/Frontend/lib/mih_services/mih_notification_services.dart b/Frontend/lib/mih_services/mih_notification_services.dart index 00298801..c58bca6f 100644 --- a/Frontend/lib/mih_services/mih_notification_services.dart +++ b/Frontend/lib/mih_services/mih_notification_services.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/notification.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_success_message.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; @@ -11,6 +12,23 @@ class MihNotificationApis { final baseAPI = AppEnviroment.baseApiUrl; //================== Notifications ========================================================================== + Future> getNotificationByUser( + String app_id, + int notificationAmount, + ) async { + var responseNotification = await http.get( + Uri.parse("$baseAPI/notifications/$app_id?amount=$notificationAmount")); + if (responseNotification.statusCode == 200) { + String body = responseNotification.body; + Iterable l = jsonDecode(body); + List notifications = List.from( + l.map((model) => MIHNotification.fromJson(model))); + return notifications; + } else { + return []; + } + } + /// This function is used to create notification to patient for access reviews /// /// Patameters:- diff --git a/Frontend/lib/mih_services/mih_patient_services.dart b/Frontend/lib/mih_services/mih_patient_services.dart new file mode 100644 index 00000000..b57e89f2 --- /dev/null +++ b/Frontend/lib/mih_services/mih_patient_services.dart @@ -0,0 +1,27 @@ +import 'dart:convert'; + +import 'package:mzansi_innovation_hub/mih_components/mih_objects/patients.dart'; +import 'package:mzansi_innovation_hub/mih_config/mih_env.dart'; +import 'package:supertokens_flutter/http.dart' as http; + +class MihPatientServices { + final baseAPI = AppEnviroment.baseApiUrl; + + Future getPatientDetails( + String appId, + ) async { + var response = await http.get( + Uri.parse("${AppEnviroment.baseApiUrl}/patient/app_id/$appId"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + ); + if (response.statusCode == 200) { + String body = response.body; + var jsonBody = jsonDecode(body); + return Patient.fromJson(jsonBody); + } else { + return null; + } + } +} diff --git a/Frontend/lib/mih_services/mih_service_calls.dart b/Frontend/lib/mih_services/mih_service_calls.dart index 4a7da538..a1b701cc 100644 --- a/Frontend/lib/mih_services/mih_service_calls.dart +++ b/Frontend/lib/mih_services/mih_service_calls.dart @@ -1,8 +1,12 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_my_business_user_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_notification_services.dart'; import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_patient_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart'; // import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; // import '../mih_components/mih_pop_up_messages/mih_success_message.dart'; // import '../mih_env/mih_env.dart'; @@ -57,38 +61,27 @@ class MIHApiCalls { // Get Userdata var uid = await SuperTokens.getUserId(); - var responseUser = await http.get(Uri.parse("$baseAPI/user/$uid")); - if (responseUser.statusCode == 200) { - // print("here"); - String body = responseUser.body; - var decodedData = jsonDecode(body); - AppUser u = AppUser.fromJson(decodedData); - userData = u; + AppUser? user = await MihUserServices().getUserDetails(uid, context); + if (user != null) { + userData = user; } else { - throw Exception( - "Error: GetUserData status code ${responseUser.statusCode}"); + throw Exception("Error: GetUserData returned null"); } // Get BusinessUserdata - var responseBUser = await http.get( - Uri.parse("$baseAPI/business-user/$uid"), - ); - if (responseBUser.statusCode == 200) { - String body = responseBUser.body; - var decodedData = jsonDecode(body); - BusinessUser business_User = BusinessUser.fromJson(decodedData); - bUserData = business_User; + BusinessUser? businessUser = + await MihMyBusinessUserServices().getBusinessUser(uid); + if (businessUser != null) { + bUserData = businessUser; } else { bUserData = null; } // Get Businessdata - var responseBusiness = - await http.get(Uri.parse("$baseAPI/business/app_id/$uid")); - if (responseBusiness.statusCode == 200) { - String body = responseBusiness.body; - var decodedData = jsonDecode(body); - Business business = Business.fromJson(decodedData); + Business? business = await MihBusinessDetailsServices().getBusinessDetails( + uid, + ); + if (business != null) { busData = business; } else { busData = null; @@ -97,76 +90,31 @@ class MIHApiCalls { //get profile picture if (userData.pro_pic_path == "") { userPic = ""; - } - // else if (AppEnviroment.getEnv() == "Dev") { - // userPic = "${AppEnviroment.baseFileUrl}/mih/${userData.pro_pic_path}"; - // } - else { + } else { userPic = await MihFileApi.getMinioFileUrl(userData.pro_pic_path, context); } //Get Notifications - var responseNotification = await http.get( - Uri.parse("$baseAPI/notifications/$uid?amount=$notificationAmount")); - if (responseNotification.statusCode == 200) { - String body = responseNotification.body; - // var decodedData = jsonDecode(body); - // MIHNotification notifications = MIHNotification.fromJson(decodedData); - - Iterable l = jsonDecode(body); - //print("Here2"); - List notifications = List.from( - l.map((model) => MIHNotification.fromJson(model))); - notifi = notifications; - } else { - notifi = []; - } + notifi = await MihNotificationApis().getNotificationByUser( + uid, + notificationAmount, + ); //get patient profile - //print("Patien manager page: $endpoint"); - final response = await http.get( - Uri.parse("${AppEnviroment.baseApiUrl}/patients/${userData.app_id}")); - // print("Here"); - // print("Body: ${response.body}"); - // print("Code: ${response.statusCode}"); - // var errorCode = response.statusCode.toString(); - // var errorBody = response.body; - - if (response.statusCode == 200) { - // print("Here1"); - var decodedData = jsonDecode(response.body); - // print("Here2"); - Patient patients = Patient.fromJson(decodedData as Map); - // print("Here3"); - // print(patients); - patientData = patients; + Patient? patient = await MihPatientServices().getPatientDetails( + uid, + ); + if (patient != null) { + patientData = patient; } else { patientData = null; } - //print(userPic); + return HomeArguments( userData, bUserData, busData, patientData, notifi, userPic); } - /// This function is used to get business details by business _id. - /// - /// Patameters: String business_id & app_id (app_id of patient). - /// - /// Returns List (List of access that match the above parameters). - static Future getBusinessDetails(String business_id) async { - var responseBusiness = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/business/business_id/$business_id")); - if (responseBusiness.statusCode == 200) { - String body = responseBusiness.body; - var decodedData = jsonDecode(body); - Business business = Business.fromJson(decodedData); - return business; - } else { - return null; - } - } - //================== BUSINESS PATIENT/PERSONAL ACCESS ========================================================================== /// This function is used to check if a business has access to a specific patients profile. diff --git a/Frontend/lib/mih_services/mih_user_services.dart b/Frontend/lib/mih_services/mih_user_services.dart index 9f016198..a0c7b8d6 100644 --- a/Frontend/lib/mih_services/mih_user_services.dart +++ b/Frontend/lib/mih_services/mih_user_services.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.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'; @@ -9,7 +10,7 @@ import 'package:flutter/material.dart'; import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/supertokens.dart'; -class MihUserApis { +class MihUserServices { final baseAPI = AppEnviroment.baseApiUrl; static Future isUsernameUnique( @@ -29,6 +30,65 @@ class MihUserApis { } } + Future getUserDetails( + String app_id, + BuildContext context, + ) async { + var response = await http.get( + Uri.parse("${AppEnviroment.baseApiUrl}/user/$app_id"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + ); + + if (response.statusCode == 200) { + String body = response.body; + var jsonBody = jsonDecode(body); + return AppUser.fromJson(jsonBody); + } else { + return null; + } + } + + Future updateUser( + AppUser signedInUser, + String firstName, + String lastName, + String username, + String profilePicture, + bool isBusinessUser, + BuildContext context, + ) async { + var fileName = profilePicture.replaceAll(RegExp(r' '), '-'); + var filePath = + "${signedInUser.app_id}/profile_files/$fileName"; + String profileType; + if (isBusinessUser) { + profileType = "business"; + } else { + profileType = "personal"; + } + var response = await http.put( + Uri.parse("${AppEnviroment.baseApiUrl}/user/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "idusers": signedInUser.idUser, + "username": username, + "fnam": firstName, + "lname": lastName, + "type": profileType, + "pro_pic_path": filePath, + }), + ); + if (response.statusCode == 200) { + return response.statusCode; + } else { + return response.statusCode; + } + } + static Future deleteAccount( String app_id, BuildContext context, diff --git a/docker-compose.yml b/docker-compose.yml index 6d7b5819..2be023d5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -169,14 +169,14 @@ services: networks: - MIH-network # === Added section for NVIDIA GPU acceleration === - runtime: nvidia - deploy: - resources: - reservations: - devices: - - driver: nvidia - count: all # or specify a number of GPUs - capabilities: [ gpu ] + # runtime: nvidia + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: all # or specify a number of GPUs + # capabilities: [ gpu ] #============== Firebaase ==================================================================== # firebase: # container_name: MIH-firebase-emulator