rename container folders

This commit is contained in:
2026-01-29 11:11:45 +02:00
parent d5349d981c
commit 5b052a1fa9
654 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,213 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_objects/patient_access.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_providers/mih_access_controlls_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_notification_services.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihAccessControlsServices {
Future<int> getBusinessAccessListOfPatient(
String app_id,
MihAccessControllsProvider mihAccessColtrollsProvider,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/access-requests/personal/patient/$app_id"));
// var errorCode = response.statusCode.toString();
// print(response.statusCode);
// print(response.body);
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<PatientAccess> patientAccesses = List<PatientAccess>.from(
l.map((model) => PatientAccess.fromJson(model)));
if (response.statusCode == 200) {
mihAccessColtrollsProvider.setAccessList(patientAccesses);
}
return response.statusCode;
} else {
throw Exception('failed to pull patient access List for business');
}
}
/// This function is used to check if a business has access to a specific patients profile.
///
/// Patameters: String business_id & app_id (app_id of patient).
///
/// Returns List<PatientAccess> (List of access that match the above parameters).
static Future<List<PatientAccess>> checkBusinessAccessToPatient(
String business_id,
String app_id,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/access-requests/patient/check/$business_id?app_id=$app_id"));
// var errorCode = response.statusCode.toString();
//print(response.body);
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<PatientAccess> patientAccesses = List<PatientAccess>.from(
l.map((model) => PatientAccess.fromJson(model)));
return patientAccesses;
} else {
throw Exception('failed to pull patient access for business');
}
}
/// This function is used to create patient access and trigger notification to patient
///
/// Patameters:-
/// String business_id,
/// String app_id,
/// String type,
/// String requested_by,
/// BuildContext context,
///
/// Returns void (triggers notification of success 201).
static Future<void> addPatientAccessAPICall(
String business_id,
String app_id,
String type,
String requested_by,
bool personalSelected,
BusinessArguments args,
BuildContext context,
) async {
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/access-requests/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
// business_id: str
// app_id: str
// type: str
// requested_by: str
body: jsonEncode(<String, dynamic>{
"business_id": business_id,
"app_id": app_id,
"type": type,
"requested_by": requested_by,
}),
);
if (response.statusCode == 201) {
await MihNotificationApis.addAccessRequestNotificationAPICall(
app_id, requested_by, personalSelected, args, context);
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
/// This function is used to reapply for access to patient.
///
/// Patameters:-
/// String business_id,
/// String app_id,
/// BuildContext context,
///
/// Returns void (on success 200 navigate to /mih-access ).
static Future<void> reapplyPatientAccessAPICall(
String business_id,
String app_id,
bool personalSelected,
BusinessArguments args,
BuildContext context,
) async {
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/access-requests/re-apply/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
// business_id: str
// app_id: str
// status: str
// approved_by: str
body: jsonEncode(<String, dynamic>{
"business_id": business_id,
"app_id": app_id,
}),
);
if (response.statusCode == 200) {
await MihNotificationApis.reapplyAccessRequestNotificationAPICall(
app_id, personalSelected, args, context);
//notification here
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
/// This function is used to UPDATE access the business has.
///
/// Patameters:-
/// String business_id,
/// String business_name,
/// String app_id,
/// String status,
/// String approved_by,
/// AppUser signedInUser,
/// BuildContext context,
///
/// Returns void (on success 200 navigate to /mih-access ).
Future<int> updatePatientAccessAPICall(
String business_id,
String business_name,
String app_id,
String status,
String approved_by,
AppUser signedInUser,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.put(
Uri.parse(
"${AppEnviroment.baseApiUrl}/access-requests/update/permission/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
// business_id: str
// app_id: str
// status: str
// approved_by: str
body: jsonEncode(<String, dynamic>{
"business_id": business_id,
"app_id": app_id,
"status": status,
"approved_by": approved_by,
}),
);
context.pop();
return response.statusCode;
// if (response.statusCode == 200) {
// //Navigator.of(context).pushNamed('/home');
// Navigator.of(context).pop();
// Navigator.of(context).pop();
// Navigator.of(context).pushNamed(
// '/mih-access',
// arguments: signedInUser,
// );
// String message = "";
// if (status == "approved") {
// message =
// "You've successfully approved the access request! $business_name now has access to your profile forever.";
// } else {
// message =
// "You've declined the access request. $business_name will not have access to your profile.";
// }
// successPopUp(message, context);
// } else {
// internetConnectionPopUp(context);
// }
}
static void loadingPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,189 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihAuthenticationServices {
final baseAPI = AppEnviroment.baseApiUrl;
Future<bool> signUserIn(
String email,
String password,
BuildContext context,
) async {
//var _backgroundColor = Colors.transparent;
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.post(
Uri.parse("$baseAPI/auth/signin"),
body:
'{"formFields": [{"id": "email","value": "$email"}, {"id": "password","value": "$password"}]}',
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
"Authorization": "leatucczyixqwkqqdrhayiwzeofkltds"
},
);
if (response.statusCode == 200) {
var userSignedin = jsonDecode(response.body);
if (userSignedin["status"] == "OK") {
context.pop();
return true;
} else {
context.pop();
return false;
}
} else {
return false;
}
}
Future<bool> forgotPassword(
String email,
) async {
var response = await http.post(
Uri.parse("$baseAPI/auth/user/password/reset/token"),
body: '{"formFields": [{"id": "email","value": "$email"}]}',
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
},
);
if (response.statusCode == 200) {
var userSignedin = jsonDecode(response.body);
if (userSignedin["status"] == "OK") {
return true;
} else {
return false;
}
} else {
return false;
}
}
Future<bool> resetPassword(
String token,
String password,
) async {
var response = await http.post(
Uri.parse("$baseAPI/auth/user/password/reset"),
body:
'{"method": "token","formFields": [{"id": "password","value": "$password"}],"token": "$token"}',
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
},
);
if (response.statusCode == 200) {
var userSignedin = jsonDecode(response.body);
if (userSignedin["status"] == "OK") {
return true;
} else {
return false;
}
} else {
return false;
}
}
void loginError(String error, BuildContext context) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: Text(error),
);
},
);
}
void signUpError(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: null,
onWindowTapClose: null,
backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
windowBody: Column(
children: [
Icon(
Icons.warning_amber_rounded,
size: 100,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
Center(
child: Text(
"Email Already Exists",
textAlign: TextAlign.center,
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 15),
Text(
"Here are some things to keep in mind:",
style: TextStyle(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text(
"1) Are you sure you're using the correct email address associated with your account?\n2) Is your caps lock key on? Passwords are case-sensitive.\n3) If you've forgotten your password, no worries! Click on \"Forgot Password?\" to reset it.",
textAlign: TextAlign.left,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 15),
MihButton(
onPressed: () {
context.pop();
},
buttonColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
width: 300,
elevation: 10,
child: Text(
"Dismiss",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
);
},
);
}
}

View File

@@ -0,0 +1,332 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:supertokens_flutter/supertokens.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihBusinessDetailsServices {
Future<int> fetchBusinessCount() async {
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/business/count/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
var jsonBody = jsonDecode(response.body);
return jsonBody['count'];
} else {
return 0;
}
}
Future<List<String>> fetchAllBusinessTypes() async {
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/business/types/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
List<dynamic> jsonList = jsonDecode(response.body);
List<String> businessTypes =
jsonList.map((item) => item['type'].toString()).toList();
return businessTypes;
} else {
return [];
}
}
Future<List<Business>> searchBusinesses(
String searchText,
String searchType,
BuildContext context,
) async {
String newSearchText = "All";
if (searchText.isNotEmpty) {
newSearchText = searchText;
}
String newSearchType = "All";
if (searchType.isNotEmpty) {
newSearchType = searchType;
}
if (searchText.isEmpty && searchType.isEmpty) {
return [];
}
var response = await http.get(
Uri.parse(
"${AppEnviroment.baseApiUrl}/business/search/$newSearchType/$newSearchText"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<Business> businesses =
List<Business>.from(l.map((model) => Business.fromJson(model)));
return businesses;
} else {
throw Exception('failed to load users');
}
}
Future<Business?> getBusinessDetailsByUser(
MzansiProfileProvider profileProvider,
) async {
String app_id = await SuperTokens.getUserId();
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/business/app_id/$app_id"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
String body = response.body;
var jsonBody = jsonDecode(body);
Business? business = Business.fromJson(jsonBody);
profileProvider.setBusiness(newBusiness: business);
return business;
} else {
return null;
}
}
Future<Business?> getBusinessDetailsByBusinessId(
String business_id,
) async {
var response = await http.get(
Uri.parse(
"${AppEnviroment.baseApiUrl}/business/business_id/$business_id"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
String body = response.body;
var jsonBody = jsonDecode(body);
return Business.fromJson(jsonBody);
} else {
return null;
}
}
Future<Response> createBusinessDetails(
MzansiProfileProvider provider,
String busineName,
String businessType,
String businessRegistrationNo,
String businessPracticeNo,
String businessVatNo,
String businessEmail,
String businessPhoneNumber,
String businessLocation,
String businessLogoFilename,
String businessWebsite,
String businessRating,
String businessMissionVision,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/business/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"Name": busineName,
"type": businessType,
"registration_no": businessRegistrationNo,
"logo_name": businessLogoFilename.replaceAll(RegExp(r' '), '-'),
"logo_path": "",
"contact_no": businessPhoneNumber,
"bus_email": businessEmail,
"gps_location": businessLocation,
"practice_no": businessPracticeNo,
"vat_no": businessVatNo,
"website": businessWebsite,
"rating": businessRating,
"mission_vision": businessMissionVision,
}),
);
context.pop();
if (response.statusCode == 201) {
int finalStatusCode = await updateBusinessDetailsV2(
jsonDecode(response.body)['business_id'],
busineName,
businessType,
businessRegistrationNo,
businessPracticeNo,
businessVatNo,
businessEmail,
businessPhoneNumber,
businessLocation,
businessLogoFilename,
businessWebsite,
businessRating,
businessMissionVision,
provider,
context,
);
if (finalStatusCode == 200) {
String logoPath = businessLogoFilename.isNotEmpty
? "${jsonDecode(response.body)['business_id']}/business_files/$businessLogoFilename"
: "";
provider.setBusiness(
newBusiness: Business(
jsonDecode(response.body)['business_id'],
busineName,
businessType,
businessRegistrationNo,
businessLogoFilename,
logoPath,
businessPhoneNumber,
businessEmail,
provider.user!.app_id,
businessLocation,
businessPracticeNo,
businessVatNo,
businessWebsite,
businessRating,
businessMissionVision,
),
);
}
}
return response;
}
Future<int> updateBusinessDetailsV2(
String business_id,
String business_name,
String business_type,
String business_registration_no,
String business_practice_no,
String business_vat_no,
String business_email,
String business_phone_number,
String business_location,
String business_logo_name,
String businessWebsite,
String businessRating,
String businessMissionVision,
MzansiProfileProvider provider,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var filePath =
"$business_id/business_files/${business_logo_name.replaceAll(RegExp(r' '), '-')}";
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/business/update/v2/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": business_id,
"Name": business_name,
"type": business_type,
"registration_no": business_registration_no,
"logo_name": business_logo_name.replaceAll(RegExp(r' '), '-'),
"logo_path": filePath,
"contact_no": business_phone_number,
"bus_email": business_email,
"gps_location": business_location,
"practice_no": business_practice_no,
"vat_no": business_vat_no,
"website": businessWebsite,
"rating": businessRating,
"mission_vision": businessMissionVision,
}),
);
context.pop();
if (response.statusCode == 200) {
provider.setBusiness(
newBusiness: Business(
business_id,
business_name,
business_type,
business_registration_no,
business_logo_name,
filePath,
business_phone_number,
business_email,
business_id,
business_location,
business_practice_no,
business_vat_no,
businessWebsite,
businessRating,
businessMissionVision,
),
);
String newProPicUrl = await MihFileApi.getMinioFileUrl(filePath);
provider.setBusinessProfilePicUrl(newProPicUrl);
return 200;
} else {
return 500;
}
}
Future<int> updateBusinessDetails(
String business_id,
String business_name,
String business_type,
String business_registration_no,
String business_practice_no,
String business_vat_no,
String business_email,
String business_phone_number,
String business_location,
String business_logo_name,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/business/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": business_id,
"Name": business_name,
"type": business_type,
"registration_no": business_registration_no,
"logo_name": business_logo_name.replaceAll(RegExp(r' '), '-'),
"logo_path":
"$business_id/business_files/${business_logo_name.replaceAll(RegExp(r' '), '-')}",
"contact_no": business_phone_number,
"bus_email": business_email,
"gps_location": business_location,
"practice_no": business_practice_no,
"vat_no": business_vat_no,
}),
);
Navigator.of(context).pop();
if (response.statusCode == 200) {
return 200;
} else {
return 500;
}
}
}

