Add business profile links

This commit is contained in:
2026-06-01 12:58:17 +02:00
parent 49c7ecce1f
commit efe225b9f8
17 changed files with 966 additions and 92 deletions
@@ -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<MihBusinessCardV2> {
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<MihBusinessCardV2> {
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<MihBusinessCardV2> {
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<MihBusinessCardV2> {
Column(
children: [
MihButton(
width: 80,
height: 80,
width: 70,
height: 70,
onPressed: () {
_launchWebsite(widget.business.website);
},
@@ -320,8 +322,8 @@ class _MihBusinessCardV2State extends State<MihBusinessCardV2> {
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<MihBusinessCardV2> {
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<MihBusinessCardV2> {
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<MihBusinessCardV2> {
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<MihBusinessCardV2> {
}
},
),
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,
),
),
),
],
),
],
);
},
@@ -76,9 +76,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
Map<String, Future<String>> userImages = {};
Future<String> 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<MihSearchMzansi> {
Map<String, Future<String>> busImagesUrl = {};
Future<String> 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)
@@ -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<BusinesProfile> {
late final MihBusinessUserSearch _businessUserSearch;
late final MihBusinessReviews _businessReviews;
late final MihBusinessQrCode _businessQrCode;
late final MihBusinessLinks _businessLinks;
Future<void> _loadInitialData() async {
setState(() {
@@ -39,6 +42,8 @@ class _BusinesProfileState extends State<BusinesProfile> {
mzansiProfileProvider,
);
}
await MihProfileLinksServices.getBusinessProfileLinks(
mzansiProfileProvider, mzansiProfileProvider.business!.business_id);
await MihBusinessEmployeeServices()
.fetchEmployees(mzansiProfileProvider, context);
setState(() {
@@ -54,6 +59,7 @@ class _BusinesProfileState extends State<BusinesProfile> {
_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<BusinesProfile> {
temp[const Icon(Icons.star_rate_rounded)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(4);
};
temp[const Icon(Icons.qr_code_rounded)] = () {
temp[const Icon(Icons.link)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(5);
};
temp[const Icon(Icons.qr_code_rounded)] = () {
context.read<MzansiProfileProvider>().setBusinessIndex(6);
};
return MihPackageTools(
tools: temp,
selectedIndex: context.watch<MzansiProfileProvider>().businessIndex,
@@ -138,6 +147,7 @@ class _BusinesProfileState extends State<BusinesProfile> {
"Team",
"Add",
"Reviews",
"Links",
"Share",
];
return toolTitles;
@@ -150,6 +160,7 @@ class _BusinesProfileState extends State<BusinesProfile> {
_businessTeam,
_businessUserSearch,
_businessReviews,
_businessLinks,
_businessQrCode,
];
}
@@ -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<MihAddBusinessLinkWindow> createState() =>
_MihAddBusinessLinkWindowState();
}
class _MihAddBusinessLinkWindowState extends State<MihAddBusinessLinkWindow> {
final _formKey = GlobalKey<FormState>();
List<String> _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<MzansiProfileProvider>(
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,
),
),
),
],
),
],
),
),
);
},
);
}
}
@@ -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<MihEditBusnessLinkWindow> createState() =>
_MihEditBusnessLinkWindowState();
}
class _MihEditBusnessLinkWindowState extends State<MihEditBusnessLinkWindow> {
final _formKey = GlobalKey<FormState>();
List<String> _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<MzansiProfileProvider>(
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,
),
),
),
],
),
],
),
),
);
},
);
}
}
@@ -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<MihManageBusinessLinkWindow> createState() =>
_MihManageBusinessLinkWindowState();
}
class _MihManageBusinessLinkWindowState
extends State<MihManageBusinessLinkWindow> {
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<MzansiProfileProvider>(
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),
],
),
);
},
);
}
}
@@ -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<MzansiBusinessProfileView> {
late final MihBusinessDetailsView _businessDetailsView;
late final MihBusinessReviews _businessReviews;
late final MihBusinessLinks _businessLinks;
late final MihBusinessQrCode _businessQrCode;
Future<void> _fetchBusinessDetails(
@@ -49,6 +51,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
_businessQrCode = MihBusinessQrCode(
business: directoryProvider.selectedBusiness!,
);
_businessLinks = MihBusinessLinks(viewMode: true);
}
@override
@@ -117,9 +120,12 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
temp[const Icon(Icons.star_rate_rounded)] = () {
context.read<MzansiDirectoryProvider>().setBusinessViewIndex(1);
};
temp[const Icon(Icons.qr_code_rounded)] = () {
temp[const Icon(Icons.link)] = () {
context.read<MzansiDirectoryProvider>().setBusinessViewIndex(2);
};
temp[const Icon(Icons.qr_code_rounded)] = () {
context.read<MzansiDirectoryProvider>().setBusinessViewIndex(3);
};
return MihPackageTools(
tools: temp,
selectedIndex: context.watch<MzansiDirectoryProvider>().businessViewIndex,
@@ -130,6 +136,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
return [
_businessDetailsView,
_businessReviews,
_businessLinks,
_businessQrCode,
];
}
@@ -138,6 +145,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
List<String> toolTitles = [
"Profile",
"Reviews",
"Links",
"Share Business",
];
return toolTitles;
@@ -169,6 +169,7 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
business: mzansiProfileProvider.business!,
// startUpSearch: null,
width: width,
viewMode: false,
),
const SizedBox(height: 30.0),
],
@@ -183,6 +183,7 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
MihBusinessCardV2(
business: directoryProvider.selectedBusiness!,
width: width,
viewMode: true,
),
],
),
@@ -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<MihBusinessLinks> createState() => _MihBusinessLinksState();
}
class _MihBusinessLinksState extends State<MihBusinessLinks> {
late Future<List<ProfileLink>> _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<MzansiDirectoryProvider>();
_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(),
],
),
),
);
});
}
}
@@ -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';
@@ -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,
@@ -204,18 +204,19 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
),
),
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),
@@ -162,41 +162,42 @@ class _MihPersonalProfileViewState extends State<MihPersonalProfileView> {
),
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,
),
],
);
}
},
),
],
),
),
@@ -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();
}
}
@@ -43,6 +43,21 @@ class MihProfileLinksServices {
}
}
static Future<List<ProfileLink>> 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<ProfileLink> myLinks =
List<ProfileLink>.from(l.map((model) => ProfileLink.fromJson(model)));
return myLinks;
} else {
throw Exception('failed to fecth user profile links');
}
}
static Future<void> getBusinessProfileLinks(
MzansiProfileProvider profileProvider,
String business_id,
+1 -2
View File
@@ -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"