update offile business view

This commit is contained in:
2025-09-10 13:35:37 +02:00
parent 21e302f81b
commit a7d5a65edd
4 changed files with 539 additions and 39 deletions

View File

@@ -1,8 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/bookmarked_business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/bookmarked_business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_review.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_review.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.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_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart';
@@ -31,6 +34,14 @@ class MihBusinessCard extends StatefulWidget {
class _MihBusinessCardState extends State<MihBusinessCard> { class _MihBusinessCardState extends State<MihBusinessCard> {
Future<BusinessReview?>? _businessReviewFuture; Future<BusinessReview?>? _businessReviewFuture;
Future<BookmarkedBusiness?>? _bookmarkedBusinessFuture; Future<BookmarkedBusiness?>? _bookmarkedBusinessFuture;
bool _isUserSignedIn = false;
Future<void> _checkUserSession() async {
final doesSessionExist = await SuperTokens.doesSessionExist();
setState(() {
_isUserSignedIn = doesSessionExist;
});
}
RedactedConfiguration getRedactedConfiguration() { RedactedConfiguration getRedactedConfiguration() {
return RedactedConfiguration( return RedactedConfiguration(
@@ -390,6 +401,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_checkUserSession();
_businessReviewFuture = getUserReview(); _businessReviewFuture = getUserReview();
_bookmarkedBusinessFuture = getUserBookmark(); _bookmarkedBusinessFuture = getUserBookmark();
} }
@@ -665,33 +677,103 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
Future<void> businessReviewRatingWindow( Future<void> businessReviewRatingWindow(
BusinessReview? myReview, bool previouslyRated, double width) async { BusinessReview? myReview, bool previouslyRated, double width) async {
showDialog( if (_isUserSignedIn) {
context: context, showDialog(
builder: (context) => MihReviewBusinessWindow( context: context,
business: widget.business, builder: (context) => MihReviewBusinessWindow(
businessReview: myReview, business: widget.business,
screenWidth: width, businessReview: myReview,
readOnly: false, screenWidth: width,
), readOnly: false,
); ),
);
} else {
showSignInRequiredAlert();
}
} }
void showAddBookmarkAlert() { void showAddBookmarkAlert() {
showDialog( if (_isUserSignedIn) {
context: context, showDialog(
builder: (context) => MihAddBookmarkAlert( context: context,
business: widget.business, builder: (context) => MihAddBookmarkAlert(
), business: widget.business,
); ),
);
} else {
showSignInRequiredAlert();
}
} }
void showDeleteBookmarkAlert(BookmarkedBusiness? bookmarkBusiness) { void showDeleteBookmarkAlert(BookmarkedBusiness? bookmarkBusiness) {
if (_isUserSignedIn) {
showDialog(
context: context,
builder: (context) => MihDeleteBookmarkAlert(
business: widget.business,
bookmarkBusiness: bookmarkBusiness,
startUpSearch: widget.startUpSearch,
));
} else {
showSignInRequiredAlert();
}
}
void showSignInRequiredAlert() {
showDialog( showDialog(
context: context, context: context,
builder: (context) => MihDeleteBookmarkAlert( builder: (context) => MihPackageAlert(
business: widget.business, alertIcon: Column(
bookmarkBusiness: bookmarkBusiness, children: [
startUpSearch: widget.startUpSearch, Icon(
)); MihIcons.mihLogo,
size: 125,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
],
),
alertTitle: "Let's Get Started",
alertBody: Column(
children: [
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,
),
),
),
)
],
),
alertColour: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
);
} }
} }

View File

@@ -1,4 +1,5 @@
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_reviews.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_reviews.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart';
@@ -108,6 +109,11 @@ class _MzansiBusinessProfileState extends State<MzansiBusinessProfile> {
_selcetedIndex = 4; _selcetedIndex = 4;
}); });
}; };
temp[const Icon(Icons.qr_code_rounded)] = () {
setState(() {
_selcetedIndex = 5;
});
};
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: _selcetedIndex,
@@ -160,6 +166,10 @@ class _MzansiBusinessProfileState extends State<MzansiBusinessProfile> {
MihMyBusinessTeam(arguments: widget.arguments), MihMyBusinessTeam(arguments: widget.arguments),
MihBusinessUserSearch(arguments: widget.arguments), MihBusinessUserSearch(arguments: widget.arguments),
MihBusinessReviews(business: widget.arguments.business!), MihBusinessReviews(business: widget.arguments.business!),
MihBusinessQrCode(
business: widget.arguments.business!,
startUpSearch: "",
),
]; ];
return toolBodies; return toolBodies;
} }
@@ -169,8 +179,9 @@ class _MzansiBusinessProfileState extends State<MzansiBusinessProfile> {
"Profile", "Profile",
"User", "User",
"Team", "Team",
"Add Member", "Add",
"Reviews", "Reviews",
"Share",
]; ];
return toolTitles; return toolTitles;
} }

