Merge pull request #240 from yaso-meth/NEW--Bookmark-Business
NEW--Bookmark-Business
@@ -71,8 +71,6 @@ class _MzansiInnovationHubState extends State<MzansiInnovationHub> {
|
||||
double width = MediaQuery.sizeOf(context).width;
|
||||
theme.setScreenType(width);
|
||||
precacheImage(theme.loadingImage(), context);
|
||||
precacheImage(theme.logoImage(), context);
|
||||
precacheImage(theme.logoFrame(), context);
|
||||
return MaterialApp(
|
||||
title: getTitle(),
|
||||
themeMode: ThemeMode.dark,
|
||||
|
||||
@@ -229,13 +229,15 @@ class MzansiAiArguments {
|
||||
}
|
||||
|
||||
class MzansiDirectoryArguments {
|
||||
final String? startUpSearch;
|
||||
final bool personalSearch;
|
||||
final int? packageIndex;
|
||||
final String? startSearchText;
|
||||
|
||||
MzansiDirectoryArguments(
|
||||
this.startUpSearch,
|
||||
this.personalSearch,
|
||||
);
|
||||
MzansiDirectoryArguments({
|
||||
required this.personalSearch,
|
||||
this.packageIndex,
|
||||
required this.startSearchText,
|
||||
});
|
||||
}
|
||||
|
||||
class TestArguments {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
class BookmarkedBusiness {
|
||||
final int idbookmarked_businesses;
|
||||
final String app_id;
|
||||
final String business_id;
|
||||
final String business_name;
|
||||
final String created_date;
|
||||
|
||||
BookmarkedBusiness({
|
||||
required this.idbookmarked_businesses,
|
||||
required this.app_id,
|
||||
required this.business_id,
|
||||
required this.business_name,
|
||||
required this.created_date,
|
||||
});
|
||||
factory BookmarkedBusiness.fromJson(Map<String, dynamic> json) {
|
||||
return switch (json) {
|
||||
{
|
||||
"idbookmarked_businesses": int idbookmarked_businesses,
|
||||
"app_id": String app_id,
|
||||
"business_id": String business_id,
|
||||
"business_name": String business_name,
|
||||
"created_date": String created_date,
|
||||
} =>
|
||||
BookmarkedBusiness(
|
||||
idbookmarked_businesses: idbookmarked_businesses,
|
||||
app_id: app_id,
|
||||
business_id: business_id,
|
||||
business_name: business_name,
|
||||
created_date: created_date,
|
||||
),
|
||||
_ => throw const FormatException(
|
||||
'Failed to load bookmarked business objects'),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,8 @@ class BusinessReview {
|
||||
date_time: date_time,
|
||||
reviewer: reviewer,
|
||||
),
|
||||
_ => throw const FormatException('Failed to load loyalty card objects'),
|
||||
_ =>
|
||||
throw const FormatException('Failed to load Business Review objects'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_business_profile_preview.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_personal_profile_preview.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/components/mih_business_info_card.dart';
|
||||
// import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_business_info_card.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
|
||||
@@ -30,6 +31,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
|
||||
import 'package:redacted/redacted.dart';
|
||||
|
||||
class PackageToolOne extends StatefulWidget {
|
||||
final AppUser user;
|
||||
@@ -291,16 +293,34 @@ class _PackageToolOneState extends State<PackageToolOne> {
|
||||
}
|
||||
}),
|
||||
const SizedBox(height: 10),
|
||||
// MihBusinessCard(
|
||||
// businessid: "123456",
|
||||
// businessName: "Mzansi Innovation Hub",
|
||||
// cellNumber: "0788300006",
|
||||
// email: "yasien.meth@mzansi-innovation-hub.co.za",
|
||||
// gpsLocation: "-26.1853611, 28.134664",
|
||||
// website:
|
||||
// "https://app.mzansi-innovation-hub.co.za/privacy.html",
|
||||
// rating: 3.25,
|
||||
// ),
|
||||
Text("This text should be redacted").redacted(
|
||||
context: context,
|
||||
redact: true,
|
||||
),
|
||||
MihBusinessCard(
|
||||
business: Business(
|
||||
"business_id",
|
||||
"Name",
|
||||
"type",
|
||||
"registration_no",
|
||||
"logo_name",
|
||||
"logo_path",
|
||||
"contact_no",
|
||||
"bus_email",
|
||||
"app_id",
|
||||
"gps_location",
|
||||
"practice_no",
|
||||
"vat_no",
|
||||
"website",
|
||||
"rating",
|
||||
"mission_vision",
|
||||
),
|
||||
startUpSearch: '',
|
||||
width: 300,
|
||||
).redacted(
|
||||
context: context,
|
||||
redact: true,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Divider(
|
||||
color:
|
||||
|
||||
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 54 KiB |
@@ -44,7 +44,7 @@ class _MihPackageState extends State<MihPackage>
|
||||
int nextPage =
|
||||
currentPage + 1 < widget.appBody.length ? currentPage + 1 : currentPage;
|
||||
if (nextPage != currentPage) {
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
await _pageController.animateTo(
|
||||
currentOffset + peakOffset,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
@@ -86,10 +86,24 @@ class _MihPackageState extends State<MihPackage>
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 400),
|
||||
);
|
||||
// if (!MzansiInnovationHub.of(context)!.theme.kIsWeb) {
|
||||
// // Trigger the peak animation on start (or call this elsewhere)
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// _peakAnimation();
|
||||
// });
|
||||
// }
|
||||
if (!MzansiInnovationHub.of(context)!.theme.kIsWeb) {
|
||||
// Trigger the peak animation on start (or call this elsewhere)
|
||||
// Trigger the peak animation only AFTER the route transition is complete
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_peakAnimation();
|
||||
final ModalRoute? currentRoute = ModalRoute.of(context);
|
||||
if (currentRoute != null) {
|
||||
currentRoute.animation?.addStatusListener((status) {
|
||||
if (status == AnimationStatus.completed && mounted) {
|
||||
// Ensure the widget is still mounted and the animation is completed
|
||||
_peakAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ class _MihSearchBarState extends State<MihSearchBar> {
|
||||
color: widget.fillColor,
|
||||
child: AnimatedContainer(
|
||||
// Keep AnimatedContainer for width/height transitions
|
||||
alignment: Alignment.centerLeft,
|
||||
width: widget.width,
|
||||
height: widget.height ?? 50,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
@@ -123,6 +124,7 @@ class _MihSearchBarState extends State<MihSearchBar> {
|
||||
),
|
||||
),
|
||||
child: TextField(
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
controller: widget.controller, // Assign the controller
|
||||
focusNode: widget.searchFocusNode,
|
||||
autocorrect: true,
|
||||
@@ -134,17 +136,20 @@ class _MihSearchBarState extends State<MihSearchBar> {
|
||||
style: TextStyle(
|
||||
color: widget.hintColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
),
|
||||
cursorColor: widget.hintColor,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
hintText: widget.hintText,
|
||||
hintStyle: TextStyle(
|
||||
color: widget.hintColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
),
|
||||
border: InputBorder.none,
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 20.0, vertical: 12.0),
|
||||
const EdgeInsets.symmetric(horizontal: 10.0, vertical: 15.0),
|
||||
prefixIcon: GestureDetector(
|
||||
onTap: widget.onPrefixIconTap,
|
||||
child: getPrefixIcon(),
|
||||
@@ -152,12 +157,15 @@ class _MihSearchBarState extends State<MihSearchBar> {
|
||||
suffixIcon: Row(
|
||||
// Use a Row for multiple suffix icons
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
// Optional suffix tools
|
||||
if (widget.suffixTools != null) ...widget.suffixTools!,
|
||||
// Clear Icon (conditionally visible)
|
||||
if (_showClearIcon) // Only show if input is not empty
|
||||
IconButton(
|
||||
iconSize: 35,
|
||||
icon: Icon(Icons.clear,
|
||||
color: widget.hintColor), // Clear icon
|
||||
onPressed: widget.onClearIconTap ??
|
||||
|
||||
@@ -163,54 +163,6 @@ class MihTheme {
|
||||
}
|
||||
}
|
||||
|
||||
AssetImage logoFrame() {
|
||||
if (mode == "Dark") {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/frame_dark.png',
|
||||
);
|
||||
} else {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/frame_light.png',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AssetImage altLogoFrame() {
|
||||
if (mode == "Light") {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/frame_dark.png',
|
||||
);
|
||||
} else {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/frame_light.png',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AssetImage logoImage() {
|
||||
if (mode == "Dark") {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/logo_dark.png',
|
||||
);
|
||||
} else {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/logo_light.png',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AssetImage altLogoImage() {
|
||||
if (mode == "Light") {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/logo_dark.png',
|
||||
);
|
||||
} else {
|
||||
return const AssetImage(
|
||||
'lib/mih_components/mih_package_components/assets/images/logo_light.png',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AssetImage loadingImage() {
|
||||
if (mode == "Dark") {
|
||||
loading = const AssetImage(
|
||||
|
||||
@@ -47,8 +47,6 @@ class _MihInfoState extends State<MihInfo> {
|
||||
bio += "(University of the Western Cape)\n";
|
||||
bio +=
|
||||
"6 Year of banking experience with one of the big 5 banks of South Africa.";
|
||||
ImageProvider logoFrame =
|
||||
MzansiInnovationHub.of(context)!.theme.altLogoFrame();
|
||||
return Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
@@ -61,18 +59,22 @@ class _MihInfoState extends State<MihInfo> {
|
||||
alignment: Alignment.center,
|
||||
fit: StackFit.loose,
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
backgroundImage: const AssetImage(
|
||||
"lib/mih_components/mih_package_components/assets/images/founder.jpg"),
|
||||
//'https://media.licdn.com/dms/image/D4D03AQGd1-QhjtWWpA/profile-displayphoto-shrink_400_400/0/1671698053061?e=2147483647&v=beta&t=a3dJI5yxs5-KeXjj10LcNCFuC9IOfa8nNn3k_Qyr0CA'),
|
||||
radius: 75,
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 4.0),
|
||||
child: CircleAvatar(
|
||||
backgroundColor:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
backgroundImage: const AssetImage(
|
||||
"lib/mih_components/mih_package_components/assets/images/founder.jpg"),
|
||||
//'https://media.licdn.com/dms/image/D4D03AQGd1-QhjtWWpA/profile-displayphoto-shrink_400_400/0/1671698053061?e=2147483647&v=beta&t=a3dJI5yxs5-KeXjj10LcNCFuC9IOfa8nNn3k_Qyr0CA'),
|
||||
radius: 75,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
MihIcons.mihRing,
|
||||
size: 165,
|
||||
color: MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
SizedBox(
|
||||
width: 165,
|
||||
child: Image(image: logoFrame),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -61,35 +61,6 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
|
||||
backgroundColor:
|
||||
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
// MIHProfilePicture(
|
||||
// profilePictureFile: widget.propicFile,
|
||||
// proPicController: proPicController,
|
||||
// proPic: null,
|
||||
// width: 60,
|
||||
// radius: 27,
|
||||
// drawerMode: true,
|
||||
// editable: false,
|
||||
// frameColor: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
// onChange: (newProPic) {},
|
||||
// ),
|
||||
|
||||
// Stack(
|
||||
// alignment: Alignment.center,
|
||||
// fit: StackFit.loose,
|
||||
// children: [
|
||||
// CircleAvatar(
|
||||
// backgroundColor:
|
||||
// MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
// backgroundImage: widget.propicFile,
|
||||
// //'https://media.licdn.com/dms/image/D4D03AQGd1-QhjtWWpA/profile-displayphoto-shrink_400_400/0/1671698053061?e=2147483647&v=beta&t=a3dJI5yxs5-KeXjj10LcNCFuC9IOfa8nNn3k_Qyr0CA'),
|
||||
// radius: 27,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: 60,
|
||||
// child: Image(image: logoFrame),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,24 +86,22 @@ class _MIHHomeLegacyState extends State<MIHHomeLegacy> {
|
||||
// );
|
||||
|
||||
void setAppsNewPersonal(List<MIHTile> tileList) {
|
||||
ImageProvider logo = MzansiInnovationHub.of(context)!.theme.logoImage();
|
||||
|
||||
if (widget.signedInUser.fname == "") {
|
||||
tileList.add(MIHTile(
|
||||
videoID: "jFV3NN65DtQ",
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed('/mzansi-profile',
|
||||
arguments: AppProfileUpdateArguments(
|
||||
widget.signedInUser, widget.propicFile));
|
||||
},
|
||||
tileName: "Setup Profie",
|
||||
tileIcon: Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
child: Image(image: logo),
|
||||
),
|
||||
p: getPrim(),
|
||||
s: getSec(),
|
||||
));
|
||||
// tileList.add(MIHTile(
|
||||
// videoID: "jFV3NN65DtQ",
|
||||
// onTap: () {
|
||||
// Navigator.of(context).pushNamed('/mzansi-profile',
|
||||
// arguments: AppProfileUpdateArguments(
|
||||
// widget.signedInUser, widget.propicFile));
|
||||
// },
|
||||
// tileName: "Setup Profie",
|
||||
// tileIcon: Padding(
|
||||
// padding: const EdgeInsets.all(15.0),
|
||||
// child: Image(image: logo),
|
||||
// ),
|
||||
// p: getPrim(),
|
||||
// s: getSec(),
|
||||
// ));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,27 +126,26 @@ class _MIHHomeLegacyState extends State<MIHHomeLegacy> {
|
||||
}
|
||||
|
||||
void setAppsPersonal(List<MIHTile> tileList) {
|
||||
ImageProvider logo = MzansiInnovationHub.of(context)!.theme.logoImage();
|
||||
ImageProvider aiLogo = MzansiInnovationHub.of(context)!.theme.aiLogoImage();
|
||||
tileList.add(MIHTile(
|
||||
videoID: "P2bM9eosJ_A",
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-profile',
|
||||
arguments: AppProfileUpdateArguments(
|
||||
widget.signedInUser,
|
||||
widget.propicFile,
|
||||
),
|
||||
);
|
||||
},
|
||||
tileName: "Mzansi Profile",
|
||||
tileIcon: Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
child: Image(image: logo),
|
||||
),
|
||||
p: getPrim(),
|
||||
s: getSec(),
|
||||
));
|
||||
// tileList.add(MIHTile(
|
||||
// videoID: "P2bM9eosJ_A",
|
||||
// onTap: () {
|
||||
// Navigator.of(context).pushNamed(
|
||||
// '/mzansi-profile',
|
||||
// arguments: AppProfileUpdateArguments(
|
||||
// widget.signedInUser,
|
||||
// widget.propicFile,
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// tileName: "Mzansi Profile",
|
||||
// tileIcon: Padding(
|
||||
// padding: const EdgeInsets.all(15.0),
|
||||
// child: Image(image: logo),
|
||||
// ),
|
||||
// p: getPrim(),
|
||||
// s: getSec(),
|
||||
// ));
|
||||
tileList.add(MIHTile(
|
||||
videoID: "6l8h0sjt08k",
|
||||
onTap: () {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.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_business_profile_preview.dart';
|
||||
|
||||
class BuildFavouriteBusinessesList extends StatefulWidget {
|
||||
final List<Business?> favouriteBusinesses;
|
||||
final String? myLocation;
|
||||
const BuildFavouriteBusinessesList({
|
||||
super.key,
|
||||
required this.favouriteBusinesses,
|
||||
required this.myLocation,
|
||||
});
|
||||
|
||||
@override
|
||||
State<BuildFavouriteBusinessesList> createState() =>
|
||||
_BuildFavouriteBusinessesListState();
|
||||
}
|
||||
|
||||
class _BuildFavouriteBusinessesListState
|
||||
extends State<BuildFavouriteBusinessesList> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: widget.favouriteBusinesses.length,
|
||||
separatorBuilder: (BuildContext context, index) {
|
||||
return Divider(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
);
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
final Business? business = widget.favouriteBusinesses[index];
|
||||
|
||||
if (business == null) {
|
||||
return const SizedBox(); // Or a placeholder if a business couldn't be loaded
|
||||
}
|
||||
|
||||
return Material(
|
||||
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
'/business-profile/view',
|
||||
arguments: BusinessViewArguments(
|
||||
business,
|
||||
business.Name,
|
||||
),
|
||||
);
|
||||
},
|
||||
splashColor: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor()
|
||||
.withOpacity(0.2),
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 25,
|
||||
),
|
||||
child: MihBusinessProfilePreview(
|
||||
business: business, myLocation: widget.myLocation),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.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_tools.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_favourite_businesses.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
|
||||
|
||||
class MzansiDirectory extends StatefulWidget {
|
||||
final MzansiDirectoryArguments arguments;
|
||||
@@ -18,9 +21,22 @@ class MzansiDirectory extends StatefulWidget {
|
||||
|
||||
class _MzansiDirectoryState extends State<MzansiDirectory> {
|
||||
int _selcetedIndex = 0;
|
||||
late Future<Position?> futurePosition =
|
||||
MIHLocationAPI().getGPSPosition(context);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.arguments.packageIndex == null) {
|
||||
_selcetedIndex = 0;
|
||||
} else {
|
||||
_selcetedIndex = widget.arguments.packageIndex!;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print('MzansiDirectory build method called!');
|
||||
return MihPackage(
|
||||
appActionButton: getAction(),
|
||||
appTools: getTools(),
|
||||
@@ -37,12 +53,41 @@ class _MzansiDirectoryState extends State<MzansiDirectory> {
|
||||
|
||||
List<Widget> getToolBody() {
|
||||
List<Widget> toolBodies = [
|
||||
MihSearchMzansi(
|
||||
startUpSearch: widget.arguments.startUpSearch,
|
||||
personalSearch: widget.arguments.personalSearch,
|
||||
),
|
||||
FutureBuilder(
|
||||
future: futurePosition,
|
||||
builder: (context, asyncSnapshot) {
|
||||
String myLocation = "";
|
||||
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
|
||||
myLocation = "Getting Your GPS Location Ready";
|
||||
} else {
|
||||
myLocation = asyncSnapshot.data
|
||||
.toString()
|
||||
.replaceAll("Latitude: ", "")
|
||||
.replaceAll("Longitude: ", "");
|
||||
}
|
||||
return MihSearchMzansi(
|
||||
personalSearch: widget.arguments.personalSearch,
|
||||
myLocation: myLocation,
|
||||
startSearchText: widget.arguments.startSearchText,
|
||||
);
|
||||
}),
|
||||
// MihContacts(),
|
||||
// MihFavouriteBusinesses(),
|
||||
FutureBuilder(
|
||||
future: futurePosition,
|
||||
builder: (context, asyncSnapshot) {
|
||||
String myLocation = "";
|
||||
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
|
||||
myLocation = "Getting Your GPS Location Ready";
|
||||
} else {
|
||||
myLocation = asyncSnapshot.data
|
||||
.toString()
|
||||
.replaceAll("Latitude: ", "")
|
||||
.replaceAll("Longitude: ", "");
|
||||
}
|
||||
return MihFavouriteBusinesses(
|
||||
myLocation: myLocation,
|
||||
);
|
||||
}),
|
||||
];
|
||||
return toolBodies;
|
||||
}
|
||||
@@ -70,11 +115,11 @@ class _MzansiDirectoryState extends State<MzansiDirectory> {
|
||||
// _selcetedIndex = 1;
|
||||
// });
|
||||
// };
|
||||
// temp[const Icon(Icons.business_center)] = () {
|
||||
// setState(() {
|
||||
// _selcetedIndex = 2;
|
||||
// });
|
||||
// };
|
||||
temp[const Icon(Icons.business_center)] = () {
|
||||
setState(() {
|
||||
_selcetedIndex = 1;
|
||||
});
|
||||
};
|
||||
return MihPackageTools(
|
||||
tools: temp,
|
||||
selcetedIndex: _selcetedIndex,
|
||||
@@ -84,8 +129,8 @@ class _MzansiDirectoryState extends State<MzansiDirectory> {
|
||||
List<String> getToolTitle() {
|
||||
List<String> toolTitles = [
|
||||
"Mzansi Search",
|
||||
"Contacts",
|
||||
"Favourite Businesses",
|
||||
"Contacts",
|
||||
];
|
||||
return toolTitles;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ class _MzansiDirectoryTileState extends State<MzansiDirectoryTile> {
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-directory',
|
||||
arguments: MzansiDirectoryArguments(
|
||||
null, // startUpSearch
|
||||
true, // personalSearch
|
||||
personalSearch: true,
|
||||
startSearchText: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.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/business.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_search_bar.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_packages/mzansi_directory/builders/build_favourite_businesses_list.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
|
||||
import 'package:supertokens_flutter/supertokens.dart';
|
||||
|
||||
class MihFavouriteBusinesses extends StatefulWidget {
|
||||
const MihFavouriteBusinesses({super.key});
|
||||
final String? myLocation;
|
||||
const MihFavouriteBusinesses({
|
||||
super.key,
|
||||
required this.myLocation,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihFavouriteBusinesses> createState() => _MihFavouriteBusinessesState();
|
||||
@@ -15,6 +28,70 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
|
||||
final TextEditingController businessSearchController =
|
||||
TextEditingController();
|
||||
final FocusNode searchFocusNode = FocusNode();
|
||||
late Future<List<BookmarkedBusiness>> boookmarkedBusinessListFuture;
|
||||
List<BookmarkedBusiness> listBookmarkedBusinesses = [];
|
||||
final ValueNotifier<List<Business?>> searchBookmarkedBusinesses =
|
||||
ValueNotifier([]);
|
||||
late Future<Map<String, Business?>> businessDetailsMapFuture;
|
||||
Map<String, Business?> _businessDetailsMap = {};
|
||||
Timer? _debounce;
|
||||
|
||||
Future<Map<String, Business?>>
|
||||
getAndMapAllBusinessDetailsForBookmarkedBusinesses() async {
|
||||
String user_id = await SuperTokens.getUserId();
|
||||
List<BookmarkedBusiness> bookmarked = await MihMzansiDirectoryServices()
|
||||
.getAllUserBookmarkedBusiness(user_id);
|
||||
listBookmarkedBusinesses = bookmarked;
|
||||
Map<String, Business?> businessMap = {};
|
||||
List<Future<Business?>> detailFutures = [];
|
||||
for (var item in bookmarked) {
|
||||
detailFutures.add(MihBusinessDetailsServices()
|
||||
.getBusinessDetailsByBusinessId(item.business_id));
|
||||
}
|
||||
List<Business?> details = await Future.wait(detailFutures);
|
||||
for (int i = 0; i < bookmarked.length; i++) {
|
||||
businessMap[bookmarked[i].business_id] = details[i];
|
||||
}
|
||||
_businessDetailsMap = businessMap;
|
||||
_filterAndSetBusinesses();
|
||||
return businessMap;
|
||||
}
|
||||
|
||||
void _filterAndSetBusinesses() {
|
||||
List<Business?> businessesToDisplay = [];
|
||||
String query = businessSearchController.text.toLowerCase();
|
||||
for (var bookmarked in listBookmarkedBusinesses) {
|
||||
if (bookmarked.business_name.toLowerCase().contains(query)) {
|
||||
if (_businessDetailsMap.containsKey(bookmarked.business_id)) {
|
||||
businessesToDisplay.add(_businessDetailsMap[bookmarked.business_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
searchBookmarkedBusinesses.value = businessesToDisplay;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
businessSearchController.dispose();
|
||||
searchFocusNode.dispose();
|
||||
searchBookmarkedBusinesses.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
businessDetailsMapFuture =
|
||||
getAndMapAllBusinessDetailsForBookmarkedBusinesses();
|
||||
businessSearchController.addListener(() {
|
||||
if (_debounce?.isActive ?? false) {
|
||||
_debounce!.cancel();
|
||||
}
|
||||
_debounce = Timer(const Duration(milliseconds: 200), () {
|
||||
_filterAndSetBusinesses();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -44,6 +121,130 @@ class _MihFavouriteBusinessesState extends State<MihFavouriteBusinesses> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
FutureBuilder<Map<String, Business?>>(
|
||||
future: businessDetailsMapFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Mihloadingcircle(
|
||||
message: "Getting your favourites",
|
||||
);
|
||||
} else if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||
// No need to re-filter here, _filterAndSetBusinesses is called in initState
|
||||
// and by the text controller listener.
|
||||
return ValueListenableBuilder<List<Business?>>(
|
||||
valueListenable:
|
||||
searchBookmarkedBusinesses, // Listen to changes in this
|
||||
builder: (context, businesses, child) {
|
||||
// Display message if no results after search
|
||||
if (businesses.isEmpty &&
|
||||
businessSearchController.text.isNotEmpty) {
|
||||
return Column(
|
||||
children: [
|
||||
const SizedBox(height: 50),
|
||||
Icon(
|
||||
Icons
|
||||
.search_off_rounded, // A different icon for "no results"
|
||||
size: 150,
|
||||
color: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10.0),
|
||||
child: SizedBox(
|
||||
width: 500,
|
||||
child: Text(
|
||||
"No businesses found for '${businessSearchController.text}'", // Specific message for no search results
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (businesses.isEmpty) {
|
||||
// Initial empty state
|
||||
return Column(
|
||||
children: [
|
||||
const SizedBox(height: 50),
|
||||
Icon(
|
||||
Icons.business_center_rounded,
|
||||
size: 150,
|
||||
color: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10.0),
|
||||
child: SizedBox(
|
||||
width: 500,
|
||||
child: Text(
|
||||
"No favourites yet, use Mzansi Search to find and bookmark businesses you like",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return BuildFavouriteBusinessesList(
|
||||
favouriteBusinesses:
|
||||
businesses, // Pass the filtered list from ValueNotifier
|
||||
myLocation: widget.myLocation,
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// This block handles the case where there are no bookmarked businesses initially
|
||||
return Column(
|
||||
children: [
|
||||
const SizedBox(height: 50),
|
||||
Icon(
|
||||
Icons.business_center_rounded,
|
||||
size: 150,
|
||||
color: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: SizedBox(
|
||||
width: 500,
|
||||
child: Text(
|
||||
"No favourites yet, use Mzansi Search to find and bookmark businesses you like",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
"Error loading bookmarked businesses: ${snapshot.error}"), // Show specific error
|
||||
);
|
||||
} else {
|
||||
// Fallback for unexpected states
|
||||
return Center(
|
||||
child: Text("An unknown error occurred."),
|
||||
);
|
||||
}
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.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_dropdwn_field.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_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
|
||||
@@ -10,17 +11,19 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_business_search_resultsList.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/builders/build_user_search_results_list.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_location_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
|
||||
|
||||
class MihSearchMzansi extends StatefulWidget {
|
||||
final String? startUpSearch;
|
||||
final bool personalSearch;
|
||||
final String? myLocation;
|
||||
final String? startSearchText;
|
||||
const MihSearchMzansi({
|
||||
super.key,
|
||||
required this.startUpSearch,
|
||||
required this.personalSearch,
|
||||
required this.myLocation,
|
||||
required this.startSearchText,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -29,14 +32,62 @@ class MihSearchMzansi extends StatefulWidget {
|
||||
|
||||
class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||
final TextEditingController mzansiSearchController = TextEditingController();
|
||||
final TextEditingController businessTypeController = TextEditingController();
|
||||
final FocusNode searchFocusNode = FocusNode();
|
||||
late bool userSearch;
|
||||
Future<List<AppUser>?> futureUserSearchResults = Future.value();
|
||||
Future<List<Business>?> futureBusinessSearchResults = Future.value();
|
||||
late Future<Position?> futurePosition =
|
||||
MIHLocationAPI().getGPSPosition(context);
|
||||
List<AppUser> userSearchResults = [];
|
||||
List<Business> businessSearchResults = [];
|
||||
late Future<List<String>> availableBusinessTypes;
|
||||
bool filterOn = false;
|
||||
|
||||
void swapPressed() {
|
||||
setState(() {
|
||||
userSearch = !userSearch;
|
||||
if (filterOn) {
|
||||
filterOn = !filterOn;
|
||||
}
|
||||
});
|
||||
if (businessTypeController.text.isNotEmpty) {
|
||||
setState(() {
|
||||
futureBusinessSearchResults = Future.value();
|
||||
businessTypeController.clear();
|
||||
});
|
||||
}
|
||||
searchPressed();
|
||||
}
|
||||
|
||||
void clearAll() {
|
||||
setState(() {
|
||||
futureUserSearchResults = Future.value();
|
||||
futureBusinessSearchResults = Future.value();
|
||||
mzansiSearchController.clear();
|
||||
businessTypeController.clear();
|
||||
});
|
||||
}
|
||||
|
||||
void searchPressed() {
|
||||
setState(() {
|
||||
// userSearch = !userSearch;
|
||||
if (userSearch && mzansiSearchController.text.isNotEmpty) {
|
||||
futureUserSearchResults =
|
||||
MihUserServices().searchUsers(mzansiSearchController.text, context);
|
||||
} else {
|
||||
if (
|
||||
// mzansiSearchController.text.isNotEmpty &&
|
||||
businessTypeController.text.isNotEmpty) {
|
||||
futureBusinessSearchResults = MihBusinessDetailsServices()
|
||||
.searchBusinesses(mzansiSearchController.text,
|
||||
businessTypeController.text, context);
|
||||
} else if (mzansiSearchController.text.isNotEmpty) {
|
||||
futureBusinessSearchResults = MihBusinessDetailsServices()
|
||||
.searchBusinesses(mzansiSearchController.text,
|
||||
businessTypeController.text, context);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@@ -49,13 +100,13 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||
super.initState();
|
||||
setState(() {
|
||||
userSearch = widget.personalSearch;
|
||||
mzansiSearchController.text = widget.startUpSearch ?? "";
|
||||
if (userSearch) {
|
||||
futureUserSearchResults =
|
||||
MihUserServices().searchUsers(mzansiSearchController.text, context);
|
||||
availableBusinessTypes =
|
||||
MihBusinessDetailsServices().fetchAllBusinessTypes();
|
||||
if (widget.startSearchText != null) {
|
||||
mzansiSearchController.text = widget.startSearchText!;
|
||||
searchPressed();
|
||||
} else {
|
||||
futureBusinessSearchResults = MihBusinessDetailsServices()
|
||||
.searchBusinesses(mzansiSearchController.text, context);
|
||||
mzansiSearchController.text = "";
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -76,76 +127,132 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: width / 20),
|
||||
child: MihSearchBar(
|
||||
controller: mzansiSearchController,
|
||||
hintText: "Search Mzansi",
|
||||
prefixIcon: Icons.search,
|
||||
prefixAltIcon: userSearch ? Icons.person : Icons.business,
|
||||
suffixTools: [
|
||||
IconButton(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: MihSearchBar(
|
||||
controller: mzansiSearchController,
|
||||
hintText: "Search Mzansi",
|
||||
prefixIcon: Icons.search,
|
||||
prefixAltIcon: userSearch ? Icons.person : Icons.business,
|
||||
suffixTools: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
swapPressed();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.swap_horiz_rounded,
|
||||
size: 35,
|
||||
color: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
],
|
||||
fillColor:
|
||||
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
hintColor:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onPrefixIconTap: () {
|
||||
searchPressed();
|
||||
},
|
||||
onClearIconTap: () {
|
||||
clearAll();
|
||||
},
|
||||
searchFocusNode: searchFocusNode,
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !userSearch,
|
||||
child: const SizedBox(width: 10),
|
||||
),
|
||||
Visibility(
|
||||
visible: !userSearch,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
if (filterOn) {
|
||||
clearAll();
|
||||
}
|
||||
setState(() {
|
||||
// searchTypeVisibility = !searchTypeVisibility;
|
||||
userSearch = !userSearch;
|
||||
if (userSearch) {
|
||||
futureUserSearchResults = MihUserServices()
|
||||
.searchUsers(
|
||||
mzansiSearchController.text, context);
|
||||
} else {
|
||||
futureBusinessSearchResults =
|
||||
MihBusinessDetailsServices().searchBusinesses(
|
||||
mzansiSearchController.text, context);
|
||||
}
|
||||
filterOn = !filterOn;
|
||||
});
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.swap_horiz_rounded,
|
||||
!filterOn
|
||||
? Icons.filter_list_rounded
|
||||
: Icons.filter_list_off_rounded,
|
||||
size: 35,
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
))
|
||||
color: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
fillColor:
|
||||
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
hintColor: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onPrefixIconTap: () {
|
||||
if (userSearch) {
|
||||
setState(() {
|
||||
futureUserSearchResults = MihUserServices()
|
||||
.searchUsers(mzansiSearchController.text, context);
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
futureBusinessSearchResults = MihBusinessDetailsServices()
|
||||
.searchBusinesses(mzansiSearchController.text, context);
|
||||
});
|
||||
}
|
||||
},
|
||||
onClearIconTap: () {
|
||||
setState(() {
|
||||
futureUserSearchResults = Future.value();
|
||||
futureBusinessSearchResults = Future.value();
|
||||
mzansiSearchController.clear();
|
||||
});
|
||||
},
|
||||
searchFocusNode: searchFocusNode,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
FutureBuilder(
|
||||
future: futurePosition,
|
||||
future: availableBusinessTypes,
|
||||
builder: (context, asyncSnapshot) {
|
||||
String myLocation = "";
|
||||
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
|
||||
myLocation = "Getting Your GPS Location Ready";
|
||||
} else {
|
||||
myLocation = asyncSnapshot.data
|
||||
.toString()
|
||||
.replaceAll("Latitude: ", "")
|
||||
.replaceAll("Longitude: ", "");
|
||||
List<String> options = [];
|
||||
if (asyncSnapshot.connectionState == ConnectionState.done) {
|
||||
options.addAll(asyncSnapshot.data!);
|
||||
}
|
||||
return displaySearchResults(userSearch, myLocation);
|
||||
return Visibility(
|
||||
visible: filterOn,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: width / 20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: MihDropdownField(
|
||||
controller: businessTypeController,
|
||||
hintText: "Business Type Filter",
|
||||
dropdownOptions: options,
|
||||
requiredText: true,
|
||||
editable: true,
|
||||
enableSearch: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
MihButton(
|
||||
onPressed: () {
|
||||
if (businessTypeController.text.isNotEmpty) {
|
||||
searchPressed();
|
||||
} else {
|
||||
MihAlertServices().errorAlert(
|
||||
"Business Type Not Selected",
|
||||
"Please ensure you have selected a Business Type before seareching for Businesses of Mzansi",
|
||||
context,
|
||||
);
|
||||
}
|
||||
},
|
||||
buttonColor: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.successColor(),
|
||||
elevation: 10,
|
||||
child: Text(
|
||||
"Search",
|
||||
style: TextStyle(
|
||||
color: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
const SizedBox(height: 10),
|
||||
displaySearchResults(userSearch, widget.myLocation ?? ""),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.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_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.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_services/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
|
||||
import 'package:supertokens_flutter/supertokens.dart';
|
||||
|
||||
class MihAddBookmarkAlert extends StatefulWidget {
|
||||
final Business business;
|
||||
const MihAddBookmarkAlert({
|
||||
super.key,
|
||||
required this.business,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihAddBookmarkAlert> createState() => _MihAddBookmarkAlertState();
|
||||
}
|
||||
|
||||
class _MihAddBookmarkAlertState extends State<MihAddBookmarkAlert> {
|
||||
Future<void> addBookmark(String business_id) async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const Mihloadingcircle();
|
||||
},
|
||||
);
|
||||
String user_id = await SuperTokens.getUserId();
|
||||
await MihMzansiDirectoryServices()
|
||||
.addBookmarkedBusiness(user_id, business_id)
|
||||
.then((statusCode) {
|
||||
if (statusCode == 201) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
'/mzansi-directory',
|
||||
ModalRoute.withName('/'),
|
||||
arguments: MzansiDirectoryArguments(
|
||||
personalSearch: false, // personalSearch
|
||||
packageIndex: 1,
|
||||
startSearchText: widget.business.Name,
|
||||
),
|
||||
);
|
||||
MihAlertServices().successAlert(
|
||||
"Successfully Bookmarked Business!",
|
||||
"${widget.business.Name} has successfully been added to favourite businessess in the Mzansi Directory.",
|
||||
context,
|
||||
);
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
MihAlertServices().errorAlert(
|
||||
"Error Adding Bookmark",
|
||||
"An error occured while add ${widget.business.Name} to you Mzansi Directory, Please try again later.",
|
||||
context,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MihPackageAlert(
|
||||
alertColour: MihColors.getSecondaryColor(context),
|
||||
alertIcon: Icon(
|
||||
Icons.warning_rounded,
|
||||
size: 100,
|
||||
color: MihColors.getSecondaryColor(context),
|
||||
),
|
||||
alertTitle: "Bookmark Business",
|
||||
alertBody: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Are you sure you want to save ${widget.business.Name} to your Mzansi Directory?",
|
||||
style: TextStyle(
|
||||
color: MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
MihButton(
|
||||
width: 300,
|
||||
onPressed: () async {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
buttonColor:
|
||||
MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||
child: Text(
|
||||
"Cancel",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
MihButton(
|
||||
width: 300,
|
||||
onPressed: () {
|
||||
addBookmark(widget.business.business_id);
|
||||
},
|
||||
buttonColor:
|
||||
MzansiInnovationHub.of(context)!.theme.successColor(),
|
||||
child: Text(
|
||||
"Bookmark Business",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,26 @@
|
||||
import 'package:flutter/material.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/business.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_package_alert.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_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_services/mih_mzansi_directory_services.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 String? startUpSearch;
|
||||
// final String businessid;
|
||||
// final String businessName;
|
||||
// final String cellNumber;
|
||||
// final String email;
|
||||
// final String gpsLocation;
|
||||
// final String? website;
|
||||
// final double rating;
|
||||
final double width;
|
||||
const MihBusinessCard({
|
||||
super.key,
|
||||
required this.business,
|
||||
required this.startUpSearch,
|
||||
// required this.businessid,
|
||||
// required this.businessName,
|
||||
// required this.cellNumber,
|
||||
// required this.email,
|
||||
// required this.gpsLocation,
|
||||
// required this.rating,
|
||||
// this.website,
|
||||
required this.width,
|
||||
});
|
||||
|
||||
@@ -41,6 +29,16 @@ class MihBusinessCard extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
Future<BusinessReview?>? _businessReviewFuture;
|
||||
Future<BookmarkedBusiness?>? _bookmarkedBusinessFuture;
|
||||
|
||||
RedactedConfiguration getRedactedConfiguration() {
|
||||
return RedactedConfiguration(
|
||||
// redactedColor: Colors.pink,
|
||||
redactedColor: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _makePhoneCall(String phoneNumber) async {
|
||||
final Uri url = Uri(scheme: 'tel', path: phoneNumber);
|
||||
if (await canLaunchUrl(url)) {
|
||||
@@ -269,6 +267,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
String subLabel,
|
||||
IconData icon,
|
||||
Color? iconColor,
|
||||
bool redacted,
|
||||
Function()? ontap,
|
||||
) {
|
||||
return Material(
|
||||
@@ -288,16 +287,25 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 45,
|
||||
height: 45,
|
||||
decoration: BoxDecoration(
|
||||
color: iconColor,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Icon(
|
||||
icon,
|
||||
size: 35,
|
||||
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
child: FittedBox(
|
||||
child: Icon(
|
||||
icon,
|
||||
// size: 35,
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
),
|
||||
),
|
||||
).redacted(
|
||||
context: context,
|
||||
redact: redacted,
|
||||
configuration: getRedactedConfiguration(),
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
Expanded(
|
||||
@@ -316,6 +324,10 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
.primaryColor(),
|
||||
height: 1.0,
|
||||
),
|
||||
).redacted(
|
||||
context: context,
|
||||
redact: redacted,
|
||||
configuration: getRedactedConfiguration(),
|
||||
),
|
||||
Text(
|
||||
subLabel,
|
||||
@@ -326,6 +338,10 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
).redacted(
|
||||
context: context,
|
||||
redact: redacted,
|
||||
configuration: getRedactedConfiguration(),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -345,6 +361,27 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
);
|
||||
}
|
||||
|
||||
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();
|
||||
_businessReviewFuture = getUserReview();
|
||||
_bookmarkedBusinessFuture = getUserBookmark();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// double screenWidth = MediaQuery.of(context).size.width;
|
||||
@@ -369,6 +406,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
"Give us a quick call.",
|
||||
Icons.phone,
|
||||
MihColors.getGreenColor(context),
|
||||
false,
|
||||
() {
|
||||
// print("Calling ${widget.cellNumber}");
|
||||
_makePhoneCall(widget.business.contact_no);
|
||||
@@ -382,6 +420,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
"Send us an email.",
|
||||
Icons.email,
|
||||
MihColors.getPinkColor(context),
|
||||
false,
|
||||
() {
|
||||
// print("Emailing ${widget.email}");
|
||||
_launchEmail(
|
||||
@@ -391,58 +430,182 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
);
|
||||
},
|
||||
),
|
||||
Divider(
|
||||
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
Visibility(
|
||||
visible: isValidGps(widget.business.gps_location),
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
),
|
||||
_buildContactInfo(
|
||||
"Location",
|
||||
"Come visit us.",
|
||||
Icons.location_on,
|
||||
MihColors.getOrangeColor(context),
|
||||
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,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildContactInfo(
|
||||
"Location",
|
||||
"Come visit us.",
|
||||
Icons.location_on,
|
||||
MihColors.getOrangeColor(context),
|
||||
() {
|
||||
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:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
),
|
||||
_buildContactInfo(
|
||||
"Website",
|
||||
"Find out more about us.",
|
||||
Icons.vpn_lock,
|
||||
MihColors.getRedColor(context),
|
||||
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: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: _buildContactInfo(
|
||||
"Loading Rating",
|
||||
"Loading your rating.",
|
||||
Icons.star_rate_rounded,
|
||||
MihColors.getYellowColor(context),
|
||||
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: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
_buildContactInfo(
|
||||
ratingDisplayTitle,
|
||||
"Let us know how we are doing.",
|
||||
Icons.star_rate_rounded,
|
||||
MihColors.getYellowColor(context),
|
||||
false,
|
||||
() {
|
||||
businessReviewRatingWindow(
|
||||
businessReview, true, widget.width);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
Visibility(
|
||||
visible: widget.business.website.isNotEmpty &&
|
||||
widget.business.website != "",
|
||||
child: Divider(
|
||||
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: widget.business.website.isNotEmpty &&
|
||||
widget.business.website != "",
|
||||
child: _buildContactInfo(
|
||||
"Website",
|
||||
"Find out more about us.",
|
||||
Icons.vpn_lock,
|
||||
MihColors.getRedColor(context),
|
||||
() {
|
||||
_launchWebsite(widget.business.website);
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Divider(
|
||||
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
),
|
||||
),
|
||||
_buildContactInfo(
|
||||
"Rate Us",
|
||||
"Let us know how we are doing.",
|
||||
Icons.star_rate_rounded,
|
||||
MihColors.getYellowColor(context),
|
||||
() {
|
||||
businessReviewRatingWindow(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: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: _buildContactInfo(
|
||||
"Loading Bookmark",
|
||||
"Loading your bookmark.",
|
||||
Icons.bookmark_add_rounded,
|
||||
MihColors.getBluishPurpleColor(context),
|
||||
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: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
_buildContactInfo(
|
||||
bookmarkDisplayTitle,
|
||||
"Save us for later.",
|
||||
bookmarkBusiness == null
|
||||
? Icons.bookmark_add_rounded
|
||||
: Icons.bookmark_remove_rounded,
|
||||
MihColors.getBluishPurpleColor(context),
|
||||
false,
|
||||
() {
|
||||
// _launchWebsite(widget.website);
|
||||
if (bookmarkBusiness == null) {
|
||||
showAddBookmarkAlert();
|
||||
} else {
|
||||
showDeleteBookmarkAlert(bookmarkBusiness);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
// Padding(
|
||||
@@ -455,7 +618,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
// "Bookmark",
|
||||
// "Save us for later.",
|
||||
// Icons.bookmark_add_rounded,
|
||||
// MihColors.getBluishPurpleColor(context),
|
||||
// MihColors.getBluishPurpleColor(context),
|
||||
// () {
|
||||
// // _launchWebsite(widget.website);
|
||||
// print("Saving ${widget.business.Name} to Directory");
|
||||
@@ -476,115 +639,34 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
||||
}
|
||||
|
||||
Future<void> businessReviewRatingWindow(
|
||||
bool previouslyRated, double width) async {
|
||||
BusinessReview? myReview, bool previouslyRated, double width) async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => FutureBuilder(
|
||||
future: getUserReview(),
|
||||
builder: (context, asyncSnapshot) {
|
||||
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Mihloadingcircle(
|
||||
message: "Checking for previous reviews...",
|
||||
);
|
||||
} else if (asyncSnapshot.connectionState == ConnectionState.done) {
|
||||
return MihReviewBusinessWindow(
|
||||
business: widget.business,
|
||||
businessReview: asyncSnapshot.data,
|
||||
screenWidth: width,
|
||||
readOnly: false,
|
||||
startUpSearch: widget.startUpSearch,
|
||||
);
|
||||
} else {
|
||||
return MihPackageAlert(
|
||||
alertColour: MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||
alertIcon: Icon(
|
||||
Icons.warning_rounded,
|
||||
size: 100,
|
||||
color: MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||
),
|
||||
alertTitle: "Error Pulling Data",
|
||||
alertBody: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Please ensure you are connectede top the internet and you are running the latest version of MIH then try again.",
|
||||
style: TextStyle(
|
||||
color: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context) => MihReviewBusinessWindow(
|
||||
business: widget.business,
|
||||
businessReview: myReview,
|
||||
screenWidth: width,
|
||||
readOnly: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void showBookmarkAlert() {
|
||||
void showAddBookmarkAlert() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => MihPackageAlert(
|
||||
alertColour: MihColors.getSecondaryColor(context),
|
||||
alertIcon: Icon(
|
||||
Icons.warning_rounded,
|
||||
size: 100,
|
||||
color: MihColors.getSecondaryColor(context),
|
||||
),
|
||||
alertTitle: "Bookmark Business",
|
||||
alertBody: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Are you sure you want to save ${widget.business.Name} to your Mzansi Directory?",
|
||||
style: TextStyle(
|
||||
color: MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
MihButton(
|
||||
width: 300,
|
||||
onPressed: () async {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
buttonColor:
|
||||
MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||
child: Text(
|
||||
"Cancel",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
MihButton(
|
||||
width: 300,
|
||||
onPressed: () {},
|
||||
buttonColor:
|
||||
MzansiInnovationHub.of(context)!.theme.successColor(),
|
||||
child: Text(
|
||||
"Save Business",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
builder: (context) => MihAddBookmarkAlert(
|
||||
business: widget.business,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void showDeleteBookmarkAlert(BookmarkedBusiness? bookmarkBusiness) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => MihDeleteBookmarkAlert(
|
||||
business: widget.business,
|
||||
bookmarkBusiness: bookmarkBusiness,
|
||||
startUpSearch: widget.startUpSearch,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.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_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.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_services/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
|
||||
|
||||
class MihDeleteBookmarkAlert extends StatefulWidget {
|
||||
final Business business;
|
||||
final BookmarkedBusiness? bookmarkBusiness;
|
||||
final String? startUpSearch;
|
||||
const MihDeleteBookmarkAlert({
|
||||
super.key,
|
||||
required this.business,
|
||||
required this.bookmarkBusiness,
|
||||
required this.startUpSearch,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihDeleteBookmarkAlert> createState() => _MihDeleteBookmarkAlertState();
|
||||
}
|
||||
|
||||
class _MihDeleteBookmarkAlertState extends State<MihDeleteBookmarkAlert> {
|
||||
Future<void> deleteBookmark(int idbookmarked_businesses) async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const Mihloadingcircle();
|
||||
},
|
||||
);
|
||||
await MihMzansiDirectoryServices()
|
||||
.deleteBookmarkedBusiness(idbookmarked_businesses)
|
||||
.then((statusCode) {
|
||||
if (statusCode == 200) {
|
||||
// Navigator.of(context).pop(); //Remove loading circle
|
||||
// Navigator.of(context).pop(); //Remove window
|
||||
// Navigator.of(context).pop(); //Remove profile
|
||||
// Navigator.of(context).pop(); //Remove directory
|
||||
// Navigator.of(context).pushNamed(
|
||||
// '/mzansi-directory',
|
||||
// arguments: MzansiDirectoryArguments(
|
||||
// startUpSearch: widget.startUpSearch, // startUpSearch
|
||||
// personalSearch: false, // personalSearch
|
||||
// ),
|
||||
// );
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
'/mzansi-directory',
|
||||
ModalRoute.withName('/'),
|
||||
arguments: MzansiDirectoryArguments(
|
||||
personalSearch: false, // personalSearch
|
||||
packageIndex: 1,
|
||||
startSearchText: widget.business.Name,
|
||||
),
|
||||
);
|
||||
MihAlertServices().successAlert(
|
||||
"Successfully Removed Bookmark!",
|
||||
"${widget.business.Name} has successfully been removed your favourite businessess in the Mzansi Directory.",
|
||||
context,
|
||||
);
|
||||
} else {
|
||||
//error messagek
|
||||
Navigator.of(context).pop();
|
||||
MihAlertServices().errorAlert(
|
||||
"Error Adding Bookmark",
|
||||
"An error occured while add ${widget.business.Name} to you Mzansi Directory, Please try again later.",
|
||||
context,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MihPackageAlert(
|
||||
alertColour: MihColors.getSecondaryColor(context),
|
||||
alertIcon: Icon(
|
||||
Icons.warning_rounded,
|
||||
size: 100,
|
||||
color: MihColors.getSecondaryColor(context),
|
||||
),
|
||||
alertTitle: "Remove Bookmark",
|
||||
alertBody: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Are you sure you want to remove ${widget.business.Name} from your Mzansi Directory?",
|
||||
style: TextStyle(
|
||||
color: MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
MihButton(
|
||||
width: 300,
|
||||
onPressed: () async {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
buttonColor:
|
||||
MzansiInnovationHub.of(context)!.theme.successColor(),
|
||||
child: Text(
|
||||
"Cancel",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
MihButton(
|
||||
width: 300,
|
||||
onPressed: () {
|
||||
// todo: remove bookmark
|
||||
deleteBookmark(
|
||||
widget.bookmarkBusiness!.idbookmarked_businesses);
|
||||
},
|
||||
buttonColor:
|
||||
MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||
child: Text(
|
||||
"Remove Business",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -23,14 +23,12 @@ class MihReviewBusinessWindow extends StatefulWidget {
|
||||
final BusinessReview? businessReview;
|
||||
final double screenWidth;
|
||||
final bool readOnly;
|
||||
final String? startUpSearch;
|
||||
const MihReviewBusinessWindow({
|
||||
super.key,
|
||||
required this.business,
|
||||
required this.businessReview,
|
||||
required this.screenWidth,
|
||||
required this.readOnly,
|
||||
required this.startUpSearch,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -101,8 +99,8 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-directory',
|
||||
arguments: MzansiDirectoryArguments(
|
||||
widget.startUpSearch, // startUpSearch
|
||||
false, // personalSearch
|
||||
personalSearch: false, // personalSearch
|
||||
startSearchText: widget.business.Name,
|
||||
),
|
||||
);
|
||||
MihAlertServices().successAlert(
|
||||
@@ -191,8 +189,8 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-directory',
|
||||
arguments: MzansiDirectoryArguments(
|
||||
widget.startUpSearch, // startUpSearch
|
||||
false, // personalSearch
|
||||
personalSearch: false, // personalSearch
|
||||
startSearchText: widget.business.Name,
|
||||
),
|
||||
);
|
||||
MihAlertServices().successAlert(
|
||||
@@ -227,8 +225,8 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-directory',
|
||||
arguments: MzansiDirectoryArguments(
|
||||
widget.startUpSearch, // startUpSearch
|
||||
false, // personalSearch
|
||||
personalSearch: false, // personalSearch
|
||||
startSearchText: widget.business.Name,
|
||||
),
|
||||
);
|
||||
MihAlertServices().successAlert(
|
||||
@@ -386,7 +384,8 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
|
||||
emptyColor: MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
halfFilledColor: MihColors.getYellowColor(context), isHalfAllowed: true,
|
||||
halfFilledColor: MihColors.getYellowColor(context),
|
||||
isHalfAllowed: true,
|
||||
initialRating: widget.businessReview != null
|
||||
? double.parse(_reviewScoreController.text)
|
||||
: 1,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
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_components/mih_package_components/mih_package.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
||||
@@ -98,6 +99,11 @@ class _MzansiBusinessProfileState extends State<MzansiBusinessProfile> {
|
||||
_selcetedIndex = 3;
|
||||
});
|
||||
};
|
||||
temp[const Icon(Icons.star_rate_rounded)] = () {
|
||||
setState(() {
|
||||
_selcetedIndex = 4;
|
||||
});
|
||||
};
|
||||
return MihPackageTools(
|
||||
tools: temp,
|
||||
selcetedIndex: _selcetedIndex,
|
||||
@@ -149,6 +155,7 @@ class _MzansiBusinessProfileState extends State<MzansiBusinessProfile> {
|
||||
// MihBusinessProfile(arguments: widget.arguments),
|
||||
MihMyBusinessTeam(arguments: widget.arguments),
|
||||
MihBusinessUserSearch(arguments: widget.arguments),
|
||||
MihBusinessReviews(business: widget.arguments.business!),
|
||||
];
|
||||
return toolBodies;
|
||||
}
|
||||
@@ -159,6 +166,7 @@ class _MzansiBusinessProfileState extends State<MzansiBusinessProfile> {
|
||||
"User",
|
||||
"Team",
|
||||
"Add Member",
|
||||
"Reviews",
|
||||
];
|
||||
return toolTitles;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ class _MihBusinessReviewsState extends State<MihBusinessReviews> {
|
||||
businessReview: businessReview,
|
||||
screenWidth: width,
|
||||
readOnly: true,
|
||||
startUpSearch: null,
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -59,6 +58,7 @@ class _MihBusinessReviewsState extends State<MihBusinessReviews> {
|
||||
} else if (asyncSnapshot.connectionState == ConnectionState.done &&
|
||||
asyncSnapshot.hasData) {
|
||||
List<BusinessReview> reviews = asyncSnapshot.data!;
|
||||
print("Reviews: ${reviews.length}");
|
||||
if (reviews.isEmpty) {
|
||||
return Column(
|
||||
children: [
|
||||
@@ -133,11 +133,16 @@ class _MihBusinessReviewsState extends State<MihBusinessReviews> {
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"${reviews[index].rating_description.substring(0, reviews[index].rating_description.length >= descriptionDisplayCOunt ? descriptionDisplayCOunt : reviews[index].rating_description.length - 1)}${reviews[index].rating_description.length >= descriptionDisplayCOunt ? "..." : ""}",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.normal,
|
||||
Visibility(
|
||||
visible: reviews[index].rating_description.isNotEmpty,
|
||||
child: Text(
|
||||
reviews[index].rating_description.isEmpty
|
||||
? ""
|
||||
: "${reviews[index].rating_description.substring(0, reviews[index].rating_description.length >= descriptionDisplayCOunt ? descriptionDisplayCOunt : reviews[index].rating_description.length - 1)}${reviews[index].rating_description.length >= descriptionDisplayCOunt ? "..." : ""}",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
|
||||
@@ -150,6 +150,9 @@ class _MihCardDisplayState extends State<MihCardDisplay> {
|
||||
case "fresmart":
|
||||
return Image.asset(
|
||||
'lib/mih_components/mih_package_components/assets/images/loyalty_cards/mini/fresmart-min.png');
|
||||
case "total energies":
|
||||
return Image.asset(
|
||||
'lib/mih_components/mih_package_components/assets/images/loyalty_cards/mini/total_energies-min.png');
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ class _MihCardsState extends State<MihCards> {
|
||||
"Spar",
|
||||
"Spur",
|
||||
"TFG Group",
|
||||
"Total Energies",
|
||||
"Toys R Us",
|
||||
"Woermann Brock",
|
||||
"Woolworths"
|
||||
@@ -367,7 +368,7 @@ class _MihCardsState extends State<MihCards> {
|
||||
builder: (BuildContext context,
|
||||
List<MIHLoyaltyCard> value, Widget? child) {
|
||||
return BuildLoyaltyCardList(
|
||||
cardList: searchShopName.value,
|
||||
cardList: value,
|
||||
signedInUser: widget.signedInUser,
|
||||
navIndex: 0,
|
||||
bannerAd: _bannerAd,
|
||||
|
||||
@@ -9,12 +9,42 @@ import '../mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:supertokens_flutter/http.dart' as http;
|
||||
|
||||
class MihBusinessDetailsServices {
|
||||
Future<List<String>> fetchAllBusinessTypes() async {
|
||||
var response = await http.get(
|
||||
Uri.parse("${AppEnviroment.baseApiUrl}/business/types/"),
|
||||
headers: <String, String>{
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
List<dynamic> jsonList = jsonDecode(response.body);
|
||||
List<String> businessTypes =
|
||||
jsonList.map((item) => item['type'].toString()).toList();
|
||||
return businessTypes;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Business>> searchBusinesses(
|
||||
String searchText,
|
||||
String searchType,
|
||||
BuildContext context,
|
||||
) async {
|
||||
String newSearchText = "All";
|
||||
if (searchText.isNotEmpty) {
|
||||
newSearchText = searchText;
|
||||
}
|
||||
String newSearchType = "All";
|
||||
if (searchType.isNotEmpty) {
|
||||
newSearchType = searchType;
|
||||
}
|
||||
if (searchText.isEmpty && searchType.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
var response = await http.get(
|
||||
Uri.parse("${AppEnviroment.baseApiUrl}/businesses/search/$searchText"),
|
||||
Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/business/search/$newSearchType/$newSearchText"),
|
||||
headers: <String, String>{
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
@@ -29,7 +59,7 @@ class MihBusinessDetailsServices {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Business?> getBusinessDetails(
|
||||
Future<Business?> getBusinessDetailsByUser(
|
||||
String app_id,
|
||||
) async {
|
||||
var response = await http.get(
|
||||
@@ -47,6 +77,25 @@ class MihBusinessDetailsServices {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Business?> getBusinessDetailsByBusinessId(
|
||||
String business_id,
|
||||
) async {
|
||||
var response = await http.get(
|
||||
Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/business/business_id/$business_id"),
|
||||
headers: <String, String>{
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
String body = response.body;
|
||||
var jsonBody = jsonDecode(body);
|
||||
return Business.fromJson(jsonBody);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Response> createBusinessDetails(
|
||||
String appId,
|
||||
String busineName,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/bookmarked_business.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_review.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
|
||||
import 'package:supertokens_flutter/http.dart' as http;
|
||||
@@ -6,6 +7,10 @@ import 'package:supertokens_flutter/http.dart' as http;
|
||||
class MihMzansiDirectoryServices {
|
||||
final baseAPI = AppEnviroment.baseApiUrl;
|
||||
|
||||
//########################################################
|
||||
//# Business Ratings #
|
||||
//########################################################
|
||||
|
||||
Future<BusinessReview?> getUserReviewOfBusiness(
|
||||
String app_id,
|
||||
String business_id,
|
||||
@@ -33,10 +38,9 @@ class MihMzansiDirectoryServices {
|
||||
List<BusinessReview> businessReviews = List<BusinessReview>.from(
|
||||
l.map((model) => BusinessReview.fromJson(model)));
|
||||
return businessReviews;
|
||||
} else if (response.statusCode == 404){
|
||||
} else if (response.statusCode == 404) {
|
||||
return [];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
throw Exception('failed to fetch Business Reviews');
|
||||
}
|
||||
}
|
||||
@@ -128,4 +132,84 @@ class MihMzansiDirectoryServices {
|
||||
return response.statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
//########################################################
|
||||
//# Bookmarked Business #
|
||||
//########################################################
|
||||
|
||||
Future<BookmarkedBusiness?> getUserBookmarkOfBusiness(
|
||||
String app_id,
|
||||
String business_id,
|
||||
) async {
|
||||
final response = await http.get(Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/$app_id/$business_id"));
|
||||
// print(response.statusCode);
|
||||
if (response.statusCode == 200) {
|
||||
String body = response.body;
|
||||
var jsonBody = jsonDecode(body);
|
||||
BookmarkedBusiness? BookmarkedBus = BookmarkedBusiness.fromJson(jsonBody);
|
||||
return BookmarkedBus;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<BookmarkedBusiness>> getAllUserBookmarkedBusiness(
|
||||
String app_id,
|
||||
) async {
|
||||
final response = await http.get(Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/user/all/$app_id"));
|
||||
if (response.statusCode == 200) {
|
||||
Iterable l = jsonDecode(response.body);
|
||||
List<BookmarkedBusiness> businessReviews = List<BookmarkedBusiness>.from(
|
||||
l.map((model) => BookmarkedBusiness.fromJson(model)));
|
||||
return businessReviews;
|
||||
} else if (response.statusCode == 404) {
|
||||
return [];
|
||||
} else {
|
||||
throw Exception('failed to fetch User Bookmarked Business');
|
||||
}
|
||||
}
|
||||
|
||||
Future<int> addBookmarkedBusiness(
|
||||
String app_id,
|
||||
String business_id,
|
||||
) async {
|
||||
var response = await http.post(
|
||||
Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/insert/"),
|
||||
headers: <String, String>{
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
body: jsonEncode(<String, dynamic>{
|
||||
"app_id": app_id,
|
||||
"business_id": business_id,
|
||||
}),
|
||||
);
|
||||
if (response.statusCode == 201) {
|
||||
return response.statusCode;
|
||||
} else {
|
||||
return response.statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
Future<int> deleteBookmarkedBusiness(
|
||||
int idbookmarked_businesses,
|
||||
) async {
|
||||
var response = await http.delete(
|
||||
Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/delete/"),
|
||||
headers: <String, String>{
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
body: jsonEncode(<String, dynamic>{
|
||||
"idbookmarked_businesses": idbookmarked_businesses,
|
||||
}),
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
return response.statusCode;
|
||||
} else {
|
||||
return response.statusCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ class MIHApiCalls {
|
||||
}
|
||||
|
||||
// Get Businessdata
|
||||
Business? business = await MihBusinessDetailsServices().getBusinessDetails(
|
||||
Business? business =
|
||||
await MihBusinessDetailsServices().getBusinessDetailsByUser(
|
||||
uid,
|
||||
);
|
||||
if (business != null) {
|
||||
|
||||
@@ -5,7 +5,7 @@ WORKDIR /app
|
||||
|
||||
COPY requirements.txt ./
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip install -r requirements.txt
|
||||
pip --default-timeout=120 install -r requirements.txt
|
||||
|
||||
# COPY . ./app
|
||||
|
||||
|
||||
@@ -64,10 +64,21 @@ class BusinessRating(Base):
|
||||
rating_description = Column(String(256), nullable=False, server_default="")
|
||||
rating_score = Column(String(45), nullable=False, server_default="")
|
||||
date_time = Column(DateTime, nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"<BusinessRating(idbusiness_ratings={self.idbusiness_ratings}, app_id='{self.app_id}', "
|
||||
f"business_id='{self.business_id}', rating_title='{self.rating_title}', rating_description='{self.rating_description}', "
|
||||
f"rating_score='{self.rating_score}', date_time='{self.date_time}')>"
|
||||
)
|
||||
class BookmarkedBusiness(Base):
|
||||
__tablename__ = 'bookmarked_businesses'
|
||||
__table_args__ = {'schema': 'mzansi_directory'}
|
||||
idbookmarked_businesses = Column(Integer, primary_key=True)
|
||||
app_id = Column(String(128), nullable=False, server_default="")
|
||||
business_id = Column(String(128), nullable=False, server_default="")
|
||||
created_date = Column(DateTime, nullable=True)
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"<BusinessRating(idbookmarked_businesses={self.idbookmarked_businesses}, app_id='{self.app_id}', "
|
||||
f"business_id='{self.business_id}', created_date='{self.created_date}')>"
|
||||
)
|
||||
@@ -1,7 +1,11 @@
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, HTTPException, status
|
||||
from pydantic import BaseModel
|
||||
#from ..mih_database import dbConnection
|
||||
import mih_database
|
||||
import mih_database.mihDbConnections
|
||||
from mih_database.mihDbObjects import User, Business, BusinessRating, BookmarkedBusiness
|
||||
from sqlalchemy import desc, or_
|
||||
from sqlalchemy.orm import Session
|
||||
#SuperToken Auth from front end
|
||||
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||
from supertokens_python.recipe.session import SessionContainer
|
||||
@@ -60,90 +64,162 @@ class businessUpdateRequestV2(BaseModel):
|
||||
|
||||
|
||||
# Get List of all files
|
||||
@router.get("/businesses/search/{search}", tags=["MIH Business"])
|
||||
async def read_all_businesses(search: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
db = mih_database.dbConnection.dbAppDataConnect()
|
||||
cursor = db.cursor()
|
||||
query = "SELECT business.business_id, business.Name, business.type, business.registration_no, "
|
||||
query += "business.logo_name, business.logo_path, business.contact_no, business.bus_email, "
|
||||
query += "business.gps_location, "
|
||||
query += "practice_no, vat_no, "
|
||||
query += "website, rating, mission_vision "
|
||||
query += "FROM business "
|
||||
query += "WHERE LOWER(business.Name) LIKE %s OR LOWER(business.type) LIKE %s "
|
||||
query += "OR LOWER(business.bus_email) LIKE %s OR LOWER(business.mission_vision) LIKE %s"
|
||||
search_term = f"%{search.lower()}%" # Add wildcards and lowercase
|
||||
cursor.execute(query, (search_term, search_term, search_term, search_term))
|
||||
items = [
|
||||
{
|
||||
"business_id": item[0],
|
||||
"Name": item[1],
|
||||
"type": item[2],
|
||||
"registration_no": item[3],
|
||||
"logo_name": item[4],
|
||||
"logo_path": item[5],
|
||||
"contact_no": item[6],
|
||||
"bus_email": item[7],
|
||||
"app_id": "",
|
||||
"gps_location": item[8],
|
||||
"practice_no": item[9],
|
||||
"vat_no": item[10],
|
||||
"website": item[11],
|
||||
"rating": item[12],
|
||||
"mission_vision": item[13],
|
||||
}
|
||||
for item in cursor.fetchall()
|
||||
]
|
||||
cursor.close()
|
||||
db.close()
|
||||
return items
|
||||
@router.get("/business/types/", tags=["MIH Business"])
|
||||
async def read_business_by_business_id(session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
dbSession = Session(dbEngine)
|
||||
try:
|
||||
queryResults = dbSession.query(Business.type).distinct().order_by(Business.type).all()
|
||||
response_data = [{"type": t[0]} for t in queryResults]
|
||||
return response_data
|
||||
except Exception as e:
|
||||
print(f"An error occurred during the ORM query: {e}")
|
||||
if dbSession.is_active:
|
||||
dbSession.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to retrieve records due to an internal server error."
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
|
||||
# Get List of all files
|
||||
@router.get("/business/search/{type}/{search}", tags=["MIH Business"])
|
||||
async def read_all_businesses(search: str, type: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
dbSession = Session(dbEngine)
|
||||
try:
|
||||
queryResults = dbSession.query(Business)
|
||||
type_term_with_wildcards = ""
|
||||
if type != "All":
|
||||
type_term_with_wildcards = f"%{type.lower()}%"
|
||||
queryResults = queryResults.filter(
|
||||
Business.type.ilike(type_term_with_wildcards)
|
||||
)
|
||||
search_term_with_wildcards = ""
|
||||
if search != "All":
|
||||
search_term_with_wildcards = f"%{search.lower()}%"
|
||||
queryResults = queryResults.filter(
|
||||
or_(
|
||||
Business.Name.ilike(search_term_with_wildcards),
|
||||
Business.bus_email.ilike(search_term_with_wildcards),
|
||||
Business.mission_vision.ilike(search_term_with_wildcards),
|
||||
)
|
||||
)
|
||||
queryResults = queryResults.all()
|
||||
response_data = []
|
||||
for business in queryResults:
|
||||
response_data.append({
|
||||
"business_id": business.business_id,
|
||||
"Name": business.Name,
|
||||
"type": business.type,
|
||||
"registration_no": business.registration_no,
|
||||
"logo_name": business.logo_name,
|
||||
"logo_path": business.logo_path,
|
||||
"contact_no": business.contact_no,
|
||||
"bus_email": business.bus_email,
|
||||
"app_id": "",
|
||||
"gps_location": business.gps_location,
|
||||
"practice_no": business.practice_no,
|
||||
"vat_no": business.vat_no,
|
||||
"website": business.website,
|
||||
"rating": business.rating,
|
||||
"mission_vision": business.mission_vision,
|
||||
})
|
||||
|
||||
return response_data
|
||||
except Exception as e:
|
||||
print(f"An error occurred during the ORM query: {e}")
|
||||
if dbSession.is_active:
|
||||
dbSession.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to retrieve records due to an internal server error."
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
# db = mih_database.dbConnection.dbAppDataConnect()
|
||||
# cursor = db.cursor()
|
||||
# query = "SELECT business.business_id, business.Name, business.type, business.registration_no, "
|
||||
# query += "business.logo_name, business.logo_path, business.contact_no, business.bus_email, "
|
||||
# query += "business.gps_location, "
|
||||
# query += "practice_no, vat_no, "
|
||||
# query += "website, rating, mission_vision "
|
||||
# query += "FROM business "
|
||||
# query += "WHERE LOWER(business.Name) LIKE %s OR LOWER(business.type) LIKE %s "
|
||||
# query += "OR LOWER(business.bus_email) LIKE %s OR LOWER(business.mission_vision) LIKE %s"
|
||||
# search_term = f"%{search.lower()}%" # Add wildcards and lowercase
|
||||
# cursor.execute(query, (search_term, search_term, search_term, search_term))
|
||||
# items = [
|
||||
# {
|
||||
# "business_id": item[0],
|
||||
# "Name": item[1],
|
||||
# "type": item[2],
|
||||
# "registration_no": item[3],
|
||||
# "logo_name": item[4],
|
||||
# "logo_path": item[5],
|
||||
# "contact_no": item[6],
|
||||
# "bus_email": item[7],
|
||||
# "app_id": "",
|
||||
# "gps_location": item[8],
|
||||
# "practice_no": item[9],
|
||||
# "vat_no": item[10],
|
||||
# "website": item[11],
|
||||
# "rating": item[12],
|
||||
# "mission_vision": item[13],
|
||||
# }
|
||||
# for item in cursor.fetchall()
|
||||
# ]
|
||||
# cursor.close()
|
||||
# db.close()
|
||||
# return items
|
||||
|
||||
# Get List of all files
|
||||
@router.get("/business/business_id/{business_id}", tags=["MIH Business"])
|
||||
async def read_business_by_business_id(business_id: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
db = mih_database.dbConnection.dbAppDataConnect()
|
||||
cursor = db.cursor()
|
||||
query = "SELECT business.business_id, business.Name, business.type, business.registration_no, "
|
||||
query += "business.logo_name, business.logo_path, business.contact_no, business.bus_email, "
|
||||
query += "business_users.app_id, business.gps_location, "
|
||||
query += "practice_no, vat_no, "
|
||||
query += "website, rating, mission_vision "
|
||||
query += "FROM business "
|
||||
query += "inner join business_users "
|
||||
query += "on business.business_id=business_users.business_id "
|
||||
query += "where business.business_id = %s"
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
dbSession = Session(dbEngine)
|
||||
try:
|
||||
cursor.execute(query, (business_id,))
|
||||
except Exception as error:
|
||||
raise HTTPException(status_code=404, detail="Failed to pull records")
|
||||
items = [
|
||||
{
|
||||
"business_id": item[0],
|
||||
"Name": item[1],
|
||||
"type": item[2],
|
||||
"registration_no": item[3],
|
||||
"logo_name": item[4],
|
||||
"logo_path": item[5],
|
||||
"contact_no": item[6],
|
||||
"bus_email": item[7],
|
||||
"app_id": item[8],
|
||||
"gps_location": item[9],
|
||||
"practice_no": item[10],
|
||||
"vat_no": item[11],
|
||||
"website": item[12],
|
||||
"rating": item[13],
|
||||
"mission_vision": item[14],
|
||||
}
|
||||
for item in cursor.fetchall()
|
||||
]
|
||||
#
|
||||
cursor.close()
|
||||
db.close()
|
||||
if(len(items)!= 0):
|
||||
return items[0]
|
||||
else:
|
||||
raise HTTPException(status_code=404, detail="No record found")
|
||||
|
||||
queryResults = dbSession.query(Business).\
|
||||
filter(
|
||||
Business.business_id == business_id,
|
||||
).first()
|
||||
if queryResults:
|
||||
return {
|
||||
"business_id": queryResults.business_id,
|
||||
"Name": queryResults.Name,
|
||||
"type": queryResults.type,
|
||||
"registration_no": queryResults.registration_no,
|
||||
"logo_name": queryResults.logo_name,
|
||||
"logo_path": queryResults.logo_path,
|
||||
"contact_no": queryResults.contact_no,
|
||||
"bus_email": queryResults.bus_email,
|
||||
"app_id": "",
|
||||
"gps_location": queryResults.gps_location,
|
||||
"practice_no": queryResults.practice_no,
|
||||
"vat_no": queryResults.vat_no,
|
||||
"website": queryResults.website,
|
||||
"rating": queryResults.rating,
|
||||
"mission_vision": queryResults.mission_vision,
|
||||
}
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Business not found for the given business_id."
|
||||
)
|
||||
except HTTPException as http_exc:
|
||||
# Re-raise HTTPException directly if it was raised within the try block
|
||||
raise http_exc
|
||||
except Exception as e:
|
||||
print(f"An error occurred during the ORM query: {e}")
|
||||
if dbSession.is_active:
|
||||
dbSession.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to retrieve records due to an internal server error."
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
|
||||
# Get List of all files
|
||||
@router.get("/business/app_id/{app_id}", tags=["MIH Business"])
|
||||
|
||||
@@ -4,7 +4,7 @@ from sqlalchemy.orm import Session
|
||||
from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
import mih_database.mihDbConnections
|
||||
from mih_database.mihDbObjects import User, Business, BusinessRating
|
||||
from mih_database.mihDbObjects import User, Business, BusinessRating, BookmarkedBusiness
|
||||
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||
from supertokens_python.recipe.session import SessionContainer
|
||||
from fastapi import Depends
|
||||
@@ -40,6 +40,17 @@ class BusinessRatingUpdateRequest(BaseModel):
|
||||
rating_old_score: str
|
||||
current_rating: str
|
||||
|
||||
class BookmarkedBusinessInsertRequest(BaseModel):
|
||||
app_id: str
|
||||
business_id: str
|
||||
|
||||
class BookmarkedBusinessDeleteRequest(BaseModel):
|
||||
idbookmarked_businesses: int
|
||||
|
||||
########################################################
|
||||
# Business Ratings #
|
||||
########################################################
|
||||
|
||||
@router.get("/mzansi-directory/business-ratings/user/{app_id}/{business_id}", tags=["Mzansi Directory"])
|
||||
async def read_all_ratings_by_business_id(app_id: str,business_id: str, session: SessionContainer = Depends(verify_session())): # , session: SessionContainer = Depends(verify_session())
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
@@ -295,4 +306,154 @@ async def UpdatePatient(itemRequest : BusinessRatingUpdateRequest, session: Sess
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
return {"message": "Successfully wUpdated Record"}
|
||||
return {"message": "Successfully wUpdated Record"}
|
||||
|
||||
########################################################
|
||||
# Bookmarked Business #
|
||||
########################################################
|
||||
|
||||
@router.get("/mzansi-directory/bookmarked-business/{app_id}/{business_id}", tags=["Mzansi Directory"])
|
||||
async def read_all_ratings_by_business_id(app_id: str,business_id: str, session: SessionContainer = Depends(verify_session())): # , session: SessionContainer = Depends(verify_session())
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
dbSession = Session(dbEngine)
|
||||
try:
|
||||
queryResults = dbSession.query(BookmarkedBusiness, Business).\
|
||||
join(Business, BookmarkedBusiness.business_id == Business.business_id).\
|
||||
filter(
|
||||
BookmarkedBusiness.business_id == business_id,
|
||||
BookmarkedBusiness.app_id == app_id,
|
||||
).order_by(
|
||||
desc(BookmarkedBusiness.created_date)
|
||||
).first()
|
||||
if queryResults:
|
||||
bookmark_obj, bus_obj = queryResults
|
||||
return {
|
||||
"idbookmarked_businesses": bookmark_obj.idbookmarked_businesses,
|
||||
"app_id": bookmark_obj.app_id,
|
||||
"business_id": bookmark_obj.business_id,
|
||||
"business_name": bus_obj.Name,
|
||||
"created_date": bookmark_obj.created_date,
|
||||
}
|
||||
else:
|
||||
# Return an empty response or a specific message
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Bookmarked Business rating not found for the given app_id & business_id."
|
||||
)
|
||||
except HTTPException as http_exc:
|
||||
# Re-raise HTTPException directly if it was raised within the try block
|
||||
raise http_exc
|
||||
except Exception as e:
|
||||
print(f"An error occurred during the ORM query: {e}")
|
||||
if dbSession.is_active:
|
||||
dbSession.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to retrieve records due to an internal server error."
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
|
||||
@router.get("/mzansi-directory/bookmarked-business/user/all/{app_id}/", tags=["Mzansi Directory"])
|
||||
async def read_all_ratings_by_business_id(app_id: str, session: SessionContainer = Depends(verify_session())): # , session: SessionContainer = Depends(verify_session())
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
dbSession = Session(dbEngine)
|
||||
try:
|
||||
queryResults = dbSession.query(BookmarkedBusiness, Business).\
|
||||
join(Business, BookmarkedBusiness.business_id == Business.business_id).\
|
||||
filter(
|
||||
BookmarkedBusiness.app_id == app_id,
|
||||
).order_by(
|
||||
desc(BookmarkedBusiness.created_date)
|
||||
).all()
|
||||
response_data = []
|
||||
for rating_obj, bus_obj in queryResults:
|
||||
response_data.append({
|
||||
"idbookmarked_businesses": rating_obj.idbookmarked_businesses,
|
||||
"app_id": rating_obj.app_id,
|
||||
"business_id": rating_obj.business_id,
|
||||
"business_name": bus_obj.Name,
|
||||
"created_date": rating_obj.created_date,
|
||||
})
|
||||
if len(response_data) > 0:
|
||||
return response_data
|
||||
else:
|
||||
# Return an empty response or a specific message
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Bookmarked Business not found for the given app_id."
|
||||
)
|
||||
except HTTPException as http_exc:
|
||||
# Re-raise HTTPException directly if it was raised within the try block
|
||||
raise http_exc
|
||||
except Exception as e:
|
||||
print(f"An error occurred during the ORM query: {e}")
|
||||
if dbSession.is_active:
|
||||
dbSession.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to retrieve records due to an internal server error."
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
|
||||
@router.post("/mzansi-directory/bookmarked-business/insert/", tags=["Mzansi Directory"], status_code=201)
|
||||
async def insert_loyalty_card(itemRequest : BookmarkedBusinessInsertRequest): #, session: SessionContainer = Depends(verify_session())
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
nowDateTime = datetime.now()
|
||||
formatedDateTime = nowDateTime.strftime("%Y-%m-%d %H:%M:%S")
|
||||
dbSession = Session(dbEngine)
|
||||
try:
|
||||
# add business rating
|
||||
new_bookmarked_business = BookmarkedBusiness(
|
||||
app_id=itemRequest.app_id,
|
||||
business_id=itemRequest.business_id,
|
||||
created_date=formatedDateTime
|
||||
)
|
||||
dbSession.add(new_bookmarked_business)
|
||||
dbSession.flush() # Ensure the new rating is added to the session
|
||||
dbSession.commit() # Commit the session to save changes
|
||||
except Exception as e:
|
||||
print(f"An error occurred during the ORM query: {e}")
|
||||
if dbSession.is_active:
|
||||
dbSession.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to insert records due to an internal server error."
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
return {"message": "Successfully Created Record"}
|
||||
|
||||
@router.delete("/mzansi-directory/bookmarked-business/delete/", tags=["Mzansi Directory"])
|
||||
async def Delete_loyalty_card(itemRequest : BookmarkedBusinessDeleteRequest, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||
dbSession = Session(dbEngine)
|
||||
try:
|
||||
# delete business rating
|
||||
rating_to_delete = dbSession.query(BookmarkedBusiness).\
|
||||
get(
|
||||
itemRequest.idbookmarked_businesses
|
||||
)
|
||||
if not rating_to_delete:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Bookmarked Business with ID {itemRequest.idbusiness_ratings} not found."
|
||||
)
|
||||
dbSession.delete(rating_to_delete)
|
||||
dbSession.flush() # Ensure the new rating is added to the session
|
||||
dbSession.commit() # Commit the session to save changes
|
||||
except HTTPException as http_exc:
|
||||
# Re-raise HTTPException directly if it was raised within the try block
|
||||
raise http_exc
|
||||
except Exception as e:
|
||||
print(f"An error occurred during the ORM query: {e}")
|
||||
if dbSession.is_active:
|
||||
dbSession.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to insert records due to an internal server error."
|
||||
)
|
||||
finally:
|
||||
dbSession.close()
|
||||
return {"message": "Successfully Deleted Record"}
|
||||
|
||||