NEW: MIH Profile Links pt1

This commit is contained in:
2025-12-11 12:57:12 +02:00
parent b945a34ad4
commit eea3248525
10 changed files with 1645 additions and 658 deletions

View File

@@ -0,0 +1,35 @@
class ProfileLink {
final int idprofile_links;
final String app_id;
final String business_id;
final String destination;
final String web_link;
const ProfileLink({
required this.idprofile_links,
required this.app_id,
required this.business_id,
required this.destination,
required this.web_link,
});
factory ProfileLink.fromJson(Map<String, dynamic> json) {
return ProfileLink(
idprofile_links: json['idprofile_links'],
app_id: json['app_id'],
business_id: json['business_id'],
destination: json['destination'],
web_link: json['web_link'],
);
}
Map<String, dynamic> toJson() {
return {
'idprofile_links': idprofile_links,
'app_id': app_id,
'business_id': business_id,
'destination': destination,
'web_link': web_link,
};
}
}

View File

@@ -38,9 +38,7 @@ class _TestPackageTileState extends State<TestPackageTile> {
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
), ),
iconSize: widget.packageSize, iconSize: widget.packageSize,
primaryColor: MihColors.getSecondaryColor( textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
secondaryColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
); );
} }

View File

@@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_profile_links.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart';
class PackageToolThree extends StatefulWidget {
const PackageToolThree({super.key});
@override
State<PackageToolThree> createState() => _PackageToolThreeState();
}
class _PackageToolThreeState extends State<PackageToolThree> {
@override
Widget build(BuildContext context) {
return MihPackageToolBody(
borderOn: false,
bodyItem: getBody(),
);
}
Widget getBody() {
List<ProfileLink> links = [
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Youtube",
web_link: "https://www.youtube.com/@MzansiInnovationHub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Threads",
web_link: "https://www.threads.com/@mzansi.innovation.hub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "TikTok",
web_link: "https://www.tiktok.com/@mzansiinnovationhub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "WhatsApp",
web_link: "https://whatsapp.com/channel/0029Vax3INCIyPtMn8KgeM2F",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Twitch",
web_link: "https://www.twitch.tv/mzansiinnovationhub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Instagram",
web_link: "https://www.instagram.com/mzansi.innovation.hub/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "X",
web_link: "https://x.com/mzansi_inno_hub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "LinkedIn",
web_link: "https://www.linkedin.com/in/yasien-meth-172352108/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Facebook",
web_link: "https://www.facebook.com/profile.php?id=61565345762136",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Reddit",
web_link: "https://www.reddit.com/r/Mzani_Innovation_Hub/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Discord",
web_link: "https://discord.gg/ZtTZYd5d",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "My App",
web_link: "https://app.mzansi-innovation-hub.co.za/about",
),
];
return Stack(
children: [
MihSingleChildScroll(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
MihProfileLinks(
links: links,
// links: [],
),
],
),
),
],
);
}
}

View File