View File

@@ -1,17 +1,24 @@
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_qr_code.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_reviews.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_reviews.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
class MzansiBusinessProfileView extends StatefulWidget { class MzansiBusinessProfileView extends StatefulWidget {
final BusinessViewArguments arguments; final BusinessViewArguments? arguments;
final String? businessId;
const MzansiBusinessProfileView({ const MzansiBusinessProfileView({
super.key, super.key,
required this.arguments, required this.arguments,
required this.businessId,
}); });
@override @override
@@ -21,21 +28,62 @@ class MzansiBusinessProfileView extends StatefulWidget {
class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> { class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
int _selcetedIndex = 0; int _selcetedIndex = 0;
Business? business;
String startUpSearch = "";
Future<void> _fetchBusinessDetails() async {
if (widget.arguments != null) {
setState(() {
business = widget.arguments!.business;
startUpSearch = widget.arguments!.startUpSearch ?? "";
});
} else if (widget.businessId != null) {
final biz = await MihBusinessDetailsServices()
.getBusinessDetailsByBusinessId(widget.businessId!);
if (biz == null) {
context.goNamed(
'mihHome',
extra: true,
);
} else {
KenLogger.success("Business found: ${biz.Name}");
setState(() {
business = biz;
startUpSearch = "";
});
}
}
}
@override
void initState() {
super.initState();
_fetchBusinessDetails();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackage( if (business == null) {
appActionButton: getAction(), KenLogger.warning("Business is null, showing loading indicator");
appTools: getTools(), return Scaffold(
appBody: getToolBody(), body: const Center(
appToolTitles: getToolTitle(), child: Mihloadingcircle(),
selectedbodyIndex: _selcetedIndex, ),
onIndexChange: (newValue) { );
setState(() { } else {
_selcetedIndex = newValue; return MihPackage(
}); appActionButton: getAction(),
}, appTools: getTools(),
); appBody: getToolBody(),
appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex,
onIndexChange: (newValue) {
setState(() {
_selcetedIndex = newValue;
});
},
);
}
} }
MihPackageAction getAction() { MihPackageAction getAction() {
@@ -47,7 +95,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
"mzansiDirectory", "mzansiDirectory",
extra: MzansiDirectoryArguments( extra: MzansiDirectoryArguments(
personalSearch: false, personalSearch: false,
startSearchText: widget.arguments.business.Name, startSearchText: business!.Name,
), ),
); );
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
@@ -67,6 +115,11 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
_selcetedIndex = 1; _selcetedIndex = 1;
}); });
}; };
temp[const Icon(Icons.qr_code_rounded)] = () {
setState(() {
_selcetedIndex = 2;
});
};
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selcetedIndex, selcetedIndex: _selcetedIndex,
@@ -76,10 +129,14 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
List<Widget> getToolBody() { List<Widget> getToolBody() {
List<Widget> toolBodies = [ List<Widget> toolBodies = [
MihBusinessDetailsView( MihBusinessDetailsView(
business: widget.arguments.business, business: business!,
startUpSearch: widget.arguments.startUpSearch, startUpSearch: startUpSearch,
), ),
MihBusinessReviews(business: widget.arguments.business), MihBusinessReviews(business: business!),
MihBusinessQrCode(
business: business!,
startUpSearch: startUpSearch,
)
]; ];
return toolBodies; return toolBodies;
} }
@@ -88,6 +145,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
List<String> toolTitles = [ List<String> toolTitles = [
"Profile", "Profile",
"Reviews", "Reviews",
"Share Business",
]; ];
return toolTitles; return toolTitles;
} }

View File