View File

@@ -0,0 +1,142 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_employee.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihBusinessEmployeeServices {
Future<int> fetchEmployees(
MzansiProfileProvider mzansiProfileProvider, BuildContext context) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/business-user/employees/${mzansiProfileProvider.businessUser!.business_id}"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<BusinessEmployee> employeeList = List<BusinessEmployee>.from(
l.map((model) => BusinessEmployee.fromJson(model)));
mzansiProfileProvider.setEmployeeList(employeeList: employeeList);
} else {
throw Exception('failed to load employees');
}
return response.statusCode;
}
Future<int> addEmployee(
MzansiProfileProvider provider,
AppUser newEmployee,
String access,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/business-user/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": provider.business!.business_id,
"app_id": newEmployee.app_id,
"signature": "",
"sig_path": "",
"title": "",
"access": access,
}),
);
if (response.statusCode == 201) {
provider.addEmployee(
newEmployee: BusinessEmployee(
provider.business!.business_id,
newEmployee.app_id,
"",
access,
newEmployee.fname,
newEmployee.lname,
newEmployee.email,
newEmployee.username,
),
);
provider.setBusinessIndex(2);
}
context.pop();
return response.statusCode;
}
Future<int> updateEmployeeDetails(
MzansiProfileProvider provider,
BusinessEmployee employee,
String newTitle,
String newAccess,
BuildContext context) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/business-user/employees/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": employee.business_id,
"app_id": employee.app_id,
"title": newTitle,
"access": newAccess,
}),
);
if (response.statusCode == 200) {
provider.updateEmplyeeDetails(
updatedEmployee: BusinessEmployee(
employee.business_id,
employee.app_id,
newTitle,
newAccess,
employee.fname,
employee.lname,
employee.email,
employee.username,
),
);
}
context.pop();
return response.statusCode;
}
Future<int> deleteEmployee(
MzansiProfileProvider provider,
BusinessEmployee employee,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/business-user/employees/delete/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": employee.business_id,
"app_id": employee.app_id,
}),
);
if (response.statusCode == 200) {
provider.deleteEmplyee(deletedEmployee: employee);
}
context.pop();
return response.statusCode;
}
}

View File

@@ -0,0 +1,246 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_objects/claim_statement_file.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_providers/patient_manager_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MIHClaimStatementGenerationApi {
final baseAPI = AppEnviroment.baseApiUrl;
/// This function is used to generate and store a claim/ statement.
///
/// Patameters: TBC .
///
/// Returns TBC.
Future<void> generateClaimStatement(
MzansiProfileProvider profileProvider,
PatientManagerProvider patientManagerProvider,
ClaimStatementGenerationArguments data,
String env,
BuildContext context,
) async {
//start loading circle
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
DateTime now = new DateTime.now();
// DateTime date = new DateTime(now.year, now.month, now.day);
String fileName =
"${data.document_type}-${data.patient_full_name}-${now.toString().substring(0, 19)}.pdf"
.replaceAll(RegExp(r' '), '-');
var response1 = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/claim-statement/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"document_type": data.document_type,
"patient_app_id": data.patient_app_id,
"env": env,
"patient_full_name": data.patient_full_name,
"fileName": fileName,
"patient_id_no": data.patient_id_no,
"has_med_aid": data.has_med_aid,
"med_aid_no": data.med_aid_no,
"med_aid_code": data.med_aid_code,
"med_aid_name": data.med_aid_name,
"med_aid_scheme": data.med_aid_scheme,
"busName": data.busName,
"busAddr": data.busAddr,
"busNo": data.busNo,
"busEmail": data.busEmail,
"provider_name": data.provider_name,
"practice_no": data.practice_no,
"vat_no": data.vat_no,
"service_date": data.service_date,
"service_desc": data.service_desc,
"service_desc_option": data.service_desc_option,
"procedure_name": data.procedure_name,
"procedure_additional_info": data.procedure_additional_info,
"icd10_code": data.icd10_code,
"amount": data.amount,
"pre_auth_no": data.pre_auth_no,
"logo_path": data.logo_path,
"sig_path": data.sig_path,
}),
);
//print(response1.statusCode);
if (response1.statusCode == 200) {
//Update this API
var response2 = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/files/claim-statement/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": data.patient_app_id,
"business_id": profileProvider.business!.business_id,
"file_path": "${data.patient_app_id}/claims-statements/$fileName",
"file_name": fileName
}),
);
if (response2.statusCode == 201) {
getClaimStatementFilesByPatient(patientManagerProvider);
String message =
"The ${data.document_type}: $fileName has been successfully generated and added to ${data.patient_full_name}'s record. You can now access and download it for their use.";
MihAlertServices().successBasicAlert(
"Success!",
message,
context,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
/// This function is used to fetch a list of claim/ statement files for a ptient.
///
/// Patameters: app_id .
///
/// Returns List<ClaimStatementFile>.
static Future<List<ClaimStatementFile>> getClaimStatementFilesByPatient(
PatientManagerProvider patientManagerProvider,
) async {
//print("Patien manager page: $endpoint");
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/files/claim-statement/patient/${patientManagerProvider.selectedPatient!.app_id}"));
// print("Here");
// print("Body: ${response.body}");
// print("Code: ${response.statusCode}");
// errorCode = response.statusCode.toString();
// errorBody = response.body;
if (response.statusCode == 200) {
//print("Here1");
Iterable l = jsonDecode(response.body);
//print("Here2");
List<ClaimStatementFile> docList = List<ClaimStatementFile>.from(
l.map((model) => ClaimStatementFile.fromJson(model)));
//print("Here3");
patientManagerProvider.setClaimsDocuments(
patientClaimsDocuments: docList);
return docList;
} else {
throw Exception(
'failed to fatch patient claims statement files with api');
}
}
/// This function is used to fetch a list of claim/ statement files for a business.
///
/// Patameters: business_id .
///
/// Returns List<ClaimStatementFile>.
static Future<List<ClaimStatementFile>> getClaimStatementFilesByBusiness(
String business_id,
) async {
//print("Patien manager page: $endpoint");
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/files/claim-statement/business/$business_id"));
// print("Here");
// print("Body: ${response.body}");
// print("Code: ${response.statusCode}");
// errorCode = response.statusCode.toString();
// errorBody = response.body;
if (response.statusCode == 200) {
//print("Here1");
Iterable l = jsonDecode(response.body);
//print("Here2");
List<ClaimStatementFile> docList = List<ClaimStatementFile>.from(
l.map((model) => ClaimStatementFile.fromJson(model)));
//print("Here3");
//print(patientQueue);
return docList;
} else {
throw Exception(
'failed to fatch business claims statement files with api');
}
}
/// This function is used to Delete loyalty card from users mzansi wallet.
///
/// Patameters:-
/// AppUser signedInUser,
/// int idloyalty_cards,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS)
static Future<void> deleteClaimStatementFilesByFileID(
PatientViewArguments args,
String env,
String filePath,
int fileID,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
// delete file from minio
var response = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/minio/delete/file/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"file_path": filePath,
"env": env,
}),
);
//print("Here4");
//print(response.statusCode);
if (response.statusCode == 200) {
//SQL delete
var response2 = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/files/claim-statement/delete/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(
<String, dynamic>{"idclaim_statement_file": fileID, "env": env}),
);
if (response2.statusCode == 200) {
context.pop();
context.pop();
context.pop();
context.pop();
//print(widget.business);
context.pushNamed('patientManagerPatient', extra: args);
// Navigator.of(context)
// .pushNamed('/patient-profile', arguments: widget.signedInUser);
// setState(() {});
String message =
"The File has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments.";
MihAlertServices().successBasicAlert(
"Success!",
message,
context,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
}
//================== POP UPS ==========================================================================

View File

@@ -0,0 +1,80 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_objects/currency.dart';
import 'package:mzansi_innovation_hub/mih_providers/mih_calculator_provider.dart';
import 'package:provider/provider.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihCurrencyExchangeRateServices {
static Future<List<Currency>> getCurrencyObjectList() async {
final response = await http.get(Uri.parse(
"https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies.min.json"));
if (response.statusCode == 200) {
final Map<String, dynamic> jsonMap = json.decode(response.body);
List<Currency> currencies = [];
jsonMap.forEach((code, dynamic nameValue) {
final String name = nameValue is String ? nameValue : 'Unknown Name';
currencies.add(Currency(code: code, name: name));
});
currencies.sort((a, b) => a.name.compareTo(b.name));
return currencies;
} else {
throw Exception('failed to fatch currencies');
}
}
static Future<void> getCurrencyCodeList(BuildContext context) async {
final response = await http.get(Uri.parse(
"https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies.min.json"));
if (response.statusCode == 200) {
final Map<String, dynamic> jsonMap = json.decode(response.body);
List<String> currencies = [];
jsonMap.forEach((code, dynamic nameValue) {
final String name = nameValue is String ? nameValue : 'Unknown Name';
currencies.add("$code - $name");
});
currencies.sort();
if (response.statusCode == 200) {
context
.read<MihCalculatorProvider>()
.setAvailableCurrencies(currencies: currencies);
}
} else {
throw Exception('failed to fatch currencies');
}
}
static Future<List<String>> getCurrencyExchangeValue(
String fromCurrencyCode,
String toCurrencyCode,
) async {
final response = await http.get(Uri.parse(
"https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/$fromCurrencyCode.min.json"));
if (response.statusCode == 200) {
final Map<String, dynamic> jsonResponse = json.decode(response.body);
final Map<String, dynamic>? baseCurrencyData =
jsonResponse[fromCurrencyCode];
final List<String> dateValue = [];
if (baseCurrencyData != null) {
final dynamic rateValue = baseCurrencyData[toCurrencyCode];
final String date = jsonResponse["date"];
if (rateValue is num) {
dateValue.add(date);
dateValue.add(rateValue.toString());
return dateValue;
} else {
print(
'Warning: Rate for $toCurrencyCode in $fromCurrencyCode is not a number or missing.');
return ["Error", "0"];
}
} else {
throw Exception(
'Base currency "$fromCurrencyCode" data not found in response.');
}
} else {
throw Exception('failed to fatch currencies');
}
}
}