@@ -0,0 +1,703 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_objects/bookmarked_business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_review.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_review_business_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_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
import 'package:provider/provider.dart';
import 'package:redacted/redacted.dart';
import 'package:supertokens_flutter/supertokens.dart';
import 'package:url_launcher/url_launcher.dart';
class MihBusinessCard extends StatefulWidget {
final Business business;
final double width;
const MihBusinessCard({
super.key,
required this.business,
required this.width,
});
@override
State<MihBusinessCard> createState() => _MihBusinessCardState();
}
class _MihBusinessCardState extends State<MihBusinessCard> {
Future<BusinessReview?>? _businessReviewFuture;
Future<BookmarkedBusiness?>? _bookmarkedBusinessFuture;
bool _isUserSignedIn = false;
Future<void> _checkUserSession() async {
final doesSessionExist = await SuperTokens.doesSessionExist();
setState(() {
_isUserSignedIn = doesSessionExist;
});
}
RedactedConfiguration getRedactedConfiguration() {
return RedactedConfiguration(
// redactedColor: Colors.pink,
redactedColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
}
Future<void> _makePhoneCall(String phoneNumber) async {
String formattedNumber = phoneNumber.replaceAll("-", "");
final Uri url = Uri(scheme: 'tel', path: formattedNumber);
if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
MihAlertServices().errorBasicAlert(
"Error Making Call",
"We couldn't open your phone app to call $formattedNumber. To fix this, make sure you have a phone application installed and it's set as your default dialer.",
context,
);
}
}
String? _encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
Future<void> _launchEmail(
String recipient, String subject, String body) async {
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: recipient,
query: _encodeQueryParameters(<String, String>{
'subject': subject,
'body': body,
}),
);
if (await canLaunchUrl(emailLaunchUri)) {
await launchUrl(emailLaunchUri);
} else {
MihAlertServices().errorBasicAlert(
"Error Creating Email",
"We couldn't launch your email app to send a message to $recipient. To fix this, please confirm that you have an email application installed and that it's set as your default.",
context,
);
}
}
Future<void> _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 {
MihAlertServices().errorBasicAlert(
"Error Opening Maps",
"There was an issue opening maps for ${widget.business.Name}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
context,
);
}
} catch (e) {
MihAlertServices().errorBasicAlert(
"Error Opening Maps",
"There was an issue opening maps for ${widget.business.Name}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
context,
);
}
}
Future<void> _launchWebsite(String urlString) async {
String newUrl = urlString;
if (!newUrl.startsWith("https://")) {
newUrl = "https://$urlString";
}
final Uri url = Uri.parse(newUrl);
try {
if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
MihAlertServices().errorBasicAlert(
"Error Opening Website",
"We couldn't open the link to $newUrl. To view this website, please ensure you have a web browser installed and set as your default.",
context,
);
}
} catch (e) {
MihAlertServices().errorBasicAlert(
"Error Opening Website",
"We couldn't open the link to $newUrl. To view this website, please ensure you have a web browser installed and set as your default.",
context,
);
}
}
Widget _buildContactInfo(
String label,
String subLabel,
IconData icon,
Color? iconColor,
bool redacted,
Function()? ontap,
) {
return Material(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
child: InkWell(
onTap: ontap,
splashColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")
.withOpacity(0.2),
borderRadius: BorderRadius.circular(15),
child: Padding(
padding: EdgeInsetsGeometry.symmetric(
// vertical: 5,
horizontal: 25,
),
child: Row(
children: [
Container(
width: 45,
height: 45,
decoration: BoxDecoration(
color: iconColor,
borderRadius: BorderRadius.circular(15),
),
padding: const EdgeInsets.all(5.0),
child: FittedBox(
child: Icon(
icon,
// size: 35,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
).redacted(
context: context,
redact: redacted,
configuration: getRedactedConfiguration(),
),
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: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
height: 1.0,
),
).redacted(
context: context,
redact: redacted,
configuration: getRedactedConfiguration(),
),
Text(
subLabel,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w700,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
).redacted(
context: context,
redact: redacted,
configuration: getRedactedConfiguration(),
),
],
),
),
],
),
),
),
);
}
Future<BusinessReview?> getUserReview() async {
String user_id = await SuperTokens.getUserId();
return await MihMzansiDirectoryServices().getUserReviewOfBusiness(
user_id,
widget.business.business_id,
);
}
Future<BookmarkedBusiness?> getUserBookmark() async {
String user_id = await SuperTokens.getUserId();
return await MihMzansiDirectoryServices().getUserBookmarkOfBusiness(
user_id,
widget.business.business_id,
);
}
bool isValidGps(String coordinateString) {
final RegExp gpsRegex = RegExp(
r"^-?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*-?(1[0-7]\d(\.\d+)?|180(\.0+)?|\d{1,2}(\.\d+)?)$");
return gpsRegex.hasMatch(coordinateString);
}
@override
void initState() {
super.initState();
_checkUserSession();
_businessReviewFuture = getUserReview();
_bookmarkedBusinessFuture = getUserBookmark();
}
@override
Widget build(BuildContext context) {
// double screenWidth = MediaQuery.of(context).size.width;
return Consumer2<MzansiProfileProvider, MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MzansiDirectoryProvider directoryProvider, Widget? child) {
return Material(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")
.withValues(alpha: 0.6),
borderRadius: BorderRadius.circular(25),
elevation: 10,
shadowColor: Colors.black,
child: Container(
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
const SizedBox(height: 10),
_buildContactInfo(
"Call",
"Give us a quick call.",
Icons.phone,
MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
false,
() {
// print("Calling ${widget.cellNumber}");
_makePhoneCall(widget.business.contact_no);
},
),
Divider(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
_buildContactInfo(
"Email",
"Send us an email.",
Icons.email,
MihColors.getPinkColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
false,
() {
// print("Emailing ${widget.email}");
_launchEmail(
widget.business.bus_email,
"Inquiery about ${widget.business.Name}",
"Dear ${widget.business.Name},\n\nI would like to inquire about your services.\n\nBest regards,\n",
);
},
),
Visibility(
visible: isValidGps(widget.business.gps_location),
child: Column(
children: [
Divider(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
_buildContactInfo(
"Location",
"Come visit us.",
Icons.location_on,
MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
false,
() {
final latitude = double.parse(
widget.business.gps_location.split(',')[0]);
final longitude = double.parse(
widget.business.gps_location.split(',')[1]);
_launchGoogleMapsWithUrl(
latitude: latitude,
longitude: longitude,
);
},
),
],
),
),
Visibility(
visible: widget.business.website.isNotEmpty &&
widget.business.website != "",
child: Column(
children: [
Divider(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
_buildContactInfo(
"Website",
"Find out more about us.",
Icons.vpn_lock,
MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
false,
() {
_launchWebsite(widget.business.website);
},
),
],
),
),
FutureBuilder(
future: _businessReviewFuture,
builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState ==
ConnectionState.waiting) {
// return const SizedBox.shrink();
return Column(
children: [
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
Container(
child: _buildContactInfo(
"Loading Rating",
"Loading your rating.",
Icons.star_rate_rounded,
MihColors.getYellowColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
true,
null,
),
).redacted(context: context, redact: true),
],
);
} else {
BusinessReview? businessReview = asyncSnapshot.data;
String ratingDisplayTitle = "";
if (businessReview == null) {
ratingDisplayTitle = "Rate Us";
} else {
ratingDisplayTitle = "Update Rating";
}
return Column(
children: [
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
_buildContactInfo(
ratingDisplayTitle,
"Let us know how we are doing.",
Icons.star_rate_rounded,
MihColors.getYellowColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
false,
() {
businessReviewRatingWindow(directoryProvider,
businessReview, true, widget.width);
},
),
],
);
}
},
),
FutureBuilder(
future: _bookmarkedBusinessFuture,
builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState ==
ConnectionState.waiting) {
// return const SizedBox.shrink();
return Column(
children: [
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
Container(
child: _buildContactInfo(
"Loading Bookmark",
"Loading your bookmark.",
Icons.bookmark_add_rounded,
MihColors.getBluishPurpleColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
true,
null,
),
),
],
);
} else {
BookmarkedBusiness? bookmarkBusiness = asyncSnapshot.data;
String bookmarkDisplayTitle = "";
if (bookmarkBusiness == null) {
bookmarkDisplayTitle = "Bookmark Us";
} else {
bookmarkDisplayTitle = "Remove Bookmark";
}
return Column(
children: [
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10.0),
child: Divider(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
_buildContactInfo(
bookmarkDisplayTitle,
"Save us for later.",
bookmarkBusiness == null
? Icons.bookmark_add_rounded
: Icons.bookmark_remove_rounded,
MihColors.getBluishPurpleColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
false,
() {
// _launchWebsite(widget.website);
if (bookmarkBusiness == null) {
showAddBookmarkAlert();
} else {
showDeleteBookmarkAlert(bookmarkBusiness);
}
},
),
],
);
}
},
),
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 10.0),
// child: Divider(
// color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// ),
// _buildContactInfo(
// "Bookmark",
// "Save us for later.",
// Icons.bookmark_add_rounded,
// MihColors.getBluishPurpleColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// () {
// // _launchWebsite(widget.website);
// print("Saving ${widget.business.Name} to Directory");
// showBookmarkAlert();
// },
// ),
const SizedBox(height: 10),
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 10.0),
// child: Divider(
// color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// ),
],
),
),
);
},
);
}
Future<void> businessReviewRatingWindow(
MzansiDirectoryProvider directoryProvider,
BusinessReview? myReview,
bool previouslyRated,
double width) async {
if (_isUserSignedIn) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => MihReviewBusinessWindow(
business: widget.business,
businessReview: myReview,
screenWidth: width,
readOnly: false,
onSuccessDismissPressed: () async {
List<Business>? businessSearchResults = [];
businessSearchResults = await MihBusinessDetailsServices()
.searchBusinesses(directoryProvider.searchTerm,
directoryProvider.businessTypeFilter, context);
Map<String, Future<String>> busImagesUrl = {};
Future<String> businessLogoUrl;
for (var bus in businessSearchResults) {
businessLogoUrl = MihFileApi.getMinioFileUrl(bus.logo_path);
busImagesUrl[bus.business_id] = businessLogoUrl;
}
directoryProvider.setSearchedBusinesses(
searchedBusinesses: businessSearchResults,
businessesImagesUrl: busImagesUrl,
);
setState(() {
_businessReviewFuture = getUserReview();
});
},
),
);
} else {
showSignInRequiredAlert();
}
}
void showAddBookmarkAlert() {
if (_isUserSignedIn) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => MihAddBookmarkAlert(
business: widget.business,
onSuccessDismissPressed: () async {
_bookmarkedBusinessFuture = getUserBookmark();
},
),
);
} else {
showSignInRequiredAlert();
}
}
void showDeleteBookmarkAlert(BookmarkedBusiness? bookmarkBusiness) {
if (_isUserSignedIn) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => MihDeleteBookmarkAlert(
business: widget.business,
bookmarkBusiness: bookmarkBusiness,
onSuccessDismissPressed: () {
_bookmarkedBusinessFuture = getUserBookmark();
},
// startUpSearch: widget.startUpSearch,
));
} else {
showSignInRequiredAlert();
}
}
void showSignInRequiredAlert() {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: null,
onWindowTapClose: () {
context.pop();
},
windowBody: Column(
children: [
Icon(
MihIcons.mihLogo,
size: 125,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
Text(
"Let's Get Started",
textAlign: TextAlign.center,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 15),
Text(
"Ready to dive in to the world of MIH?\nSign in or create a free MIH account to unlock all the powerful features of the MIH app. It's quick and easy!",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15,
),
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
context.goNamed(
'mihHome',
extra: true,
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
elevation: 10,
width: 300,
child: Text(
"Sign In/ Create Account",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
);
},
);
}
}

View File

@@ -161,7 +161,7 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
} }
}, },
icon: Icon( icon: Icon(
Icons.edit, Icons.camera_alt,
), ),
), ),
), ),

