diff --git a/mih_ui/lib/mih_package_components/mih_business_info_card_v2.dart b/mih_ui/lib/mih_package_components/mih_business_info_card_v2.dart index f4ddf222..2541c0b8 100644 --- a/mih_ui/lib/mih_package_components/mih_business_info_card_v2.dart +++ b/mih_ui/lib/mih_package_components/mih_business_info_card_v2.dart @@ -21,10 +21,12 @@ import 'package:url_launcher/url_launcher.dart'; class MihBusinessCardV2 extends StatefulWidget { final Business business; final double width; + final bool viewMode; const MihBusinessCardV2({ super.key, required this.business, required this.width, + required this.viewMode, }); @override @@ -190,8 +192,8 @@ class _MihBusinessCardV2State extends State { Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () { _makePhoneCall(widget.business.contact_no); }, @@ -218,8 +220,8 @@ class _MihBusinessCardV2State extends State { Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () { _launchEmail( widget.business.bus_email, @@ -251,8 +253,8 @@ class _MihBusinessCardV2State extends State { Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () { final latitude = double.parse( widget.business.gps_location.split(',')[0]); @@ -288,8 +290,8 @@ class _MihBusinessCardV2State extends State { Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () { _launchWebsite(widget.business.website); }, @@ -320,8 +322,8 @@ class _MihBusinessCardV2State extends State { return Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () {}, buttonColor: MihColors.grey(), child: Icon( @@ -354,8 +356,8 @@ class _MihBusinessCardV2State extends State { return Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () { businessReviewRatingWindow(directoryProvider, businessReview, true, widget.width); @@ -390,8 +392,8 @@ class _MihBusinessCardV2State extends State { return Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () {}, buttonColor: MihColors.grey(), child: Icon( @@ -424,8 +426,8 @@ class _MihBusinessCardV2State extends State { return Column( children: [ MihButton( - width: 80, - height: 80, + width: 70, + height: 70, onPressed: () { if (bookmarkBusiness == null) { showAddBookmarkAlert(); @@ -458,6 +460,39 @@ class _MihBusinessCardV2State extends State { } }, ), + Column( + children: [ + MihButton( + width: 70, + height: 70, + onPressed: () { + // _makePhoneCall(widget.business.contact_no); + if (!widget.viewMode) { + profileProvider.setBusinessIndex(5); + } else { + directoryProvider.setBusinessViewIndex(2); + } + }, + buttonColor: MihColors.secondary(), + child: Icon( + MihIcons.link, + color: MihColors.primary(), + size: iconSize, + ), + ), + const SizedBox(height: 2), + FittedBox( + child: Text( + "Links", + style: TextStyle( + fontWeight: FontWeight.bold, + color: MihColors.secondary(), + fontSize: 20, + ), + ), + ), + ], + ), ], ); }, diff --git a/mih_ui/lib/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart b/mih_ui/lib/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart index 596fc160..05e878da 100644 --- a/mih_ui/lib/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart +++ b/mih_ui/lib/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart @@ -76,9 +76,7 @@ class _MihSearchMzansiState extends State { Map> userImages = {}; Future usernProPicUrl; for (var user in userResults) { - KenLogger.success("Business Logo Path: ${user.pro_pic_path}"); usernProPicUrl = MihFileApi.getMinioFileUrl(user.pro_pic_path); - KenLogger.success("Business Logo Path: ${user.pro_pic_path}"); userImages[user.app_id] = usernProPicUrl; // != "" // ? CachedNetworkImageProvider(usernProPicUrl) @@ -103,9 +101,7 @@ class _MihSearchMzansiState extends State { Map> busImagesUrl = {}; Future businessLogoUrl; for (var bus in businessSearchResults) { - KenLogger.success("Business Logo Path: ${bus.logo_path}"); businessLogoUrl = MihFileApi.getMinioFileUrl(bus.logo_path); - KenLogger.success("Business Logo Path: ${bus.logo_path}"); busImagesUrl[bus.business_id] = businessLogoUrl; // != "" // ? CachedNetworkImageProvider(businessLogoUrl) diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/busines_profile.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/busines_profile.dart index 8360aca3..c13e079c 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/busines_profile.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/busines_profile.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:mih_package_toolkit/mih_package_toolkit.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_links.dart'; import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart'; @@ -10,6 +11,7 @@ import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profi import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_my_business_user.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_employee_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_data_helper_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_profile_links_service.dart'; import 'package:provider/provider.dart'; class BusinesProfile extends StatefulWidget { @@ -27,6 +29,7 @@ class _BusinesProfileState extends State { late final MihBusinessUserSearch _businessUserSearch; late final MihBusinessReviews _businessReviews; late final MihBusinessQrCode _businessQrCode; + late final MihBusinessLinks _businessLinks; Future _loadInitialData() async { setState(() { @@ -39,6 +42,8 @@ class _BusinesProfileState extends State { mzansiProfileProvider, ); } + await MihProfileLinksServices.getBusinessProfileLinks( + mzansiProfileProvider, mzansiProfileProvider.business!.business_id); await MihBusinessEmployeeServices() .fetchEmployees(mzansiProfileProvider, context); setState(() { @@ -54,6 +59,7 @@ class _BusinesProfileState extends State { _businessTeam = MihMyBusinessTeam(); _businessUserSearch = MihBusinessUserSearch(); _businessReviews = MihBusinessReviews(business: null); + _businessLinks = MihBusinessLinks(viewMode: false); _businessQrCode = MihBusinessQrCode(business: null); _loadInitialData(); } @@ -122,9 +128,12 @@ class _BusinesProfileState extends State { temp[const Icon(Icons.star_rate_rounded)] = () { context.read().setBusinessIndex(4); }; - temp[const Icon(Icons.qr_code_rounded)] = () { + temp[const Icon(Icons.link)] = () { context.read().setBusinessIndex(5); }; + temp[const Icon(Icons.qr_code_rounded)] = () { + context.read().setBusinessIndex(6); + }; return MihPackageTools( tools: temp, selectedIndex: context.watch().businessIndex, @@ -138,6 +147,7 @@ class _BusinesProfileState extends State { "Team", "Add", "Reviews", + "Links", "Share", ]; return toolTitles; @@ -150,6 +160,7 @@ class _BusinesProfileState extends State { _businessTeam, _businessUserSearch, _businessReviews, + _businessLinks, _businessQrCode, ]; } diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_add_business_link_window.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_add_business_link_window.dart new file mode 100644 index 00000000..a74f79c9 --- /dev/null +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_add_business_link_window.dart @@ -0,0 +1,185 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.dart'; +import 'package:mih_package_toolkit/mih_package_toolkit.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_profile_links_service.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; +import 'package:provider/provider.dart'; + +class MihAddBusinessLinkWindow extends StatefulWidget { + const MihAddBusinessLinkWindow({super.key}); + + @override + State createState() => + _MihAddBusinessLinkWindowState(); +} + +class _MihAddBusinessLinkWindowState extends State { + final _formKey = GlobalKey(); + List _dropdowOptions = [ + "YouTube", + "TikTok", + "Twitch", + "Threads", + "WhatsApp", + "Instagram", + "X", + "LinkedIn", + "Facebook", + "Reddit", + "Discord", + "Git", + "Telegram", + "Pinterest", + "Snapchat", + "Messenger", + "Medium", + "Substack", + "Spotify", + "YT Music", + "Apple Music", + "Patreon", + "Loolio", + "WeChat", + "Other" + ]; + TextEditingController _dropdownLinkNameController = TextEditingController(); + TextEditingController _linkNameController = TextEditingController(); + TextEditingController _destinationController = TextEditingController(); + + void successPopUp(String title, String message, int packageIndex) { + MihAlertServices().successBasicAlert( + title, + message, + context, + ); + } + + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + _dropdowOptions.sort(); + bool isOtherSelected = _dropdownLinkNameController.text == "Other"; + return Consumer( + builder: ( + BuildContext context, + MzansiProfileProvider profileProvider, + Widget? child, + ) { + return MihPackageWindow( + fullscreen: false, + windowTitle: "Add Link", + onWindowTapClose: () { + _dropdownLinkNameController.clear(); + _destinationController.clear(); + _linkNameController.clear(); + Navigator.pop(context); + }, + windowBody: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: screenWidth * 0.05) + : EdgeInsets.symmetric(horizontal: screenWidth * 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihDropdownField( + controller: _dropdownLinkNameController, + hintText: 'Site Name', + dropdownOptions: _dropdowOptions, + requiredText: true, + editable: true, + enableSearch: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + onSelected: (value) { + setState(() {}); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.secondary(), + inputColor: MihColors.primary(), + controller: _linkNameController, + hintText: "Custom Name", + requiredText: isOtherSelected, + validator: (value) { + if (isOtherSelected) { + return MihValidationServices().isEmpty(value); + } + return null; + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.secondary(), + inputColor: MihColors.primary(), + controller: _destinationController, + hintText: "Link", + requiredText: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + MihButton( + onPressed: () async { + if (_formKey.currentState!.validate()) { + MihProfileLinksServices.loadingPopUp(context); + int statusCode = + await MihProfileLinksServices.addProfileLink( + profileProvider, + "", + profileProvider.business!.business_id, + _dropdownLinkNameController.text, + _linkNameController.text, + _destinationController.text, + profileProvider.businessLinks.length + 1, + ); + KenLogger.success("Status COde: $statusCode"); + context.pop(); + if (statusCode == 201) { + await MihProfileLinksServices + .getBusinessProfileLinks( + profileProvider, + profileProvider.business!.business_id, + ); + context.pop(); + successPopUp( + "Profile Link Added", + "You have successfully added a new link to your business", + 0); + } else { + MihAlertServices().internetConnectionAlert(context); + } + } else { + MihAlertServices().inputErrorAlert(context); + } + }, + buttonColor: MihColors.green(), + width: 300, + child: Text( + "Add", + style: TextStyle( + color: MihColors.primary(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_edit_business_link_window.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_edit_business_link_window.dart new file mode 100644 index 00000000..f1cba9d7 --- /dev/null +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_edit_business_link_window.dart @@ -0,0 +1,193 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:mih_package_toolkit/mih_package_toolkit.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; +import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_profile_links_service.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart'; +import 'package:provider/provider.dart'; + +class MihEditBusnessLinkWindow extends StatefulWidget { + final ProfileLink link; + const MihEditBusnessLinkWindow({ + super.key, + required this.link, + }); + + @override + State createState() => + _MihEditBusnessLinkWindowState(); +} + +class _MihEditBusnessLinkWindowState extends State { + final _formKey = GlobalKey(); + List _dropdowOptions = [ + "YouTube", + "TikTok", + "Twitch", + "Threads", + "WhatsApp", + "Instagram", + "X", + "LinkedIn", + "Facebook", + "Reddit", + "Discord", + "Git", + "Telegram", + "Pinterest", + "Snapchat", + "Messenger", + "Medium", + "Substack", + "Spotify", + "YT Music", + "Apple Music", + "Patreon", + "Loolio", + "WeChat", + "Other" + ]; + TextEditingController _dropdownLinkNameController = TextEditingController(); + TextEditingController _linkNameController = TextEditingController(); + TextEditingController _destinationController = TextEditingController(); + + void successPopUp(String title, String message, int packageIndex) { + MihAlertServices().successBasicAlert( + title, + message, + context, + ); + } + + @override + void initState() { + super.initState(); + _dropdownLinkNameController.text = widget.link.site_name; + _linkNameController.text = widget.link.custom_name; + _destinationController.text = widget.link.destination; + } + + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + _dropdowOptions.sort(); + bool isOtherSelected = _dropdownLinkNameController.text == "Other"; + return Consumer( + builder: ( + BuildContext context, + MzansiProfileProvider profileProvider, + Widget? child, + ) { + return MihPackageWindow( + fullscreen: false, + windowTitle: "Update Link", + onWindowTapClose: () { + _dropdownLinkNameController.clear(); + _destinationController.clear(); + _linkNameController.clear(); + Navigator.pop(context); + }, + windowBody: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: screenWidth * 0.05) + : EdgeInsets.symmetric(horizontal: screenWidth * 0), + child: Column( + children: [ + MihForm( + formKey: _formKey, + formFields: [ + MihDropdownField( + controller: _dropdownLinkNameController, + hintText: 'Site Name', + dropdownOptions: _dropdowOptions, + requiredText: true, + editable: true, + enableSearch: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + onSelected: (value) { + setState(() {}); + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.secondary(), + inputColor: MihColors.primary(), + controller: _linkNameController, + hintText: "Custom Name", + requiredText: isOtherSelected, + validator: (value) { + if (isOtherSelected) { + return MihValidationServices().isEmpty(value); + } + return null; + }, + ), + const SizedBox(height: 10), + MihTextFormField( + fillColor: MihColors.secondary(), + inputColor: MihColors.primary(), + controller: _destinationController, + hintText: "Link", + requiredText: true, + validator: (value) { + return MihValidationServices().isEmpty(value); + }, + ), + const SizedBox(height: 20), + MihButton( + onPressed: () async { + if (_formKey.currentState!.validate()) { + MihProfileLinksServices.loadingPopUp(context); + int statusCode = + await MihProfileLinksServices.updateProfileLink( + profileProvider, + widget.link.idprofile_links, + "", + profileProvider.business!.business_id, + _dropdownLinkNameController.text, + _linkNameController.text, + _destinationController.text, + widget.link.order, + context, + ); + context.pop(); + if (statusCode == 200) { + context.pop(); + successPopUp( + "Profile Link Updated", + "You have successfully update a link in your business", + 0); + } else { + MihAlertServices().internetConnectionAlert(context); + } + } else { + MihAlertServices().inputErrorAlert(context); + } + }, + buttonColor: MihColors.green(), + width: 300, + child: Text( + "Update", + style: TextStyle( + color: MihColors.primary(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_manage_business_link_window.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_manage_business_link_window.dart new file mode 100644 index 00000000..e97b3b26 --- /dev/null +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/components/mih_manage_business_link_window.dart @@ -0,0 +1,223 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:ken_logger/ken_logger.dart'; +import 'package:mih_package_toolkit/mih_package_toolkit.dart'; +import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_edit_business_link_window.dart'; +import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_profile_links_service.dart'; +import 'package:provider/provider.dart'; + +class MihManageBusinessLinkWindow extends StatefulWidget { + const MihManageBusinessLinkWindow({super.key}); + + @override + State createState() => + _MihManageBusinessLinkWindowState(); +} + +class _MihManageBusinessLinkWindowState + extends State { + void successPopUp(String title, String message, int packageIndex) { + MihAlertServices().successBasicAlert( + title, + message, + context, + ); + } + + void removeLinkWarning( + MzansiProfileProvider profileProvider, int idprofile_links) { + MihAlertServices().warningAdvancedAlert( + "Remove Link?", + "Are you sure you want to remove this link from your business?", + [ + MihButton( + onPressed: () async { + MihProfileLinksServices.loadingPopUp(context); + int statusCode = await MihProfileLinksServices.deleteProfileLink( + profileProvider, + idprofile_links, + ); + context.pop(); + context.pop(); + if (statusCode == 200) { + successPopUp("profile Link Deleted", + "you have successfully deleted a link to your business", 0); + } else { + MihAlertServices().internetConnectionAlert(context); + } + }, + buttonColor: MihColors.red(), + width: 300, + child: Text( + "Remove", + style: TextStyle( + color: MihColors.primary(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + MihButton( + onPressed: () async { + context.pop(); + }, + buttonColor: MihColors.green(), + width: 300, + child: Text( + "Cancel", + style: TextStyle( + color: MihColors.primary(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + context, + ); + } + + void editLinkWindow(ProfileLink link) { + showDialog( + context: context, + builder: (context) => MihEditBusnessLinkWindow(link: link), + ); + } + + Widget linkActions(MzansiProfileProvider profileProvider, ProfileLink link) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + color: MihColors.green(), + onPressed: () { + editLinkWindow(link); + }, + icon: Icon( + Icons.edit, + ), + ), + const SizedBox(width: 2), + IconButton( + color: MihColors.red(), + onPressed: () { + removeLinkWarning(profileProvider, link.idprofile_links); + }, + icon: Icon( + Icons.delete, + ), + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + // double screenWidth = MediaQuery.of(context).size.width; + return Consumer( + builder: ( + BuildContext context, + MzansiProfileProvider profileProvider, + Widget? child, + ) { + // return Placeholder(); + return MihPackageWindow( + fullscreen: true, + windowTitle: "Manage Links", + onWindowTapClose: () { + Navigator.pop(context); + }, + windowBody: Column( + children: [ + Expanded( + child: Theme( + data: Theme.of(context).copyWith( + iconTheme: IconThemeData( + color: MihColors.grey(), + ), + ), + child: ReorderableListView.builder( + itemBuilder: (context, index) { + ProfileLink link = profileProvider.businessLinks[index]; + String display = link.site_name; + if (link.custom_name.isNotEmpty) { + display += " (${link.custom_name})"; + } + return ListTile( + key: ValueKey("$index"), + title: Text( + "$display", + style: TextStyle( + // fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + leading: linkActions( + profileProvider, + link, + ), + ); + }, + itemCount: profileProvider.businessLinks.length, + onReorder: (oldIndex, newIndex) { + profileProvider.reorderBusinessLinks( + oldIndex: oldIndex, newIndex: newIndex); + }), + ), + ), + MihButton( + onPressed: () async { + MihProfileLinksServices.loadingPopUp(context); + int newIndex = 1; + bool hasError = false; + for (var link in profileProvider.businessLinks) { + int statusCode = + await MihProfileLinksServices.updateProfileLink( + profileProvider, + link.idprofile_links, + link.app_id, + link.business_id, + link.site_name, + link.custom_name, + link.destination, + newIndex, + context); + if (statusCode != 200) { + hasError = true; + break; + } + newIndex++; + } + if (hasError) { + MihAlertServices().internetConnectionAlert(context); + } else { + context.pop(); + context.pop(); + successPopUp( + "profile Link Reordered", + "you have successfully reordered your profile links", + 0); + } + }, + buttonColor: MihColors.green(), + width: 300, + child: Text( + "Update Order", + style: TextStyle( + color: MihColors.primary(), + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 10), + ], + ), + ); + }, + ); + } +} diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart index ac299908..a50647b7 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/mzansi_business_profile_view.dart @@ -2,6 +2,7 @@ import 'package:go_router/go_router.dart'; import 'package:ken_logger/ken_logger.dart'; import 'package:flutter/material.dart'; import 'package:mih_package_toolkit/mih_package_toolkit.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_links.dart'; import 'package:mzansi_innovation_hub/mih_providers/mzansi_directory_provider.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart'; @@ -26,6 +27,7 @@ class MzansiBusinessProfileView extends StatefulWidget { class _MzansiBusinessProfileViewState extends State { late final MihBusinessDetailsView _businessDetailsView; late final MihBusinessReviews _businessReviews; + late final MihBusinessLinks _businessLinks; late final MihBusinessQrCode _businessQrCode; Future _fetchBusinessDetails( @@ -49,6 +51,7 @@ class _MzansiBusinessProfileViewState extends State { _businessQrCode = MihBusinessQrCode( business: directoryProvider.selectedBusiness!, ); + _businessLinks = MihBusinessLinks(viewMode: true); } @override @@ -117,9 +120,12 @@ class _MzansiBusinessProfileViewState extends State { temp[const Icon(Icons.star_rate_rounded)] = () { context.read().setBusinessViewIndex(1); }; - temp[const Icon(Icons.qr_code_rounded)] = () { + temp[const Icon(Icons.link)] = () { context.read().setBusinessViewIndex(2); }; + temp[const Icon(Icons.qr_code_rounded)] = () { + context.read().setBusinessViewIndex(3); + }; return MihPackageTools( tools: temp, selectedIndex: context.watch().businessViewIndex, @@ -130,6 +136,7 @@ class _MzansiBusinessProfileViewState extends State { return [ _businessDetailsView, _businessReviews, + _businessLinks, _businessQrCode, ]; } @@ -138,6 +145,7 @@ class _MzansiBusinessProfileViewState extends State { List toolTitles = [ "Profile", "Reviews", + "Links", "Share Business", ]; return toolTitles; diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart index a254feea..dd1b00f1 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details.dart @@ -169,6 +169,7 @@ class _MihBusinessDetailsState extends State { business: mzansiProfileProvider.business!, // startUpSearch: null, width: width, + viewMode: false, ), const SizedBox(height: 30.0), ], diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart index a88f9ed3..7db8d42e 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart @@ -183,6 +183,7 @@ class _MihBusinessDetailsViewState extends State { MihBusinessCardV2( business: directoryProvider.selectedBusiness!, width: width, + viewMode: true, ), ], ), diff --git a/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_links.dart b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_links.dart new file mode 100644 index 00000000..dec60676 --- /dev/null +++ b/mih_ui/lib/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_links.dart @@ -0,0 +1,193 @@ +import 'package:flutter/material.dart'; +import 'package:mih_package_toolkit/mih_package_toolkit.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; +import 'package:mzansi_innovation_hub/mih_package_components/mih_profile_links.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_add_business_link_window.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_manage_business_link_window.dart'; +import 'package:mzansi_innovation_hub/mih_providers/mzansi_directory_provider.dart'; +import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; +import 'package:mzansi_innovation_hub/mih_services/mih_profile_links_service.dart'; +import 'package:provider/provider.dart'; +import 'package:redacted/redacted.dart'; + +class MihBusinessLinks extends StatefulWidget { + final bool viewMode; + const MihBusinessLinks({ + super.key, + required this.viewMode, + }); + + @override + State createState() => _MihBusinessLinksState(); +} + +class _MihBusinessLinksState extends State { + late Future> _futureLinks; + + void manageProfileLinksWindow() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MihManageBusinessLinkWindow(), + ); + } + + void addProfileLinksWindow() { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => MihAddBusinessLinkWindow(), + ); + } + + void getLinkData() async { + if (widget.viewMode) { + MzansiDirectoryProvider directoryProvider = + context.read(); + _futureLinks = MihProfileLinksServices.getBusinessProfileLinksMD( + directoryProvider.selectedBusiness!.business_id); + } + } + + @override + void initState() { + super.initState(); + getLinkData(); + } + + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + return MihPackageToolBody( + backgroundColor: MihColors.primary(), + bodyItem: getBody(screenWidth), + ); + } + + Widget getBody(double width) { + return Consumer(builder: (BuildContext context, + MzansiProfileProvider profileProvider, Widget? child) { + return MihSingleChildScroll( + scrollbarOn: true, + child: Padding( + padding: + MzansiInnovationHub.of(context)!.theme.screenType == "desktop" + ? EdgeInsets.symmetric(horizontal: width * 0.2) + : EdgeInsets.symmetric(horizontal: width * 0), + child: Column( + children: [ + FittedBox( + child: Text( + "Profile Links", + style: TextStyle( + fontSize: 35, + fontWeight: FontWeight.bold, + color: MihColors.secondary(), + ), + ), + ), + const SizedBox(height: 15.0), + if (widget.viewMode) + FutureBuilder( + future: _futureLinks, + builder: (context, asyncSnapshot) { + if (asyncSnapshot.connectionState == ConnectionState.done && + asyncSnapshot.hasData) { + return MihProfileLinks( + links: asyncSnapshot.requireData, + ); + } else { + return Wrap( + alignment: WrapAlignment.center, + runAlignment: WrapAlignment.center, + runSpacing: 10, + spacing: 10, + children: [ + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + ], + ); + } + }, + ), + if (!widget.viewMode) + Column( + children: [ + MihProfileLinks( + links: profileProvider.businessLinks, + ), + const SizedBox(height: 8.0), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MihButton( + onPressed: () { + addProfileLinksWindow(); + }, + buttonColor: MihColors.green(), + width: profileProvider.businessLinks.isNotEmpty + ? 50 + : null, + height: 50, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.add, + color: MihColors.primary(), + ), + if (profileProvider.businessLinks.isEmpty) + Text( + "Add Links", + style: TextStyle( + color: MihColors.primary(), + fontSize: 15, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + const SizedBox(width: 8.0), + if (profileProvider.businessLinks.isNotEmpty) + MihButton( + onPressed: () { + manageProfileLinksWindow(); + }, + buttonColor: MihColors.green(), + width: 50, + height: 50, + child: Icon( + Icons.edit, + color: MihColors.primary(), + ), + ), + ], + ), + const SizedBox(height: 20.0), + ], + ), + // Placeholder(), + ], + ), + ), + ); + }); + } +} diff --git a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_edit_user_profile_links_window.dart b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_edit_user_profile_links_window.dart index 48bdf2a6..f4d3c2ae 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_edit_user_profile_links_window.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_edit_user_profile_links_window.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; -import 'package:ken_logger/ken_logger.dart'; import 'package:mih_package_toolkit/mih_package_toolkit.dart'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; diff --git a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_manage_user_profile_links_window.dart b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_manage_user_profile_links_window.dart index 496c870a..b29b1ed7 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_manage_user_profile_links_window.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/components/mih_manage_user_profile_links_window.dart @@ -161,12 +161,8 @@ class _MihManageUserProfileLinksWindowState }, itemCount: profileProvider.personalLinks.length, onReorder: (oldIndex, newIndex) { - if (oldIndex < newIndex) { - newIndex -= 1; - } - final ProfileLink link = - profileProvider.personalLinks.removeAt(oldIndex); - profileProvider.personalLinks.insert(newIndex, link); + profileProvider.reorderPersonalLinks( + oldIndex: oldIndex, newIndex: newIndex); }), ), ), @@ -174,6 +170,7 @@ class _MihManageUserProfileLinksWindowState onPressed: () async { MihProfileLinksServices.loadingPopUp(context); int newIndex = 1; + bool hasError = false; for (var link in profileProvider.personalLinks) { int statusCode = await MihProfileLinksServices.updateProfileLink( @@ -187,23 +184,21 @@ class _MihManageUserProfileLinksWindowState newIndex, context); if (statusCode != 200) { - await MihProfileLinksServices.updateProfileLink( - profileProvider, - link.idprofile_links, - link.app_id, - link.business_id, - link.site_name, - link.custom_name, - link.destination, - newIndex, - context); + hasError = true; + break; } newIndex++; } - context.pop(); - context.pop(); - successPopUp("profile Link Reordered", - "you have successfully reordered your profile links", 0); + if (hasError) { + MihAlertServices().internetConnectionAlert(context); + } else { + context.pop(); + context.pop(); + successPopUp( + "profile Link Reordered", + "you have successfully reordered your profile links", + 0); + } }, buttonColor: MihColors.green(), width: 300, diff --git a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index 33c79207..333e2807 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -204,18 +204,19 @@ class _MihPersonalProfileState extends State { ), ), const SizedBox(width: 8.0), - MihButton( - onPressed: () { - editProfileLinksWindow(); - }, - buttonColor: MihColors.green(), - width: 50, - height: 50, - child: Icon( - Icons.edit, - color: MihColors.primary(), + if (mzansiProfileProvider.personalLinks.isNotEmpty) + MihButton( + onPressed: () { + editProfileLinksWindow(); + }, + buttonColor: MihColors.green(), + width: 50, + height: 50, + child: Icon( + Icons.edit, + color: MihColors.primary(), + ), ), - ), ], ), const SizedBox(height: 20.0), diff --git a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile_view.dart b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile_view.dart index dea2b437..8529afe1 100644 --- a/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile_view.dart +++ b/mih_ui/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile_view.dart @@ -162,41 +162,42 @@ class _MihPersonalProfileViewState extends State { ), const SizedBox(height: 15.0), FutureBuilder( - future: futureLinks, - builder: (context, asyncSnapshot) { - if (asyncSnapshot.connectionState == - ConnectionState.done && - asyncSnapshot.hasData) { - return MihProfileLinks( - links: asyncSnapshot.requireData, - ); - } else { - return Wrap( - alignment: WrapAlignment.center, - runAlignment: WrapAlignment.center, - runSpacing: 10, - spacing: 10, - children: [ - Container(width: 70, height: 70).redacted( - context: context, - redact: true, - ), - Container(width: 70, height: 70).redacted( - context: context, - redact: true, - ), - Container(width: 70, height: 70).redacted( - context: context, - redact: true, - ), - Container(width: 70, height: 70).redacted( - context: context, - redact: true, - ), - ], - ); - } - }), + future: futureLinks, + builder: (context, asyncSnapshot) { + if (asyncSnapshot.connectionState == + ConnectionState.done && + asyncSnapshot.hasData) { + return MihProfileLinks( + links: asyncSnapshot.requireData, + ); + } else { + return Wrap( + alignment: WrapAlignment.center, + runAlignment: WrapAlignment.center, + runSpacing: 10, + spacing: 10, + children: [ + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + Container(width: 70, height: 70).redacted( + context: context, + redact: true, + ), + ], + ); + } + }, + ), ], ), ), diff --git a/mih_ui/lib/mih_providers/mzansi_profile_provider.dart b/mih_ui/lib/mih_providers/mzansi_profile_provider.dart index 22a197fe..8c4afc50 100644 --- a/mih_ui/lib/mih_providers/mzansi_profile_provider.dart +++ b/mih_ui/lib/mih_providers/mzansi_profile_provider.dart @@ -179,8 +179,26 @@ class MzansiProfileProvider extends ChangeNotifier { personalLinks[personalIndex] = updatedLink; } if (businessIndex != -1) { - businessLinks[personalIndex] = updatedLink; + businessLinks[businessIndex] = updatedLink; } notifyListeners(); } + + void reorderPersonalLinks({required int oldIndex, required int newIndex}) { + if (oldIndex < newIndex) { + newIndex -= 1; + } + final ProfileLink link = personalLinks.removeAt(oldIndex); + personalLinks.insert(newIndex, link); + notifyListeners(); + } + + void reorderBusinessLinks({required int oldIndex, required int newIndex}) { + if (oldIndex < newIndex) { + newIndex -= 1; + } + final ProfileLink link = businessLinks.removeAt(oldIndex); + businessLinks.insert(newIndex, link); + notifyListeners(); + } } diff --git a/mih_ui/lib/mih_services/mih_profile_links_service.dart b/mih_ui/lib/mih_services/mih_profile_links_service.dart index 4990074e..51fff852 100644 --- a/mih_ui/lib/mih_services/mih_profile_links_service.dart +++ b/mih_ui/lib/mih_services/mih_profile_links_service.dart @@ -43,6 +43,21 @@ class MihProfileLinksServices { } } + static Future> getBusinessProfileLinksMD( + String business_id, + ) async { + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/profile-links/business/$business_id")); + if (response.statusCode == 200) { + Iterable l = jsonDecode(response.body); + List myLinks = + List.from(l.map((model) => ProfileLink.fromJson(model))); + return myLinks; + } else { + throw Exception('failed to fecth user profile links'); + } + } + static Future getBusinessProfileLinks( MzansiProfileProvider profileProvider, String business_id, diff --git a/mih_ui/pubspec.yaml b/mih_ui/pubspec.yaml index b4247da3..c08763a1 100644 --- a/mih_ui/pubspec.yaml +++ b/mih_ui/pubspec.yaml @@ -1,8 +1,7 @@ name: mzansi_innovation_hub description: "" publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.2.7+131 -# version: 1.1.1+97 #--- Updated version for upgrader package testing +version: 1.2.7+132 environment: sdk: ">=3.5.3 <4.0.0"