View File

@@ -0,0 +1,67 @@
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_my_business_user_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_consent_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
class MihDataHelperServices {
Future<void> getUserData(MzansiProfileProvider profileProvider) async {
String url;
await MihUserServices().getMyUserDetails(profileProvider);
url = await MihFileApi.getMinioFileUrl(
profileProvider.user!.pro_pic_path,
);
profileProvider.setUserProfilePicUrl(url);
}
Future<void> getUserConsentStatus(
MzansiProfileProvider profileProvider) async {
await MihUserConsentServices().getUserConsentStatus(profileProvider);
}
Future<void> getBusinessData(MzansiProfileProvider profileProvider) async {
AppUser? user = profileProvider.user;
String logoUrl;
String signatureUrl;
Business? responseBusiness = await MihBusinessDetailsServices()
.getBusinessDetailsByUser(profileProvider);
if (responseBusiness != null && user!.type == "business") {
logoUrl = await MihFileApi.getMinioFileUrl(
profileProvider.business!.logo_path,
);
profileProvider.setBusinessProfilePicUrl(logoUrl);
await MihMyBusinessUserServices().getBusinessUser(profileProvider);
signatureUrl = await MihFileApi.getMinioFileUrl(
profileProvider.businessUser!.sig_path,
);
profileProvider.setBusinessUserSignatureUrl(signatureUrl);
}
}
Future<void> loadUserDataOnly(MzansiProfileProvider profileProvider) async {
if (profileProvider.user == null) {
await getUserData(profileProvider);
}
if (profileProvider.userConsent == null) {
await getUserConsentStatus(profileProvider);
}
}
Future<void> loadUserDataWithBusinessesData(
MzansiProfileProvider profileProvider) async {
if (profileProvider.user == null) {
await getUserData(profileProvider);
}
if (profileProvider.userConsent == null) {
await getUserConsentStatus(profileProvider);
}
if (profileProvider.user != null &&
profileProvider.user!.type == "business" &&
profileProvider.business == null) {
await getBusinessData(profileProvider);
}
}
}

View File

@@ -0,0 +1,115 @@
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:flutter/material.dart';
import 'package:supertokens_flutter/http.dart' as http;
import 'package:http/http.dart' as http2;
import 'package:supertokens_flutter/supertokens.dart';
class MihFileApi {
final baseAPI = AppEnviroment.baseApiUrl;
static Future<String> getMinioFileUrl(
String filePath,
) async {
// loadingPopUp(context);
// print("here");
// var url =
// "${AppEnviroment.baseApiUrl}/minio/pull/file/${AppEnviroment.getEnv()}/$filePath";
// var response = await http.get(Uri.parse(url));
String fileUrl = "";
// print(response.statusCode);
// if (response.statusCode == 200) {
// String body = response.body;
// var decodedData = jsonDecode(body);
// fileUrl = decodedData['minioURL'];
// } else {
// fileUrl = "";
// }
// Navigator.of(context).pop(); // Pop loading dialog
// return fileUrl;
try {
var url =
"${AppEnviroment.baseApiUrl}/minio/pull/file/${AppEnviroment.getEnv()}/$filePath";
var response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
fileUrl = decodedData['minioURL'];
} else {
// internetConnectionPopUp(context);
// KenLogger.error("Get File Error: $url");
// KenLogger.error("Get File Error: ${response.statusCode}");
// KenLogger.error("Get File Error: ${response.body}");
}
} catch (e) {
// internetConnectionPopUp(context);
print("Error getting url");
} finally {
// Navigator.of(context).pop(); // Always pop loading dialog
}
return fileUrl;
}
static Future<int> uploadFile(
String app_id,
String env,
String folderName,
PlatformFile? file,
BuildContext context,
) async {
loadingPopUp(context);
var token = await SuperTokens.getAccessToken();
var request = http2.MultipartRequest(
'POST', Uri.parse("${AppEnviroment.baseApiUrl}/minio/upload/file/"));
request.headers['accept'] = 'application/json';
request.headers['Authorization'] = 'Bearer $token';
request.headers['Content-Type'] = 'multipart/form-data';
request.fields['app_id'] = app_id;
request.fields['env'] = env;
request.fields['folder'] = folderName;
request.files.add(await http2.MultipartFile.fromBytes('file', file!.bytes!,
filename: file.name.replaceAll(RegExp(r' '), '-')));
var response = await request.send();
context.pop(); // Pop loading dialog
return response.statusCode;
}
static Future<int> deleteFile(
String app_id,
String env,
String folderName,
String fileName,
BuildContext context,
) async {
loadingPopUp(context);
var fname = fileName.replaceAll(RegExp(r' '), '-');
var filePath = "$app_id/$folderName/$fname";
var response = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/minio/delete/file/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"file_path": filePath,
"env": env,
}),
);
context.pop(); // Pop loading dialog
return response.statusCode;
}
//================== POP UPS ==========================================================================
static void loadingPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
}
}

View File

@@ -0,0 +1,55 @@
import 'dart:convert';
import 'package:mzansi_innovation_hub/mih_objects/icd10_code.dart.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:flutter/material.dart';
import 'package:supertokens_flutter/http.dart' as http;
import '../mih_config/mih_env.dart';
class MIHIcd10CodeApis {
final baseAPI = AppEnviroment.baseApiUrl;
/// This function is used to fetch a list of icd 10 codes based on a search .
///
/// Patameters: String search, BuildContext context
///
/// Returns List<ICD10Code>.
static Future<List<ICD10Code>> getIcd10Codes(
String search, BuildContext context) async {
//print("Patien manager page: $endpoint");
mihLoadingPopUp(context);
final response = await http
.get(Uri.parse("${AppEnviroment.baseApiUrl}/icd10-codes/$search"));
// print("Here");
// print("Body: ${response.body}");
// print("Code: ${response.statusCode}");
// errorCode = response.statusCode.toString();
// errorBody = response.body;
if (response.statusCode == 200) {
//print("Here1");
Iterable l = jsonDecode(response.body);
//print("Here2");
List<ICD10Code> icd10Codes =
List<ICD10Code>.from(l.map((model) => ICD10Code.fromJson(model)));
//print("Here3");
//print(patientQueue);
Navigator.of(context).pop();
return icd10Codes;
} else {
Navigator.of(context).pop();
throw Exception('failed to fetch icd-10 codes with api');
}
}
static void mihLoadingPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
}
}

View File

