NEW: MIH Profile Links pt1
This commit is contained in:
35
Frontend/lib/mih_objects/profile_link.dart
Normal file
35
Frontend/lib/mih_objects/profile_link.dart
Normal 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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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: [],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
703
Frontend/lib/mih_package_components/mih_business_info_card.dart
Normal file
703
Frontend/lib/mih_package_components/mih_business_info_card.dart
Normal 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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -161,7 +161,7 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.edit,
|
Icons.camera_alt,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
165
Frontend/lib/mih_package_components/mih_profile_links.dart
Normal file
165
Frontend/lib/mih_package_components/mih_profile_links.dart
Normal 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(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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,27 +154,50 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Stack(
|
||||||
child: MihCircleAvatar(
|
children: [
|
||||||
imageFile: mzansiProfileProvider.userProfilePicture,
|
MihCircleAvatar(
|
||||||
width: 150,
|
imageFile: mzansiProfileProvider.userProfilePicture,
|
||||||
editable: false,
|
width: 150,
|
||||||
fileNameController: proPicController,
|
editable: false,
|
||||||
userSelectedfile: newSelectedProPic,
|
fileNameController: proPicController,
|
||||||
frameColor: MihColors.getSecondaryColor(
|
userSelectedfile: newSelectedProPic,
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
frameColor: MihColors.getSecondaryColor(
|
||||||
"Dark"),
|
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||||
backgroundColor: MihColors.getPrimaryColor(
|
"Dark"),
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
backgroundColor: MihColors.getPrimaryColor(
|
||||||
"Dark"),
|
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||||
onChange: (selectedImage) {
|
"Dark"),
|
||||||
setState(() {
|
onChange: (selectedImage) {
|
||||||
newSelectedProPic = selectedImage;
|
setState(() {
|
||||||
});
|
newSelectedProPic = selectedImage;
|
||||||
},
|
});
|
||||||
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(
|
||||||
child: MihButton(
|
children: [
|
||||||
onPressed: () {
|
MihProfileLinks(
|
||||||
// Connect with the user
|
// links: mzansiProfileProvider.personalLinks,
|
||||||
editProfileWindow(width);
|
links: getTempLinks(),
|
||||||
},
|
buttonSize: 80,
|
||||||
buttonColor: MihColors.getGreenColor(
|
paddingOn: false,
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
),
|
||||||
"Dark"),
|
Positioned(
|
||||||
width: 300,
|
top: 5,
|
||||||
child: Text(
|
left: 5,
|
||||||
mzansiProfileProvider.user!.username.isEmpty
|
child: MihButton(
|
||||||
? "Set Up Profile"
|
onPressed: () {
|
||||||
: "Edit Profile",
|
editProfileWindow(width);
|
||||||
style: TextStyle(
|
},
|
||||||
color: MihColors.getPrimaryColor(
|
buttonColor: MihColors.getGreenColor(
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||||
"Dark"),
|
"Dark"),
|
||||||
fontSize: 20,
|
width: 35,
|
||||||
fontWeight: FontWeight.bold,
|
height: 35,
|
||||||
|
child: Icon(
|
||||||
|
Icons.link,
|
||||||
|
color: MihColors.getPrimaryColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||||
|
"Dark"),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user