View File

@@ -167,40 +167,34 @@ class _MihPackageTileState extends State<MihPackageTile> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
// alignment: Alignment.topCenter, alignment: Alignment.topCenter,
// color: Colors.black, // color: Colors.black,
// width: widget.iconSize, width: widget.iconSize,
// height: widget.iconSize + widget.iconSize / 3, height: widget.iconSize,
child: GestureDetector( child: GestureDetector(
onTap: () async { onTap: () async {
authenticateUser(); authenticateUser();
}, },
onLongPress: null, // Do this later onLongPress: null, // Do this later
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Flexible( Expanded(
flex: 3, child: FittedBox(
child: LayoutBuilder( fit: BoxFit.contain,
builder: (context, constraints) { alignment: Alignment.center,
double iconHeight = constraints.maxWidth; child: widget.appIcon,
return Container(
width: iconHeight,
height: iconHeight,
child:
FittedBox(fit: BoxFit.fitHeight, child: widget.appIcon),
);
},
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Flexible( Padding(
flex: 1, // Add a little padding for better visual spacing
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: FittedBox( child: FittedBox(
child: Text( child: Text(
widget.appName, widget.appName,
textAlign: TextAlign.center, textAlign: TextAlign.center, // This centers the text content
// softWrap: true, maxLines: 1, // Allow up to 2 lines to prevent clipping
// overflow: TextOverflow.visible,
style: TextStyle( style: TextStyle(
color: widget.textColor, color: widget.textColor,
fontSize: 20.0, fontSize: 20.0,
@@ -208,7 +202,7 @@ class _MihPackageTileState extends State<MihPackageTile> {
), ),
), ),
), ),
) ),
], ],
), ),
), ),

View File

@@ -0,0 +1,165 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tile.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
class MihProfileLinks extends StatefulWidget {
final List<ProfileLink> links;
final double? buttonSize;
final bool? paddingOn;
const MihProfileLinks({
super.key,
required this.links,
this.buttonSize,
this.paddingOn,
});
@override
State<MihProfileLinks> createState() => _MihProfileLinksState();
}
class _MihProfileLinksState extends State<MihProfileLinks> {
Widget displayLinkButton(ProfileLink link) {
IconData iconData;
Color iconColor;
switch (link.destination.toLowerCase()) {
case "youtube":
iconData = FontAwesomeIcons.youtube;
iconColor = const Color(0xFFFF0000);
break;
case "tiktok":
iconData = FontAwesomeIcons.tiktok;
iconColor = const Color(0xFF000000);
break;
case "twitch":
iconData = FontAwesomeIcons.twitch;
iconColor = const Color(0xFF6441a5);
break;
case "threads":
iconData = FontAwesomeIcons.threads;
iconColor = const Color(0xFF000000);
break;
case "whatsapp":
iconData = FontAwesomeIcons.whatsapp;
iconColor = const Color(0xFF25D366);
break;
case "instagram":
iconData = FontAwesomeIcons.instagram;
iconColor = const Color(0xFFF56040);
break;
case "x":
iconData = FontAwesomeIcons.xTwitter;
iconColor = const Color(0xFF000000);
break;
case "linkedin":
iconData = FontAwesomeIcons.linkedin;
iconColor = const Color(0xFF0a66c2);
break;
case "facebook":
iconData = FontAwesomeIcons.facebook;
iconColor = const Color(0xFF4267B2);
break;
case "reddit":
iconData = FontAwesomeIcons.reddit;
iconColor = const Color(0xFFFF4500);
break;
case "discord":
iconData = FontAwesomeIcons.discord;
iconColor = const Color(0xFF5865F2);
break;
default:
iconData = FontAwesomeIcons.link;
iconColor = MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
}
return MihPackageTile(
onTap: () {
launchSocialUrl(Uri.parse(link.web_link));
},
appName: link.destination,
appIcon: Icon(
iconData,
color: iconColor,
),
iconSize: 200,
textColor: Colors.black,
// MihColors.getPrimaryColor(
// MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
}
Future<void> launchSocialUrl(Uri linkUrl) async {
if (!await launchUrl(linkUrl)) {
throw Exception('Could not launch $linkUrl');
}
}
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return Consumer<MzansiProfileProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
Widget? child) {
return Padding(
padding: widget.paddingOn == null || widget.paddingOn!
? MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075)
: EdgeInsetsGeometry.all(0),
child: Material(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")
.withValues(alpha: 0.6),
borderRadius: BorderRadius.circular(25),
elevation: 10,
shadowColor: Colors.black,
child: Container(
width: 500,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
borderRadius: BorderRadius.circular(10),
),
child: widget.links.isEmpty
? SizedBox(
height: 35,
child: Text(
"No Profile Links",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
)
: Wrap(
alignment: WrapAlignment.center,
runSpacing: 15,
spacing: 15,
children: widget.links.map(
(link) {
return SizedBox(
width: widget.buttonSize ?? 80,
height: widget.buttonSize ?? 80,
child: displayLinkButton(link),
);
},
).toList(),
),
),
),
);
},
);
}
}