@@ -0,0 +1,64 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:pwa_install/pwa_install.dart';
// import 'package:universal_html/js.dart' as js;
import 'package:url_launcher/url_launcher.dart';
class MihInstallServices {
String? errorMessage;
Future<void> launchSocialUrl(Uri linkUrl) async {
if (!await launchUrl(linkUrl)) {
throw Exception('Could not launch $linkUrl');
}
}
void installMihTrigger(BuildContext context) {
final isWebAndroid =
kIsWeb && (defaultTargetPlatform == TargetPlatform.android);
final isWebIos = kIsWeb && (defaultTargetPlatform == TargetPlatform.iOS);
if (isWebAndroid) {
launchSocialUrl(
Uri.parse(
"https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih",
),
);
} else if (isWebIos) {
//Show pop up for IOS
launchSocialUrl(
Uri.parse(
"https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890",
),
);
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Android") {
//Installed Android App
launchSocialUrl(
Uri.parse(
"https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih",
),
);
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() == "iOS") {
launchSocialUrl(
Uri.parse(
"https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890",
),
);
} else {
//Web
if (PWAInstall().installPromptEnabled) {
try {
PWAInstall().promptInstall_();
} catch (e) {
errorMessage = e.toString();
debugPrint('Error prompting install: $e');
}
} else {
// Fallback for unsupported platforms
debugPrint('Install prompt not available for this platform.');
}
// js.context.callMethod("presentAddToHome");
}
}
}

View File

@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
class MIHLocationAPI {
final LocationSettings locationSettings = const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
);
///This function is to get the current location of the signed in user.
///First checks the permission, if permission is denied (new user), request permission from user.
///if user has blocked permission (denied or denied forver), user will get error pop up.
///if user has granted permission (while in use), function will return Position object.
Future<Position?> getGPSPosition(BuildContext context) async {
print("Before checkPermission"); // Debug
LocationPermission permission = await Geolocator.checkPermission();
print("After checkPermission: $permission"); // Debug
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
MihAlertServices().locationPermissionAlert(context);
return null;
} else if (permission == LocationPermission.deniedForever) {
MihAlertServices().locationPermissionAlert(context);
return null;
} else {
Position location = await Geolocator.getCurrentPosition(
locationSettings: locationSettings);
return location;
}
} else if (permission == LocationPermission.deniedForever) {
MihAlertServices().locationPermissionAlert(context);
return null;
} else {
Position location = await Geolocator.getCurrentPosition(
locationSettings: locationSettings);
return location;
}
}
double getDistanceInMeaters(String startPosition, String endPosition) {
double startLatitude = double.parse(startPosition.split(", ")[0]);
double startLogitude = double.parse(startPosition.split(", ")[1]);
double endLatitude = double.parse(endPosition.split(", ")[0]);
double endLogitude = double.parse(endPosition.split(", ")[1]);
return Geolocator.distanceBetween(
startLatitude, startLogitude, endLatitude, endLogitude);
}
}

View File

@@ -0,0 +1,80 @@
import 'dart:convert';
import 'package:mzansi_innovation_hub/mih_objects/minesweeper_player_score.dart';
import 'package:mzansi_innovation_hub/mih_providers/mih_mine_sweeper_provider.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihMinesweeperServices {
Future<int> getTop20Leaderboard(
MihMineSweeperProvider mineSweeperProvider,
) async {
String difficulty = mineSweeperProvider.difficulty;
var response = await http.get(
Uri.parse(
"${AppEnviroment.baseApiUrl}/minesweeper/leaderboard/top20/$difficulty"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<MinesweeperPlayerScore> leaderboard =
List<MinesweeperPlayerScore>.from(
l.map((model) => MinesweeperPlayerScore.fromJson(model)));
mineSweeperProvider.setLeaderboard(leaderboard: leaderboard);
} else {
mineSweeperProvider.setLeaderboard(leaderboard: null);
}
return response.statusCode;
}
Future<int> getMyScoreboard(
MzansiProfileProvider profileProvider,
MihMineSweeperProvider mineSweeperProvider,
) async {
String difficulty = mineSweeperProvider.difficulty;
var response = await http.get(
Uri.parse(
"${AppEnviroment.baseApiUrl}/minesweeper/leaderboard/top_score/$difficulty/${profileProvider.user!.app_id}"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<MinesweeperPlayerScore> leaderboard =
List<MinesweeperPlayerScore>.from(
l.map((model) => MinesweeperPlayerScore.fromJson(model)));
mineSweeperProvider.setMyScoreboard(myScoreboard: leaderboard);
} else {
mineSweeperProvider.setMyScoreboard(myScoreboard: null);
}
return response.statusCode;
}
Future<int> addPlayerScore(
MzansiProfileProvider profileProvider,
MihMineSweeperProvider mineSweeperProvider,
String game_time,
double game_score,
) async {
DateTime now = DateTime.now();
String formattedDateTime = now.toString();
var response = await http.post(
Uri.parse(
"${AppEnviroment.baseApiUrl}/minesweeper/leaderboard/player_score/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": profileProvider.user!.app_id,
"difficulty": mineSweeperProvider.difficulty,
"game_time": game_time,
"game_score": game_score,
"played_date": formattedDateTime,
}),
);
return response.statusCode;
}
}

View File

@@ -0,0 +1,133 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_user.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:supertokens_flutter/supertokens.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihMyBusinessUserServices {
Future<BusinessUser?> getBusinessUser(
MzansiProfileProvider profileProvider,
) async {
String app_id = await SuperTokens.getUserId();
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/business-user/$app_id"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
// KenLogger.success(response.body);
BusinessUser? businessUser =
BusinessUser.fromJson(jsonDecode(response.body));
profileProvider.setBusinessUser(newBusinessUser: businessUser);
return businessUser;
} else {
return null;
}
}
Future<int> createBusinessUser(
String business_id,
String app_id,
String signatureFilename,
String title,
String access,
MzansiProfileProvider provider,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
String filename = signatureFilename.replaceAll(RegExp(r' '), '-');
String sigPath = "$business_id/business_files/$signatureFilename";
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/business-user/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": business_id,
"app_id": app_id,
"signature": filename,
"sig_path": sigPath.replaceAll(RegExp(r' '), '-'),
"title": title,
"access": access,
}),
);
context.pop();
if (response.statusCode == 201) {
provider.setBusinessUser(
newBusinessUser: BusinessUser(
0, business_id, app_id, filename, sigPath, title, access),
);
return 201;
} else {
MihAlertServices().internetConnectionAlert(context);
return 500;
}
}
/// This function updates the business user details.
Future<int> updateBusinessUser(
String app_id,
String business_id,
String bUserTitle,
String bUserAccess,
String signatureFileName,
MzansiProfileProvider provider,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var filename = signatureFileName.replaceAll(RegExp(r' '), '-');
var filePath =
"$app_id/business_files/${signatureFileName.replaceAll(RegExp(r' '), '-')}";
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/business-user/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"business_id": business_id,
"app_id": app_id,
"signature": filename,
"sig_path": filePath,
"title": bUserTitle,
"access": bUserAccess,
}),
);
context.pop();
if (response.statusCode == 200) {
provider.setBusinessUser(
newBusinessUser: BusinessUser(
provider.businessUser!.idbusiness_users,
business_id,
app_id,
filename,
filePath,
bUserTitle,
bUserAccess,
),
);
String newProPicUrl = await MihFileApi.getMinioFileUrl(filePath);
provider.setBusinessUserSignatureUrl(newProPicUrl);
return 200;
} else {
MihAlertServices().internetConnectionAlert(context);
return 500;
}
}
}

View File