@@ -0,0 +1,349 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
import 'package:supertokens_flutter/supertokens.dart';
import 'package:url_launcher/url_launcher.dart';
class MihBusinessQrCode extends StatefulWidget {
final Business business;
final String? startUpSearch;
const MihBusinessQrCode({
super.key,
required this.business,
required this.startUpSearch,
});
@override
State<MihBusinessQrCode> createState() => _MihBusinessQrCodeState();
}
class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
late Future<String> futureImageUrl;
PlatformFile? file;
String qrCodedata =
"${AppEnviroment.baseAppUrl}/business-profile/view?business_id=";
int qrSize = 500;
bool _isUserSignedIn = false;
Future<void> _checkUserSession() async {
final doesSessionExist = await SuperTokens.doesSessionExist();
setState(() {
_isUserSignedIn = doesSessionExist;
});
}
String getQrCodeData(int qrSize) {
String color = MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")
.toARGB32()
.toRadixString(16)
.substring(2, 8);
// KenLogger.warning(color);
String bgColor = MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")
.toARGB32()
.toRadixString(16)
.substring(2, 8);
// KenLogger.warning(bgColor);
String encodedData =
Uri.encodeComponent("$qrCodedata${widget.business.business_id}");
return "https://api.qrserver.com/v1/create-qr-code/?data=$encodedData&size=${qrSize}x${qrSize}&bgcolor=$bgColor&color=$color";
}
Future<void> downloadQrCode() async {
if (_isUserSignedIn) {
final Uri uri = Uri.parse(getQrCodeData(1024));
if (!await launchUrl(uri)) {
throw 'Could not launch $uri';
}
} else {
showSignInRequiredAlert();
}
}
void showSignInRequiredAlert() {
showDialog(
context: context,
builder: (context) => MihPackageAlert(
alertIcon: Column(
children: [
Icon(
MihIcons.mihLogo,
size: 125,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
],
),
alertTitle: "Let's Get Started",
alertBody: Column(
children: [
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,
),
),
),
)
],
),
alertColour: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
);
}
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
_checkUserSession();
futureImageUrl =
MihFileApi.getMinioFileUrl(widget.business.logo_path, context);
}
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;
return MihPackageToolBody(
borderOn: false,
innerHorizontalPadding: 10,
bodyItem: getBody(screenSize, context),
);
}
Widget getBody(Size screenSize, BuildContext context) {
double profilePictureWidth = 150;
return SizedBox(
height: screenSize.height,
child: Stack(
alignment: Alignment.topCenter,
children: [
MihSingleChildScroll(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop"
? EdgeInsets.symmetric(horizontal: screenSize.width * 0.2)
: EdgeInsets.symmetric(
horizontal: screenSize.width * 0), //.075),
child: Padding(
padding: const EdgeInsets.only(top: 10.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(
decoration: BoxDecoration(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
borderRadius: BorderRadius.circular(20),
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
FutureBuilder(
future: futureImageUrl,
builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState ==
ConnectionState.done &&
asyncSnapshot.hasData) {
if (asyncSnapshot.requireData != "") {
return MihCircleAvatar(
imageFile: NetworkImage(
asyncSnapshot.requireData),
width: profilePictureWidth,
editable: false,
fileNameController:
TextEditingController(),
userSelectedfile: file,
frameColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
backgroundColor:
MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
onChange: () {},
);
} else {
return Icon(
MihIcons.iDontKnow,
size: profilePictureWidth,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
);
}
} else {
return Icon(
MihIcons.mihRing,
size: profilePictureWidth,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
);
}
},
),
FittedBox(
child: Text(
widget.business.Name,
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
),
FittedBox(
child: Text(
widget.business.type,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
),
const SizedBox(height: 10),
SizedBox(
width: 300,
height: 300,
child: CachedNetworkImage(
imageUrl: getQrCodeData(qrSize.toInt()),
placeholder: (context, url) =>
const Mihloadingcircle(),
errorWidget: (context, url, error) =>
const Icon(Icons.error),
),
),
const SizedBox(height: 10),
FittedBox(
child: Text(
"Scan & Connect",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
),
],
)),
),
),
),
),
),
),
Positioned(
right: 10,
bottom: 10,
child: MihFloatingMenu(
animatedIcon: AnimatedIcons.menu_close,
children: [
SpeedDialChild(
child: Icon(
Icons.download_rounded,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
label: "Download QR Code",
labelBackgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
labelStyle: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
),
backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onTap: () {
downloadQrCode();
},
)
]),
)
],
),
);
}
}