Merge pull request #235 from yaso-meth/NEW--Mzansi-Directory-Ratings
NEW--Mzansi-Directory-Ratings
This commit is contained in:
@@ -31,6 +31,16 @@ class BusinessArguments {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BusinessViewArguments {
|
||||||
|
final Business business;
|
||||||
|
final String? startUpSearch;
|
||||||
|
|
||||||
|
BusinessViewArguments(
|
||||||
|
this.business,
|
||||||
|
this.startUpSearch,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class HomeArguments {
|
class HomeArguments {
|
||||||
final AppUser signedInUser;
|
final AppUser signedInUser;
|
||||||
final BusinessUser? businessUser;
|
final BusinessUser? businessUser;
|
||||||
@@ -218,6 +228,16 @@ class MzansiAiArguments {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MzansiDirectoryArguments {
|
||||||
|
final String? startUpSearch;
|
||||||
|
final bool personalSearch;
|
||||||
|
|
||||||
|
MzansiDirectoryArguments(
|
||||||
|
this.startUpSearch,
|
||||||
|
this.personalSearch,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class TestArguments {
|
class TestArguments {
|
||||||
final AppUser user;
|
final AppUser user;
|
||||||
final Business? business;
|
final Business? business;
|
||||||
|
|||||||
46
Frontend/lib/mih_components/mih_objects/business_review.dart
Normal file
46
Frontend/lib/mih_components/mih_objects/business_review.dart
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
class BusinessReview {
|
||||||
|
final int idbusiness_ratings;
|
||||||
|
final String app_id;
|
||||||
|
final String business_id;
|
||||||
|
final String rating_title;
|
||||||
|
final String rating_description;
|
||||||
|
final String rating_score;
|
||||||
|
final String date_time;
|
||||||
|
final String reviewer;
|
||||||
|
|
||||||
|
BusinessReview({
|
||||||
|
required this.idbusiness_ratings,
|
||||||
|
required this.app_id,
|
||||||
|
required this.business_id,
|
||||||
|
required this.rating_title,
|
||||||
|
required this.rating_description,
|
||||||
|
required this.rating_score,
|
||||||
|
required this.date_time,
|
||||||
|
required this.reviewer,
|
||||||
|
});
|
||||||
|
factory BusinessReview.fromJson(Map<String, dynamic> json) {
|
||||||
|
return switch (json) {
|
||||||
|
{
|
||||||
|
"idbusiness_ratings": int idbusiness_ratings,
|
||||||
|
"app_id": String app_id,
|
||||||
|
"business_id": String business_id,
|
||||||
|
"rating_title": String rating_title,
|
||||||
|
"rating_description": String rating_description,
|
||||||
|
"rating_score": String rating_score,
|
||||||
|
"date_time": String date_time,
|
||||||
|
"reviewer": String reviewer,
|
||||||
|
} =>
|
||||||
|
BusinessReview(
|
||||||
|
idbusiness_ratings: idbusiness_ratings,
|
||||||
|
app_id: app_id,
|
||||||
|
business_id: business_id,
|
||||||
|
rating_title: rating_title,
|
||||||
|
rating_description: rating_description,
|
||||||
|
rating_score: rating_score,
|
||||||
|
date_time: date_time,
|
||||||
|
reviewer: reviewer,
|
||||||
|
),
|
||||||
|
_ => throw const FormatException('Failed to load loyalty card objects'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +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_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_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_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_alert_services.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
|
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
|
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
|
||||||
@@ -291,14 +291,16 @@ class _PackageToolOneState extends State<PackageToolOne> {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
MihBusinessCard(
|
// MihBusinessCard(
|
||||||
businessName: "Mzansi Innovation Hub",
|
// businessid: "123456",
|
||||||
cellNumber: "0788300006",
|
// businessName: "Mzansi Innovation Hub",
|
||||||
email: "yasien.meth@mzansi-innovation-hub.co.za",
|
// cellNumber: "0788300006",
|
||||||
gpsLocation: "-26.1853611, 28.134664",
|
// email: "yasien.meth@mzansi-innovation-hub.co.za",
|
||||||
website:
|
// gpsLocation: "-26.1853611, 28.134664",
|
||||||
"https://app.mzansi-innovation-hub.co.za/privacy.html",
|
// website:
|
||||||
),
|
// "https://app.mzansi-innovation-hub.co.za/privacy.html",
|
||||||
|
// rating: 3.25,
|
||||||
|
// ),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Divider(
|
Divider(
|
||||||
color:
|
color:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:custom_rating_bar/custom_rating_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
import 'package:mzansi_innovation_hub/main.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
|
||||||
@@ -36,6 +37,14 @@ class _PackageToolTwoState extends State<PackageToolTwo> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
|
RatingBar(
|
||||||
|
filledIcon: Icons.star,
|
||||||
|
emptyIcon: Icons.star_border,
|
||||||
|
onRatingChanged: (value) => debugPrint('$value'),
|
||||||
|
initialRating: 3,
|
||||||
|
maxRating: 5,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
Container(
|
Container(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
width: 200,
|
width: 200,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_print_prevew.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_print_prevew.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_test.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_test.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_notification_message.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_notification_message.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_packages/about_mih/about_mih.dart';
|
import 'package:mzansi_innovation_hub/mih_packages/about_mih/about_mih.dart';
|
||||||
@@ -122,13 +121,13 @@ class RouteGenerator {
|
|||||||
// }
|
// }
|
||||||
// break; // Use break and fall through to _errorRoute if argument type is wrong
|
// break; // Use break and fall through to _errorRoute if argument type is wrong
|
||||||
case AppRoutes.mzansiDirectory:
|
case AppRoutes.mzansiDirectory:
|
||||||
// if (args is AuthArguments) {
|
if (args is MzansiDirectoryArguments) {
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
settings: settings,
|
settings: settings,
|
||||||
builder: (_) => MzansiDirectory(),
|
builder: (_) => MzansiDirectory(arguments: args),
|
||||||
);
|
);
|
||||||
// }
|
}
|
||||||
// break;
|
break;
|
||||||
case AppRoutes.notifications:
|
case AppRoutes.notifications:
|
||||||
if (args is NotificationArguments) {
|
if (args is NotificationArguments) {
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
@@ -188,10 +187,10 @@ class RouteGenerator {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AppRoutes.businessProfileView:
|
case AppRoutes.businessProfileView:
|
||||||
if (args is Business) {
|
if (args is BusinessViewArguments) {
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
settings: settings,
|
settings: settings,
|
||||||
builder: (_) => MzansiBusinessProfileView(business: args),
|
builder: (_) => MzansiBusinessProfileView(arguments: args),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -394,48 +394,51 @@ class _MihSignInState extends State<MihSignIn> {
|
|||||||
|
|
||||||
//spacer
|
//spacer
|
||||||
const SizedBox(height: 35),
|
const SizedBox(height: 35),
|
||||||
Center(
|
Visibility(
|
||||||
child: SizedBox(
|
visible: AppEnviroment.getEnv() == "Dev",
|
||||||
width: width,
|
child: Center(
|
||||||
//height: 100.0,
|
child: SizedBox(
|
||||||
child: Row(
|
width: width,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
//height: 100.0,
|
||||||
children: [
|
child: Row(
|
||||||
const Flexible(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
flex: 1,
|
children: [
|
||||||
child: Padding(
|
const Flexible(
|
||||||
padding: EdgeInsets.only(right: 10.0),
|
flex: 1,
|
||||||
child: Divider(),
|
child: Padding(
|
||||||
),
|
padding: EdgeInsets.only(right: 10.0),
|
||||||
),
|
child: Divider(),
|
||||||
Flexible(
|
|
||||||
flex: 1,
|
|
||||||
child: GestureDetector(
|
|
||||||
child: Text(
|
|
||||||
'Use Sandox Profile',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 15,
|
|
||||||
color: MzansiInnovationHub.of(context)!
|
|
||||||
.theme
|
|
||||||
.secondaryColor()),
|
|
||||||
),
|
),
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
showProfiles = !showProfiles;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
Flexible(
|
||||||
const Flexible(
|
flex: 1,
|
||||||
flex: 1,
|
child: GestureDetector(
|
||||||
child: Padding(
|
child: Text(
|
||||||
padding: EdgeInsets.only(left: 10.0),
|
'Use Sandox Profile',
|
||||||
child: Divider(),
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 15,
|
||||||
|
color: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor()),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
showProfiles = !showProfiles;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const Flexible(
|
||||||
],
|
flex: 1,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10.0),
|
||||||
|
child: Divider(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
import 'package:mzansi_innovation_hub/main.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_business_profile_preview.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_business_profile_preview.dart';
|
||||||
|
|
||||||
class BuildBusinessSearchResultsList extends StatefulWidget {
|
class BuildBusinessSearchResultsList extends StatefulWidget {
|
||||||
final List<Business> businessList;
|
final List<Business> businessList;
|
||||||
final String myLocation;
|
final String myLocation;
|
||||||
|
final String? startUpSearch;
|
||||||
const BuildBusinessSearchResultsList({
|
const BuildBusinessSearchResultsList({
|
||||||
super.key,
|
super.key,
|
||||||
required this.businessList,
|
required this.businessList,
|
||||||
required this.myLocation,
|
required this.myLocation,
|
||||||
|
required this.startUpSearch,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -37,7 +40,10 @@ class _BuildBusinessSearchResultsListState
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
'/business-profile/view',
|
'/business-profile/view',
|
||||||
arguments: widget.businessList[index],
|
arguments: BusinessViewArguments(
|
||||||
|
widget.businessList[index],
|
||||||
|
widget.businessList[index].Name,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
splashColor: MzansiInnovationHub.of(context)!
|
splashColor: MzansiInnovationHub.of(context)!
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart';
|
import 'package:mzansi_innovation_hub/mih_packages/mzansi_directory/package_tools/mih_search_mzansi.dart';
|
||||||
|
|
||||||
class MzansiDirectory extends StatefulWidget {
|
class MzansiDirectory extends StatefulWidget {
|
||||||
const MzansiDirectory({super.key});
|
final MzansiDirectoryArguments arguments;
|
||||||
|
const MzansiDirectory({
|
||||||
|
super.key,
|
||||||
|
required this.arguments,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MzansiDirectory> createState() => _MzansiDirectoryState();
|
State<MzansiDirectory> createState() => _MzansiDirectoryState();
|
||||||
@@ -32,7 +37,10 @@ class _MzansiDirectoryState extends State<MzansiDirectory> {
|
|||||||
|
|
||||||
List<Widget> getToolBody() {
|
List<Widget> getToolBody() {
|
||||||
List<Widget> toolBodies = [
|
List<Widget> toolBodies = [
|
||||||
MihSearchMzansi(),
|
MihSearchMzansi(
|
||||||
|
startUpSearch: widget.arguments.startUpSearch,
|
||||||
|
personalSearch: widget.arguments.personalSearch,
|
||||||
|
),
|
||||||
// MihContacts(),
|
// MihContacts(),
|
||||||
// MihFavouriteBusinesses(),
|
// MihFavouriteBusinesses(),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
import 'package:mzansi_innovation_hub/main.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.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_icons.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tile.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tile.dart';
|
||||||
|
|
||||||
@@ -21,7 +22,10 @@ class _MzansiDirectoryTileState extends State<MzansiDirectoryTile> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
'/mzansi-directory',
|
'/mzansi-directory',
|
||||||
// arguments: WalletArguments(widget.signedInUser, 0),
|
arguments: MzansiDirectoryArguments(
|
||||||
|
null, // startUpSearch
|
||||||
|
true, // personalSearch
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
appName: "Mzansi Directory",
|
appName: "Mzansi Directory",
|
||||||
|
|||||||
@@ -15,7 +15,13 @@ import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
|
|||||||
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
|
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
|
||||||
|
|
||||||
class MihSearchMzansi extends StatefulWidget {
|
class MihSearchMzansi extends StatefulWidget {
|
||||||
const MihSearchMzansi({super.key});
|
final String? startUpSearch;
|
||||||
|
final bool personalSearch;
|
||||||
|
const MihSearchMzansi({
|
||||||
|
super.key,
|
||||||
|
required this.startUpSearch,
|
||||||
|
required this.personalSearch,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MihSearchMzansi> createState() => _MihSearchMzansiState();
|
State<MihSearchMzansi> createState() => _MihSearchMzansiState();
|
||||||
@@ -24,7 +30,7 @@ class MihSearchMzansi extends StatefulWidget {
|
|||||||
class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||||
final TextEditingController mzansiSearchController = TextEditingController();
|
final TextEditingController mzansiSearchController = TextEditingController();
|
||||||
final FocusNode searchFocusNode = FocusNode();
|
final FocusNode searchFocusNode = FocusNode();
|
||||||
bool userSearch = true;
|
late bool userSearch;
|
||||||
Future<List<AppUser>?> futureUserSearchResults = Future.value();
|
Future<List<AppUser>?> futureUserSearchResults = Future.value();
|
||||||
Future<List<Business>?> futureBusinessSearchResults = Future.value();
|
Future<List<Business>?> futureBusinessSearchResults = Future.value();
|
||||||
late Future<Position?> futurePosition =
|
late Future<Position?> futurePosition =
|
||||||
@@ -41,6 +47,17 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
setState(() {
|
||||||
|
userSearch = widget.personalSearch;
|
||||||
|
mzansiSearchController.text = widget.startUpSearch ?? "";
|
||||||
|
if (userSearch) {
|
||||||
|
futureUserSearchResults =
|
||||||
|
MihUserServices().searchUsers(mzansiSearchController.text, context);
|
||||||
|
} else {
|
||||||
|
futureBusinessSearchResults = MihBusinessDetailsServices()
|
||||||
|
.searchBusinesses(mzansiSearchController.text, context);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -82,7 +99,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.display_settings,
|
Icons.swap_horiz_rounded,
|
||||||
size: 35,
|
size: 35,
|
||||||
color:
|
color:
|
||||||
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
@@ -246,6 +263,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
|||||||
BuildBusinessSearchResultsList(
|
BuildBusinessSearchResultsList(
|
||||||
businessList: snapshot.requireData!,
|
businessList: snapshot.requireData!,
|
||||||
myLocation: myLocation,
|
myLocation: myLocation,
|
||||||
|
startUpSearch: mzansiSearchController.text,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,21 +1,38 @@
|
|||||||
|
import 'package:custom_rating_bar/custom_rating_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
import 'package:mzansi_innovation_hub/main.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_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_package_alert.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_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:supertokens_flutter/supertokens.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
class MihBusinessCard extends StatefulWidget {
|
class MihBusinessCard extends StatefulWidget {
|
||||||
final String businessName;
|
final Business business;
|
||||||
final String cellNumber;
|
final String? startUpSearch;
|
||||||
final String email;
|
// final String businessid;
|
||||||
final String gpsLocation;
|
// final String businessName;
|
||||||
final String? website;
|
// final String cellNumber;
|
||||||
|
// final String email;
|
||||||
|
// final String gpsLocation;
|
||||||
|
// final String? website;
|
||||||
|
// final double rating;
|
||||||
|
final double width;
|
||||||
const MihBusinessCard({
|
const MihBusinessCard({
|
||||||
super.key,
|
super.key,
|
||||||
required this.businessName,
|
required this.business,
|
||||||
required this.cellNumber,
|
required this.startUpSearch,
|
||||||
required this.email,
|
// required this.businessid,
|
||||||
required this.gpsLocation,
|
// required this.businessName,
|
||||||
this.website,
|
// required this.cellNumber,
|
||||||
|
// required this.email,
|
||||||
|
// required this.gpsLocation,
|
||||||
|
// required this.rating,
|
||||||
|
// this.website,
|
||||||
|
required this.width,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -41,7 +58,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
alertBody: Column(
|
alertBody: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"We couldn't open your phone app to call ${widget.cellNumber}. To fix this, make sure you have a phone application installed and it's set as your default dialer.",
|
"We couldn't open your phone app to call ${widget.business.contact_no}. To fix this, make sure you have a phone application installed and it's set as your default dialer.",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: MzansiInnovationHub.of(context)!
|
color: MzansiInnovationHub.of(context)!
|
||||||
.theme
|
.theme
|
||||||
@@ -91,7 +108,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
alertBody: Column(
|
alertBody: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"We couldn't launch your email app to send a message to ${widget.email}. To fix this, please confirm that you have an email application installed and that it's set as your default.",
|
"We couldn't launch your email app to send a message to ${widget.business.bus_email}. To fix this, please confirm that you have an email application installed and that it's set as your default.",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: MzansiInnovationHub.of(context)!
|
color: MzansiInnovationHub.of(context)!
|
||||||
.theme
|
.theme
|
||||||
@@ -132,7 +149,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
alertBody: Column(
|
alertBody: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"There was an issue opening maps for ${widget.businessName}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
|
"There was an issue opening maps for ${widget.business.Name}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: MzansiInnovationHub.of(context)!
|
color: MzansiInnovationHub.of(context)!
|
||||||
.theme
|
.theme
|
||||||
@@ -161,7 +178,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
alertBody: Column(
|
alertBody: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"There was an issue opening maps for ${widget.businessName}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
|
"There was an issue opening maps for ${widget.business.Name}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: MzansiInnovationHub.of(context)!
|
color: MzansiInnovationHub.of(context)!
|
||||||
.theme
|
.theme
|
||||||
@@ -319,8 +336,17 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<BusinessReview?> getUserReview() async {
|
||||||
|
String user_id = await SuperTokens.getUserId();
|
||||||
|
return await MihMzansiDirectoryServices().getUserReviewOfBusiness(
|
||||||
|
user_id,
|
||||||
|
widget.business.business_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
// double screenWidth = MediaQuery.of(context).size.width;
|
||||||
return Material(
|
return Material(
|
||||||
color: MzansiInnovationHub.of(context)!
|
color: MzansiInnovationHub.of(context)!
|
||||||
.theme
|
.theme
|
||||||
@@ -336,6 +362,36 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
RatingBar.readOnly(
|
||||||
|
size: 50,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
filledIcon: Icons.star,
|
||||||
|
emptyIcon: Icons.star_border,
|
||||||
|
halfFilledIcon: Icons.star_half,
|
||||||
|
filledColor: const Color(0xffe9e8a1),
|
||||||
|
// MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
emptyColor: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
halfFilledColor: const Color(0xffe9e8a1),
|
||||||
|
// MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
isHalfAllowed: true,
|
||||||
|
initialRating: widget.business.rating.isNotEmpty
|
||||||
|
? double.parse(widget.business.rating)
|
||||||
|
: 0,
|
||||||
|
maxRating: 5,
|
||||||
|
),
|
||||||
|
// Text(
|
||||||
|
// "Rating: ${widget.rating}",
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 15,
|
||||||
|
// fontWeight: FontWeight.bold,
|
||||||
|
// color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
// height: 1.0,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Divider(
|
||||||
|
// color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
// ),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
_buildContactInfo(
|
_buildContactInfo(
|
||||||
"Call",
|
"Call",
|
||||||
@@ -344,7 +400,7 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
const Color(0xffaff0b3),
|
const Color(0xffaff0b3),
|
||||||
() {
|
() {
|
||||||
// print("Calling ${widget.cellNumber}");
|
// print("Calling ${widget.cellNumber}");
|
||||||
_makePhoneCall(widget.cellNumber);
|
_makePhoneCall(widget.business.contact_no);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Divider(
|
Divider(
|
||||||
@@ -358,9 +414,9 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
() {
|
() {
|
||||||
// print("Emailing ${widget.email}");
|
// print("Emailing ${widget.email}");
|
||||||
_launchEmail(
|
_launchEmail(
|
||||||
widget.email,
|
widget.business.bus_email,
|
||||||
"Inquiery about ${widget.businessName}",
|
"Inquiery about ${widget.business.Name}",
|
||||||
"Dear ${widget.businessName},\n\nI would like to inquire about your services.\n\nBest regards,\n",
|
"Dear ${widget.business.Name},\n\nI would like to inquire about your services.\n\nBest regards,\n",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -371,11 +427,12 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
"Location",
|
"Location",
|
||||||
"Come visit us.",
|
"Come visit us.",
|
||||||
Icons.location_on,
|
Icons.location_on,
|
||||||
const Color(0xffe9e8a1),
|
const Color(0xffd69d7d),
|
||||||
() {
|
() {
|
||||||
final latitude = double.parse(widget.gpsLocation.split(',')[0]);
|
final latitude =
|
||||||
|
double.parse(widget.business.gps_location.split(',')[0]);
|
||||||
final longitude =
|
final longitude =
|
||||||
double.parse(widget.gpsLocation.split(',')[1]);
|
double.parse(widget.business.gps_location.split(',')[1]);
|
||||||
_launchGoogleMapsWithUrl(
|
_launchGoogleMapsWithUrl(
|
||||||
latitude: latitude,
|
latitude: latitude,
|
||||||
longitude: longitude,
|
longitude: longitude,
|
||||||
@@ -383,39 +440,40 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: widget.website != null && widget.website! != "",
|
visible: widget.business.website.isNotEmpty &&
|
||||||
|
widget.business.website != "",
|
||||||
child: Divider(
|
child: Divider(
|
||||||
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: widget.website != null && widget.website! != "",
|
visible: widget.business.website.isNotEmpty &&
|
||||||
|
widget.business.website != "",
|
||||||
child: _buildContactInfo(
|
child: _buildContactInfo(
|
||||||
"Website",
|
"Website",
|
||||||
"Find out more about us.",
|
"Find out more about us.",
|
||||||
Icons.vpn_lock,
|
Icons.vpn_lock,
|
||||||
const Color(0xffd67d8a),
|
const Color(0xffd67d8a),
|
||||||
() {
|
() {
|
||||||
_launchWebsite(widget.website!);
|
_launchWebsite(widget.business.website);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Padding(
|
Padding(
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
// child: Divider(
|
child: Divider(
|
||||||
// color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// _buildContactInfo(
|
_buildContactInfo(
|
||||||
// "Rate Us",
|
"Rate Us",
|
||||||
// "Let us know how we are doing.",
|
"Let us know how we are doing.",
|
||||||
// Icons.star_rate_rounded,
|
Icons.star_rate_rounded,
|
||||||
// const Color(0xffd69d7d),
|
const Color(0xffe9e8a1),
|
||||||
// () {
|
() {
|
||||||
// print("Opeining rating dialog");
|
businessReviewRatingWindow(true, widget.width);
|
||||||
// // _launchWebsite(widget.website);
|
},
|
||||||
// },
|
),
|
||||||
// ),
|
|
||||||
// Padding(
|
// Padding(
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
// padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
// child: Divider(
|
// child: Divider(
|
||||||
@@ -444,4 +502,52 @@ class _MihBusinessCardState extends State<MihBusinessCard> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> businessReviewRatingWindow(
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,537 @@
|
|||||||
|
import 'package:custom_rating_bar/custom_rating_bar.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_speed_dial/flutter_speed_dial.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_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_form.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.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:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
|
||||||
|
import 'package:supertokens_flutter/supertokens.dart';
|
||||||
|
|
||||||
|
class MihReviewBusinessWindow extends StatefulWidget {
|
||||||
|
final Business business;
|
||||||
|
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
|
||||||
|
State<MihReviewBusinessWindow> createState() =>
|
||||||
|
_MihReviewBusinessWindowState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
final TextEditingController _reviewTitleController = TextEditingController();
|
||||||
|
final TextEditingController _reviewScoreController = TextEditingController();
|
||||||
|
final TextEditingController _reviewReviewerController =
|
||||||
|
TextEditingController();
|
||||||
|
final TextEditingController _reviewDescriptionController =
|
||||||
|
TextEditingController();
|
||||||
|
late final VoidCallback _reviewDescriptionListener;
|
||||||
|
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
|
||||||
|
String userId = "";
|
||||||
|
|
||||||
|
void showDeleteReviewAlert() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => MihPackageAlert(
|
||||||
|
alertColour: MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
alertIcon: Icon(
|
||||||
|
Icons.warning_rounded,
|
||||||
|
size: 100,
|
||||||
|
color: MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
alertTitle: "Delete Review",
|
||||||
|
alertBody: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Are you sure you want to delete this review? This action cannot be undone.",
|
||||||
|
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 {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const Mihloadingcircle();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
await MihMzansiDirectoryServices()
|
||||||
|
.deleteBusinessReview(
|
||||||
|
widget.businessReview!.idbusiness_ratings,
|
||||||
|
widget.businessReview!.business_id,
|
||||||
|
widget.businessReview!.rating_score,
|
||||||
|
widget.business.rating,
|
||||||
|
)
|
||||||
|
.then((statusCode) {
|
||||||
|
Navigator.of(context).pop(); //Remove loading dialog
|
||||||
|
Navigator.of(context).pop(); //Remove delete dialog
|
||||||
|
if (statusCode == 200) {
|
||||||
|
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(
|
||||||
|
widget.startUpSearch, // startUpSearch
|
||||||
|
false, // personalSearch
|
||||||
|
),
|
||||||
|
);
|
||||||
|
MihAlertServices().successAlert(
|
||||||
|
"Successfully Deleted Review!",
|
||||||
|
"Your review has successfully been delete and will no longer appear under the business.",
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
MihAlertServices().errorAlert(
|
||||||
|
"Error Deleting Review",
|
||||||
|
"There was an error deleting your review. Please try again later.",
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
buttonColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
child: Text(
|
||||||
|
"Delete",
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MihButton(
|
||||||
|
width: 300,
|
||||||
|
onPressed: () {
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color getMissionVisionLimitColor(int limit) {
|
||||||
|
if (_counter.value <= limit) {
|
||||||
|
return MzansiInnovationHub.of(context)!.theme.secondaryColor();
|
||||||
|
} else {
|
||||||
|
return MzansiInnovationHub.of(context)!.theme.errorColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void submitForm() async {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const Mihloadingcircle();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (widget.businessReview != null) {
|
||||||
|
await MihMzansiDirectoryServices()
|
||||||
|
.updateBusinessReview(
|
||||||
|
widget.businessReview!.idbusiness_ratings,
|
||||||
|
widget.businessReview!.business_id,
|
||||||
|
_reviewTitleController.text,
|
||||||
|
_reviewDescriptionController.text,
|
||||||
|
_reviewScoreController.text,
|
||||||
|
widget.businessReview!.rating_score,
|
||||||
|
widget.business.rating,
|
||||||
|
)
|
||||||
|
.then((statusCode) {
|
||||||
|
Navigator.of(context).pop(); //Remove loading dialog
|
||||||
|
if (statusCode == 200) {
|
||||||
|
Navigator.of(context).pop(); //pop window
|
||||||
|
Navigator.of(context).pop(); //pop business profile
|
||||||
|
Navigator.of(context).pop(); //pop directory
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
'/mzansi-directory',
|
||||||
|
arguments: MzansiDirectoryArguments(
|
||||||
|
widget.startUpSearch, // startUpSearch
|
||||||
|
false, // personalSearch
|
||||||
|
),
|
||||||
|
);
|
||||||
|
MihAlertServices().successAlert(
|
||||||
|
"Successfully Updated Review!",
|
||||||
|
"Your review has successfully been updated and will now appear under the business.",
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
MihAlertServices().errorAlert(
|
||||||
|
"Error Updating Review",
|
||||||
|
"There was an error updating your review. Please try again later.",
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await MihMzansiDirectoryServices()
|
||||||
|
.addBusinessReview(
|
||||||
|
userId,
|
||||||
|
widget.business.business_id,
|
||||||
|
_reviewTitleController.text,
|
||||||
|
_reviewDescriptionController.text,
|
||||||
|
_reviewScoreController.text,
|
||||||
|
widget.business.rating.isEmpty ? "0.0" : widget.business.rating,
|
||||||
|
)
|
||||||
|
.then((statusCode) {
|
||||||
|
Navigator.of(context).pop(); //Remove loading dialog
|
||||||
|
if (statusCode == 201) {
|
||||||
|
Navigator.of(context).pop(); // pop window
|
||||||
|
Navigator.of(context).pop(); // pop business profile
|
||||||
|
Navigator.of(context).pop(); // pop directory
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
'/mzansi-directory',
|
||||||
|
arguments: MzansiDirectoryArguments(
|
||||||
|
widget.startUpSearch, // startUpSearch
|
||||||
|
false, // personalSearch
|
||||||
|
),
|
||||||
|
);
|
||||||
|
MihAlertServices().successAlert(
|
||||||
|
"Successfully Added Review!",
|
||||||
|
"Your review has successfully been added and will now appear under the business.",
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
MihAlertServices().errorAlert(
|
||||||
|
"Error Adding Review",
|
||||||
|
"There was an error adding your review. Please try again later.",
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getWindowTitle() {
|
||||||
|
if (widget.readOnly) {
|
||||||
|
return "Review Details";
|
||||||
|
} else if (widget.businessReview != null) {
|
||||||
|
return "Update Review";
|
||||||
|
} else {
|
||||||
|
return "Add Review";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
_reviewDescriptionController.removeListener(_reviewDescriptionListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_reviewDescriptionListener = () {
|
||||||
|
setState(() {
|
||||||
|
_counter.value = _reviewDescriptionController.text.characters.length;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
_reviewDescriptionController.addListener(_reviewDescriptionListener);
|
||||||
|
if (widget.businessReview != null) {
|
||||||
|
setState(() {
|
||||||
|
_reviewTitleController.text = widget.businessReview!.rating_title;
|
||||||
|
_reviewDescriptionController.text =
|
||||||
|
widget.businessReview!.rating_description;
|
||||||
|
_reviewScoreController.text = widget.businessReview!.rating_score;
|
||||||
|
_reviewReviewerController.text = widget.businessReview!.reviewer;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_reviewScoreController.text = "1.0"; // Default score
|
||||||
|
}
|
||||||
|
SuperTokens.getUserId().then((value) {
|
||||||
|
setState(() {
|
||||||
|
userId = value;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// return const Placeholder();
|
||||||
|
return MihPackageWindow(
|
||||||
|
fullscreen: false,
|
||||||
|
windowTitle: getWindowTitle(),
|
||||||
|
onWindowTapClose: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
menuOptions: widget.businessReview != null && !widget.readOnly
|
||||||
|
? [
|
||||||
|
SpeedDialChild(
|
||||||
|
child: Icon(
|
||||||
|
Icons.delete,
|
||||||
|
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
),
|
||||||
|
label: "Delete Review",
|
||||||
|
labelBackgroundColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
backgroundColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
onTap: () {
|
||||||
|
showDeleteReviewAlert();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
windowBody: MihSingleChildScroll(
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||||
|
? EdgeInsets.symmetric(horizontal: widget.screenWidth * 0.05)
|
||||||
|
: EdgeInsets.symmetric(horizontal: widget.screenWidth * 0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
MihForm(
|
||||||
|
formKey: _formKey,
|
||||||
|
formFields: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Business Rating",
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
widget.readOnly
|
||||||
|
? RatingBar.readOnly(
|
||||||
|
size: 50,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
filledIcon: Icons.star,
|
||||||
|
emptyIcon: Icons.star_border,
|
||||||
|
halfFilledIcon: Icons.star_half,
|
||||||
|
filledColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
emptyColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
halfFilledColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
isHalfAllowed: true,
|
||||||
|
initialRating: widget.businessReview != null
|
||||||
|
? double.parse(_reviewScoreController.text)
|
||||||
|
: 1,
|
||||||
|
maxRating: 5,
|
||||||
|
)
|
||||||
|
: RatingBar(
|
||||||
|
size: 50,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
filledIcon: Icons.star,
|
||||||
|
emptyIcon: Icons.star_border,
|
||||||
|
halfFilledIcon: Icons.star_half,
|
||||||
|
filledColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
emptyColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
halfFilledColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
isHalfAllowed: true,
|
||||||
|
initialRating: widget.businessReview != null
|
||||||
|
? double.parse(_reviewScoreController.text)
|
||||||
|
: 1,
|
||||||
|
maxRating: 5,
|
||||||
|
onRatingChanged: (double) {
|
||||||
|
setState(() {
|
||||||
|
_reviewScoreController.text =
|
||||||
|
double.toStringAsFixed(1);
|
||||||
|
});
|
||||||
|
print(_reviewScoreController.text);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: widget.readOnly,
|
||||||
|
child: const SizedBox(height: 10),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: widget.readOnly,
|
||||||
|
child: MihTextFormField(
|
||||||
|
// width: 200,
|
||||||
|
fillColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
inputColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
controller: _reviewReviewerController,
|
||||||
|
multiLineInput: false,
|
||||||
|
requiredText: true,
|
||||||
|
readOnly: true,
|
||||||
|
hintText: "Reviewer",
|
||||||
|
validator: (value) {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
MihTextFormField(
|
||||||
|
// width: 200,
|
||||||
|
fillColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
inputColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
controller: _reviewTitleController,
|
||||||
|
multiLineInput: false,
|
||||||
|
requiredText: true,
|
||||||
|
readOnly: widget.readOnly,
|
||||||
|
hintText: "Review Title",
|
||||||
|
validator: (value) {
|
||||||
|
return MihValidationServices()
|
||||||
|
.isEmpty(_reviewTitleController.text);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
MihTextFormField(
|
||||||
|
height: 250,
|
||||||
|
fillColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
inputColor:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
controller: _reviewDescriptionController,
|
||||||
|
multiLineInput: true,
|
||||||
|
requiredText: widget.readOnly,
|
||||||
|
readOnly: widget.readOnly,
|
||||||
|
hintText: "Review Description",
|
||||||
|
validator: (value) {
|
||||||
|
if (_reviewDescriptionController.text.isEmpty) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return MihValidationServices().validateLength(
|
||||||
|
_reviewDescriptionController.text, 256);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: !widget.readOnly,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 15,
|
||||||
|
child: ValueListenableBuilder(
|
||||||
|
valueListenable: _counter,
|
||||||
|
builder:
|
||||||
|
(BuildContext context, int value, Widget? child) {
|
||||||
|
return Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"$value",
|
||||||
|
style: TextStyle(
|
||||||
|
color: getMissionVisionLimitColor(256),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(
|
||||||
|
"/256",
|
||||||
|
style: TextStyle(
|
||||||
|
color: getMissionVisionLimitColor(256),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
Visibility(
|
||||||
|
visible: !widget.readOnly,
|
||||||
|
child: Center(
|
||||||
|
child: MihButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
submitForm();
|
||||||
|
} else {
|
||||||
|
MihAlertServices().formNotFilledCompletely(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buttonColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.successColor(),
|
||||||
|
width: 300,
|
||||||
|
child: Text(
|
||||||
|
widget.businessReview != null
|
||||||
|
? "Update Review"
|
||||||
|
: "Add Review",
|
||||||
|
style: TextStyle(
|
||||||
|
color: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.primaryColor(),
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.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.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart';
|
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_details_view.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/package_tools/mih_business_reviews.dart';
|
||||||
|
|
||||||
class MzansiBusinessProfileView extends StatefulWidget {
|
class MzansiBusinessProfileView extends StatefulWidget {
|
||||||
final Business business;
|
final BusinessViewArguments arguments;
|
||||||
const MzansiBusinessProfileView({
|
const MzansiBusinessProfileView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.business,
|
required this.arguments,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -54,6 +55,11 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
|
|||||||
_selcetedIndex = 0;
|
_selcetedIndex = 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
temp[const Icon(Icons.star_rate_rounded)] = () {
|
||||||
|
setState(() {
|
||||||
|
_selcetedIndex = 1;
|
||||||
|
});
|
||||||
|
};
|
||||||
return MihPackageTools(
|
return MihPackageTools(
|
||||||
tools: temp,
|
tools: temp,
|
||||||
selcetedIndex: _selcetedIndex,
|
selcetedIndex: _selcetedIndex,
|
||||||
@@ -62,7 +68,11 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
|
|||||||
|
|
||||||
List<Widget> getToolBody() {
|
List<Widget> getToolBody() {
|
||||||
List<Widget> toolBodies = [
|
List<Widget> toolBodies = [
|
||||||
MihBusinessDetailsView(business: widget.business),
|
MihBusinessDetailsView(
|
||||||
|
business: widget.arguments.business,
|
||||||
|
startUpSearch: widget.arguments.startUpSearch,
|
||||||
|
),
|
||||||
|
MihBusinessReviews(business: widget.arguments.business),
|
||||||
];
|
];
|
||||||
return toolBodies;
|
return toolBodies;
|
||||||
}
|
}
|
||||||
@@ -70,6 +80,7 @@ class _MzansiBusinessProfileViewState extends State<MzansiBusinessProfileView> {
|
|||||||
List<String> getToolTitle() {
|
List<String> getToolTitle() {
|
||||||
List<String> toolTitles = [
|
List<String> toolTitles = [
|
||||||
"Profile",
|
"Profile",
|
||||||
|
"Reviews",
|
||||||
];
|
];
|
||||||
return toolTitles;
|
return toolTitles;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -680,12 +680,18 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 700,
|
width: 700,
|
||||||
child: MihBusinessCard(
|
child: MihBusinessCard(
|
||||||
businessName: widget.arguments.business!.Name,
|
// businessid: widget.arguments.business!.business_id,
|
||||||
cellNumber: widget.arguments.business!.contact_no,
|
// businessName: widget.arguments.business!.Name,
|
||||||
email: widget.arguments.business!.bus_email,
|
// cellNumber: widget.arguments.business!.contact_no,
|
||||||
gpsLocation: widget.arguments.business!.gps_location,
|
// email: widget.arguments.business!.bus_email,
|
||||||
//To-Do: Add the business Website
|
// gpsLocation: widget.arguments.business!.gps_location,
|
||||||
website: widget.arguments.business!.website,
|
// rating: widget.arguments.business!.rating.isNotEmpty
|
||||||
|
// ? double.parse(widget.arguments.business!.rating)
|
||||||
|
// : 0,
|
||||||
|
// website: widget.arguments.business!.website,
|
||||||
|
business: widget.arguments.business!,
|
||||||
|
startUpSearch: null,
|
||||||
|
width: width,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30.0),
|
const SizedBox(height: 30.0),
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
|
|||||||
|
|
||||||
class MihBusinessDetailsView extends StatefulWidget {
|
class MihBusinessDetailsView extends StatefulWidget {
|
||||||
final Business business;
|
final Business business;
|
||||||
|
final String? startUpSearch;
|
||||||
const MihBusinessDetailsView({
|
const MihBusinessDetailsView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.business,
|
required this.business,
|
||||||
|
required this.startUpSearch,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -162,12 +164,18 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 700,
|
width: 700,
|
||||||
child: MihBusinessCard(
|
child: MihBusinessCard(
|
||||||
businessName: widget.business.Name,
|
business: widget.business,
|
||||||
cellNumber: widget.business.contact_no,
|
startUpSearch: widget.startUpSearch,
|
||||||
email: widget.business.bus_email,
|
// businessid: widget.business.business_id,
|
||||||
gpsLocation: widget.business.gps_location,
|
// businessName: widget.business.Name,
|
||||||
//To-Do: Add the business Website
|
// cellNumber: widget.business.contact_no,
|
||||||
website: widget.business.website,
|
// email: widget.business.bus_email,
|
||||||
|
// gpsLocation: widget.business.gps_location,
|
||||||
|
// rating: widget.business.rating.isNotEmpty
|
||||||
|
// ? double.parse(widget.business.rating)
|
||||||
|
// : 0,
|
||||||
|
// website: widget.business.website,
|
||||||
|
width: width,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
import 'package:custom_rating_bar/custom_rating_bar.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/main.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business_review.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_review_business_window.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
|
||||||
|
|
||||||
|
class MihBusinessReviews extends StatefulWidget {
|
||||||
|
final Business business;
|
||||||
|
const MihBusinessReviews({
|
||||||
|
super.key,
|
||||||
|
required this.business,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MihBusinessReviews> createState() => _MihBusinessReviewsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MihBusinessReviewsState extends State<MihBusinessReviews> {
|
||||||
|
// late Future<List<BusinessReview>> _reviews;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// super.initState();
|
||||||
|
// _reviews = MihMzansiDirectoryServices().getAllReviewsofBusiness(
|
||||||
|
// widget.businessId,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
void onReviewTap(BusinessReview? businessReview, double width) {
|
||||||
|
// showDialog(context: context, builder: (context)=> )
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return MihReviewBusinessWindow(
|
||||||
|
business: widget.business,
|
||||||
|
businessReview: businessReview,
|
||||||
|
screenWidth: width,
|
||||||
|
readOnly: true,
|
||||||
|
startUpSearch: null,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
double screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
return FutureBuilder(
|
||||||
|
future: MihMzansiDirectoryServices().getAllReviewsofBusiness(
|
||||||
|
widget.business.business_id,
|
||||||
|
),
|
||||||
|
builder: (context, asyncSnapshot) {
|
||||||
|
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return const Mihloadingcircle();
|
||||||
|
} else if (asyncSnapshot.connectionState == ConnectionState.done &&
|
||||||
|
asyncSnapshot.hasData) {
|
||||||
|
List<BusinessReview> reviews = asyncSnapshot.data!;
|
||||||
|
if (reviews.isEmpty) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 50),
|
||||||
|
Icon(
|
||||||
|
Icons.star_rate_rounded,
|
||||||
|
size: 150,
|
||||||
|
color:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No reviews yet, be the first the review\n${widget.business.Name}",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
int descriptionDisplayCOunt = 75;
|
||||||
|
return ListView.separated(
|
||||||
|
itemCount: reviews.length,
|
||||||
|
separatorBuilder: (context, index) => Divider(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return ListTile(
|
||||||
|
onTap: () {
|
||||||
|
onReviewTap(reviews[index], screenWidth);
|
||||||
|
},
|
||||||
|
title: RatingBar.readOnly(
|
||||||
|
size: 25,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
filledIcon: Icons.star,
|
||||||
|
emptyIcon: Icons.star_border,
|
||||||
|
halfFilledIcon: Icons.star_half,
|
||||||
|
filledColor: const Color(0xffe9e8a1),
|
||||||
|
// MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
emptyColor: MzansiInnovationHub.of(context)!
|
||||||
|
.theme
|
||||||
|
.secondaryColor(),
|
||||||
|
halfFilledColor: const Color(0xffe9e8a1),
|
||||||
|
// MzansiInnovationHub.of(context)!.theme.primaryColor(),
|
||||||
|
// filledColor:
|
||||||
|
// MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
// emptyColor:
|
||||||
|
// MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
// halfFilledColor:
|
||||||
|
// MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
isHalfAllowed: true,
|
||||||
|
initialRating: double.parse(reviews[index].rating_score),
|
||||||
|
maxRating: 5,
|
||||||
|
),
|
||||||
|
subtitle: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
// Text(
|
||||||
|
// "${reviews[index].reviewer} ",
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 15,
|
||||||
|
// fontWeight: FontWeight.bold,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
Text(
|
||||||
|
reviews[index].rating_title,
|
||||||
|
softWrap: true,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"${reviews[index].date_time.split("T")[0]} ",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Center(child: Text('Error'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,4 +55,66 @@ class MihAlertServices {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void successAlert(String title, String message, BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return MihPackageAlert(
|
||||||
|
alertIcon: Icon(
|
||||||
|
Icons.check_circle_outline_rounded,
|
||||||
|
size: 150,
|
||||||
|
color: MzansiInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
),
|
||||||
|
alertTitle: title,
|
||||||
|
alertBody: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
message,
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
alertColour: MzansiInnovationHub.of(context)!.theme.successColor(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void errorAlert(String title, String message, BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return MihPackageAlert(
|
||||||
|
alertIcon: Icon(
|
||||||
|
Icons.warning_amber_rounded,
|
||||||
|
size: 150,
|
||||||
|
color: MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
),
|
||||||
|
alertTitle: title,
|
||||||
|
alertBody: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
message,
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
MzansiInnovationHub.of(context)!.theme.secondaryColor(),
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
alertColour: MzansiInnovationHub.of(context)!.theme.errorColor(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
128
Frontend/lib/mih_services/mih_mzansi_directory_services.dart
Normal file
128
Frontend/lib/mih_services/mih_mzansi_directory_services.dart
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
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;
|
||||||
|
|
||||||
|
class MihMzansiDirectoryServices {
|
||||||
|
final baseAPI = AppEnviroment.baseApiUrl;
|
||||||
|
|
||||||
|
Future<BusinessReview?> getUserReviewOfBusiness(
|
||||||
|
String app_id,
|
||||||
|
String business_id,
|
||||||
|
) async {
|
||||||
|
final response = await http.get(Uri.parse(
|
||||||
|
"${AppEnviroment.baseApiUrl}/mzansi-directory/business-ratings/user/$app_id/$business_id"));
|
||||||
|
print(response.statusCode);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
String body = response.body;
|
||||||
|
var jsonBody = jsonDecode(body);
|
||||||
|
BusinessReview? busRev = BusinessReview.fromJson(jsonBody);
|
||||||
|
return busRev;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<BusinessReview>> getAllReviewsofBusiness(
|
||||||
|
String business_id,
|
||||||
|
) async {
|
||||||
|
final response = await http.get(Uri.parse(
|
||||||
|
"${AppEnviroment.baseApiUrl}/mzansi-directory/business-ratings/all/$business_id"));
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
Iterable l = jsonDecode(response.body);
|
||||||
|
List<BusinessReview> businessReviews = List<BusinessReview>.from(
|
||||||
|
l.map((model) => BusinessReview.fromJson(model)));
|
||||||
|
return businessReviews;
|
||||||
|
} else {
|
||||||
|
throw Exception('failed to fetch Business Reviews');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> addBusinessReview(
|
||||||
|
String app_id,
|
||||||
|
String business_id,
|
||||||
|
String rating_title,
|
||||||
|
String rating_description,
|
||||||
|
String rating_score,
|
||||||
|
String current_rating,
|
||||||
|
) async {
|
||||||
|
var response = await http.post(
|
||||||
|
Uri.parse(
|
||||||
|
"${AppEnviroment.baseApiUrl}/mzansi-directory/business-rating/insert/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
body: jsonEncode(<String, dynamic>{
|
||||||
|
"app_id": app_id,
|
||||||
|
"business_id": business_id,
|
||||||
|
"rating_title": rating_title,
|
||||||
|
"rating_description": rating_description,
|
||||||
|
"rating_score": rating_score,
|
||||||
|
"current_rating": current_rating,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if (response.statusCode == 201) {
|
||||||
|
return response.statusCode;
|
||||||
|
} else {
|
||||||
|
return response.statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> deleteBusinessReview(
|
||||||
|
int idbusiness_ratings,
|
||||||
|
String business_id,
|
||||||
|
String rating_score,
|
||||||
|
String current_rating,
|
||||||
|
) async {
|
||||||
|
var response = await http.delete(
|
||||||
|
Uri.parse(
|
||||||
|
"${AppEnviroment.baseApiUrl}/mzansi-directory/business-rating/delete/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
body: jsonEncode(<String, dynamic>{
|
||||||
|
"idbusiness_ratings": idbusiness_ratings,
|
||||||
|
"business_id": business_id,
|
||||||
|
"rating_score": rating_score,
|
||||||
|
"current_rating": current_rating,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
return response.statusCode;
|
||||||
|
} else {
|
||||||
|
return response.statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> updateBusinessReview(
|
||||||
|
int idbusiness_ratings,
|
||||||
|
String business_id,
|
||||||
|
String rating_title,
|
||||||
|
String rating_description,
|
||||||
|
String rating_new_score,
|
||||||
|
String rating_old_score,
|
||||||
|
String current_rating,
|
||||||
|
) async {
|
||||||
|
var response = await http.put(
|
||||||
|
Uri.parse(
|
||||||
|
"${AppEnviroment.baseApiUrl}/mzansi-directory/business-rating/update/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
body: jsonEncode(<String, dynamic>{
|
||||||
|
"idbusiness_ratings": idbusiness_ratings,
|
||||||
|
"business_id": business_id,
|
||||||
|
"rating_title": rating_title,
|
||||||
|
"rating_description": rating_description,
|
||||||
|
"rating_new_score": rating_new_score,
|
||||||
|
"rating_old_score": rating_old_score,
|
||||||
|
"current_rating": current_rating,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
return response.statusCode;
|
||||||
|
} else {
|
||||||
|
return response.statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -265,6 +265,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
custom_rating_bar:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: custom_rating_bar
|
||||||
|
sha256: c2dafa488843b29f50ac2c2905b6a4cefd2cb603de31c6224adb047b6ed8593e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ dependencies:
|
|||||||
pwa_install: ^0.0.6
|
pwa_install: ^0.0.6
|
||||||
google_mobile_ads: ^6.0.0
|
google_mobile_ads: ^6.0.0
|
||||||
redacted: ^1.0.13
|
redacted: ^1.0.13
|
||||||
|
custom_rating_bar: ^3.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
2
backend/.gitignore
vendored
2
backend/.gitignore
vendored
@@ -1,3 +1,3 @@
|
|||||||
database/__pycache__/
|
.env
|
||||||
__pycache__/
|
__pycache__/
|
||||||
temp*.pdf
|
temp*.pdf
|
||||||
@@ -1,19 +1,25 @@
|
|||||||
from minio import Minio
|
from minio import Minio
|
||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
minioAccess = os.getenv("MINIO_ACCESS_KEY")
|
||||||
|
minioSecret = os.getenv("MINIO_SECRET_KEY")
|
||||||
|
|
||||||
def minioConnect(env):
|
def minioConnect(env):
|
||||||
if(env == "Dev"):
|
if(env == "Dev"):
|
||||||
return Minio(
|
return Minio(
|
||||||
"minio:9000",
|
"minio:9000",
|
||||||
# "minio.mzansi-innovation-hub.co.za",
|
# "minio.mzansi-innovation-hub.co.za",
|
||||||
access_key="0RcgutfvcDq28lz7",
|
access_key=minioAccess,
|
||||||
secret_key="nEED72ZlKYgDqH9Iy46fVGGT9TfabGWO",
|
secret_key=minioSecret,
|
||||||
secure=False
|
secure=False
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return Minio(
|
return Minio(
|
||||||
#"minio:9000",
|
#"minio:9000",
|
||||||
"minio.mzansi-innovation-hub.co.za",
|
"minio.mzansi-innovation-hub.co.za",
|
||||||
access_key="0RcgutfvcDq28lz7",
|
access_key=minioAccess,
|
||||||
secret_key="nEED72ZlKYgDqH9Iy46fVGGT9TfabGWO",
|
secret_key=minioSecret,
|
||||||
secure=True
|
secure=True
|
||||||
)
|
)
|
||||||
@@ -1,48 +1,62 @@
|
|||||||
import mysql.connector
|
import mysql.connector
|
||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
dbUser = os.getenv("DB_USER")
|
||||||
|
dbPass = os.getenv("DB_PASSWD")
|
||||||
|
|
||||||
def dbPatientManagerConnect():
|
def dbPatientManagerConnect():
|
||||||
return mysql.connector.connect(
|
return mysql.connector.connect(
|
||||||
host="mysqldb",
|
host="mysqldb",
|
||||||
user="root",
|
user=dbUser,
|
||||||
passwd="C@rtoon1995",
|
passwd=dbPass,
|
||||||
database="patient_manager"
|
database="patient_manager"
|
||||||
)
|
)
|
||||||
|
|
||||||
def dbAppDataConnect():
|
def dbAppDataConnect():
|
||||||
return mysql.connector.connect(
|
return mysql.connector.connect(
|
||||||
host="mysqldb",
|
host="mysqldb",
|
||||||
user="root",
|
user=dbUser,
|
||||||
passwd="C@rtoon1995",
|
passwd=dbPass,
|
||||||
database="app_data"
|
database="app_data"
|
||||||
)
|
)
|
||||||
|
|
||||||
def dbDataAccessConnect():
|
def dbDataAccessConnect():
|
||||||
return mysql.connector.connect(
|
return mysql.connector.connect(
|
||||||
host="mysqldb",
|
host="mysqldb",
|
||||||
user="root",
|
user=dbUser,
|
||||||
passwd="C@rtoon1995",
|
passwd=dbPass,
|
||||||
database="data_access"
|
database="data_access"
|
||||||
)
|
)
|
||||||
|
|
||||||
def dbMzansiWalletConnect():
|
def dbMzansiWalletConnect():
|
||||||
return mysql.connector.connect(
|
return mysql.connector.connect(
|
||||||
host="mysqldb",
|
host="mysqldb",
|
||||||
user="root",
|
user=dbUser,
|
||||||
passwd="C@rtoon1995",
|
passwd=dbPass,
|
||||||
database="mzansi_wallet"
|
database="mzansi_wallet"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def dbMzansiDirectoryConnect():
|
||||||
|
return mysql.connector.connect(
|
||||||
|
host="mysqldb",
|
||||||
|
user=dbUser,
|
||||||
|
passwd=dbPass,
|
||||||
|
database="mzansi_directory"
|
||||||
|
)
|
||||||
|
|
||||||
def dbMzansiCalendarConnect():
|
def dbMzansiCalendarConnect():
|
||||||
return mysql.connector.connect(
|
return mysql.connector.connect(
|
||||||
host="mysqldb",
|
host="mysqldb",
|
||||||
user="root",
|
user=dbUser,
|
||||||
passwd="C@rtoon1995",
|
passwd=dbPass,
|
||||||
database="mzansi_calendar"
|
database="mzansi_calendar"
|
||||||
)
|
)
|
||||||
|
|
||||||
def dbAllConnect():
|
def dbAllConnect():
|
||||||
return mysql.connector.connect(
|
return mysql.connector.connect(
|
||||||
host="mysqldb",
|
host="mysqldb",
|
||||||
user="root",
|
user=dbUser,
|
||||||
passwd="C@rtoon1995",
|
passwd=dbPass,
|
||||||
)
|
)
|
||||||
@@ -17,6 +17,7 @@ import routers.business as business
|
|||||||
import routers.access_request as access_request
|
import routers.access_request as access_request
|
||||||
import routers.patient_access as patient_access
|
import routers.patient_access as patient_access
|
||||||
import routers.mzansi_wallet as mzansi_wallet
|
import routers.mzansi_wallet as mzansi_wallet
|
||||||
|
import routers.mzansi_directory as mzansi_directory
|
||||||
import routers.icd10_codes as icd10_codes
|
import routers.icd10_codes as icd10_codes
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.middleware import Middleware
|
from fastapi.middleware import Middleware
|
||||||
@@ -92,6 +93,7 @@ app.include_router(business_user.router)
|
|||||||
app.include_router(business.router)
|
app.include_router(business.router)
|
||||||
app.include_router(notifications.router)
|
app.include_router(notifications.router)
|
||||||
app.include_router(mzansi_wallet.router)
|
app.include_router(mzansi_wallet.router)
|
||||||
|
app.include_router(mzansi_directory.router)
|
||||||
app.include_router(icd10_codes.router)
|
app.include_router(icd10_codes.router)
|
||||||
app.include_router(appointments.router)
|
app.include_router(appointments.router)
|
||||||
|
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ reportlab
|
|||||||
requests
|
requests
|
||||||
watchfiles
|
watchfiles
|
||||||
python-multipart
|
python-multipart
|
||||||
|
python-dotenv
|
||||||
xlrd
|
xlrd
|
||||||
supertokens-python==0.29.2
|
supertokens-python==0.29.2
|
||||||
@@ -72,9 +72,10 @@ async def read_all_businesses(search: str, session: SessionContainer = Depends(v
|
|||||||
query += "practice_no, vat_no, "
|
query += "practice_no, vat_no, "
|
||||||
query += "website, rating, mission_vision "
|
query += "website, rating, mission_vision "
|
||||||
query += "FROM business "
|
query += "FROM business "
|
||||||
query += "WHERE LOWER(business.Name) LIKE %s OR LOWER(business.type) LIKE %s"
|
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
|
search_term = f"%{search.lower()}%" # Add wildcards and lowercase
|
||||||
cursor.execute(query, (search_term, search_term))
|
cursor.execute(query, (search_term, search_term, search_term, search_term))
|
||||||
items = [
|
items = [
|
||||||
{
|
{
|
||||||
"business_id": item[0],
|
"business_id": item[0],
|
||||||
|
|||||||
236
backend/routers/mzansi_directory.py
Normal file
236
backend/routers/mzansi_directory.py
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
from fastapi import APIRouter, HTTPException
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from datetime import datetime
|
||||||
|
import database
|
||||||
|
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||||
|
from supertokens_python.recipe.session import SessionContainer
|
||||||
|
from fastapi import Depends
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
# class BusinessRatingUserGet(BaseModel):
|
||||||
|
# app_id: str
|
||||||
|
# business_id: str
|
||||||
|
|
||||||
|
class BusinessRatingInsertRequest(BaseModel):
|
||||||
|
app_id: str
|
||||||
|
business_id: str
|
||||||
|
rating_title: str
|
||||||
|
rating_description: str
|
||||||
|
rating_score: str
|
||||||
|
current_rating: str
|
||||||
|
|
||||||
|
class BusinessRatingDeleteRequest(BaseModel):
|
||||||
|
idbusiness_ratings: int
|
||||||
|
business_id: str
|
||||||
|
rating_score: str
|
||||||
|
current_rating: str
|
||||||
|
|
||||||
|
class BusinessRatingUpdateRequest(BaseModel):
|
||||||
|
idbusiness_ratings: int
|
||||||
|
business_id: str
|
||||||
|
rating_title: str
|
||||||
|
rating_description: str
|
||||||
|
rating_new_score: str
|
||||||
|
rating_old_score: str
|
||||||
|
current_rating: str
|
||||||
|
|
||||||
|
@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())
|
||||||
|
db = database.dbConnection.dbAllConnect()
|
||||||
|
cursor = db.cursor()
|
||||||
|
query = ""
|
||||||
|
query += "SELECT business_ratings.idbusiness_ratings, business_ratings.app_id, business_ratings.business_id, "
|
||||||
|
query += "business_ratings.rating_title, business_ratings.rating_description, business_ratings.rating_score, "
|
||||||
|
query += "business_ratings.date_time, users.username as 'reviewer' "
|
||||||
|
query += "FROM mzansi_directory.business_ratings "
|
||||||
|
query += "inner join app_data.users "
|
||||||
|
query += "on business_ratings.app_id = users.app_id "
|
||||||
|
query += "where business_ratings.business_id = %s and business_ratings.app_id = %s;"
|
||||||
|
cursor.execute(query, (business_id,
|
||||||
|
app_id,))
|
||||||
|
item = cursor.fetchone() # Get only one row
|
||||||
|
cursor.close()
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
if item:
|
||||||
|
# Return a single dictionary
|
||||||
|
return {
|
||||||
|
"idbusiness_ratings": item[0],
|
||||||
|
"app_id": item[1],
|
||||||
|
"business_id": item[2],
|
||||||
|
"rating_title": item[3],
|
||||||
|
"rating_description": item[4],
|
||||||
|
"rating_score": item[5],
|
||||||
|
"date_time": item[6],
|
||||||
|
"reviewer": item[7],
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
# Return an empty response or a specific message
|
||||||
|
return None
|
||||||
|
# items = [
|
||||||
|
# {
|
||||||
|
# "idbusiness_ratings": item[0],
|
||||||
|
# "app_id": item[1],
|
||||||
|
# "business_id": item[2],
|
||||||
|
# "rating_title": item[3],
|
||||||
|
# "rating_description": item[4],
|
||||||
|
# "rating_score": item[5],
|
||||||
|
# "date_time": item[6],
|
||||||
|
# "reviewer": item[7],
|
||||||
|
# }
|
||||||
|
# for item in cursor.fetchall()
|
||||||
|
# ]
|
||||||
|
# cursor.close()
|
||||||
|
# db.close()
|
||||||
|
# return items[0]
|
||||||
|
|
||||||
|
@router.get("/mzansi-directory/business-ratings/all/{business_id}", tags=["Mzansi Directory"])
|
||||||
|
async def read_all_ratings_by_business_id(business_id: str, session: SessionContainer = Depends(verify_session())): # , session: SessionContainer = Depends(verify_session())
|
||||||
|
db = database.dbConnection.dbAllConnect()
|
||||||
|
cursor = db.cursor()
|
||||||
|
query = ""
|
||||||
|
query += "SELECT business_ratings.idbusiness_ratings, business_ratings.app_id, business_ratings.business_id, "
|
||||||
|
query += "business_ratings.rating_title, business_ratings.rating_description, business_ratings.rating_score, "
|
||||||
|
query += "business_ratings.date_time, users.username as 'reviewer' "
|
||||||
|
query += "FROM mzansi_directory.business_ratings "
|
||||||
|
query += "inner join app_data.users "
|
||||||
|
query += "on business_ratings.app_id = users.app_id "
|
||||||
|
query += "where business_ratings.business_id = %s "
|
||||||
|
query += "order by business_ratings.date_time desc;"
|
||||||
|
cursor.execute(query, (business_id,))
|
||||||
|
items = [
|
||||||
|
{
|
||||||
|
"idbusiness_ratings": item[0],
|
||||||
|
"app_id": item[1],
|
||||||
|
"business_id": item[2],
|
||||||
|
"rating_title": item[3],
|
||||||
|
"rating_description": item[4],
|
||||||
|
"rating_score": item[5],
|
||||||
|
"date_time": item[6],
|
||||||
|
"reviewer": item[7],
|
||||||
|
}
|
||||||
|
for item in cursor.fetchall()
|
||||||
|
]
|
||||||
|
cursor.close()
|
||||||
|
db.close()
|
||||||
|
return items
|
||||||
|
|
||||||
|
@router.post("/mzansi-directory/business-rating/insert/", tags=["Mzansi Directory"], status_code=201)
|
||||||
|
async def insert_loyalty_card(itemRequest : BusinessRatingInsertRequest): #, session: SessionContainer = Depends(verify_session())
|
||||||
|
db = database.dbConnection.dbAllConnect()
|
||||||
|
nowDateTime = datetime.now()
|
||||||
|
formatedDateTime = nowDateTime.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
cursor = db.cursor()
|
||||||
|
try:
|
||||||
|
# Get No Of reviews for business
|
||||||
|
businessReviewCountQuery = "select count(*) from mzansi_directory.business_ratings where business_ratings.business_id = %s"
|
||||||
|
countData = (itemRequest.business_id,)
|
||||||
|
cursor.execute(businessReviewCountQuery, countData)
|
||||||
|
countResult = cursor.fetchone()
|
||||||
|
row_count = countResult[0] if countResult else 0
|
||||||
|
print(f"Number of rows in business_ratings: {row_count}")
|
||||||
|
# add business rating
|
||||||
|
addQuery = "insert into mzansi_directory.business_ratings "
|
||||||
|
addQuery += "(business_ratings.app_id, business_ratings.business_id, business_ratings.rating_title, business_ratings.rating_description, business_ratings.rating_score, business_ratings.date_time) "
|
||||||
|
addQuery += "values (%s, %s, %s, %s, %s, %s)"
|
||||||
|
addQueryData = (itemRequest.app_id,
|
||||||
|
itemRequest.business_id,
|
||||||
|
itemRequest.rating_title,
|
||||||
|
itemRequest.rating_description,
|
||||||
|
itemRequest.rating_score,
|
||||||
|
formatedDateTime,
|
||||||
|
)
|
||||||
|
cursor.execute(addQuery, addQueryData)
|
||||||
|
# Calc New Rating and update business rating
|
||||||
|
newRating = ((float(itemRequest.current_rating) * row_count) + float(itemRequest.rating_score)) / (row_count + 1)
|
||||||
|
print(f"New Rating: {newRating}")
|
||||||
|
updateBusinessQuery = "update app_data.business "
|
||||||
|
updateBusinessQuery += "set rating = %s "
|
||||||
|
updateBusinessQuery += "where business_id = %s"
|
||||||
|
updateBusinessData = (newRating, itemRequest.business_id)
|
||||||
|
cursor.execute(updateBusinessQuery, updateBusinessData)
|
||||||
|
db.commit()
|
||||||
|
except Exception as error:
|
||||||
|
print(error)
|
||||||
|
raise HTTPException(status_code=404, detail="Failed to Create Record")
|
||||||
|
# return {"message": error}
|
||||||
|
cursor.close()
|
||||||
|
db.close()
|
||||||
|
return {"message": "Successfully Created Record"}
|
||||||
|
|
||||||
|
@router.delete("/mzansi-directory/business-rating/delete/", tags=["Mzansi Directory"])
|
||||||
|
async def Delete_loyalty_card(itemRequest : BusinessRatingDeleteRequest, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||||
|
db = database.dbConnection.dbAllConnect()
|
||||||
|
cursor = db.cursor()
|
||||||
|
try:
|
||||||
|
# Get No Of reviews for business
|
||||||
|
businessReviewCountQuery = "select count(*) from mzansi_directory.business_ratings where business_ratings.business_id = %s"
|
||||||
|
countData = (itemRequest.business_id,)
|
||||||
|
cursor.execute(businessReviewCountQuery, countData)
|
||||||
|
countResult = cursor.fetchone()
|
||||||
|
row_count = countResult[0] if countResult else 0
|
||||||
|
print(f"Number of rows in business_ratings: {row_count}")
|
||||||
|
# Delete business rating
|
||||||
|
query = "delete from mzansi_directory.business_ratings "
|
||||||
|
query += "where business_ratings.idbusiness_ratings=%s"
|
||||||
|
cursor.execute(query, (str(itemRequest.idbusiness_ratings),))
|
||||||
|
# Calc New Rating and update business rating
|
||||||
|
if(row_count <= 1):
|
||||||
|
newRating = 0.0
|
||||||
|
else:
|
||||||
|
newRating = ((float(itemRequest.current_rating) * row_count) - float(itemRequest.rating_score)) / (row_count - 1)
|
||||||
|
print(f"New Rating: {newRating}")
|
||||||
|
updateBusinessQuery = "update app_data.business "
|
||||||
|
updateBusinessQuery += "set rating = %s "
|
||||||
|
updateBusinessQuery += "where business_id = %s"
|
||||||
|
updateBusinessData = (newRating, itemRequest.business_id)
|
||||||
|
cursor.execute(updateBusinessQuery, updateBusinessData)
|
||||||
|
db.commit()
|
||||||
|
except Exception as error:
|
||||||
|
print(error)
|
||||||
|
raise HTTPException(status_code=404, detail="Failed to Delete Record")
|
||||||
|
cursor.close()
|
||||||
|
db.close()
|
||||||
|
return {"message": "Successfully deleted Record"}
|
||||||
|
|
||||||
|
@router.put("/mzansi-directory/business-rating/update/", tags=["Mzansi Directory"])
|
||||||
|
async def UpdatePatient(itemRequest : BusinessRatingUpdateRequest, session: SessionContainer = Depends(verify_session())):
|
||||||
|
db = database.dbConnection.dbMzansiDirectoryConnect()
|
||||||
|
cursor = db.cursor()
|
||||||
|
nowDateTime = datetime.now()
|
||||||
|
formatedDateTime = nowDateTime.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
try:
|
||||||
|
# Get No Of reviews for business
|
||||||
|
businessReviewCountQuery = "select count(*) from mzansi_directory.business_ratings where business_ratings.business_id = %s"
|
||||||
|
countData = (itemRequest.business_id,)
|
||||||
|
cursor.execute(businessReviewCountQuery, countData)
|
||||||
|
countResult = cursor.fetchone()
|
||||||
|
row_count = countResult[0] if countResult else 0
|
||||||
|
print(f"Number of rows in business_ratings: {row_count}")
|
||||||
|
# Update business rating
|
||||||
|
query = "update business_ratings "
|
||||||
|
query += "set rating_title=%s, rating_description=%s, rating_score=%s, date_time=%s "
|
||||||
|
query += "where idbusiness_ratings=%s"
|
||||||
|
notetData = (itemRequest.rating_title,
|
||||||
|
itemRequest.rating_description,
|
||||||
|
itemRequest.rating_new_score,
|
||||||
|
formatedDateTime,
|
||||||
|
itemRequest.idbusiness_ratings,
|
||||||
|
)
|
||||||
|
cursor.execute(query, notetData)
|
||||||
|
# Calc New Rating and update business rating
|
||||||
|
# add new rating and old rating params
|
||||||
|
newRating = ((float(itemRequest.current_rating) * row_count) - float(itemRequest.rating_old_score) + float(itemRequest.rating_new_score)) / (row_count)
|
||||||
|
print(f"New Rating: {newRating}")
|
||||||
|
updateBusinessQuery = "update app_data.business "
|
||||||
|
updateBusinessQuery += "set rating = %s "
|
||||||
|
updateBusinessQuery += "where business_id = %s"
|
||||||
|
updateBusinessData = (newRating, itemRequest.business_id)
|
||||||
|
cursor.execute(updateBusinessQuery, updateBusinessData)
|
||||||
|
db.commit()
|
||||||
|
except Exception as error:
|
||||||
|
raise HTTPException(status_code=404, detail="Failed to Update Record")
|
||||||
|
cursor.close()
|
||||||
|
db.close()
|
||||||
|
return {"message": "Successfully Updated Record"}
|
||||||
@@ -74,10 +74,12 @@ async def read_all_users(search: str, session: SessionContainer = Depends(verify
|
|||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
query = ""
|
query = ""
|
||||||
query += "SELECT * FROM users "
|
query += "SELECT * FROM users "
|
||||||
query += "WHERE (LOWER(email) LIKE %s OR LOWER(username) LIKE %s) "
|
query += "WHERE (LOWER(email) LIKE %s OR LOWER(username) LIKE %s "
|
||||||
|
query += "OR LOWER(fname) LIKE %s OR LOWER(lname) LIKE %s "
|
||||||
|
query += "OR LOWER(purpose) LIKE %s) "
|
||||||
query += "AND username != ''"
|
query += "AND username != ''"
|
||||||
search_term = f"%{search.lower()}%" # Add wildcards and lowercase
|
search_term = f"%{search.lower()}%" # Add wildcards and lowercase
|
||||||
cursor.execute(query, (search_term, search_term))
|
cursor.execute(query, (search_term, search_term,search_term, search_term, search_term))
|
||||||
items = [
|
items = [
|
||||||
{
|
{
|
||||||
"idUser": item[0],
|
"idUser": item[0],
|
||||||
|
|||||||
Reference in New Issue
Block a user