@@ -0,0 +1,546 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/appointment.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_user.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_providers/mih_calendar_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihMzansiCalendarApis {
final baseAPI = AppEnviroment.baseApiUrl;
/// This function is used to fetch a list of appointment for a personal user.
///
/// Patameters:
/// app_id,
/// date (yyyy-mm-dd),
///
/// Returns Future<List<Appointment>>.
static Future<int> getPersonalAppointments(
String app_id,
String date,
MihCalendarProvider mihCalendarProvider,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/appointments/personal/$app_id?date=$date"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<Appointment> personalAppointments =
List<Appointment>.from(l.map((model) => Appointment.fromJson(model)));
mihCalendarProvider.setPersonalAppointments(
appointments: personalAppointments);
return response.statusCode;
} else {
throw Exception('failed to fatch personal appointments');
}
}
/// This function is used to fetch a list of appointment for a personal user.
///
/// Patameters:
/// app_id,
/// date (yyyy-mm-dd),
///
/// Returns Future<List<Appointment>>.
static Future<int> getBusinessAppointments(
String business_id,
bool waitingRoom,
String date,
MihCalendarProvider mihCalendarProvider,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/appointments/business/$business_id?date=$date"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<Appointment> businessAppointments =
List<Appointment>.from(l.map((model) => Appointment.fromJson(model)));
mihCalendarProvider.setBusinessAppointments(
appointments: businessAppointments);
return response.statusCode;
} else {
throw Exception('failed to fatch business appointments');
}
}
/// This function is used to Delete loyalty card from users mzansi Calendar.
///
/// Patameters:-
/// AppUser signedInUser,
/// int idloyalty_cards,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS)
static Future<int> deleteAppointmentAPICall(
AppUser signedInUser,
bool personalSelected,
Business? business,
BusinessUser? businessUser,
bool inWaitingRoom,
int idappointments,
MihCalendarProvider mihCalendarProvider,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/appointment/delete/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{"idappointments": idappointments}),
);
context.pop();
if (response.statusCode == 200) {
if (personalSelected == true) {
mihCalendarProvider.deletePersonalAppointment(
appointmentId: idappointments);
getPersonalAppointments(signedInUser.app_id,
mihCalendarProvider.selectedDay, mihCalendarProvider);
} else {
mihCalendarProvider.deleteBusinessAppointment(
appointmentId: idappointments);
getBusinessAppointments(business!.business_id, inWaitingRoom,
mihCalendarProvider.selectedDay, mihCalendarProvider);
}
}
return response.statusCode;
//print("Here4");
//print(response.statusCode);
// if (response.statusCode == 200) {
// Navigator.of(context).pop();
// Navigator.of(context).pop();
// Navigator.of(context).pop();
// if (inWaitingRoom == true && personalSelected == false) {
// Navigator.of(context).pushNamed(
// '/patient-manager',
// arguments: PatManagerArguments(
// signedInUser,
// false,
// business,
// businessUser,
// ),
// );
// } else {
// Navigator.of(context).pushNamed(
// '/calendar',
// arguments: CalendarArguments(
// signedInUser,
// personalSelected,
// business,
// businessUser,
// ),
// );
// }
// String message =
// "The appointment has been deleted successfully. This means it will no longer be visible in your Calendar.";
// successPopUp(message, context);
// } else {
// internetConnectionPopUp(context);
// }
}
/// This function is used to add an appointment to users mzansi Calendar.
///
/// Patameters:-
/// AppUser signedInUser,
/// String app_id,
/// String title,
/// String description,
/// String date,
/// String time,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS SUCCESS pop up)
static Future<int> addPersonalAppointment(
AppUser signedInUser,
String title,
String description,
String date,
String time,
MihCalendarProvider mihCalendarProvider,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/appointment/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": signedInUser.app_id,
"business_id": "",
"title": title,
"description": description,
"date": date,
"time": time,
}),
);
context.pop();
if (response.statusCode == 201) {
mihCalendarProvider.addPersonalAppointment(
newAppointment: Appointment(
idappointments: 0,
app_id: signedInUser.app_id,
business_id: "",
date_time: "$date $time",
title: title,
description: description,
),
);
}
return response.statusCode;
// if (response.statusCode == 201) {
// Navigator.pop(context);
// Navigator.pop(context);
// Navigator.pop(context);
// String message =
// "Your appointment \"$title\" for the $date $title has been deleted.";
// // Navigator.pop(context);
// Navigator.of(context).pushNamed(
// '/calendar',
// arguments: CalendarArguments(
// signedInUser,
// true,
// null,
// null,
// ),
// );
// successPopUp(message, context);
// } else {
// Navigator.pop(context);
// internetConnectionPopUp(context);
// }
}
/// This function is used to add an appointment to users mzansi Calendar.
///
/// Patameters:-
/// AppUser signedInUser,
/// String app_id,
/// String title,
/// String description,
/// String date,
/// String time,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS SUCCESS pop up)
static Future<int> addBusinessAppointment(
AppUser signedInUser,
Business business,
BusinessUser businessUser,
bool inWaitingRoom,
String title,
String description,
String date,
String time,
MihCalendarProvider mihCalendarProvider,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/appointment/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": "",
"business_id": business.business_id,
"title": title,
"description": description,
"date": date,
"time": time,
}),
);
context.pop();
if (response.statusCode == 201) {
mihCalendarProvider.addBusinessAppointment(
newAppointment: Appointment(
idappointments: 0,
app_id: "",
business_id: business.business_id,
date_time: "$date $time",
title: title,
description: description,
),
);
}
return response.statusCode;
}
/// This function is used to add an appointment to users mzansi Calendar.
///
/// Patameters:-
/// AppUser signedInUser,
/// String app_id,
/// String title,
/// String description,
/// String date,
/// String time,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS SUCCESS pop up)
static Future<int> addPatientAppointment(
AppUser signedInUser,
bool personalSelected,
String patientAppId,
String businessId,
String title,
String description,
String date,
String time,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/appointment/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": patientAppId,
"business_id": businessId,
"title": title,
"description": description,
"date": date,
"time": time,
}),
);
context.pop();
return response.statusCode;
}
/// This function is used to update an appointment to users mzansi Calendar.
///
/// Patameters:-
/// AppUser signedInUser,
/// String app_id,
/// int idappointments,
/// String title,
/// String description,
/// String date,
/// String time,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS SUCCESS pop up)
static Future<int> updatePersonalAppointment(
AppUser signedInUser,
Business? business,
BusinessUser? businessUser,
int idappointments,
String title,
String description,
String date,
String time,
MihCalendarProvider mihCalendarProvider,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/appointment/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"idappointments": idappointments,
"title": title,
"description": description,
"date": date,
"time": time,
}),
);
context.pop();
if (response.statusCode == 200) {
mihCalendarProvider.editPersonalAppointment(
updatedAppointment: Appointment(
idappointments: idappointments,
app_id: signedInUser.app_id,
business_id: "",
date_time: "$date $time",
title: title,
description: description,
),
);
}
return response.statusCode;
// if (response.statusCode == 200) {
// Navigator.pop(context);
// Navigator.pop(context);
// Navigator.pop(context);
// String message =
// "Your appointment \"$title\" has been updates to the $date $title.";
// Navigator.pop(context);
// Navigator.of(context).pushNamed(
// '/calendar',
// arguments: CalendarArguments(
// signedInUser,
// true,
// business,
// businessUser,
// ),
// );
// successPopUp(message, context);
// } else {
// Navigator.pop(context);
// internetConnectionPopUp(context);
// }
}
/// This function is used to update an appointment to users mzansi Calendar.
///
/// Patameters:-
/// AppUser signedInUser,
/// String app_id,
/// int idappointments,
/// String title,
/// String description,
/// String date,
/// String time,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS SUCCESS pop up)
static Future<int> updateBusinessAppointment(
AppUser signedInUser,
Business? business,
BusinessUser? businessUser,
int idappointments,
String title,
String description,
String date,
String time,
MihCalendarProvider mihCalendarProvider,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/appointment/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"idappointments": idappointments,
"title": title,
"description": description,
"date": date,
"time": time,
}),
);
context.pop();
if (response.statusCode == 200) {
mihCalendarProvider.editBusinessAppointment(
updatedAppointment: Appointment(
idappointments: idappointments,
app_id: "",
business_id: business!.business_id,
date_time: "$date $time",
title: title,
description: description,
),
);
}
return response.statusCode;
// if (response.statusCode == 200) {
// Navigator.pop(context);
// Navigator.pop(context);
// Navigator.pop(context);
// String message =
// "Your appointment \"$title\" has been updates to the $date $title.";
// Navigator.pop(context);
// Navigator.of(context).pushNamed(
// '/calendar',
// arguments: CalendarArguments(
// signedInUser,
// false,
// business,
// businessUser,
// ),
// );
// successPopUp(message, context);
// } else {
// Navigator.pop(context);
// internetConnectionPopUp(context);
// }
}
/// This function is used to update an appointment to users mzansi Calendar.
///
/// Patameters:-
/// AppUser signedInUser,
/// String app_id,
/// int idappointments,
/// String title,
/// String description,
/// String date,
/// String time,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS SUCCESS pop up)
static Future<int> updatePatientAppointment(
AppUser signedInUser,
Business? business,
BusinessUser? businessUser,
int idappointments,
String title,
String description,
String date,
String time,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/appointment/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"idappointments": idappointments,
"title": title,
"description": description,
"date": date,
"time": time,
}),
);
context.pop();
return response.statusCode;
// if (response.statusCode == 200) {
// Navigator.pop(context);
// Navigator.pop(context);
// Navigator.pop(context);
// Navigator.pop(context);
// String message =
// "Your appointment \"$title\" has been updates to the $date $title.";
// // Navigator.pop(context);
// Navigator.of(context).pushNamed(
// '/patient-manager',
// arguments: PatManagerArguments(
// signedInUser,
// false,
// business,
// businessUser,
// ),
// );
// successPopUp(message, context);
// } else {
// Navigator.pop(context);
// internetConnectionPopUp(context);
// }
}
//================== POP UPS ==========================================================================
static void loadingPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
}
}

View File

@@ -0,0 +1,220 @@
import 'dart:convert';
import 'package:mzansi_innovation_hub/mih_objects/bookmarked_business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_review.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_directory_provider.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;
//########################################################
//# Business Ratings #
//########################################################
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 if (response.statusCode == 404) {
return [];
} 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;
}
}
//########################################################
//# Bookmarked Business #
//########################################################
Future<BookmarkedBusiness?> getUserBookmarkOfBusiness(
String app_id,
String business_id,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/$app_id/$business_id"));
// print(response.statusCode);
if (response.statusCode == 200) {
String body = response.body;
var jsonBody = jsonDecode(body);
BookmarkedBusiness? BookmarkedBus = BookmarkedBusiness.fromJson(jsonBody);
return BookmarkedBus;
} else {
return null;
}
}
Future<List<BookmarkedBusiness>> getAllUserBookmarkedBusiness(
String app_id,
MzansiDirectoryProvider directoryProvider,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/user/all/$app_id/"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<BookmarkedBusiness> favouriteBusinesses =
List<BookmarkedBusiness>.from(
l.map((model) => BookmarkedBusiness.fromJson(model)));
directoryProvider.setBookmarkedeBusinesses(
businesses: favouriteBusinesses);
return favouriteBusinesses;
} else if (response.statusCode == 404) {
return [];
} else {
throw Exception('failed to fetch User Bookmarked Business');
}
}
Future<int> addBookmarkedBusiness(
String app_id,
String business_id,
) async {
var response = await http.post(
Uri.parse(
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": app_id,
"business_id": business_id,
}),
);
if (response.statusCode == 201) {
return response.statusCode;
} else {
return response.statusCode;
}
}
Future<int> deleteBookmarkedBusiness(
int idbookmarked_businesses,
) async {
var response = await http.delete(
Uri.parse(
"${AppEnviroment.baseApiUrl}/mzansi-directory/bookmarked-business/delete/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"idbookmarked_businesses": idbookmarked_businesses,
}),
);
if (response.statusCode == 200) {
return response.statusCode;
} else {
return response.statusCode;
}
}
}

View File