View File

@@ -1,7 +1,8 @@
import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tile.dart'; import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_profile_links.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart';
@@ -27,25 +28,6 @@ class MihInfo extends StatefulWidget {
class _MihInfoState extends State<MihInfo> { class _MihInfoState extends State<MihInfo> {
late Future<int> _futureUserCount; late Future<int> _futureUserCount;
late Future<int> _futureBusinessCount; late Future<int> _futureBusinessCount;
final Uri _tiktokUrl =
Uri.parse('https://www.tiktok.com/@mzansi.innovation.hub');
final Uri _whatsappUrl =
Uri.parse('https://whatsapp.com/channel/0029Vax3INCIyPtMn8KgeM2F');
final Uri _twitch = Uri.parse('https://www.twitch.tv/mzansi_innovation_hub');
final Uri _kick = Uri.parse('https://kick.com/mzansi-innovation-hub');
final Uri _threadsUrl =
Uri.parse('https://www.threads.net/@mzansi.innovation.hub');
final Uri _instagramUrl =
Uri.parse('https://www.instagram.com/mzansi.innovation.hub');
final Uri _youtubeUrl =
Uri.parse('https://www.youtube.com/@mzansiinnovationhub');
final Uri _xUrl = Uri.parse('https://x.com/mzansi_inno_hub');
final Uri _linkedinUrl =
Uri.parse('https://www.linkedin.com/company/mzansi-innovation-hub/');
final Uri _facebookUrl =
Uri.parse('https://www.facebook.com/profile.php?id=61565345762136');
final Uri _redditUrl =
Uri.parse('https://www.reddit.com/r/Mzani_Innovation_Hub/');
Widget founderBio() { Widget founderBio() {
String bio = ""; String bio = "";
@@ -190,368 +172,6 @@ class _MihInfoState extends State<MihInfo> {
); );
} }
Widget womenForChange() {
String heading = "MIH Stands with Women For Change SA";
String mission =
"South Africa is facing a devastating crisis of Gender-Based Violence and Femicide (GBVF), with at least 15 women murdered and 117 women reporting rape daily, often at the hands of known individuals, as highlighted by a shocking 33.8% rise in femicide in the last year, despite the existence of the National Strategic Plan on GBVF (NSP GBVF). Due to the government's lack of urgent action and funding for the NSP GBVF's implementation, organizations like Women For Change are urgently calling for the immediate declaration of GBVF as a National Disaster to mobilize resources and political will for decisive action, which must include judicial reforms (like opposing bail and implementing harsher sentences), immediate funding of the NSP GBVF and the new National Council, making the National Sex Offenders Register publicly accessible, and mandating comprehensive GBVF education and continuous public awareness campaigns.";
return SizedBox(
width: 500,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
heading,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
const SizedBox(
height: 10,
),
Wrap(
alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 10,
runSpacing: 10,
children: [
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://www.tiktok.com/@womenforchange.sa",
),
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
width: 300,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
FontAwesomeIcons.tiktok,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
const SizedBox(width: 10),
Text(
"@womenforchange.sa",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://www.change.org/p/declare-gbvf-a-national-disaster-in-south-africa",
),
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
width: 300,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
Icons.edit,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
const SizedBox(width: 10),
Text(
"Sign Petition",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
const SizedBox(
height: 10,
),
Text(
mission,
textAlign: TextAlign.center,
style: const TextStyle(
//fontWeight: FontWeight.bold,
fontSize: 17,
),
),
],
),
);
}
Widget mihSocials() {
String heading = "Follow Our Journey";
return Column(
children: [
Text(
heading,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
const SizedBox(
height: 10,
),
SizedBox(
width: 500,
height: 600,
child: GridView.builder(
padding: const EdgeInsets.only(
// left: width / 10,
// right: width / 10,
// //bottom: height / 5,
// top: 20,
),
physics: const NeverScrollableScrollPhysics(),
// shrinkWrap: true,
itemCount: getSocialsList().length,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
mainAxisSpacing: 15, maxCrossAxisExtent: 150),
itemBuilder: (context, index) {
return getSocialsList()[index];
},
),
),
],
);
}
List<Widget> getSocialsList() {
List<Widget> socials = [];
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_youtubeUrl);
},
appName: "YouTube",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.youtube,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_tiktokUrl);
},
appName: "TikTok",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.tiktok,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_twitch);
},
appName: "Twitch",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.twitch,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_threadsUrl);
},
appName: "Threads",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.threads,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_whatsappUrl);
},
appName: "Whatsapp",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.whatsapp,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_instagramUrl);
},
appName: "Instagram",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.instagram,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_xUrl);
},
appName: "X",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.xTwitter,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_linkedinUrl);
},
appName: "LinkedIn",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.linkedin,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_facebookUrl);
},
appName: "FaceBook",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.facebook,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_redditUrl);
},
appName: "Reddit",
appIcon: Center(
child: FaIcon(
FontAwesomeIcons.reddit,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
size: 200,
),
),
iconSize: 200,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
socials.add(MihPackageTile(
onTap: () {
launchSocialUrl(_kick);
},
appName: "Kick",
appIcon: Center(
child: Text(
"KICK",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontWeight: FontWeight.bold,
fontSize: 100,
),
),
// FaIcon(
// FontAwesomeIcons.tv,
// color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// size: 200,
// ),
),
iconSize: 100,
textColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
));
//==================================================================
return socials;
}
Future<void> launchSocialUrl(Uri linkUrl) async { Future<void> launchSocialUrl(Uri linkUrl) async {
if (!await launchUrl(linkUrl)) { if (!await launchUrl(linkUrl)) {
throw Exception('Could not launch $linkUrl'); throw Exception('Could not launch $linkUrl');
@@ -720,27 +340,22 @@ class _MihInfoState extends State<MihInfo> {
); );
} }
@override Widget mihDivider() {
void initState() { return Padding(
super.initState(); padding: EdgeInsets.symmetric(
_futureUserCount = MihUserServices().fetchUserCount(); vertical: 10.0,
_futureBusinessCount = MihBusinessDetailsServices().fetchBusinessCount(); horizontal: 25,
} ),
child: Divider(
@override thickness: 1,
Widget build(BuildContext context) { color: MihColors.getGreyColor(
return MihPackageToolBody( MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
borderOn: false, ),
innerHorizontalPadding: 10,
bodyItem: getBody(),
); );
} }
Widget getBody() { Widget aboutHeadings() {
return Stack( return Column(
children: [
MihSingleChildScroll(
child: Column(
children: [ children: [
SizedBox( SizedBox(
width: 165, width: 165,
@@ -774,6 +389,13 @@ class _MihInfoState extends State<MihInfo> {
const SizedBox( const SizedBox(
height: 10, height: 10,
), ),
],
);
}
Widget communityCounter() {
return Column(
children: [
Wrap( Wrap(
alignment: WrapAlignment.spaceAround, alignment: WrapAlignment.spaceAround,
crossAxisAlignment: WrapCrossAlignment.center, crossAxisAlignment: WrapCrossAlignment.center,
@@ -795,6 +417,13 @@ class _MihInfoState extends State<MihInfo> {
const SizedBox( const SizedBox(
height: 10, height: 10,
), ),
],
);
}
Widget callToActionsButtons() {
return Column(
children: [
Wrap( Wrap(
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center, crossAxisAlignment: WrapCrossAlignment.center,
@@ -827,8 +456,7 @@ class _MihInfoState extends State<MihInfo> {
FaIcon( FaIcon(
FontAwesomeIcons.youtube, FontAwesomeIcons.youtube,
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
"Dark"),
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
Text( Text(
@@ -861,8 +489,7 @@ class _MihInfoState extends State<MihInfo> {
FaIcon( FaIcon(
FontAwesomeIcons.patreon, FontAwesomeIcons.patreon,
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
"Dark"),
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
Text( Text(
@@ -883,18 +510,128 @@ class _MihInfoState extends State<MihInfo> {
const SizedBox( const SizedBox(
height: 10, height: 10,
), ),
// // ===================== Divider ],
Padding( );
padding: EdgeInsets.symmetric( }
vertical: 10.0,
horizontal: 25, Widget womenForChange() {
String heading = "MIH Stands with Women For Change SA";
String mission =
"South Africa is facing a devastating crisis of Gender-Based Violence and Femicide (GBVF), with at least 15 women murdered and 117 women reporting rape daily, often at the hands of known individuals, as highlighted by a shocking 33.8% rise in femicide in the last year, despite the existence of the National Strategic Plan on GBVF (NSP GBVF). Due to the government's lack of urgent action and funding for the NSP GBVF's implementation, organizations like Women For Change are urgently calling for the immediate declaration of GBVF as a National Disaster to mobilize resources and political will for decisive action, which must include judicial reforms (like opposing bail and implementing harsher sentences), immediate funding of the NSP GBVF and the new National Council, making the National Sex Offenders Register publicly accessible, and mandating comprehensive GBVF education and continuous public awareness campaigns.";
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: SizedBox(
width: 500,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
heading,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
), ),
child: Divider( ),
thickness: 1, const SizedBox(
color: MihColors.getGreyColor( height: 10,
),
Wrap(
alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 10,
runSpacing: 10,
children: [
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://www.tiktok.com/@womenforchange.sa",
),
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
width: 300,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
FontAwesomeIcons.tiktok,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
const SizedBox(width: 10),
Text(
"@womenforchange.sa",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
), ),
), ),
],
),
),
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://www.change.org/p/declare-gbvf-a-national-disaster-in-south-africa",
),
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
width: 300,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
Icons.edit,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
const SizedBox(width: 10),
Text(
"Sign Petition",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
const SizedBox(
height: 10,
),
Text(
mission,
textAlign: TextAlign.center,
style: const TextStyle(
//fontWeight: FontWeight.bold,
fontSize: 17,
),
),
],
),
),
);
}
Widget missionAndVission() {
return Column(
children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0), padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Wrap( child: Wrap(
@@ -903,53 +640,155 @@ class _MihInfoState extends State<MihInfo> {
spacing: 10, spacing: 10,
runSpacing: 10, runSpacing: 10,
children: [ children: [
womenForChange(),
ourVision(), ourVision(),
ourMission(), ourMission(),
], ],
), ),
), ),
const SizedBox(
height: 25,
),
const SizedBox( const SizedBox(
height: 10, height: 10,
), ),
// ===================== Divider ],
Padding( );
padding: EdgeInsets.symmetric( }
vertical: 10.0,
horizontal: 25, Widget founderDetails() {
), return Column(
child: Divider(
thickness: 1,
color: MihColors.getGreyColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
// spacing: 10,
// runSpacing: 10,
children: [ children: [
founderTitle(), founderTitle(),
founderBio(), founderBio(),
], ],
);
}
Widget mihSocials() {
List<ProfileLink> links = [
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Youtube",
web_link: "https://www.youtube.com/@MzansiInnovationHub",
), ),
// ===================== Divider ProfileLink(
Padding( idprofile_links: 1,
padding: EdgeInsets.symmetric( app_id: "1234",
vertical: 10.0, business_id: "",
horizontal: 25, destination: "TikTok",
web_link: "https://www.tiktok.com/@mzansiinnovationhub",
), ),
child: Divider( ProfileLink(
thickness: 1, idprofile_links: 1,
color: MihColors.getGreyColor( app_id: "1234",
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), business_id: "",
destination: "Twitch",
web_link: "https://www.twitch.tv/mzansiinnovationhub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Threads",
web_link: "https://www.threads.com/@mzansi.innovation.hub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "WhatsApp",
web_link: "https://whatsapp.com/channel/0029Vax3INCIyPtMn8KgeM2F",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Instagram",
web_link: "https://www.instagram.com/mzansi.innovation.hub/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "X",
web_link: "https://x.com/mzansi_inno_hub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "LinkedIn",
web_link: "https://www.linkedin.com/company/mzansi-innovation-hub/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Facebook",
web_link: "https://www.facebook.com/profile.php?id=61565345762136",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Reddit",
web_link: "https://www.reddit.com/r/Mzani_Innovation_Hub/",
),
];
return Column(
children: [
Text(
"Follow Our Journey",
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
), ),
), ),
const SizedBox(
height: 10,
),
MihProfileLinks(links: links),
const SizedBox(
height: 25,
),
],
);
}
@override
void initState() {
super.initState();
_futureUserCount = MihUserServices().fetchUserCount();
_futureBusinessCount = MihBusinessDetailsServices().fetchBusinessCount();
}
@override
Widget build(BuildContext context) {
return MihPackageToolBody(
borderOn: false,
bodyItem: getBody(),
);
}
Widget getBody() {
return Stack(
children: [
MihSingleChildScroll(
child: Column(
children: [
aboutHeadings(),
communityCounter(),
callToActionsButtons(),
mihDivider(),
womenForChange(),
mihDivider(),
missionAndVission(),
mihDivider(),
founderDetails(),
mihDivider(),
mihSocials(), mihSocials(),
], ],
), ),

View File

@@ -1,9 +1,11 @@
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.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_button.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_circle_avatar.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_profile_links.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
@@ -35,12 +37,100 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
); );
} }
List<ProfileLink> getTempLinks() {
return [
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Youtube",
web_link: "https://www.youtube.com/@MzansiInnovationHub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Threads",
web_link: "https://www.threads.com/@mzansi.innovation.hub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "TikTok",
web_link: "https://www.tiktok.com/@mzansiinnovationhub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "WhatsApp",
web_link: "https://whatsapp.com/channel/0029Vax3INCIyPtMn8KgeM2F",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Twitch",
web_link: "https://www.twitch.tv/mzansiinnovationhub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Instagram",
web_link: "https://www.instagram.com/mzansi.innovation.hub/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "X",
web_link: "https://x.com/mzansi_inno_hub",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "LinkedIn",
web_link: "https://www.linkedin.com/in/yasien-meth-172352108/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Facebook",
web_link: "https://www.facebook.com/profile.php?id=61565345762136",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Reddit",
web_link: "https://www.reddit.com/r/Mzani_Innovation_Hub/",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Discord",
web_link: "https://discord.gg/ZtTZYd5d",
),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "My App",
web_link: "https://app.mzansi-innovation-hub.co.za/about",
),
];
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width; double screenWidth = MediaQuery.of(context).size.width;
return MihPackageToolBody( return MihPackageToolBody(
borderOn: false, borderOn: false,
innerHorizontalPadding: 10,
bodyItem: getBody(screenWidth), bodyItem: getBody(screenWidth),
); );
} }
@@ -64,8 +154,9 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Center( Stack(
child: MihCircleAvatar( children: [
MihCircleAvatar(
imageFile: mzansiProfileProvider.userProfilePicture, imageFile: mzansiProfileProvider.userProfilePicture,
width: 150, width: 150,
editable: false, editable: false,
@@ -84,7 +175,29 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
}, },
key: ValueKey(mzansiProfileProvider.userProfilePicUrl), key: ValueKey(mzansiProfileProvider.userProfilePicUrl),
), ),
Positioned(
bottom: 5,
right: 5,
child: MihButton(
onPressed: () {
editProfileWindow(width);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 35,
height: 35,
child: Icon(
Icons.edit,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
), ),
),
),
],
),
const SizedBox(height: 10.0),
FittedBox( FittedBox(
child: Text( child: Text(
mzansiProfileProvider.user!.username.isNotEmpty mzansiProfileProvider.user!.username.isNotEmpty
@@ -134,7 +247,7 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
child: Text( child: Text(
mzansiProfileProvider.user!.purpose.isNotEmpty mzansiProfileProvider.user!.purpose.isNotEmpty
? mzansiProfileProvider.user!.purpose ? mzansiProfileProvider.user!.purpose
: "No Personal Mission added yet", : "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
@@ -146,30 +259,36 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
), ),
), ),
), ),
const SizedBox(height: 30.0), const SizedBox(height: 15.0),
Center( Stack(
children: [
MihProfileLinks(
// links: mzansiProfileProvider.personalLinks,
links: getTempLinks(),
buttonSize: 80,
paddingOn: false,
),
Positioned(
top: 5,
left: 5,
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
// Connect with the user
editProfileWindow(width); editProfileWindow(width);
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
width: 300, width: 35,
child: Text( height: 35,
mzansiProfileProvider.user!.username.isEmpty child: Icon(
? "Set Up Profile" Icons.link,
: "Edit Profile",
style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
), ),
), ),
), ),
],
), ),
], ],
), ),

View File

@@ -4,6 +4,7 @@ import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_employee.dart'; import 'package:mzansi_innovation_hub/mih_objects/business_employee.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_user.dart'; import 'package:mzansi_innovation_hub/mih_objects/business_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart'; import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart';
class MzansiProfileProvider extends ChangeNotifier { class MzansiProfileProvider extends ChangeNotifier {
@@ -23,6 +24,7 @@ class MzansiProfileProvider extends ChangeNotifier {
List<BusinessEmployee>? employeeList; List<BusinessEmployee>? employeeList;
List<AppUser> userSearchResults = []; List<AppUser> userSearchResults = [];
bool hideBusinessUserDetails; bool hideBusinessUserDetails;
List<ProfileLink> personalLinks = [];
MzansiProfileProvider({ MzansiProfileProvider({
this.personalHome = true, this.personalHome = true,
@@ -149,4 +151,9 @@ class MzansiProfileProvider extends ChangeNotifier {
this.userSearchResults = userSearchResults; this.userSearchResults = userSearchResults;
notifyListeners(); notifyListeners();
} }
void setPersonalLinks({required List<ProfileLink> personalLinks}) {
this.personalLinks = personalLinks;
notifyListeners();
}
} }