@@ -0,0 +1,222 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/loyalty_card.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_wallet_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MIHMzansiWalletApis {
final baseAPI = AppEnviroment.baseApiUrl;
static Future<void> getLoyaltyCards(
MzansiWalletProvider walletProvider,
String app_id,
BuildContext context,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/$app_id"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<MIHLoyaltyCard> myCards = List<MIHLoyaltyCard>.from(
l.map((model) => MIHLoyaltyCard.fromJson(model)));
walletProvider.setLoyaltyCards(cards: myCards);
// return myCards;
} else {
throw Exception('failed to fatch loyalty cards');
}
}
static Future<void> getFavouriteLoyaltyCards(
MzansiWalletProvider walletProvider,
String app_id,
BuildContext context,
) async {
//print("Patien manager page: $endpoint");
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/favourites/$app_id"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<MIHLoyaltyCard> myCards = List<MIHLoyaltyCard>.from(
l.map((model) => MIHLoyaltyCard.fromJson(model)));
walletProvider.setFavouriteCards(cards: myCards);
}
// else {
// throw Exception('failed to fatch loyalty cards');
// }
}
/// This function is used to Delete loyalty card from users mzansi wallet.
///
/// Patameters:-
/// AppUser signedInUser,
/// int idloyalty_cards,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS)
static Future<int> deleteLoyaltyCardAPICall(
MzansiWalletProvider walletProvider,
AppUser signedInUser,
int idloyalty_cards,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.delete(
Uri.parse(
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/delete/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{"idloyalty_cards": idloyalty_cards}),
);
//print("Here4");
//print(response.statusCode);
context.pop();
if (response.statusCode == 200) {
walletProvider.deleteLoyaltyCard(cardId: idloyalty_cards);
}
return response.statusCode;
// if (response.statusCode == 200) {
// Navigator.of(context).pop();
// Navigator.of(context).pop();
// Navigator.of(context).pop();
// Navigator.of(context).pop();
// Navigator.of(context).pushNamed(
// '/mzansi-wallet',
// arguments: WalletArguments(signedInUser, navIndex),
// );
// String message =
// "The loyalty card has been deleted successfully. This means it will no longer be visible in your Mzansi Wallet.";
// successPopUp(message, context);
// } else {
// Navigator.pop(context);
// internetConnectionPopUp(context);
// }
}
/// This function is used to add a lopyalty card to users mzansi wallet.
///
/// Patameters:-
/// AppUser signedInUser,
/// String app_id,
/// String shop_name,
/// String card_number,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS SUCCESS pop up)
static Future<int> addLoyaltyCardAPICall(
MzansiWalletProvider walletProvider,
AppUser signedInUser,
String app_id,
String shop_name,
String card_number,
String favourite,
int priority_index,
String nickname,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.post(
Uri.parse(
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": app_id,
"shop_name": shop_name,
"card_number": card_number,
"favourite": favourite,
"priority_index": priority_index,
"nickname": nickname,
}),
);
context.pop();
KenLogger.success("Response: $response");
if (response.statusCode == 201) {
await getLoyaltyCards(walletProvider, app_id, context);
}
return response.statusCode;
// if (response.statusCode == 201) {
// // Navigator.pop(context);
// // String message =
// // "Your $shop_name Loyalty Card was successfully added to your Mzansi Wallet.";
// // Navigator.pop(context);
// // Navigator.pop(context);
// // Navigator.of(context).pushNamed(
// // '/mzansi-wallet',
// // arguments: WalletArguments(signedInUser, navIndex),
// // );
// // successPopUp(message, context);
// } else {
// // Navigator.pop(context);
// // internetConnectionPopUp(context);
// }
}
/// This function is used to Update loyalty card from users mzansi wallet.
///
/// Patameters:-
/// AppUser signedInUser,
/// int idloyalty_cards,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS)
static Future<int> updateLoyaltyCardAPICall(
MzansiWalletProvider walletProvider,
AppUser signedInUser,
int idloyalty_cards,
String shopName,
String favourite,
int priority_index,
String nickname,
String card_number,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.put(
Uri.parse(
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"idloyalty_cards": idloyalty_cards,
"favourite": favourite,
"priority_index": priority_index,
"nickname": nickname,
"card_number": card_number,
}),
);
context.pop();
if (response.statusCode == 200) {
walletProvider.editLoyaltyCard(
updatedCard: MIHLoyaltyCard(
idloyalty_cards: idloyalty_cards,
app_id: signedInUser.app_id,
shop_name: shopName,
card_number: card_number,
favourite: favourite,
priority_index: priority_index,
nickname: nickname,
),
);
}
return response.statusCode;
}
//================== POP UPS ==========================================================================
static void loadingPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
}
}

View File

@@ -0,0 +1,319 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_objects/notification.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihNotificationApis {
final baseAPI = AppEnviroment.baseApiUrl;
//================== Notifications ==========================================================================
Future<List<MIHNotification>> getNotificationByUser(
String app_id,
int notificationAmount,
) async {
var responseNotification = await http.get(
Uri.parse("$baseAPI/notifications/$app_id?amount=$notificationAmount"));
if (responseNotification.statusCode == 200) {
String body = responseNotification.body;
Iterable l = jsonDecode(body);
List<MIHNotification> notifications = List<MIHNotification>.from(
l.map((model) => MIHNotification.fromJson(model)));
return notifications;
} else {
return [];
}
}
/// This function is used to create notification to patient for access reviews
///
/// Patameters:-
/// String app_id,
/// String business_name,
/// BuildContext context,
///
/// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager)
static Future<void> addAccessRequestNotificationAPICall(
String app_id,
String business_name,
bool personalSelected,
BusinessArguments args,
BuildContext context,
) async {
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": app_id,
"notification_type": "Forever Access Request",
"notification_message":
"A new Forever Access Request has been sent by $business_name in order to access your Patient Profile. Please review request.",
"action_path": "/mih-access",
}),
);
if (response.statusCode == 201) {
String message =
"A request has been sent to the patient advising that you have requested access to their profile. Only once access has been granted will you be able to book an appointment.";
Navigator.of(context).pop();
context.goNamed(
'patientManager',
extra: PatManagerArguments(
args.signedInUser,
personalSelected,
args.business,
args.businessUser,
),
);
MihAlertServices().successBasicAlert(
"Success!",
message,
context,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
/// This function is used to create notification to patient for access reviews
///
/// Patameters:-
/// String app_id,
/// String business_name,
/// BuildContext context,
///
/// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager)
static Future<void> reapplyAccessRequestNotificationAPICall(
String app_id,
bool personalSelected,
BusinessArguments args,
BuildContext context,
) async {
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": app_id,
"notification_type": "Re-applying for Access",
"notification_message":
"${args.business!.Name} is re-applying for access to your Patient Profile. Please review request.",
"action_path": "/mih-access",
}),
);
if (response.statusCode == 201) {
String message =
"A request has been sent to the patient advising that you have re-applied for access to their profile. Only once access has been granted will you be able to book an appointment.";
Navigator.of(context).pop();
context.goNamed(
'patientManager',
extra: PatManagerArguments(
args.signedInUser,
personalSelected,
args.business,
args.businessUser,
),
);
// Navigator.of(context).pop();
// Navigator.of(context).pushNamed(
// '/patient-manager',
// arguments: PatManagerArguments(
// args.signedInUser,
// personalSelected,
// args.business,
// args.businessUser,
// ),
// );
MihAlertServices().successBasicAlert(
"Success!",
message,
context,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
/// This function is used to create notification to patient for access reviews
///
/// Patameters:-
/// String app_id,
/// String business_name,
/// String origDate_time,
/// String date,
/// String time,
/// BusinessArguments args,
/// BuildContext context,
///
/// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager)
static Future<void> addRescheduledAppointmentNotificationAPICall(
String app_id,
bool personalSelected,
String business_name,
String origDate_time,
String date,
String time,
BusinessArguments args,
BuildContext context,
) async {
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": app_id,
"notification_type": "Appointment Rescheduled",
"notification_message":
"Your appointment with $business_name for the ${origDate_time.replaceAll("T", " ").substring(0, origDate_time.length - 3)} has been rescheduled to the ${date} ${time}.",
"action_path": "/appointments",
}),
);
if (response.statusCode == 201) {
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pushNamed(
'/patient-manager',
arguments: PatManagerArguments(
args.signedInUser,
personalSelected,
args.business,
args.businessUser,
),
);
String message = "The appointment has been successfully rescheduled.";
MihAlertServices().successBasicAlert(
"Success!",
message,
context,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
/// This function is used to create notification to patient for access reviews
///
/// Patameters:-
/// String app_id,
/// String business_name,
/// String origDate_time,
/// String date,
/// String time,
/// BusinessArguments args,
/// BuildContext context,
///
/// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager)
static Future<void> addCancelledAppointmentNotificationAPICall(
String app_id,
bool personalSelected,
String date_time,
BusinessArguments args,
BuildContext context,
) async {
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": app_id,
"notification_type": "Appointment Cancelled",
"notification_message":
"Your appointment with ${args.business!.Name} for the ${date_time.replaceAll("T", " ")} has been cancelled.",
"action_path": "/appointments",
}),
);
if (response.statusCode == 201) {
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pushNamed(
'/patient-manager',
arguments: PatManagerArguments(
args.signedInUser,
personalSelected,
args.business,
args.businessUser,
),
);
String message =
"The appointment has been cancelled successfully. This means it will no longer be visible in your waiting room and calender.";
MihAlertServices().successBasicAlert(
"Success!",
message,
context,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
/// This function is used to create notification to patient for access reviews
///
/// Patameters:-
/// String app_id,
/// String business_name,
/// String origDate_time,
/// String date,
/// String time,
/// BusinessArguments args,
/// BuildContext context,
///
/// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager)
static Future<void> addNewAppointmentNotificationAPICall(
String app_id,
bool personalSelected,
String date,
String time,
BusinessArguments args,
BuildContext context,
) async {
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": app_id,
"notification_type": "New Appointment Booked",
"notification_message":
"An appointment with ${args.business!.Name} has been booked for the $date $time.",
"action_path": "/appointments",
}),
);
if (response.statusCode == 201) {
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pushNamed(
'/patient-manager',
arguments: PatManagerArguments(
args.signedInUser,
personalSelected,
args.business,
args.businessUser,
),
);
String message =
"The appointment was been created successfully. This means it will now be visible in your waiting room and calender.";
MihAlertServices().successBasicAlert(
"Success!",
message,
context,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
}
//================== POP UPS ==========================================================================

View File

@@ -0,0 +1,326 @@
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
import 'package:mzansi_innovation_hub/mih_objects/files.dart';
import 'package:mzansi_innovation_hub/mih_objects/notes.dart';
import 'package:mzansi_innovation_hub/mih_objects/patient_access.dart';
import 'package:mzansi_innovation_hub/mih_objects/patients.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_providers/patient_manager_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:supertokens_flutter/http.dart' as http;
class MihPatientServices {
final baseAPI = AppEnviroment.baseApiUrl;
Future<Patient?> getPatientDetails(
String appId,
PatientManagerProvider patientManagerProvider,
) async {
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/patients/$appId"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
String body = response.body;
var jsonBody = jsonDecode(body);
Patient patient = Patient.fromJson(jsonBody);
patientManagerProvider.setSelectedPatient(selectedPatient: patient);
return patient;
} else {
return null;
}
}
static Future<List<Patient>> searchPatients(
PatientManagerProvider patientManagerProvider,
String search,
) async {
final response = await http
.get(Uri.parse("${AppEnviroment.baseApiUrl}/patients/search/$search"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<Patient> patients =
List<Patient>.from(l.map((model) => Patient.fromJson(model)));
patientManagerProvider.setPatientSearchResults(
patientSearchResults: patients);
return patients;
} else {
throw Exception('failed to load patients');
}
}
Future<int> addPatientService(
String id_no,
String fname,
String lname,
String email,
String cell,
String medAid,
String medMainMem,
String medNo,
String medAidCode,
String medName,
String medScheme,
String address,
MzansiProfileProvider profileProvider,
PatientManagerProvider patientManagerProvider,
) async {
var response = await http.post(
Uri.parse("$baseAPI/patients/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"id_no": id_no,
"first_name": fname,
"last_name": lname,
"email": email,
"cell_no": cell,
"medical_aid": medAid,
"medical_aid_main_member": medMainMem,
"medical_aid_no": medNo,
"medical_aid_code": medAidCode,
"medical_aid_name": medName,
"medical_aid_scheme": medScheme,
"address": address,
"app_id": profileProvider.user!.app_id,
}),
);
if (response.statusCode == 201) {
await getPatientDetails(
profileProvider.user!.app_id, patientManagerProvider);
// patientManagerProvider.setSelectedPatient(
// selectedPatient: Patient(
// idpatients: 0,
// id_no: id_no,
// first_name: fname,
// last_name: lname,
// email: email,
// cell_no: cell,
// medical_aid: medAid,
// medical_aid_name: medName,
// medical_aid_no: medNo,
// medical_aid_main_member: medMainMem,
// medical_aid_code: medAidCode,
// medical_aid_scheme: medScheme,
// address: address,
// app_id: profileProvider.user!.app_id,
// ),
// );
}
return response.statusCode;
}
Future<int> updatePatientService(
String app_id,
String id_no,
String fname,
String lname,
String email,
String cell,
String medAid,
String medMainMem,
String medNo,
String medAidCode,
String medName,
String medScheme,
String address,
PatientManagerProvider patientManagerProvider,
) async {
var response = await http.put(
Uri.parse("$baseAPI/patients/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"id_no": id_no,
"first_name": fname,
"last_name": lname,
"email": email,
"cell_no": cell,
"medical_aid": medAid,
"medical_aid_main_member": medMainMem,
"medical_aid_no": medNo,
"medical_aid_code": medAidCode,
"medical_aid_name": medName,
"medical_aid_scheme": medScheme,
"address": address,
"app_id": app_id,
}),
);
if (response.statusCode == 200) {
await getPatientDetails(app_id, patientManagerProvider);
}
return response.statusCode;
}
Future<int> getPatientConsultationNotes(
PatientManagerProvider patientManagerProvider) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/notes/patients/${patientManagerProvider.selectedPatient!.app_id}"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<Note> notes =
List<Note>.from(l.map((model) => Note.fromJson(model)));
patientManagerProvider.setConsultationNotes(consultationNotes: notes);
}
return response.statusCode;
}
Future<int> addPatientNoteAPICall(
String title,
String noteText,
MzansiProfileProvider profileProvider,
PatientManagerProvider patientManagerProvider,
) async {
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/notes/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"note_name": title,
"note_text": noteText,
"doc_office": profileProvider.business!.Name,
"doctor":
"${profileProvider.user!.fname} ${profileProvider.user!.lname}",
"app_id": patientManagerProvider.selectedPatient!.app_id,
}),
);
if (response.statusCode == 201) {
await getPatientConsultationNotes(patientManagerProvider);
}
return response.statusCode;
}
Future<int> deletePatientConsultaionNote(
int NoteId,
PatientManagerProvider patientManagerProvider,
) async {
var response = await http.delete(
Uri.parse("$baseAPI/notes/delete/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{"idpatient_notes": NoteId}),
);
if (response.statusCode == 201) {
await getPatientConsultationNotes(patientManagerProvider);
}
return response.statusCode;
}
Future<int> getPatientDocuments(
PatientManagerProvider patientManagerProvider) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/patient_files/get/${patientManagerProvider.selectedPatient!.app_id}"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<PFile> patientDocuments =
List<PFile>.from(l.map((model) => PFile.fromJson(model)));
patientManagerProvider.setPatientDocuments(
patientDocuments: patientDocuments);
}
return response.statusCode;
}
Future<int> addPatientFile(
PlatformFile? file,
PatientManagerProvider patientManagerProvider,
) async {
var fname = file!.name.replaceAll(RegExp(r' '), '-');
var filePath =
"${patientManagerProvider.selectedPatient!.app_id}/patient_files/$fname";
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/patient_files/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"file_path": filePath,
"file_name": fname,
"app_id": patientManagerProvider.selectedPatient!.app_id
}),
);
if (response.statusCode == 201) {
await getPatientDocuments(patientManagerProvider);
}
return response.statusCode;
}
Future<int> generateMedicalCertificate(
String startDate,
String endDate,
String returnDate,
MzansiProfileProvider profileProvider,
PatientManagerProvider patientManagerProvider,
) async {
DateTime now = DateTime.now();
String fileName =
"Med-Cert-${patientManagerProvider.selectedPatient!.first_name} ${patientManagerProvider.selectedPatient!.last_name}-${now.toString().substring(0, 19)}.pdf"
.replaceAll(RegExp(r' '), '-');
var response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/med-cert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": patientManagerProvider.selectedPatient!.app_id,
"env": AppEnviroment.getEnv(),
"patient_full_name":
"${patientManagerProvider.selectedPatient!.first_name} ${patientManagerProvider.selectedPatient!.last_name}",
"fileName": fileName,
"id_no": patientManagerProvider.selectedPatient!.id_no,
"docfname":
"DR. ${profileProvider.user!.fname} ${profileProvider.user!.lname}",
"startDate": startDate,
"busName": profileProvider.business!.Name,
"busAddr": "*TO BE ADDED IN THE FUTURE*",
"busNo": profileProvider.business!.contact_no,
"busEmail": profileProvider.business!.bus_email,
"endDate": endDate,
"returnDate": returnDate,
"logo_path": profileProvider.business!.logo_path,
"sig_path": profileProvider.businessUser!.sig_path,
}),
);
if (response.statusCode == 200) {
var responseAddFiletoDB = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/patient_files/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"file_path":
"${patientManagerProvider.selectedPatient!.app_id}/patient_files/$fileName",
"file_name": fileName,
"app_id": patientManagerProvider.selectedPatient!.app_id
}),
);
if (responseAddFiletoDB.statusCode == 201) {
await getPatientDocuments(patientManagerProvider);
}
}
return response.statusCode;
}
Future<List<PatientAccess>> getPatientAccessListOfBusiness(
PatientManagerProvider patientManagerProvider,
String business_id,
) async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/access-requests/business/patient/$business_id"));
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<PatientAccess> patientAccesses = List<PatientAccess>.from(
l.map((model) => PatientAccess.fromJson(model)));
patientManagerProvider.setMyPatientList(myPaitentList: patientAccesses);
return patientAccesses;
} else {
throw Exception('failed to pull patient access List for business');
}
}
}

View File

@@ -0,0 +1,63 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_objects/user_consent.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:supertokens_flutter/http.dart' as http;
import 'package:supertokens_flutter/supertokens.dart';
class MihUserConsentServices {
Future<void> getUserConsentStatus(
MzansiProfileProvider profileProvider,
) async {
var app_id = await SuperTokens.getUserId();
final response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/user-consent/user/$app_id"));
if (response.statusCode == 200) {
Map<String, dynamic> userMap = jsonDecode(response.body);
UserConsent userConsent = UserConsent.fromJson(userMap);
profileProvider.setUserConsent(userConsent);
}
}
Future<int> insertUserConsentStatus(
String latestPrivacyPolicyDate,
String latestTermOfServiceDate,
MzansiProfileProvider provider,
BuildContext context,
) async {
UserConsent userConsent = UserConsent(
app_id: provider.user!.app_id,
privacy_policy_accepted: DateTime.parse(latestPrivacyPolicyDate),
terms_of_services_accepted: DateTime.parse(latestTermOfServiceDate),
);
final response = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/user-consent/insert/"),
headers: {"Content-Type": "application/json"},
body: jsonEncode(userConsent.toJson()),
);
provider.setUserConsent(userConsent);
return response.statusCode;
}
Future<int> updateUserConsentStatus(
String latestPrivacyPolicyDate,
String latestTermOfServiceDate,
MzansiProfileProvider provider,
BuildContext context,
) async {
UserConsent userConsent = UserConsent(
app_id: provider.user!.app_id,
privacy_policy_accepted: DateTime.parse(latestPrivacyPolicyDate),
terms_of_services_accepted: DateTime.parse(latestTermOfServiceDate),
);
final response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/user-consent/update"),
headers: {"Content-Type": "application/json"},
body: jsonEncode(userConsent.toJson()),
);
provider.setUserConsent(userConsent);
return response.statusCode;
}
}

View File

@@ -0,0 +1,311 @@
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:provider/provider.dart';
import 'package:supertokens_flutter/http.dart' as http;
import 'package:supertokens_flutter/supertokens.dart';
class MihUserServices {
final baseAPI = AppEnviroment.baseApiUrl;
static Future<bool> isUsernameUnique(
String username,
BuildContext context,
) async {
var response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/users/validate/username/$username"));
if (response.statusCode == 200) {
String body = response.body;
var jsonBody = jsonDecode(body);
return jsonBody["available"];
} else {
throw Exception(
"Error: isUsernameUnique status code ${response.statusCode}");
}
}
Future<int> fetchUserCount() async {
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/users/count/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
var jsonBody = jsonDecode(response.body);
return jsonBody['count'];
} else {
return 0;
}
}
Future<void> createUser(
String email,
String app_id,
BuildContext context,
) async {
var response = await http.post(
Uri.parse("$baseAPI/user/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"email": email,
"app_id": app_id,
}),
);
if (response.statusCode == 201) {
context.goNamed(
'mihHome',
extra: true,
);
} else {
MihAlertServices().internetConnectionAlert(context);
}
}
Future<List<AppUser>> searchUsers(
MzansiProfileProvider profileProvider,
String searchText,
BuildContext context,
) async {
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/users/search/$searchText"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<AppUser> users =
List<AppUser>.from(l.map((model) => AppUser.fromJson(model)));
profileProvider.setUserearchResults(userSearchResults: users);
return users;
} else {
throw Exception('failed to load users');
}
}
Future<AppUser?> getMIHUserDetails(
String app_id,
BuildContext context,
) async {
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/user/$app_id"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
String body = response.body;
var jsonBody = jsonDecode(body);
return AppUser.fromJson(jsonBody);
} else {
return null;
}
}
Future<AppUser?> getMyUserDetails(
MzansiProfileProvider profileProvider,
) async {
String app_id = await SuperTokens.getUserId();
var response = await http.get(
Uri.parse("${AppEnviroment.baseApiUrl}/user/$app_id"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
);
if (response.statusCode == 200) {
String body = response.body;
var jsonBody = jsonDecode(body);
profileProvider.setUser(
newUser: AppUser.fromJson(jsonBody),
);
return AppUser.fromJson(jsonBody);
} else {
return null;
}
}
Future<int> updateUserV2(
AppUser signedInUser,
String firstName,
String lastName,
String username,
String profilePicture,
String purpose,
bool isBusinessUser,
BuildContext context,
) async {
var fileName = profilePicture.replaceAll(RegExp(r' '), '-');
var filePath = "${signedInUser.app_id}/profile_files/$fileName";
String profileType;
KenLogger.success("is Busines User: $isBusinessUser");
if (isBusinessUser) {
profileType = "business";
} else {
profileType = "personal";
}
KenLogger.success("Profile Type: $profileType");
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/user/update/v2/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"idusers": signedInUser.idUser,
"username": username,
"fnam": firstName,
"lname": lastName,
"type": profileType,
"pro_pic_path": filePath,
"purpose": purpose,
}),
);
if (response.statusCode == 200) {
context.read<MzansiProfileProvider>().setUser(
newUser: AppUser(
signedInUser.idUser,
signedInUser.email,
firstName,
lastName,
profileType,
signedInUser.app_id,
username,
filePath,
purpose,
),
);
String newProPicUrl = await MihFileApi.getMinioFileUrl(filePath);
context.read<MzansiProfileProvider>().setUserProfilePicUrl(newProPicUrl);
return response.statusCode;
} else {
return response.statusCode;
}
}
Future<int> updateUser(
AppUser signedInUser,
String firstName,
String lastName,
String username,
String profilePicture,
bool isBusinessUser,
BuildContext context,
) async {
var fileName = profilePicture.replaceAll(RegExp(r' '), '-');
var filePath = "${signedInUser.app_id}/profile_files/$fileName";
String profileType;
if (isBusinessUser) {
profileType = "business";
} else {
profileType = "personal";
}
var response = await http.put(
Uri.parse("${AppEnviroment.baseApiUrl}/user/update/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"idusers": signedInUser.idUser,
"username": username,
"fnam": firstName,
"lname": lastName,
"type": profileType,
"pro_pic_path": filePath,
}),
);
if (response.statusCode == 200) {
return response.statusCode;
} else {
return response.statusCode;
}
}
static Future<void> deleteAccount(
MzansiProfileProvider provider,
BuildContext context,
) async {
loadingPopUp(context);
var response = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/user/delete/all/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": provider.user!.app_id,
"env": AppEnviroment.getEnv(),
}),
);
if (response.statusCode == 200) {
await SuperTokens.signOut(completionHandler: (error) {
print(error);
});
if (await SuperTokens.doesSessionExist() == false) {
successPopUp(
"Account Deleted Successfully",
"Your account has been successfully deleted. We are sorry to see you go, but we respect your decision.",
context,
); // Show success message.
provider.dispose();
}
} else {
Navigator.of(context).pop(); // Pop loading dialog
MihAlertServices().internetConnectionAlert(context);
}
}
//================== POP UPS ==========================================================================
static void successPopUp(String title, String message, BuildContext context) {
MihAlertServices().successAdvancedAlert(
title,
message,
[
MihButton(
onPressed: () {
context.goNamed(
'mihHome',
extra: true,
);
},
buttonColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
elevation: 10,
width: 300,
child: Text(
"Dismiss",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
context,
);
}
static void loadingPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
}
}

View File

@@ -0,0 +1,128 @@
class MihValidationServices {
String? isEmpty(String? value) {
if (value == null || value.isEmpty) {
return "This field is required";
}
return null;
}
String? validateNoSpecialChars(String? value) {
if (value == null || value.isEmpty) {
return "This field is required";
}
final specialCharRegex = RegExp(r"^[\w,'& ]+$");
if (!specialCharRegex.hasMatch(value)) {
return "Only , ' & _ Special characters are allowed";
}
return null;
}
String? validateLength(String? value, int maxLength) {
if (value == null || value.isEmpty) {
return "This field is required";
}
if (value.length > maxLength) {
return "Length must not exceed $maxLength characters";
}
return null;
}
String? validateWebsite(String? website, bool required) {
final websiteRegex = RegExp(
r'^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$');
if (!required && website!.isEmpty) {
return null;
}
if (!websiteRegex.hasMatch(website!)) {
return "Invalid Website Format";
}
return null;
}
String? validateEmail(String? email) {
if (email == null || email.isEmpty) {
return "Email is required";
}
final emailRegex =
RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
if (!emailRegex.hasMatch(email)) {
return "Invalid Email Format";
}
return null;
}
String? validateUsername(String? username) {
String? errorMessage = "";
if (username == null || username.isEmpty) {
errorMessage += "Username is required";
return errorMessage;
}
if (!RegExp(r'^[a-zA-Z]').hasMatch(username)) {
errorMessage += "\n• Your username should start with a letter.";
}
if (!RegExp(r'^[a-zA-Z0-9_]+$').hasMatch(username)) {
errorMessage +=
"\n• You can use letters, numbers, and/or underscores only.";
}
if (username.length < 6 || username.length > 30) {
errorMessage += "\n• Keep it between 6 and 30 characters.";
}
if (RegExp(r'[@#\$]').hasMatch(username)) {
errorMessage += "\n• Avoid special characters like @, #, or \$.";
}
if (errorMessage.isEmpty) {
return null; // No errors, username is valid
}
return "Let's create a great username for you!$errorMessage";
}
String? validateNumber(String? number, int? minValue, int? maxValue) {
String? errorMessage = "";
if (number == null || number.isEmpty) {
errorMessage += "This field is required";
return errorMessage;
}
int? value = int.tryParse(number);
if (value == null) {
errorMessage += "Please enter a valid number";
return errorMessage;
}
if (value < (minValue ?? 0)) {
errorMessage += "Value must be >= ${minValue ?? 0}";
}
if (maxValue != null && value > maxValue) {
if (errorMessage.isNotEmpty) errorMessage += "\n";
errorMessage += "Value must be <= $maxValue";
}
return errorMessage.isEmpty ? null : errorMessage;
}
String? validatePassword(String? password) {
String? errorMessage = "";
if (password == null || password.isEmpty) {
errorMessage += "Password is required";
return errorMessage;
}
if (password.length < 8) {
errorMessage += "\n• Contains at least 8 characters long";
}
if (!RegExp(r'[A-Z]').hasMatch(password)) {
errorMessage += "\n• Contains at least 1 uppercase letter";
}
if (!RegExp(r'[a-z]').hasMatch(password)) {
errorMessage += "\n• Contains at least 1 lowercase letter";
}
if (!RegExp(r'[0-9]').hasMatch(password)) {
errorMessage += "\n• Contains at least 1 digit";
}
if (!RegExp(r'[!@#$%^&*]').hasMatch(password)) {
errorMessage += "\n• Contains at least 1 special character (!@#\$%^&*)";
}
if (errorMessage.isEmpty) {
return null; // No errors, password is valid
}
errorMessage = "Let's create a great password for you!$errorMessage";
return errorMessage;
}
}