Merge branch 'master' into dev_aamir

# Conflicts:
#	lib/main.dart
#	lib/presentation/home/landing_page.dart
#	lib/theme/colors.dart
#	lib/widgets/buttons/custom_button.dart
pull/8/head
aamir-csol 2 months ago
commit 23a4035117

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -41,11 +41,20 @@ PODS:
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/Analytics (11.15.0):
- Firebase/Core
- Firebase/Core (11.15.0):
- Firebase/CoreOnly
- FirebaseAnalytics (~> 11.15.0)
- Firebase/CoreOnly (11.15.0):
- FirebaseCore (~> 11.15.0)
- Firebase/Messaging (11.15.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 11.15.0)
- firebase_analytics (11.6.0):
- Firebase/Analytics (= 11.15.0)
- firebase_core
- Flutter
- firebase_core (3.15.2):
- Firebase/CoreOnly (= 11.15.0)
- Flutter
@ -53,6 +62,24 @@ PODS:
- Firebase/Messaging (= 11.15.0)
- firebase_core
- Flutter
- FirebaseAnalytics (11.15.0):
- FirebaseAnalytics/Default (= 11.15.0)
- FirebaseCore (~> 11.15.0)
- FirebaseInstallations (~> 11.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (11.15.0):
- FirebaseCore (~> 11.15.0)
- FirebaseInstallations (~> 11.0)
- GoogleAppMeasurement/Default (= 11.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (11.15.0):
- FirebaseCoreInternal (~> 11.15.0)
- GoogleUtilities/Environment (~> 8.1)
@ -371,14 +398,16 @@ SPEC CHECKSUMS:
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
firebase_analytics: bf93e20703c95030404d6ddbb1adf05bf5c3885b
firebase_core: 99a37263b3c27536063a7b601d9e2a49400a433c
firebase_messaging: bf6697c61f31c7cc0f654131212ff04c0115c2c7
FirebaseAnalytics: 6433dfd311ba78084fc93bdfc145e8cb75740eae
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
flutter_ios_voip_kit_karmm: 7ea37381a8841c92d186edf1f4604df5cc437579
flutter_local_notifications: ff50f8405aaa0ccdc7dcfb9022ca192e8ad9688f
@ -387,6 +416,8 @@ SPEC CHECKSUMS:
geolocator_apple: 66b711889fd333205763b83c9dcf0a57a28c7afd
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
google_maps_flutter_ios: e31555a04d1986ab130f2b9f24b6cdc861acc6d3
GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64
GoogleAppMeasurement: 700dce7541804bec33db590a5c496b663fbe2539
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
@ -423,4 +454,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 5df9d8aa8f2c105eacd5ad7a310503d93c68c86b
COCOAPODS: 1.15.2
COCOAPODS: 1.16.2

@ -2,21 +2,25 @@ import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:http/http.dart' as http;
import '../exceptions/api_failure.dart';
abstract class ApiClient {
Future<void> post(
String endPoint, {
required Map<String, dynamic> body,
required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
required Function(dynamic response, int statusCode, {int? messageStatus}) onSuccess,
required Function(String error, int statusCode, {int? messageStatus, Failure? failureType}) onFailure,
bool isAllowAny,
bool isExternal,
bool isRCService,
@ -32,61 +36,69 @@ abstract class ApiClient {
bool isRCService,
});
Future<void> simplePost(
String fullUrl, {
required Map<dynamic, dynamic> body,
required Map<String, String> headers,
required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
});
Future<void> simpleGet(
String fullUrl, {
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure,
Map<String, dynamic>? queryParams,
Map<String, String>? headers,
});
Future<void> simplePut(
String fullUrl, {
Map<String, dynamic>? body,
Map<String, String>? headers,
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure,
});
Future<void> simpleDelete(
String fullUrl, {
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure,
Map<String, String>? queryParams,
Map<String, String>? headers,
});
Future<bool> handleUnauthorized(int statusCode, {required String forUrl});
String getSessionId(String id);
Future<String> generatePackagesToken();
// Future<void> simplePost(
// String fullUrl, {
// required Map<dynamic, dynamic> body,
// required Map<String, String> headers,
// required Function(dynamic response, int statusCode) onSuccess,
// required Function(String error, int statusCode) onFailure,
// });
//
// Future<void> simpleGet(
// String fullUrl, {
// Function(dynamic response, int statusCode)? onSuccess,
// Function(String error, int statusCode)? onFailure,
// Map<String, dynamic>? queryParams,
// Map<String, String>? headers,
// });
//
// Future<void> simplePut(
// String fullUrl, {
// Map<String, dynamic>? body,
// Map<String, String>? headers,
// Function(dynamic response, int statusCode)? onSuccess,
// Function(String error, int statusCode)? onFailure,
// });
//
// Future<void> simpleDelete(
// String fullUrl, {
// Function(dynamic response, int statusCode)? onSuccess,
// Function(String error, int statusCode)? onFailure,
// Map<String, String>? queryParams,
// Map<String, String>? headers,
// });
// Future<bool> handleUnauthorized(int statusCode, {required String forUrl});
// Future<String> generatePackagesToken();
}
class ApiClientImp implements ApiClient {
final _analytics = getIt<GAnalytics>();
final LoggerService loggerService;
final AppState appState;
final DialogService dialogService;
ApiClientImp({required this.loggerService});
ApiClientImp({
required this.loggerService,
required this.dialogService,
required this.appState,
});
@override
post(String endPoint,
{required Map<String, dynamic> body,
required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
bool isAllowAny = false,
bool isExternal = false,
bool isRCService = false,
bool bypassConnectionCheck = false}) async {
post(
String endPoint, {
required Map<String, dynamic> body,
required Function(dynamic response, int statusCode, {int? messageStatus}) onSuccess,
required Function(String error, int statusCode, {int? messageStatus, Failure? failureType}) onFailure,
bool isAllowAny = false,
bool isExternal = false,
bool isRCService = false,
bool bypassConnectionCheck = false,
}) async {
AppState appState = getIt.get<AppState>();
String url;
if (isExternal) {
@ -103,7 +115,7 @@ class ApiClientImp implements ApiClient {
Map<String, String> headers = {'Content-Type': 'application/json', 'Accept': 'application/json'};
if (!isExternal) {
String? token = appState.appAuthToken;
String? languageID = (appState.postParamsObject?.languageID == 1 ? 'ar' : 'en') ?? 'ar';
String? languageID = (appState.postParamsObject?.languageID == 1 ? 'ar' : 'en');
if (endPoint == ApiConsts.sendActivationCode) {
languageID = 'en';
}
@ -113,7 +125,6 @@ class ApiClientImp implements ApiClient {
if (body.containsKey('LanguageID')) {
if (body['LanguageID'] != null) {
//change this line because language issue happened on dental
body['LanguageID'] = body['LanguageID'] == 'ar'
? 1
: body['LanguageID'] == 'en'
@ -128,7 +139,6 @@ class ApiClientImp implements ApiClient {
: IS_DENTAL_ALLOWED_BACKEND;
}
//Todo: I have converted it to string
body['DeviceTypeID'] = Platform.isIOS
? "1"
@ -160,40 +170,46 @@ class ApiClientImp implements ApiClient {
}
}
body['LanguageID'] = body['LanguageID'] ?? "2";
body['VersionID'] = body['VersionID'] ?? "18.7";
body['Channel'] = body['Channel'] ?? "3";
body['IPAdress'] = body['IPAdress'] ?? "10.20.10.20";
body['generalid'] = body['generalid'] ?? "Cs2020@2016\$2958";
body['Latitude'] = body['Latitude'] ?? "0.0";
body['Longitude'] = body['Longitude'] ?? "0.0";
// request.versionID = VERSION_ID;
// request.channel = CHANNEL;
// request.iPAdress = IP_ADDRESS;
// request.generalid = GENERAL_ID;
// request.languageID = (languageID == 'ar' ? 1 : 2);
// request.patientOutSA = (request.zipCode == '966' || request.zipCode == '+966') ? 0 : 1;
// TODO : we will use all these from appState
body['LanguageID'] = body['LanguageID'] ?? "2";
body['VersionID'] = body['VersionID'] ?? "18.7";
body['Channel'] = body['Channel'] ?? "3";
body['IPAdress'] = body['IPAdress'] ?? "10.20.10.20";
body['generalid'] = body['generalid'] ?? "Cs2020@2016\$2958";
body['Latitude'] = body['Latitude'] ?? "0.0";
body['Longitude'] = body['Longitude'] ?? "0.0";
body['DeviceTypeID'] = body['DeviceTypeID'] ??
(Platform.isIOS ? "1" : await Utils.isGoogleServicesAvailable() ? "2" : "3");
//"LanguageID":1,"VersionID":18.7,"Channel":3,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","Latitude":0.0,"Longitude":0.0,"DeviceTypeID":2,"PatientType":1}
(Platform.isIOS
? "1"
: await Utils.isGoogleServicesAvailable()
? "2"
: "3");
body.removeWhere((key, value) => value == null);
log("bodi: ${json.encode(body)}");
log("bodi: ${Uri.parse(url.trim())}");
log("body: ${json.encode(body)}");
log("uri: ${Uri.parse(url.trim())}");
if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) {
final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers);
final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400) {
onFailure('Error While Fetching data', statusCode);
onFailure('Error While Fetching data', statusCode, failureType: StatusCodeFailure("Error While Fetching data"));
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
} else {
var parsed = json.decode(utf8.decode(response.bodyBytes));
var parsed = json.decode(utf8.decode(response.bodyBytes));
log("parsed: ${parsed.toString()}");
if (isAllowAny) {
onSuccess(parsed, statusCode);
} else {
if (parsed['Response_Message'] != null) {
onSuccess(parsed, statusCode);
onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus']);
} else {
if (parsed['ErrorType'] == 4) {
//TODO : handle app update
@ -204,19 +220,18 @@ class ApiClientImp implements ApiClient {
logApiEndpointError(endPoint, "session logged out", statusCode);
}
if (isAllowAny) {
onSuccess(parsed, statusCode);
onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus']);
} else if (parsed['IsAuthenticated'] == null) {
if (parsed['isSMSSent'] == true) {
onSuccess(parsed, statusCode);
onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus']);
} else if (parsed['MessageStatus'] == 1) {
onSuccess(parsed, statusCode);
} else if (parsed['Result'] == 'OK') {
onSuccess(parsed, statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode,
failureType: ServerFailure("Error While Fetching data"));
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
} else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
onSuccess(parsed, statusCode);
@ -226,28 +241,46 @@ class ApiClientImp implements ApiClient {
} else {
if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) {
onFailure("Server Error found with no available message", statusCode);
onFailure(
"Server Error found with no available message",
statusCode,
failureType: ServerFailure("Error While Fetching data"),
);
logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
} else {
onFailure(parsed['ErrorSearchMsg'], statusCode);
onFailure(
parsed['ErrorSearchMsg'],
statusCode,
failureType: ServerFailure("Error While Fetching data"),
);
logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
}
} else {
onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
onFailure(
parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode,
failureType: ServerFailure("Error While Fetching data"),
);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
}
}
}
else {
} else {
if (parsed['SameClinicApptList'] != null) {
onSuccess(parsed, statusCode);
} else {
if (parsed['message'] != null) {
onFailure(parsed['message'] ?? parsed['message'], statusCode);
onFailure(
parsed['message'] ?? parsed['message'],
statusCode,
failureType: ServerFailure("Error While Fetching data"),
);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
onFailure(
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode,
failureType: ServerFailure("Error While Fetching data"),
);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
@ -256,13 +289,17 @@ class ApiClientImp implements ApiClient {
}
}
} else {
onFailure('Please Check The Internet Connection 1', -1);
onFailure(
'Please Check The Internet Connection 1',
-1,
failureType: ConnectivityFailure("Error While Fetching data"),
);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
} catch (e) {
loggerService.errorLogs(e.toString());
if (e.toString().contains("ClientException")) {
onFailure('Something went wrong, plase try again', -1);
onFailure('Something went wrong, plase try again', -1, failureType: InvalidCredentials('Something went wrong, plase try again'));
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
} else {
onFailure(e.toString(), -1);
@ -271,6 +308,7 @@ class ApiClientImp implements ApiClient {
}
}
@override
get(String endPoint,
{required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
@ -304,203 +342,173 @@ class ApiClientImp implements ApiClient {
// print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400) {
onFailure!('Error While Fetching data', statusCode);
onFailure('Error While Fetching data', statusCode);
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
} else {
var parsed = json.decode(utf8.decode(response.bodyBytes));
onSuccess!(parsed, statusCode);
}
} else {
onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simplePost(
String fullUrl, {
required Map<dynamic, dynamic> body,
required Map<String, String> headers,
required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
}) async {
String url = fullUrl;
// print("URL Query String: $url");
// print("body: $body");
if (await Utils.checkConnection()) {
headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.post(
Uri.parse(url.trim()),
body: json.encode(body),
headers: headers,
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl))
simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers);
// print(response.body.toString());
if (statusCode < 200 || statusCode >= 400) {
onFailure!('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess!(response.body.toString(), statusCode);
onSuccess(parsed, statusCode);
}
} else {
onFailure!('Please Check The Internet Connection', -1);
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simpleGet(String fullUrl,
{Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure,
Map<String, dynamic>? queryParams,
Map<String, String>? headers}) async {
headers = headers ?? {};
String url = fullUrl;
var haveParams = (queryParams != null);
if (haveParams) {
String queryString = Uri(queryParameters: queryParams).query;
url += '?$queryString';
// print("URL Query String: $url");
}
if (await Utils.checkConnection()) {
headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.get(
Uri.parse(url.trim()),
headers: headers,
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl))
simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams);
if (statusCode < 200 || statusCode >= 400) {
onFailure!('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess!(response.body.toString(), statusCode);
}
} else {
onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simplePut(String fullUrl,
{Map<String, dynamic>? body,
Map<String, String>? headers,
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure}) async {
String url = fullUrl;
// print("URL Query String: $url");
if (await Utils.checkConnection()) {
headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.put(
Uri.parse(url.trim()),
body: json.encode(body),
headers: headers,
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl))
simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body);
if (statusCode < 200 || statusCode >= 400) {
onFailure!('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess!(response.body.toString(), statusCode);
}
} else {
onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
simpleDelete(String fullUrl,
{Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure,
Map<String, String>? queryParams,
Map<String, String>? headers}) async {
String url = fullUrl;
// print("URL Query String: $url");
var haveParams = (queryParams != null);
if (haveParams) {
String queryString = Uri(queryParameters: queryParams).query;
url += '?$queryString';
// print("URL Query String: $url");
}
if (await Utils.checkConnection()) {
headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.delete(
Uri.parse(url.trim()),
headers: headers,
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl))
simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers);
if (statusCode < 200 || statusCode >= 400) {
onFailure!('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess!(response.body.toString(), statusCode);
}
} else {
onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
Future<bool> handleUnauthorized(int statusCode, {required String forUrl}) async {
if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) {
final token = await generatePackagesToken();
ApiConsts.packagesAuthHeader['Authorization'] = 'Bearer $token';
return (token is String);
}
return false;
}
// @override
// simplePost(
// String fullUrl, {
// required Map<dynamic, dynamic> body,
// required Map<String, String> headers,
// required Function(dynamic response, int statusCode) onSuccess,
// required Function(String error, int statusCode) onFailure,
// }) async {
// String url = fullUrl;
// // print("URL Query String: $url");
// // print("body: $body");
//
// if (await Utils.checkConnection()) {
// headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
// final response = await http.post(
// Uri.parse(url.trim()),
// body: json.encode(body),
// headers: headers,
// );
// final int statusCode = response.statusCode;
// // print("statusCode :$statusCode");
// if (await handleUnauthorized(statusCode, forUrl: fullUrl)) {
// simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers);
// }
//
// // print(response.body.toString());
//
// if (statusCode < 200 || statusCode >= 400) {
// onFailure!('Error While Fetching data', statusCode);
// logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
// } else {
// onSuccess!(response.body.toString(), statusCode);
// }
// } else {
// onFailure!('Please Check The Internet Connection', -1);
// _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
// }
// }
// simpleGet(String fullUrl,
// {Function(dynamic response, int statusCode)? onSuccess,
// Function(String error, int statusCode)? onFailure,
// Map<String, dynamic>? queryParams,
// Map<String, String>? headers}) async {
// headers = headers ?? {};
// String url = fullUrl;
//
// var haveParams = (queryParams != null);
// if (haveParams) {
// String queryString = Uri(queryParameters: queryParams).query;
// url += '?$queryString';
// // print("URL Query String: $url");
// }
//
// if (await Utils.checkConnection()) {
// headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
// final response = await http.get(
// Uri.parse(url.trim()),
// headers: headers,
// );
//
// final int statusCode = response.statusCode;
// // print("statusCode :$statusCode");
// if (await handleUnauthorized(statusCode, forUrl: fullUrl))
// simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams);
//
// if (statusCode < 200 || statusCode >= 400) {
// onFailure!('Error While Fetching data', statusCode);
// logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
// } else {
// onSuccess!(response.body.toString(), statusCode);
// }
// } else {
// onFailure!('Please Check The Internet Connection', -1);
// _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
// }
// }
// simplePut(String fullUrl,
// {Map<String, dynamic>? body,
// Map<String, String>? headers,
// Function(dynamic response, int statusCode)? onSuccess,
// Function(String error, int statusCode)? onFailure}) async {
// String url = fullUrl;
// // print("URL Query String: $url");
//
// if (await Utils.checkConnection()) {
// headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
// final response = await http.put(
// Uri.parse(url.trim()),
// body: json.encode(body),
// headers: headers,
// );
//
// final int statusCode = response.statusCode;
// // print("statusCode :$statusCode");
// if (await handleUnauthorized(statusCode, forUrl: fullUrl))
// simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body);
//
// if (statusCode < 200 || statusCode >= 400) {
// onFailure!('Error While Fetching data', statusCode);
// logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
// } else {
// onSuccess!(response.body.toString(), statusCode);
// }
// } else {
// onFailure!('Please Check The Internet Connection', -1);
// _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
// }
// }
//
// simpleDelete(String fullUrl,
// {Function(dynamic response, int statusCode)? onSuccess,
// Function(String error, int statusCode)? onFailure,
// Map<String, String>? queryParams,
// Map<String, String>? headers}) async {
// String url = fullUrl;
// // print("URL Query String: $url");
//
// var haveParams = (queryParams != null);
// if (haveParams) {
// String queryString = Uri(queryParameters: queryParams).query;
// url += '?$queryString';
// // print("URL Query String: $url");
// }
//
// if (await Utils.checkConnection()) {
// headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
// final response = await http.delete(
// Uri.parse(url.trim()),
// headers: headers,
// );
//
// final int statusCode = response.statusCode;
// // print("statusCode :$statusCode");
// if (await handleUnauthorized(statusCode, forUrl: fullUrl))
// simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers);
//
// if (statusCode < 200 || statusCode >= 400) {
// onFailure!('Error While Fetching data', statusCode);
// logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
// } else {
// onSuccess!(response.body.toString(), statusCode);
// }
// } else {
// onFailure!('Please Check The Internet Connection', -1);
// _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
// }
// }
@override
String getSessionId(String id) {
return id.replaceAll(RegExp('/[^a-zA-Z]'), '');
}
Future<String> generatePackagesToken() async {
var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN;
var body = {
"api_client": {
"client_id": "a4ab6be4-424f-4836-b032-46caed88e184",
"client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"
}
};
String? token;
final completer = Completer();
simplePost(url, body: body, headers: {}, onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
token = jsonResponse['auth_token'];
completer.complete();
}
}, onFailure: (String error, int statusCode) {
completer.complete();
logApiFullUrlError(url, error, statusCode);
});
await completer.future;
return token!;
}
logApiFullUrlError(String fullUrl, error, code) {
final endpoint = Uri.parse(fullUrl).pathSegments.last;
logApiEndpointError(endpoint, error, code);

@ -2,8 +2,6 @@ class AppAssets {
static const String svgBasePath = 'assets/images/svg';
static const String pngBasePath = 'assets/images/png';
static const String hmg = '$svgBasePath/hmg.svg';
static const String arrow_back = '$svgBasePath/arrow-back.svg';
static const String calendar = '$svgBasePath/calendar.svg';
@ -53,11 +51,25 @@ class AppAssets {
static const String home_calendar_icon = '$svgBasePath/home_calendar_icon.svg';
static const String add_icon = '$svgBasePath/add_icon.svg';
static const String livecare_icon = '$svgBasePath/livecare_icon.svg';
static const String file_icon = '$svgBasePath/file_icon.svg';
static const String checkmark_icon = '$svgBasePath/checkmark_icon.svg';
static const String blood_icon = '$svgBasePath/blood_icon.svg';
static const String insurance_active_icon = '$svgBasePath/insurance_active_icon.svg';
static const String saudi_riyal_icon = '$svgBasePath/Saudi_Riyal_Symbol.svg';
static const String habib_background_icon = '$svgBasePath/habib_logo_background.svg';
static const String show_icon = '$svgBasePath/show_icon.svg';
static const String recharge_icon = '$svgBasePath/recharge_icon.svg';
// PNGS //
static const String hmg_logo = '$pngBasePath/hmg_logo.png';
static const String livecare_service = '$pngBasePath/livecare_service.png';
static const String male_img = '$pngBasePath/male_img.png';
static const String apple_pay = '$pngBasePath/Apple_Pay.png';
static const String mada = '$pngBasePath/Mada.png';
static const String Mastercard = '$pngBasePath/Mastercard.png';
static const String tamara_en = '$pngBasePath/tamara_en.png';
static const String visa = '$pngBasePath/visa.png';
}
class AppAnimations {
@ -65,5 +77,4 @@ class AppAnimations {
static const String login = '$lottieBasePath/login.json';
static const String register = '$lottieBasePath/register.json';
static const String checkmark = '$lottieBasePath/checkmark.json';
}
}

@ -1,15 +1,14 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:hmg_patient_app_new/core/post_params_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/authenticated_user_model.dart';
import 'package:hmg_patient_app_new/main.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'api_consts.dart' as ApiConsts;
class AppState {
// Simple constructor - let get_it handle the singleton behavior
AppState();
NavigationService navigationService;
AppState({required this.navigationService});
bool isAuthenticated = true;
@ -40,9 +39,7 @@ class AppState {
PostParamsModel? get postParamsObject => _postParams;
Map<String, dynamic> get postParamsJson => isAuthenticated
? (_postParams?.toJsonAfterLogin() ?? {})
: (_postParams?.toJson() ?? {});
Map<String, dynamic> get postParamsJson => isAuthenticated ? (_postParams?.toJsonAfterLogin() ?? {}) : (_postParams?.toJson() ?? {});
void setPostParamsModel(PostParamsModel _postParams) {
this._postParams = _postParams;
@ -51,12 +48,9 @@ class AppState {
double userLat = 0.0;
double userLong = 0.0;
bool isArabic() =>
EasyLocalization.of(navigatorKey.currentContext!)?.locale.languageCode ==
"ar";
bool isArabic() => EasyLocalization.of(navigationService.navigatorKey.currentContext!)?.locale.languageCode == "ar";
int getLanguageID(context) =>
EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2;
int getLanguageID(context) => EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2;
AuthenticatedUser? _authenticatedUser;

@ -0,0 +1,34 @@
class GenericApiModel<T> {
final int? messageStatus;
final String? errorMessage;
final int? statusCode;
final T? data;
GenericApiModel({
this.messageStatus,
this.errorMessage,
this.statusCode,
this.data,
});
factory GenericApiModel.fromJson(
Map<String, dynamic> json,
T Function(Object? json)? fromJsonT,
) {
return GenericApiModel<T>(
messageStatus: json['messageStatus'] as int?,
errorMessage: json['errorMessage'] as String?,
statusCode: json['statusCode'] as int?,
data: fromJsonT != null ? fromJsonT(json['data']) : json['data'] as T?,
);
}
Map<String, dynamic> toJson(Object Function(T value)? toJsonT) {
return {
'messageStatus': messageStatus,
'errorMessage': errorMessage,
'statusCode': statusCode,
'data': toJsonT != null && data != null ? toJsonT(data as T) : data,
};
}
}

@ -1,13 +1,18 @@
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/location_util.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_repo.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/common/common_repo.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart';
import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:logger/web.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -15,25 +20,62 @@ GetIt getIt = GetIt.instance;
class AppDependencies {
static Future<void> addDependencies() async {
// Services
getIt.registerLazySingleton<LoggerService>(() => LoggerServiceImp(logger: Logger(printer: PrettyPrinter(
methodCount: 2, // number of stack trace lines
errorMethodCount: 5, // number of stack trace lines for errors
lineLength: 100, // wrap width
colors: true, // colorful logs
printEmojis: true, // include emojis
),)));
Logger logger = Logger(
printer: PrettyPrinter(
methodCount: 2,
errorMethodCount: 5,
lineLength: 100,
colors: true,
printEmojis: true,
),
);
// Core Services
getIt.registerLazySingleton<LoggerService>(() => LoggerServiceImp(logger: logger));
getIt.registerLazySingleton<NavigationService>(() => NavigationService());
getIt.registerLazySingleton<GAnalytics>(() => GAnalytics());
getIt.registerLazySingleton<AppState>(() => AppState(navigationService: getIt()));
getIt.registerLazySingleton<LocationUtils>(() => LocationUtils(
isShowConfirmDialog: false,
navigationService: getIt(),
appState: getIt(),
));
getIt.registerLazySingleton<DialogService>(() => DialogServiceImp(navigationService: getIt<NavigationService>()));
getIt.registerLazySingleton<ErrorHandlerService>(() => ErrorHandlerServiceImp(
dialogService: getIt(),
loggerService: getIt(),
navigationService: getIt(),
));
final sharedPreferences = await SharedPreferences.getInstance();
getIt.registerLazySingleton<CacheService>(() => CacheServiceImp(sharedPreferences: sharedPreferences));
getIt.registerSingleton(AppState());
getIt.registerSingleton(GAnalytics());
getIt.registerLazySingleton<ApiClient>(() => ApiClientImp(loggerService: getIt()));
getIt.registerLazySingleton<ApiClient>(() => ApiClientImp(loggerService: getIt(), dialogService: getIt(), appState: getIt()));
// Repositories
getIt.registerLazySingleton<CommonRepo>(() => CommonRepoImp(loggerService: getIt()));
getIt.registerLazySingleton<AuthenticationRepo>(() => AuthenticationRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<BookAppointmentsRepo>(() => BookAppointmentsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<BookAppointmentsRepo>(
() => BookAppointmentsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<MyAppointmentsRepo>(() => MyAppointmentsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
// ViewModels
// Global/shared VMs LazySingleton
getIt.registerLazySingleton<AuthenticationViewModel>(
() => AuthenticationViewModel(
authenticationRepo: getIt(),
dialogService: getIt(),
appState: getIt(),
errorHandlerService: getIt(),
),
);
// Screen-specific VMs Factory
// getIt.registerFactory<BookAppointmentsViewModel>(
// () => BookAppointmentsViewModel(
// bookAppointmentsRepo: getIt(),
// dialogService: getIt(),
// errorHandlerService: getIt(),
// ),
// );
}
}

@ -5,7 +5,7 @@
// unverified,
// }
enum AuthMethodTypes {
enum AuthMethodTypesEnum {
sms,
whatsApp,
fingerPrint,
@ -13,7 +13,7 @@ enum AuthMethodTypes {
moreOptions,
}
enum ViewState {
enum ViewStateEnum {
hide,
idle,
busy,
@ -22,20 +22,44 @@ enum ViewState {
errorLocal,
}
enum LoginType {
enum LoginTypeEnum {
fromLogin,
silentLogin,
silentWithOTP,
}
enum OTPType { sms, whatsapp }
enum OTPTypeEnum { sms, whatsapp }
enum Country { saudiArabia, unitedArabEmirates }
enum CountryEnum { saudiArabia, unitedArabEmirates }
enum SelectionType { dropdown, calendar }
enum SelectionTypeEnum { dropdown, calendar }
enum GenderType { male, female }
enum GenderTypeEnum { male, female }
enum MaritalStatusType { single, married, divorced, widowed }
enum MaritalStatusTypeEnum { single, married, divorced, widowed }
enum ChipType { success, error, alert, info, warning }
enum ChipTypeEnum { success, error, alert, info, warning }
extension OTPTypeEnumExtension on OTPTypeEnum {
/// Convert enum to int
int toInt() {
switch (this) {
case OTPTypeEnum.sms:
return 1;
case OTPTypeEnum.whatsapp:
return 2;
}
}
/// Convert int to enum
static OTPTypeEnum fromInt(int value) {
switch (value) {
case 1:
return OTPTypeEnum.sms;
case 2:
return OTPTypeEnum.whatsapp;
default:
throw Exception("Invalid OTPTypeEnum value: $value");
}
}
}

@ -1,8 +1,8 @@
import 'package:equatable/equatable.dart';
abstract class Failure extends Equatable implements Exception {
final String message;
const Failure(this.message);
}
@ -13,6 +13,13 @@ class ServerFailure extends Failure {
List<Object?> get props => [message];
}
class StatusCodeFailure extends Failure {
const StatusCodeFailure(super.message);
@override
List<Object?> get props => [message];
}
class ConnectivityFailure extends Failure {
const ConnectivityFailure(super.message);
@ -27,16 +34,33 @@ class LocalStorageFailure extends Failure {
List<Object?> get props => [message];
}
class DataParsingFailure extends Failure {
const DataParsingFailure(super.message);
@override
List<Object?> get props => [message];
}
class UnknownFailure extends Failure {
const UnknownFailure(super.message);
@override
List<Object?> get props => [message];
}
class DuplicateUsername extends Failure {
const DuplicateUsername({String? message}) : super(message ?? '');
const DuplicateUsername(String? message) : super(message ?? '');
@override
List<Object?> get props => [message];
}
class InvalidCredentials extends Failure {
const InvalidCredentials({String? message}) : super(message ?? '');
const InvalidCredentials(String? message) : super(message ?? '');
@override
List<Object?> get props => [message];
}

@ -1,41 +1,40 @@
import 'dart:io';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/consts.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
// import 'package:huawei_location/huawei_location.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class LocationUtils {
NavigationService navigationService;
AppState appState;
bool isShowConfirmDialog;
bool isShowLocationTimeoutDialog;
BuildContext context;
bool isHuawei;
final GeolocatorPlatform _geolocatorPlatform = GeolocatorPlatform.instance;
LocationUtils({required this.isShowConfirmDialog, required this.context, this.isHuawei = false, this.isShowLocationTimeoutDialog = true});
LocationUtils({
required this.isShowConfirmDialog,
required this.navigationService,
required this.appState,
this.isHuawei = false,
this.isShowLocationTimeoutDialog = true,
});
void getCurrentLocation({Function(LatLng)? callBack}) async {
Geolocator.isLocationServiceEnabled().then((value) async {
if (value) {
await Geolocator.checkPermission().then((permission) async {
if (permission == LocationPermission.always || permission == LocationPermission.whileInUse) {
// Geolocator.getCurrentPosition(locationSettings: LocationSettings(accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 5))).then((value) {
Geolocator.getLastKnownPosition().then((value) {
setLocation(value);
if (callBack != null) callBack(LatLng(value?.latitude ?? 24.7101433, value?.longitude ?? 46.6757709));
}).catchError((err) {
print(err);
if (isShowConfirmDialog && isShowLocationTimeoutDialog) {
// showLocationTimeOutDialog(failureCallBack: () {
// Geolocator.openAppSettings();
// });
}
if (isShowConfirmDialog && isShowLocationTimeoutDialog) {}
});
}
@ -62,15 +61,11 @@ class LocationUtils {
}
}
}
}).catchError((err) {
print(err);
});
}).catchError((err) {});
} else {
if (isShowConfirmDialog) showErrorLocationDialog(false, failureCallBack: () {});
}
}).catchError((err) {
print(err);
});
}).catchError((err) {});
}
Future<bool> checkIfGPSIsEnabled() async {
@ -151,8 +146,8 @@ class LocationUtils {
Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, position?.latitude ?? 0.0);
Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, position?.longitude ?? 0.0);
AppState().setUserLat = position?.latitude ?? 0.0;
AppState().setUserLong = position?.longitude ?? 0.0;
appState.setUserLat = position?.latitude ?? 0.0;
appState.setUserLong = position?.longitude ?? 0.0;
// projectViewModel.setLatitudeLongitude(position?.latitude ?? 0.0, position?.longitude ?? 0.0);
}
@ -161,8 +156,8 @@ class LocationUtils {
Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, 0.0);
Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, 0.0);
AppState().setUserLat = 0.0;
AppState().setUserLong = 0.0;
appState.setUserLat = 0.0;
appState.setUserLong = 0.0;
}
Future<bool> requestPermissions() async {

@ -3,19 +3,17 @@ import 'dart:developer';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir;
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
// import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:hmg_patient_app_new/core/utils/LocalNotification.dart';
import 'package:hmg_patient_app_new/core/utils/local_notifications.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart';
import '../consts.dart';
@ -365,7 +363,9 @@ class PushNotificationHandler {
Future<void> requestPermissions() async {
try {
if (Platform.isIOS) {
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(alert: true, badge: true, sound: true);
} else if (Platform.isAndroid) {
Map<Permission, PermissionStatus> statuses = await [
Permission.notification,

@ -0,0 +1,91 @@
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/send_activation_request_model.dart';
class RequestUtils {
static dynamic getCommonRequestWelcome({
required String phoneNumber,
required OTPTypeEnum otpTypeEnum,
required String? deviceToken,
required bool patientOutSA,
required String? loginTokenID,
required var registeredData,
required int? patientId,
required String nationIdText,
required String countryCode,
}) {
bool fileNo = false;
if (nationIdText.isNotEmpty) {
fileNo = nationIdText.length < 10;
}
var request = SendActivationRequest();
request.patientMobileNumber = int.parse(phoneNumber);
request.mobileNo = '0$phoneNumber';
request.deviceToken = deviceToken;
request.projectOutSA = patientOutSA;
request.loginType = otpTypeEnum.toInt();
request.oTPSendType = otpTypeEnum.toInt(); // could map OTPTypeEnum if needed
request.zipCode = countryCode; // or countryCode if defined elsewhere
request.logInTokenID = loginTokenID ?? "";
if (registeredData != null) {
request.searchType = registeredData.searchType ?? 1;
request.patientID = registeredData.patientID ?? 0;
request.patientIdentificationID = request.nationalID = registeredData.patientIdentificationID ?? '0';
request.dob = registeredData.dob;
request.isRegister = registeredData.isRegister;
} else {
if (fileNo) {
request.patientID = patientId ?? int.parse(nationIdText);
request.patientIdentificationID = request.nationalID = "";
request.searchType = 2;
} else {
request.patientID = 0;
request.searchType = 1;
request.patientIdentificationID = request.nationalID = nationIdText.isNotEmpty ? nationIdText : '0';
}
request.isRegister = false;
}
request.deviceTypeID = request.searchType;
return request;
}
static getCommonRequestAuthProvider({
required OTPTypeEnum otpTypeEnum,
required registeredData,
required deviceToken,
required mobileNumber,
required zipCode,
required patientOutSA,
required loginTokenID,
required selectedOption,
required int? patientId,
}) {
var request = SendActivationRequest();
request.patientMobileNumber = mobileNumber;
request.mobileNo = '0$mobileNumber';
request.deviceToken = deviceToken;
request.projectOutSA = patientOutSA == true ? true : false;
request.loginType = selectedOption;
request.oTPSendType = otpTypeEnum.toInt(); //this.selectedOption == 1 ? 1 : 2;
request.zipCode = zipCode;
request.logInTokenID = loginTokenID ?? "";
if (registeredData != null) {
request.searchType = registeredData.searchType ?? 1;
request.patientID = registeredData.patientID ?? 0;
request.patientIdentificationID = request.nationalID = registeredData.patientIdentificationID ?? '0';
request.dob = registeredData.dob;
request.isRegister = registeredData.isRegister;
} else {
request.searchType = request.searchType ?? 2;
request.patientID = patientId ?? 0;
request.nationalID = request.nationalID ?? '0';
request.patientIdentificationID = request.patientIdentificationID ?? '0';
request.isRegister = false;
}
request.deviceTypeID = request.searchType;
return request;
}
}

@ -1,24 +1,29 @@
import 'dart:convert';
import 'package:crypto/crypto.dart' as crypto;
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:crypto/crypto.dart' as crypto;
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_api_availability/google_api_availability.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/main.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/dialogs/confirm_dialog.dart';
import 'package:hmg_patient_app_new/widgets/loading_dialog.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:lottie/lottie.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Utils {
static AppState appState = getIt.get<AppState>();
static NavigationService navigationService = getIt.get<NavigationService>();
static bool _isLoadingVisible = false;
static bool get isLoading => _isLoadingVisible;
@ -47,14 +52,16 @@ class Utils {
}
static String getFreeSlotsTimeText(String startTime, {bool isAddHours = false}) {
// return DateFormat('hh:mm a', AppState().isArabic() ? "ar_SA" : "en_US").format(DateTime.tryParse(startTime)!.add(
// return DateFormat('hh:mm a', appState.isArabic() ? "ar_SA" : "en_US").format(DateTime.tryParse(startTime)!.add(
// Duration(
// hours: isAddHours ? 3 : 0,
// ),
// ));
return !isAddHours
? DateFormat('hh:mm a', AppState().isArabic() ? "ar_SA" : "en_US").format(DateTime.tryParse(startTime.contains("T") ? startTime : convertStringToDateTime(startTime))!.toLocal())
: DateFormat('hh:mm a', AppState().isArabic() ? "ar_SA" : "en_US").format(DateTime.tryParse(startTime.contains("T") ? startTime : convertStringToDateTime(startTime))!.add(
? DateFormat('hh:mm a', appState.isArabic() ? "ar_SA" : "en_US")
.format(DateTime.tryParse(startTime.contains("T") ? startTime : convertStringToDateTime(startTime))!.toLocal())
: DateFormat('hh:mm a', appState.isArabic() ? "ar_SA" : "en_US")
.format(DateTime.tryParse(startTime.contains("T") ? startTime : convertStringToDateTime(startTime))!.add(
Duration(
hours: isAddHours ? 3 : 0,
),
@ -82,12 +89,9 @@ class Utils {
}
static String getMonthDayYearDateFormatted(DateTime dateTime) {
if (dateTime != null)
return AppState().isArabic()
? getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString()
: getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString();
else
return "";
return appState.isArabic()
? getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString()
: getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString();
}
/// get month by
@ -200,7 +204,7 @@ class Utils {
static void showLoadingDialog() {
_isLoadingVisible = true;
showDialog(
context: navigatorKey.currentContext!,
context: navigationService.navigatorKey.currentContext!,
barrierColor: Colors.black.withOpacity(0.5),
builder: (BuildContext context) => LoadingDialog(),
)
@ -217,7 +221,7 @@ class Utils {
try {
if (_isLoadingVisible) {
_isLoadingVisible = false;
Navigator.of(navigatorKey.currentContext!).pop();
Navigator.of(navigationService.navigatorKey.currentContext!).pop();
}
_isLoadingVisible = false;
} catch (e) {}
@ -242,9 +246,6 @@ class Utils {
static bool isSAUDIIDValid(String id, type) {
if (type == 1) {
if (id == null) {
return false;
}
try {
id = id.toString();
id = id.trim();
@ -304,13 +305,15 @@ class Utils {
}
static String removeHtmlTags(String htmlString) {
if (htmlString == null || htmlString.isEmpty) {
if (htmlString.isEmpty) {
return '';
}
// Replace HTML line breaks with newlines
var withLineBreaks =
htmlString.replaceAll(RegExp(r'<br\s*\/?>', multiLine: true), '\n').replaceAll(RegExp(r'<\/p>', multiLine: true), '\n').replaceAll(RegExp(r'<divider>', multiLine: true), '\n');
var withLineBreaks = htmlString
.replaceAll(RegExp(r'<br\s*\/?>', multiLine: true), '\n')
.replaceAll(RegExp(r'<\/p>', multiLine: true), '\n')
.replaceAll(RegExp(r'<divider>', multiLine: true), '\n');
// Remove all other HTML tags
var withoutTags = withLineBreaks.replaceAll(RegExp(r'<[^>]*>'), '');
@ -376,7 +379,20 @@ class Utils {
final year = parts[0];
// Map month number to short month name (Hijri months)
const hijriMonthNames = ['Muharram', 'Safar', 'Rabi I', 'Rabi II', 'Jumada I', 'Jumada II', 'Rajab', 'Sha\'ban', 'Ramadan', 'Shawwal', 'Dhu al-Qi\'dah', 'Dhu al-Hijjah'];
const hijriMonthNames = [
'Muharram',
'Safar',
'Rabi I',
'Rabi II',
'Jumada I',
'Jumada II',
'Rajab',
'Sha\'ban',
'Ramadan',
'Shawwal',
'Dhu al-Qi\'dah',
'Dhu al-Hijjah'
];
final monthIndex = int.tryParse(parts[1]) ?? 1;
final month = hijriMonthNames[monthIndex - 1];
@ -458,13 +474,21 @@ class Utils {
);
}
static Widget getPaymentMethods() {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(AppAssets.mada, width: 25, height: 25),
Image.asset(AppAssets.tamara_en, width: 25, height: 25),
Image.asset(AppAssets.visa, width: 25, height: 25),
Image.asset(AppAssets.Mastercard, width: 25, height: 25),
Image.asset(AppAssets.apple_pay, width: 25, height: 25),
],
);
}
static Future<bool> isGoogleServicesAvailable() async {
GooglePlayServicesAvailability availability = await GoogleApiAvailability
.instance
.checkGooglePlayServicesAvailability();
GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability();
String status = availability.toString().split('.').last;
if (status == "success") {
return true;
@ -472,26 +496,17 @@ class Utils {
return false;
}
static Future<bool> checkConnection(
{bool bypassConnectionCheck = false}) async {
static Future<bool> checkConnection({bool bypassConnectionCheck = false}) async {
if (bypassConnectionCheck) return true;
List<ConnectivityResult> connectivityResult =
await (Connectivity().checkConnectivity());
if (connectivityResult.contains(ConnectivityResult.mobile) ||
connectivityResult.contains(ConnectivityResult.wifi)) {
List<ConnectivityResult> connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult.contains(ConnectivityResult.mobile) || connectivityResult.contains(ConnectivityResult.wifi)) {
return true;
} else {
return false;
}
}
static String generateMd5Hash(String input) {
return crypto.md5.convert(utf8.encode(input)).toString();
}
}

@ -193,33 +193,33 @@ Widget widthSpacer5per() => SizedBox(height: 5.w);
extension ChipTypeExtension on ChipType {
extension ChipTypeEnumExtension on ChipTypeEnum {
Color get color {
switch (this) {
case ChipType.success:
case ChipTypeEnum.success:
return AppColors.successColor; // Replace with your actual color
case ChipType.error:
case ChipTypeEnum.error:
return AppColors.errorColor; // Replace with your actual color
case ChipType.alert:
case ChipTypeEnum.alert:
return AppColors.alertColor; // Replace with your actual color
case ChipType.info:
case ChipTypeEnum.info:
return AppColors.infoColor; // Replace with your actual color
case ChipType.warning:
case ChipTypeEnum.warning:
return AppColors.warningColor; // Replace with your actual color
}
}
Color get backgroundColor {
switch (this) {
case ChipType.success:
case ChipTypeEnum.success:
return AppColors.successLightColor; // Replace with your actual color
case ChipType.error:
case ChipTypeEnum.error:
return AppColors.errorLightColor; // Replace with your actual color
case ChipType.alert:
case ChipTypeEnum.alert:
return AppColors.alertLightColor; // Replace with your actual color
case ChipType.info:
case ChipTypeEnum.info:
return AppColors.infoLightColor; // Replace with your actual color
case ChipType.warning:
case ChipTypeEnum.warning:
return AppColors.warningLightColor; // Replace with your actual color
}
}

@ -1,16 +1,27 @@
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:dartz/dartz.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_exception.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/authentication/models/select_device_by_imei.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/check_patient_authentication_request_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_activation_code_resp_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class AuthenticationRepo {
Future<Either<Failure, SelectDeviceByImeiRespModelElement?>> selectDeviceByImei({required String firebaseToken});
Future<Either<Failure, GenericApiModel<SelectDeviceByImeiRespModelElement>>> selectDeviceByImei({
required String firebaseToken,
});
Future<Either<Failure, GenericApiModel<dynamic>>> checkPatientAuthentication({
required CheckPatientAuthenticationReq checkPatientAuthenticationReq,
});
Future<Either<Failure, GenericApiModel<dynamic>>> sendActivationCodeRegister(
{required CheckPatientAuthenticationReq checkPatientAuthenticationReq, String? languageID});
}
class AuthenticationRepoImp implements AuthenticationRepo {
@ -20,38 +31,130 @@ class AuthenticationRepoImp implements AuthenticationRepo {
AuthenticationRepoImp({required this.loggerService, required this.apiClient});
@override
Future<Either<Failure, SelectDeviceByImeiRespModelElement?>> selectDeviceByImei({
required String firebaseToken,
}) async {
Future<Either<Failure, GenericApiModel<SelectDeviceByImeiRespModelElement>>> selectDeviceByImei({required String firebaseToken}) async {
final mapDevice = {"IMEI": firebaseToken};
try {
GenericApiModel<SelectDeviceByImeiRespModelElement>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.selectDeviceImei,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus}) {
try {
final list = response['Patient_SELECTDeviceIMEIbyIMEIList'];
if (list == null || list.isEmpty) {
throw Exception("Device list is empty");
}
final completer = Completer<Either<Failure, SelectDeviceByImeiRespModelElement?>>();
await apiClient.post(
ApiConsts.selectDeviceImei,
body: mapDevice,
onSuccess: (response, statusCode) {
try {
final SelectDeviceByImeiRespModelElement model =
SelectDeviceByImeiRespModelElement.fromJson(response['Patient_SELECTDeviceIMEIbyIMEIList'][0]);
completer.complete(Right(model));
} catch (e) {
completer.complete(Left(ServerFailure(e.toString())));
}
},
onFailure: (error, statusCode) {
loggerService.logInfo(("$error - $statusCode").toString());
completer.complete(Left(ServerFailure(error)));
},
);
return await completer.future;
} on APIException catch (e) {
loggerService.errorLogs(e.toString());
return Left(ServerFailure(e.message));
final model = SelectDeviceByImeiRespModelElement.fromJson(list[0] as Map<String, dynamic>);
apiResponse = GenericApiModel<SelectDeviceByImeiRespModelElement>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: model,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<dynamic>>> checkPatientAuthentication({
required CheckPatientAuthenticationReq checkPatientAuthenticationReq,
String? languageID,
}) async {
int isOutKsa = (checkPatientAuthenticationReq.zipCode == '966' || checkPatientAuthenticationReq.zipCode == '+966') ? 0 : 1;
//TODO : We will use all these from AppState directly in the ApiClient
checkPatientAuthenticationReq.versionID = VERSION_ID;
checkPatientAuthenticationReq.channel = CHANNEL;
checkPatientAuthenticationReq.iPAdress = IP_ADDRESS;
checkPatientAuthenticationReq.generalid = GENERAL_ID;
checkPatientAuthenticationReq.languageID = (languageID == 'ar' ? 1 : 2);
checkPatientAuthenticationReq.patientOutSA = isOutKsa;
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.selectDeviceImei,
body: checkPatientAuthenticationReq.toJson(),
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: response,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<dynamic>>> sendActivationCodeRegister(
{required CheckPatientAuthenticationReq checkPatientAuthenticationReq, String? languageID}) async {
int isOutKsa = (checkPatientAuthenticationReq.zipCode == '966' || checkPatientAuthenticationReq.zipCode == '+966') ? 0 : 1;
//TODO : We will use all these from AppState directly in the ApiClient
checkPatientAuthenticationReq.versionID = VERSION_ID;
checkPatientAuthenticationReq.channel = CHANNEL;
checkPatientAuthenticationReq.iPAdress = IP_ADDRESS;
checkPatientAuthenticationReq.generalid = GENERAL_ID;
checkPatientAuthenticationReq.languageID = (languageID == 'ar' ? 1 : 2);
checkPatientAuthenticationReq.deviceTypeID = Platform.isIOS ? 1 : 2;
checkPatientAuthenticationReq.patientOutSA = isOutKsa;
checkPatientAuthenticationReq.isDentalAllowedBackend = false;
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(
SEND_ACTIVATION_CODE_REGISTER,
body: checkPatientAuthenticationReq.toJson(),
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: CheckActivationCode.fromJson(response),
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
loggerService.errorLogs(e.toString());
return Left(ServerFailure(e.toString()));
return Left(UnknownFailure(e.toString()));
}
}
}

@ -1,47 +1,135 @@
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/request_utils.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_repo.dart';
import 'package:hmg_patient_app_new/features/authentication/models/check_activation_code_request_register.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/check_patient_authentication_request_model.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
class AuthenticationViewModel extends ChangeNotifier {
AuthenticationRepo authenticationRepo;
AppState appState;
ErrorHandlerService errorHandlerService;
DialogService dialogService;
AuthenticationViewModel({
required this.appState,
required this.authenticationRepo,
required this.errorHandlerService,
required this.dialogService,
});
final TextEditingController nationalIdController = TextEditingController();
final TextEditingController phoneNumberController = TextEditingController();
Future<void> selectDeviceImei({
Function(dynamic)? onSuccess,
Function(String)? onError
}) async {
final String firebaseToken =
"cIkkB7h7Q7uoFkC4Qv82xG:APA91bEb53Z9XzqymCIctaLxCoMX6bm9fuKlWILQ59uUqfwhCoD42AOP1-jWGB1WYd9BVN5PT2pUUFxrT07vcNg1KH9OH39mrPgCl0m21XVIgWrzNnCkufg";
final resultEither =
await authenticationRepo.selectDeviceByImei(firebaseToken: firebaseToken);
Future<void> selectDeviceImei({Function(dynamic)? onSuccess, Function(String)? onError}) async {
String firebaseToken =
"dOGRRszQQMGe_9wA5Hx3kO:APA91bFV5IcIJXvcCXXk0tc2ddtZgWwCPq7sGSuPr-YW7iiJpQZKgFGN9GAzCVOWL8MfheaP1slE8MdxB7lczdPBGdONQ7WbMmhgHcsUCUktq-hsapGXXqc";
final result = await authenticationRepo.selectDeviceByImei(firebaseToken: firebaseToken);
resultEither.fold(
(failure) {
notifyListeners();
if (onError != null) onError(failure.message);
},
(data) {
log("resultEither: ${data.toString()} ");
notifyListeners();
if (onSuccess != null) onSuccess(data);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
//todo: move to next api call
}
},
);
}
// Future<void> checkUserAuthentication({Function(dynamic)? onSuccess, Function(String)? onError}) async {
// CheckPatientAuthenticationReq checkPatientAuthenticationReq = RequestUtils.getCommonRequestWelcome(
// phoneNumber: '0567184134',
// otpTypeEnum: OTPTypeEnum.sms,
// deviceToken: 'dummyDeviceToken123',
// patientOutSA: true,
// loginTokenID: 'dummyLoginToken456',
// registeredData: null,
// patientId: 12345,
// nationIdText: '1234567890',
// countryCode: 'SA',
// );
//
// final result = await authenticationRepo.checkPatientAuthentication(checkPatientAuthenticationReq: checkPatientAuthenticationReq);
// result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),
// (apiResponse) {
// if (apiResponse.data['isSMSSent']) {
// // TODO: set this in AppState
// // sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']);
// // loginTokenID = value['LogInTokenID'],
// // sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request),
// sendActivationCode(type);
// } else {
// if (apiResponse.data['IsAuthenticated']) {
// checkActivationCode(onWrongActivationCode: (String? message) {});
// }
// }
// },
// );
// }
// Future<void> sendActivationCode({required OTPTypeEnum otpTypeEnum}) async {
// var request = RequestUtils.getCommonRequestAuthProvider(
// otpTypeEnum: otpTypeEnum,
// registeredData: null,
// deviceToken: "dummyLoginToken456",
// mobileNumber: "0567184134",
// zipCode: "SA",
// patientOutSA: true,
// loginTokenID: "dummyLoginToken456",
// selectedOption: selectedOption,
// patientId: 12345,
// );
//
// request.sMSSignature = await SMSOTP.getSignature();
// selectedOption = type;
// // GifLoaderDialogUtils.showMyDialog(context);
// if (healthId != null || isDubai) {
// if (!isDubai) {
// request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob));
// }
// request.healthId = healthId;
// request.isHijri = isHijri;
// await this.apiClient.sendActivationCodeRegister(request).then((result) {
// // GifLoaderDialogUtils.hideDialog(context);
// if (result != null && result['isSMSSent'] == true) {
// this.startSMSService(type);
// }
// }).catchError((r) {
// GifLoaderDialogUtils.hideDialog(context);
// context.showBottomSheet(
// child: ExceptionBottomSheet(
// message: r.toString(),
// onOkPressed: () {
// Navigator.of(context).pop();
// },
// ));
// // AppToast.showErrorToast(message: r);
// });
// } else {
// request.dob = "";
// request.healthId = "";
// request.isHijri = 0;
// await this.authService.sendActivationCode(request).then((result) {
// GifLoaderDialogUtils.hideDialog(context);
// if (result != null && result['isSMSSent'] == true) {
// this.startSMSService(type);
// }
// }).catchError((r) {
// GifLoaderDialogUtils.hideDialog(context);
// context.showBottomSheet(
// child: ExceptionBottomSheet(
// message: r.toString(),
// onOkPressed: () {
// Navigator.of(context).pop();
// },
// ));
// // AppToast.showErrorToast(message: r.toString());
// });
// }
// }
}

@ -1,121 +0,0 @@
class CheckActivationCodeRegisterReq {
int? patientMobileNumber;
String? mobileNo;
String? deviceToken;
bool? projectOutSA;
int? loginType;
String? zipCode;
bool? isRegister;
String? logInTokenID;
int? searchType;
int? patientID;
String? nationalID;
String? patientIdentificationID;
String? activationCode;
bool? isSilentLogin;
double? versionID;
int? channel;
int? languageID;
String? iPAdress;
String? generalid;
int? patientOutSA;
dynamic sessionID;
bool? isDentalAllowedBackend;
int? deviceTypeID;
bool? forRegisteration;
String? dob;
int? isHijri;
String? healthId;
CheckActivationCodeRegisterReq({
this.patientMobileNumber,
this.mobileNo,
this.deviceToken,
this.projectOutSA,
this.loginType,
this.zipCode,
this.isRegister,
this.logInTokenID,
this.searchType,
this.patientID,
this.nationalID,
this.patientIdentificationID,
this.activationCode,
this.isSilentLogin,
this.versionID,
this.channel,
this.languageID,
this.iPAdress,
this.generalid,
this.patientOutSA,
this.sessionID,
this.isDentalAllowedBackend,
this.deviceTypeID,
this.forRegisteration,
this.dob,
this.isHijri,
this.healthId,
});
CheckActivationCodeRegisterReq.fromJson(Map<String, dynamic> json) {
patientMobileNumber = json['PatientMobileNumber'];
mobileNo = json['MobileNo'];
deviceToken = json['DeviceToken'];
projectOutSA = json['ProjectOutSA'];
loginType = json['LoginType'];
zipCode = json['ZipCode'];
isRegister = json['isRegister'];
logInTokenID = json['LogInTokenID'];
searchType = json['SearchType'];
patientID = json['PatientID'];
nationalID = json['NationalID'];
patientIdentificationID = json['PatientIdentificationID'];
activationCode = json['activationCode'];
isSilentLogin = json['IsSilentLogin'];
versionID = json['VersionID'];
channel = json['Channel'];
languageID = json['LanguageID'];
iPAdress = json['IPAdress'];
generalid = json['generalid'];
patientOutSA = json['PatientOutSA'];
sessionID = json['SessionID'];
isDentalAllowedBackend = json['isDentalAllowedBackend'];
deviceTypeID = json['DeviceTypeID'];
forRegisteration = json['ForRegisteration'];
dob = json['DOB'];
isHijri = json['IsHijri'];
healthId = json['HealthId'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['PatientMobileNumber'] = this.patientMobileNumber;
data['MobileNo'] = this.mobileNo;
data['DeviceToken'] = this.deviceToken;
data['ProjectOutSA'] = this.projectOutSA;
data['LoginType'] = this.loginType;
data['ZipCode'] = this.zipCode;
data['isRegister'] = this.isRegister;
data['LogInTokenID'] = this.logInTokenID;
data['SearchType'] = this.searchType;
data['PatientID'] = this.patientID;
data['NationalID'] = this.nationalID;
data['PatientIdentificationID'] = this.patientIdentificationID;
data['activationCode'] = this.activationCode;
data['IsSilentLogin'] = this.isSilentLogin;
data['VersionID'] = this.versionID;
data['Channel'] = this.channel;
data['LanguageID'] = this.languageID;
data['IPAdress'] = this.iPAdress;
data['generalid'] = this.generalid;
data['PatientOutSA'] = this.patientOutSA;
data['SessionID'] = this.sessionID;
data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
data['DeviceTypeID'] = this.deviceTypeID;
data['ForRegisteration'] = this.forRegisteration;
data['DOB'] = dob;
data['IsHijri'] = isHijri;
data['HealthId'] = healthId;
return data;
}
}

@ -0,0 +1,121 @@
// class CheckActivationCodeRegisterReq {
// int? patientMobileNumber;
// String? mobileNo;
// String? deviceToken;
// bool? projectOutSA;
// int? loginType;
// String? zipCode;
// bool? isRegister;
// String? logInTokenID;
// int? searchType;
// int? patientID;
// String? nationalID;
// String? patientIdentificationID;
// String? activationCode;
// bool? isSilentLogin;
// double? versionID;
// int? channel;
// int? languageID;
// String? iPAdress;
// String? generalid;
// int? patientOutSA;
// dynamic sessionID;
// bool? isDentalAllowedBackend;
// int? deviceTypeID;
// bool? forRegisteration;
// String? dob;
// int? isHijri;
// String? healthId;
//
// CheckActivationCodeRegisterReq({
// this.patientMobileNumber,
// this.mobileNo,
// this.deviceToken,
// this.projectOutSA,
// this.loginType,
// this.zipCode,
// this.isRegister,
// this.logInTokenID,
// this.searchType,
// this.patientID,
// this.nationalID,
// this.patientIdentificationID,
// this.activationCode,
// this.isSilentLogin,
// this.versionID,
// this.channel,
// this.languageID,
// this.iPAdress,
// this.generalid,
// this.patientOutSA,
// this.sessionID,
// this.isDentalAllowedBackend,
// this.deviceTypeID,
// this.forRegisteration,
// this.dob,
// this.isHijri,
// this.healthId,
// });
//
// CheckActivationCodeRegisterReq.fromJson(Map<String, dynamic> json) {
// patientMobileNumber = json['PatientMobileNumber'];
// mobileNo = json['MobileNo'];
// deviceToken = json['DeviceToken'];
// projectOutSA = json['ProjectOutSA'];
// loginType = json['LoginType'];
// zipCode = json['ZipCode'];
// isRegister = json['isRegister'];
// logInTokenID = json['LogInTokenID'];
// searchType = json['SearchType'];
// patientID = json['PatientID'];
// nationalID = json['NationalID'];
// patientIdentificationID = json['PatientIdentificationID'];
// activationCode = json['activationCode'];
// isSilentLogin = json['IsSilentLogin'];
// versionID = json['VersionID'];
// channel = json['Channel'];
// languageID = json['LanguageID'];
// iPAdress = json['IPAdress'];
// generalid = json['generalid'];
// patientOutSA = json['PatientOutSA'];
// sessionID = json['SessionID'];
// isDentalAllowedBackend = json['isDentalAllowedBackend'];
// deviceTypeID = json['DeviceTypeID'];
// forRegisteration = json['ForRegisteration'];
// dob = json['DOB'];
// isHijri = json['IsHijri'];
// healthId = json['HealthId'];
// }
//
// Map<String, dynamic> toJson() {
// final Map<String, dynamic> data = new Map<String, dynamic>();
// data['PatientMobileNumber'] = this.patientMobileNumber;
// data['MobileNo'] = this.mobileNo;
// data['DeviceToken'] = this.deviceToken;
// data['ProjectOutSA'] = this.projectOutSA;
// data['LoginType'] = this.loginType;
// data['ZipCode'] = this.zipCode;
// data['isRegister'] = this.isRegister;
// data['LogInTokenID'] = this.logInTokenID;
// data['SearchType'] = this.searchType;
// data['PatientID'] = this.patientID;
// data['NationalID'] = this.nationalID;
// data['PatientIdentificationID'] = this.patientIdentificationID;
// data['activationCode'] = this.activationCode;
// data['IsSilentLogin'] = this.isSilentLogin;
// data['VersionID'] = this.versionID;
// data['Channel'] = this.channel;
// data['LanguageID'] = this.languageID;
// data['IPAdress'] = this.iPAdress;
// data['generalid'] = this.generalid;
// data['PatientOutSA'] = this.patientOutSA;
// data['SessionID'] = this.sessionID;
// data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
// data['DeviceTypeID'] = this.deviceTypeID;
// data['ForRegisteration'] = this.forRegisteration;
// data['DOB'] = dob;
// data['IsHijri'] = isHijri;
// data['HealthId'] = healthId;
// return data;
// }
// }

@ -0,0 +1,88 @@
class CheckPatientAuthenticationReq {
int? patientMobileNumber;
String? zipCode;
bool? isRegister;
String? tokenID;
int? searchType;
String? patientIdentificationID;
int? patientID;
double? versionID;
int? channel;
int? languageID;
String? iPAdress;
String? generalid;
int? patientOutSA;
dynamic sessionID;
bool? isDentalAllowedBackend;
int? deviceTypeID;
String? dob;
int? isHijri;
String? healthId;
CheckPatientAuthenticationReq(
{this.patientMobileNumber,
this.zipCode,
this.isRegister,
this.tokenID,
this.searchType,
this.patientIdentificationID,
this.patientID,
this.versionID,
this.channel,
this.languageID,
this.iPAdress,
this.generalid,
this.patientOutSA,
this.sessionID,
this.isDentalAllowedBackend,
this.deviceTypeID,
this.dob,
this.isHijri,
this.healthId});
CheckPatientAuthenticationReq.fromJson(Map<String, dynamic> json) {
patientMobileNumber = json['PatientMobileNumber'];
zipCode = json['ZipCode'];
isRegister = json['isRegister'];
tokenID = json['TokenID'];
searchType = json['SearchType'];
patientIdentificationID = json['PatientIdentificationID'];
patientID = json['PatientID'];
versionID = json['VersionID'];
channel = json['Channel'];
languageID = json['LanguageID'];
iPAdress = json['IPAdress'];
generalid = json['generalid'];
patientOutSA = json['PatientOutSA'];
sessionID = json['SessionID'];
isDentalAllowedBackend = json['isDentalAllowedBackend'];
deviceTypeID = json['DeviceTypeID'];
dob = json['dob'];
isHijri = json['isHijri'];
healthId = json['HealthId'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['PatientMobileNumber'] = patientMobileNumber;
data['ZipCode'] = zipCode;
data['isRegister'] = isRegister;
data['TokenID'] = tokenID;
data['SearchType'] = searchType;
data['PatientIdentificationID'] = patientIdentificationID;
data['PatientID'] = patientID;
data['VersionID'] = versionID;
data['Channel'] = channel;
data['LanguageID'] = languageID;
data['IPAdress'] = iPAdress;
data['generalid'] = generalid;
data['PatientOutSA'] = patientOutSA;
data['SessionID'] = sessionID;
data['isDentalAllowedBackend'] = isDentalAllowedBackend;
data['DeviceTypeID'] = deviceTypeID;
data['dob'] = dob;
data['isHijri'] = isHijri;
data['HealthId'] = healthId;
return data;
}
}

@ -0,0 +1,132 @@
class SendActivationRequest {
int? patientMobileNumber;
String? mobileNo;
String? deviceToken;
bool? projectOutSA;
int? loginType;
String? zipCode;
bool? isRegister;
String? logInTokenID;
int? searchType;
int? patientID;
String? nationalID;
String? patientIdentificationID;
int? oTPSendType;
int? languageID;
double? versionID;
int? channel;
String? iPAdress;
String? generalid;
int? patientOutSA;
dynamic sessionID;
bool? isDentalAllowedBackend;
int? deviceTypeID;
String? sMSSignature;
String? dob;
int? isHijri;
String? healthId;
int? responseID;
int? status;
int? familyRegionID;
bool? isPatientExcluded;
SendActivationRequest(
{this.patientMobileNumber,
this.mobileNo,
this.deviceToken,
this.projectOutSA,
this.loginType,
this.zipCode,
this.isRegister,
this.logInTokenID,
this.searchType,
this.patientID,
this.nationalID,
this.patientIdentificationID,
this.oTPSendType,
this.languageID,
this.versionID,
this.channel,
this.iPAdress,
this.generalid,
this.patientOutSA,
this.sessionID,
this.isDentalAllowedBackend,
this.deviceTypeID,
this.sMSSignature,
this.dob,
this.isHijri,
this.healthId,
this.responseID,
this.status,
this.familyRegionID,
this.isPatientExcluded
});
SendActivationRequest.fromJson(Map<String, dynamic> json) {
patientMobileNumber = json['PatientMobileNumber'];
mobileNo = json['MobileNo'];
deviceToken = json['DeviceToken'];
projectOutSA = json['ProjectOutSA'];
loginType = json['LoginType'];
zipCode = json['ZipCode'];
isRegister = json['isRegister'];
logInTokenID = json['LogInTokenID'];
searchType = json['SearchType'];
patientID = json['PatientID'];
nationalID = json['NationalID'];
patientIdentificationID = json['PatientIdentificationID'];
oTPSendType = json['OTP_SendType'];
languageID = json['LanguageID'];
versionID = json['VersionID'];
channel = json['Channel'];
iPAdress = json['IPAdress'];
generalid = json['generalid'];
patientOutSA = json['PatientOutSA'];
sessionID = json['SessionID'];
isDentalAllowedBackend = json['isDentalAllowedBackend'];
deviceTypeID = json['DeviceTypeID'];
sMSSignature = json['SMSSignature'];
dob = json['DOB'];
isHijri = json['IsHijri'];
healthId = json['HealthId'];
responseID = json['ReponseID'];
status = json['Status'];
familyRegionID = json['FamilyRegionID'];
isPatientExcluded = json['IsPatientExcluded'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['PatientMobileNumber'] = patientMobileNumber;
data['MobileNo'] = mobileNo;
data['DeviceToken'] = deviceToken;
data['ProjectOutSA'] = projectOutSA;
data['LoginType'] = loginType;
data['ZipCode'] = zipCode;
data['isRegister'] = isRegister;
data['LogInTokenID'] = logInTokenID;
data['SearchType'] = searchType;
data['PatientID'] = patientID;
data['NationalID'] = nationalID;
data['PatientIdentificationID'] = patientIdentificationID;
data['OTP_SendType'] = oTPSendType;
data['LanguageID'] = languageID;
data['VersionID'] = versionID;
data['Channel'] = channel;
data['IPAdress'] = iPAdress;
data['generalid'] = generalid;
data['PatientOutSA'] = patientOutSA;
data['SessionID'] = sessionID;
data['isDentalAllowedBackend'] = isDentalAllowedBackend;
data['DeviceTypeID'] = deviceTypeID;
data['SMSSignature'] = sMSSignature;
data['DOB'] = dob;
data['IsHijri'] = isHijri;
data['HealthId'] = healthId;
data['ResponseID'] = responseID;
data['Status'] = status;
data['FamilyRegionID'] = familyRegionID;
data['IsPatientExcluded'] = isPatientExcluded;
return data;
}
}

@ -0,0 +1,546 @@
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
class CheckActivationCode {
dynamic date;
int? languageID;
int? serviceName;
dynamic time;
dynamic androidLink;
String? authenticationTokenID;
dynamic data;
bool? dataw;
int? dietType;
dynamic errorCode;
dynamic errorEndUserMessage;
dynamic errorEndUserMessageN;
dynamic errorMessage;
int? errorType;
int? foodCategory;
dynamic iOSLink;
bool? isAuthenticated;
int? mealOrderStatus;
int? mealType;
int? messageStatus;
int? numberOfResultRecords;
dynamic patientBlodType;
dynamic successMsg;
dynamic successMsgN;
dynamic doctorInformationList;
dynamic getAllPendingRecordsList;
dynamic getAllSharedRecordsByStatusList;
dynamic getResponseFileList;
bool? isHMGPatient;
bool? isLoginSuccessfully;
bool? isNeedUpdateIdintificationNo;
bool? kioskSendSMS;
AuthenticatedUser? list;
dynamic listAskHabibMobileLoginInfo;
dynamic listAskHabibPatientFile;
dynamic listMergeFiles;
dynamic listMobileLoginInfo;
dynamic listPatientCount;
dynamic logInTokenID;
dynamic mohemmPrivilegeList;
int? pateintID;
String? patientBloodType;
bool? patientHasFile;
dynamic patientMergedIDs;
bool? patientOutSA;
int? patientShareRequestID;
int? patientType;
int? projectIDOut;
dynamic returnMessage;
bool? sMSLoginRequired;
dynamic servicePrivilegeList;
dynamic sharePatientName;
dynamic verificationCode;
dynamic email;
dynamic errorList;
bool? hasFile;
bool? isActiveCode;
bool? isMerged;
bool? isNeedUserAgreement;
bool? isSMSSent;
dynamic memberList;
dynamic message;
int? statusCode;
CheckActivationCode(
{this.date,
this.languageID,
this.serviceName,
this.time,
this.androidLink,
this.authenticationTokenID,
this.data,
this.dataw,
this.dietType,
this.errorCode,
this.errorEndUserMessage,
this.errorEndUserMessageN,
this.errorMessage,
this.errorType,
this.foodCategory,
this.iOSLink,
this.isAuthenticated,
this.mealOrderStatus,
this.mealType,
this.messageStatus,
this.numberOfResultRecords,
this.patientBlodType,
this.successMsg,
this.successMsgN,
this.doctorInformationList,
this.getAllPendingRecordsList,
this.getAllSharedRecordsByStatusList,
this.getResponseFileList,
this.isHMGPatient,
this.isLoginSuccessfully,
this.isNeedUpdateIdintificationNo,
this.kioskSendSMS,
this.list,
this.listAskHabibMobileLoginInfo,
this.listAskHabibPatientFile,
this.listMergeFiles,
this.listMobileLoginInfo,
this.listPatientCount,
this.logInTokenID,
this.mohemmPrivilegeList,
this.pateintID,
this.patientBloodType,
this.patientHasFile,
this.patientMergedIDs,
this.patientOutSA,
this.patientShareRequestID,
this.patientType,
this.projectIDOut,
this.returnMessage,
this.sMSLoginRequired,
this.servicePrivilegeList,
this.sharePatientName,
this.verificationCode,
this.email,
this.errorList,
this.hasFile,
this.isActiveCode,
this.isMerged,
this.isNeedUserAgreement,
this.isSMSSent,
this.memberList,
this.message,
this.statusCode});
CheckActivationCode.fromJson(Map<String, dynamic> json) {
date = json['Date'];
languageID = json['LanguageID'];
serviceName = json['ServiceName'];
time = json['Time'];
androidLink = json['AndroidLink'];
authenticationTokenID = json['AuthenticationTokenID'];
data = json['Data'];
dataw = json['Dataw'];
dietType = json['DietType'];
errorCode = json['ErrorCode'];
errorEndUserMessage = json['ErrorEndUserMessage'];
errorEndUserMessageN = json['ErrorEndUserMessageN'];
errorMessage = json['ErrorMessage'];
errorType = json['ErrorType'];
foodCategory = json['FoodCategory'];
iOSLink = json['IOSLink'];
isAuthenticated = json['IsAuthenticated'];
mealOrderStatus = json['MealOrderStatus'];
mealType = json['MealType'];
messageStatus = json['MessageStatus'];
numberOfResultRecords = json['NumberOfResultRecords'];
patientBlodType = json['PatientBlodType'];
successMsg = json['SuccessMsg'];
successMsgN = json['SuccessMsgN'];
doctorInformationList = json['DoctorInformation_List'];
getAllPendingRecordsList = json['GetAllPendingRecordsList'];
getAllSharedRecordsByStatusList = json['GetAllSharedRecordsByStatusList'];
getResponseFileList = json['GetResponseFileList'];
isHMGPatient = json['IsHMGPatient'];
isLoginSuccessfully = json['IsLoginSuccessfully'];
isNeedUpdateIdintificationNo = json['IsNeedUpdateIdintificationNo'];
kioskSendSMS = json['KioskSendSMS'];
if (json['List'] != null) {
list = AuthenticatedUser.fromJson(json['List'][0]);
}
listAskHabibMobileLoginInfo = json['List_AskHabibMobileLoginInfo'];
listAskHabibPatientFile = json['List_AskHabibPatientFile'];
listMergeFiles = json['List_MergeFiles'];
listMobileLoginInfo = json['List_MobileLoginInfo'];
listPatientCount = json['List_PatientCount'];
logInTokenID = json['LogInTokenID'];
mohemmPrivilegeList = json['MohemmPrivilege_List'];
pateintID = json['PateintID'];
patientBloodType = json['PatientBloodType'];
patientHasFile = json['PatientHasFile'];
patientMergedIDs = json['PatientMergedIDs'];
patientOutSA = json['PatientOutSA'];
patientShareRequestID = json['PatientShareRequestID'];
patientType = json['PatientType'];
projectIDOut = json['ProjectIDOut'];
returnMessage = json['ReturnMessage'];
sMSLoginRequired = json['SMSLoginRequired'];
servicePrivilegeList = json['ServicePrivilege_List'];
sharePatientName = json['SharePatientName'];
verificationCode = json['VerificationCode'];
email = json['email'];
errorList = json['errorList'];
hasFile = json['hasFile'];
isActiveCode = json['isActiveCode'];
isMerged = json['isMerged'];
isNeedUserAgreement = json['isNeedUserAgreement'];
isSMSSent = json['isSMSSent'];
memberList = json['memberList'];
message = json['message'];
statusCode = json['statusCode'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['Date'] = date;
data['LanguageID'] = languageID;
data['ServiceName'] = serviceName;
data['Time'] = time;
data['AndroidLink'] = androidLink;
data['AuthenticationTokenID'] = authenticationTokenID;
data['Data'] = this.data;
data['Dataw'] = dataw;
data['DietType'] = dietType;
data['ErrorCode'] = errorCode;
data['ErrorEndUserMessage'] = errorEndUserMessage;
data['ErrorEndUserMessageN'] = errorEndUserMessageN;
data['ErrorMessage'] = errorMessage;
data['ErrorType'] = errorType;
data['FoodCategory'] = foodCategory;
data['IOSLink'] = iOSLink;
data['IsAuthenticated'] = isAuthenticated;
data['MealOrderStatus'] = mealOrderStatus;
data['MealType'] = mealType;
data['MessageStatus'] = messageStatus;
data['NumberOfResultRecords'] = numberOfResultRecords;
data['PatientBlodType'] = patientBlodType;
data['SuccessMsg'] = successMsg;
data['SuccessMsgN'] = successMsgN;
data['DoctorInformation_List'] = doctorInformationList;
data['GetAllPendingRecordsList'] = getAllPendingRecordsList;
data['GetAllSharedRecordsByStatusList'] = getAllSharedRecordsByStatusList;
data['GetResponseFileList'] = getResponseFileList;
data['IsHMGPatient'] = isHMGPatient;
data['IsLoginSuccessfully'] = isLoginSuccessfully;
data['IsNeedUpdateIdintificationNo'] = isNeedUpdateIdintificationNo;
data['KioskSendSMS'] = kioskSendSMS;
if (list != null) {
data['List'] = list;
}
data['List_AskHabibMobileLoginInfo'] = listAskHabibMobileLoginInfo;
data['List_AskHabibPatientFile'] = listAskHabibPatientFile;
data['List_MergeFiles'] = listMergeFiles;
data['List_MobileLoginInfo'] = listMobileLoginInfo;
data['List_PatientCount'] = listPatientCount;
data['LogInTokenID'] = logInTokenID;
data['MohemmPrivilege_List'] = mohemmPrivilegeList;
data['PateintID'] = pateintID;
data['PatientBloodType'] = patientBloodType;
data['PatientHasFile'] = patientHasFile;
data['PatientMergedIDs'] = patientMergedIDs;
data['PatientOutSA'] = patientOutSA;
data['PatientShareRequestID'] = patientShareRequestID;
data['PatientType'] = patientType;
data['ProjectIDOut'] = projectIDOut;
data['ReturnMessage'] = returnMessage;
data['SMSLoginRequired'] = sMSLoginRequired;
data['ServicePrivilege_List'] = servicePrivilegeList;
data['SharePatientName'] = sharePatientName;
data['VerificationCode'] = verificationCode;
data['email'] = email;
data['errorList'] = errorList;
data['hasFile'] = hasFile;
data['isActiveCode'] = isActiveCode;
data['isMerged'] = isMerged;
data['isNeedUserAgreement'] = isNeedUserAgreement;
data['isSMSSent'] = isSMSSent;
data['memberList'] = memberList;
data['message'] = message;
data['statusCode'] = statusCode;
return data;
}
}
class List {
String? setupID;
int? patientType;
int? patientID;
String? firstName;
String? middleName;
String? lastName;
String? firstNameN;
String? middleNameN;
String? lastNameN;
int? relationshipID;
int? gender;
String? dateofBirth;
dynamic dateofBirthN;
String? nationalityID;
dynamic phoneResi;
dynamic phoneOffice;
String? mobileNumber;
dynamic faxNumber;
String? emailAddress;
dynamic bloodGroup;
dynamic rHFactor;
bool? isEmailAlertRequired;
bool? isSMSAlertRequired;
String? preferredLanguage;
bool? isPrivilegedMember;
dynamic memberID;
dynamic expiryDate;
dynamic isHmgEmployee;
dynamic employeeID;
dynamic emergencyContactName;
dynamic emergencyContactNo;
int? patientPayType;
dynamic dHCCPatientRefID;
bool? isPatientDummy;
int? status;
dynamic isStatusCleared;
int? patientIdentificationType;
String? patientIdentificationNo;
int? projectID;
int? infoSourceID;
dynamic address;
int? age;
String? ageDesc;
int? areaID;
int? createdBy;
String? genderDescription;
dynamic iR;
dynamic iSOCityID;
dynamic iSOCountryID;
ListPrivilege? listPrivilege;
dynamic marital;
int? outSA;
dynamic pOBox;
bool? receiveHealthSummaryReport;
int? sourceType;
dynamic strDateofBirth;
dynamic tempAddress;
dynamic zipCode;
List({
this.setupID,
this.patientType,
this.patientID,
this.firstName,
this.middleName,
this.lastName,
this.firstNameN,
this.middleNameN,
this.lastNameN,
this.relationshipID,
this.gender,
this.dateofBirth,
this.dateofBirthN,
this.nationalityID,
this.phoneResi,
this.phoneOffice,
this.mobileNumber,
this.faxNumber,
this.emailAddress,
this.bloodGroup,
this.rHFactor,
this.isEmailAlertRequired,
this.isSMSAlertRequired,
this.preferredLanguage,
this.isPrivilegedMember,
this.memberID,
this.expiryDate,
this.isHmgEmployee,
this.employeeID,
this.emergencyContactName,
this.emergencyContactNo,
this.patientPayType,
this.dHCCPatientRefID,
this.isPatientDummy,
this.status,
this.isStatusCleared,
this.patientIdentificationType,
this.patientIdentificationNo,
this.projectID,
this.infoSourceID,
this.address,
this.age,
this.ageDesc,
this.areaID,
this.createdBy,
this.genderDescription,
this.iR,
this.iSOCityID,
this.iSOCountryID,
this.listPrivilege,
this.marital,
this.outSA,
this.pOBox,
this.receiveHealthSummaryReport,
this.sourceType,
this.strDateofBirth,
this.tempAddress,
this.zipCode,
});
List.fromJson(Map<String, dynamic> json) {
setupID = json['SetupID'];
patientType = json['PatientType'];
patientID = json['PatientID'];
firstName = json['FirstName'];
middleName = json['MiddleName'];
lastName = json['LastName'];
firstNameN = json['FirstNameN'];
middleNameN = json['MiddleNameN'];
lastNameN = json['LastNameN'];
relationshipID = json['RelationshipID'];
gender = json['Gender'];
dateofBirth = json['DateofBirth'];
dateofBirthN = json['DateofBirthN'];
nationalityID = json['NationalityID'];
phoneResi = json['PhoneResi'];
phoneOffice = json['PhoneOffice'];
mobileNumber = json['MobileNumber'];
faxNumber = json['FaxNumber'];
emailAddress = json['EmailAddress'];
bloodGroup = json['BloodGroup'];
rHFactor = json['RHFactor'];
isEmailAlertRequired = json['IsEmailAlertRequired'];
isSMSAlertRequired = json['IsSMSAlertRequired'];
preferredLanguage = json['PreferredLanguage'];
isPrivilegedMember = json['IsPrivilegedMember'];
memberID = json['MemberID'];
expiryDate = json['ExpiryDate'];
isHmgEmployee = json['IsHmgEmployee'];
employeeID = json['EmployeeID'];
emergencyContactName = json['EmergencyContactName'];
emergencyContactNo = json['EmergencyContactNo'];
patientPayType = json['PatientPayType'];
dHCCPatientRefID = json['DHCCPatientRefID'];
isPatientDummy = json['IsPatientDummy'];
status = json['Status'];
isStatusCleared = json['IsStatusCleared'];
patientIdentificationType = json['PatientIdentificationType'];
patientIdentificationNo = json['PatientIdentificationNo'];
projectID = json['ProjectID'];
infoSourceID = json['InfoSourceID'];
address = json['Address'];
age = json['Age'];
ageDesc = json['AgeDesc'];
areaID = json['AreaID'];
createdBy = json['CreatedBy'];
genderDescription = json['GenderDescription'];
iR = json['IR'];
iSOCityID = json['ISOCityID'];
iSOCountryID = json['ISOCountryID'];
if (json['ListPrivilege'] != null) {
listPrivilege = ListPrivilege.fromJson(json['ListPrivilege']);
}
marital = json['Marital'];
outSA = json['OutSA'];
pOBox = json['POBox'];
receiveHealthSummaryReport = json['ReceiveHealthSummaryReport'];
sourceType = json['SourceType'];
strDateofBirth = json['StrDateofBirth'];
tempAddress = json['TempAddress'];
zipCode = json['ZipCode'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['SetupID'] = setupID;
data['PatientType'] = patientType;
data['PatientID'] = patientID;
data['FirstName'] = firstName;
data['MiddleName'] = middleName;
data['LastName'] = lastName;
data['FirstNameN'] = firstNameN;
data['MiddleNameN'] = middleNameN;
data['LastNameN'] = lastNameN;
data['RelationshipID'] = relationshipID;
data['Gender'] = gender;
data['DateofBirth'] = dateofBirth;
data['DateofBirthN'] = dateofBirthN;
data['NationalityID'] = nationalityID;
data['PhoneResi'] = phoneResi;
data['PhoneOffice'] = phoneOffice;
data['MobileNumber'] = mobileNumber;
data['FaxNumber'] = faxNumber;
data['EmailAddress'] = emailAddress;
data['BloodGroup'] = bloodGroup;
data['RHFactor'] = rHFactor;
data['IsEmailAlertRequired'] = isEmailAlertRequired;
data['IsSMSAlertRequired'] = isSMSAlertRequired;
data['PreferredLanguage'] = preferredLanguage;
data['IsPrivilegedMember'] = isPrivilegedMember;
data['MemberID'] = memberID;
data['ExpiryDate'] = expiryDate;
data['IsHmgEmployee'] = isHmgEmployee;
data['EmployeeID'] = employeeID;
data['EmergencyContactName'] = emergencyContactName;
data['EmergencyContactNo'] = emergencyContactNo;
data['PatientPayType'] = patientPayType;
data['DHCCPatientRefID'] = dHCCPatientRefID;
data['IsPatientDummy'] = isPatientDummy;
data['Status'] = status;
data['IsStatusCleared'] = isStatusCleared;
data['PatientIdentificationType'] = patientIdentificationType;
data['PatientIdentificationNo'] = patientIdentificationNo;
data['ProjectID'] = projectID;
data['InfoSourceID'] = infoSourceID;
data['Address'] = address;
data['Age'] = age;
data['AgeDesc'] = ageDesc;
data['AreaID'] = areaID;
data['CreatedBy'] = createdBy;
data['GenderDescription'] = genderDescription;
data['IR'] = iR;
data['ISOCityID'] = iSOCityID;
data['ISOCountryID'] = iSOCountryID;
if (listPrivilege != null) {
data['ListPrivilege'] = listPrivilege;
}
data['Marital'] = marital;
data['OutSA'] = outSA;
data['POBox'] = pOBox;
data['ReceiveHealthSummaryReport'] = receiveHealthSummaryReport;
data['SourceType'] = sourceType;
data['StrDateofBirth'] = strDateofBirth;
data['TempAddress'] = tempAddress;
data['ZipCode'] = zipCode;
return data;
}
}
class ListPrivilege {
int? iD;
String? serviceName;
bool? previlege;
dynamic region;
ListPrivilege({this.iD, this.serviceName, this.previlege, this.region});
ListPrivilege.fromJson(Map<String, dynamic> json) {
iD = json['ID'];
serviceName = json['ServiceName'];
previlege = json['Previlege'];
region = json['Region'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['ID'] = iD;
data['ServiceName'] = serviceName;
data['Previlege'] = previlege;
data['Region'] = region;
return data;
}
}

@ -0,0 +1,73 @@
import 'dart:convert';
Map<String, dynamic> selectDeviceByImeiRespModelFromJson(String str) => Map<String, dynamic>.from(json.decode(str));
String selectDeviceByImeiRespModelToJson(Map<String, dynamic> data) => json.encode(Map<String, dynamic>.from(data));
class SelectDeviceByImeiRespModelElement {
int? id;
String? imei;
int? logInType;
int? patientId;
bool? outSa;
String? mobile;
String? identificationNo;
String? name;
String? nameN;
String? createdOn;
String? editedOn;
bool? biometricEnabled;
int? patientType;
int? preferredLanguage;
SelectDeviceByImeiRespModelElement({
this.id,
this.imei,
this.logInType,
this.patientId,
this.outSa,
this.mobile,
this.identificationNo,
this.name,
this.nameN,
this.createdOn,
this.editedOn,
this.biometricEnabled,
this.patientType,
this.preferredLanguage,
});
factory SelectDeviceByImeiRespModelElement.fromJson(Map<String, dynamic> json) => SelectDeviceByImeiRespModelElement(
id: json["ID"] as int?,
imei: json["IMEI"] as String?,
logInType: json["LogInType"] as int?,
patientId: json["PatientID"] as int?,
outSa: json["OutSA"] as bool?,
mobile: json["Mobile"] as String?,
identificationNo: json["IdentificationNo"] as String?,
name: json["Name"] as String?,
nameN: json["NameN"] as String?,
createdOn: json["CreatedOn"] as String?,
editedOn: json["EditedOn"] as String?,
biometricEnabled: json["BiometricEnabled"] as bool?,
patientType: json["PatientType"] as int?,
preferredLanguage: json["PreferredLanguage"] as int?,
);
Map<String, dynamic> toJson() => {
"ID": id,
"IMEI": imei,
"LogInType": logInType,
"PatientID": patientId,
"OutSA": outSa,
"Mobile": mobile,
"IdentificationNo": identificationNo,
"Name": name,
"NameN": nameN,
"CreatedOn": createdOn,
"EditedOn": editedOn,
"BiometricEnabled": biometricEnabled,
"PatientType": patientType,
"PreferredLanguage": preferredLanguage,
};
}

@ -1,77 +0,0 @@
// To parse this JSON data, do
//
// final selectDeviceByImeiRespModel = selectDeviceByImeiRespModelFromJson(jsonString);
import 'dart:convert';
Map<String, dynamic> selectDeviceByImeiRespModelFromJson(String str) => Map.from(json.decode(str)).map((k, v) => MapEntry<String, dynamic>(k, v));
String selectDeviceByImeiRespModelToJson(Map<String, dynamic> data) => json.encode(Map.from(data).map((k, v) => MapEntry<String, dynamic>(k, v)));
class SelectDeviceByImeiRespModelElement {
int id;
String imei;
int logInType;
int patientId;
bool outSa;
String mobile;
String identificationNo;
String name;
String nameN;
String createdOn;
String editedOn;
bool biometricEnabled;
int patientType;
int preferredLanguage;
SelectDeviceByImeiRespModelElement({
required this.id,
required this.imei,
required this.logInType,
required this.patientId,
required this.outSa,
required this.mobile,
required this.identificationNo,
required this.name,
required this.nameN,
required this.createdOn,
required this.editedOn,
required this.biometricEnabled,
required this.patientType,
required this.preferredLanguage,
});
factory SelectDeviceByImeiRespModelElement.fromJson(Map<String, dynamic> json) => SelectDeviceByImeiRespModelElement(
id: json["ID"],
imei: json["IMEI"],
logInType: json["LogInType"],
patientId: json["PatientID"],
outSa: json["OutSA"],
mobile: json["Mobile"],
identificationNo: json["IdentificationNo"],
name: json["Name"],
nameN: json["NameN"],
createdOn: json["CreatedOn"],
editedOn: json["EditedOn"],
biometricEnabled: json["BiometricEnabled"],
patientType: json["PatientType"],
preferredLanguage: json["PreferredLanguage"],
);
Map<String, dynamic> toJson() => {
"ID": id,
"IMEI": imei,
"LogInType": logInType,
"PatientID": patientId,
"OutSA": outSa,
"Mobile": mobile,
"IdentificationNo": identificationNo,
"Name": name,
"NameN": nameN,
"CreatedOn": createdOn,
"EditedOn": editedOn,
"BiometricEnabled": biometricEnabled,
"PatientType": patientType,
"PreferredLanguage": preferredLanguage,
};
}

@ -7,19 +7,17 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/core/utils/size_config.dart';
import 'package:hmg_patient_app_new/providers/bottom_navigation_provider.dart';
import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/app_theme.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'core/utils/size_utils.dart';
import 'firebase_options.dart';
var globalMessengerKey = GlobalKey<ScaffoldMessengerState>();
final navigatorKey = GlobalKey<NavigatorState>();
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
@ -57,7 +55,12 @@ void main() async {
create: (_) => BottomNavigationProvider(),
),
ChangeNotifierProvider<AuthenticationViewModel>(
create: (_) => AuthenticationViewModel(authenticationRepo: getIt(), appState: getIt()),
create: (_) => AuthenticationViewModel(
authenticationRepo: getIt(),
appState: getIt(),
dialogService: getIt(),
errorHandlerService: getIt(),
),
),
], child: MyApp()),
),
@ -70,13 +73,13 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
top: false, // Set to true if you want to avoid the notch area as well
bottom: Platform.isIOS ? false : true,
child: LayoutBuilder(
builder: (context, constraints) {
return Sizer(
builder: (context, orientation, deviceType) {
SizeConfig().init(constraints, orientation);
// SizeConfig().init(constraints, orientation);
return MaterialApp(
title: 'Dr. AlHabib',
builder: (context, mchild) {
@ -94,7 +97,7 @@ class MyApp extends StatelessWidget {
initialRoute: AppRoutes.initialRoute,
routes: AppRoutes.routes,
theme: AppTheme.getTheme(EasyLocalization.of(context)?.locale.languageCode == "ar"),
navigatorKey: navigatorKey,
navigatorKey: getIt.get<NavigationService>().navigatorKey,
);
},
);

@ -3,19 +3,24 @@ import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/int_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/habib_wallet_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/providers/bottom_navigation_provider.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
class LandingPage extends StatefulWidget {
@ -26,9 +31,10 @@ class LandingPage extends StatefulWidget {
}
class _LandingPageState extends State<LandingPage> {
@override
Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>();
final AuthenticationViewModel authenticationViewModel = context.read<AuthenticationViewModel>();
return Consumer<BottomNavigationProvider>(builder: (context, navigationProvider, child) {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
@ -44,10 +50,8 @@ class _LandingPageState extends State<LandingPage> {
children: [
CustomButton(
text: LocaleKeys.loginOrRegister.tr(context: context),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) => LoginScreen()),
);
onPressed: () async {
await authenticationViewModel.selectDeviceImei();
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
@ -62,12 +66,19 @@ class _LandingPageState extends State<LandingPage> {
icon: AppAssets.contact_icon,
width: 24,
height: 24,
),
).onPress(() {
Navigator.of(context).push(
FadePage(
page: MedicalFilePage(),
// page: LoginScreen(),
),
);
}),
],
),
),
SizedBox(height: 16.h),
AppState().isAuthenticated
appState.isAuthenticated
? Column(
children: [
Container(
@ -110,7 +121,7 @@ class _LandingPageState extends State<LandingPage> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Quick Links".toText14(isBold: true),
"Quick Links".toText16(isBold: true),
Row(
children: [
"View medical file".toText12(color: AppColors.primaryRedColor),
@ -213,7 +224,7 @@ class _LandingPageState extends State<LandingPage> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Services".toText14(isBold: true),
"Services".toText16(isBold: true),
Row(
children: [
"View all services".toText12(color: AppColors.primaryRedColor),
@ -258,25 +269,7 @@ class _LandingPageState extends State<LandingPage> {
),
),
SizedBox(height: 16.h),
AppState().isAuthenticated
? Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"My Balance".toText14(isBold: true),
Row(
children: [
"View all services".toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
],
),
],
)
: SizedBox(),
appState.isAuthenticated ? HabibWalletCard() : SizedBox(),
],
),
),

@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
class HabibWalletCard extends StatelessWidget {
const HabibWalletCard({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"My Balance".toText16(isBold: true),
Row(
children: [
"View all services".toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
],
),
SizedBox(height: 16.h),
Container(
// height: 150.h,
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Stack(children: [
Positioned(
right: 0,
child: ClipRRect(borderRadius: BorderRadius.circular(24.0), child: Utils.buildSvgWithAssets(icon: AppAssets.habib_background_icon, width: 150.h, height: 150.h)),
),
Padding(
padding: EdgeInsets.all(14.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Habib Wallet".toText15(isBold: true),
Container(
height: 40.h,
width: 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor,
borderRadius: 8.h,
),
child: Padding(
padding: EdgeInsets.all(8.h),
child: Utils.buildSvgWithAssets(
icon: AppAssets.show_icon,
width: 12.h,
height: 12.h,
fit: BoxFit.contain,
),
),
),
],
),
SizedBox(height: 4.h),
Row(
children: [
Utils.buildSvgWithAssets(
icon: AppAssets.saudi_riyal_icon,
iconColor: AppColors.dividerColor,
width: 24.h,
height: 24.h,
fit: BoxFit.contain,
),
SizedBox(width: 8.h),
"200.18".toText32(isBold: true),
],
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 50.h),
child: Row(
children: [
"View details".toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 150.h,
child: Utils.getPaymentMethods(),
),
CustomButton(
icon: AppAssets.recharge_icon,
iconSize: 18.h,
text: "Recharge",
onPressed: () {},
backgroundColor: AppColors.infoColor,
borderColor: AppColors.infoColor,
textColor: AppColors.whiteColor,
fontSize: 12,
fontWeight: FontWeight.bold,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 35.h,
),
],
),
],
),
),
]),
)
],
);
}
}

@ -1,5 +1,13 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
class MedicalFilePage extends StatelessWidget {
const MedicalFilePage({super.key});
@ -12,12 +20,152 @@ class MedicalFilePage extends StatelessWidget {
title: const Text('Appointments'),
backgroundColor: AppColors.bgScaffoldColor,
),
body: const Center(
child: Text(
'Appointments Page',
style: TextStyle(fontSize: 24),
body: Padding(
padding: EdgeInsets.all(24.h),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.medicalFile.tr(context: context).toText22(isBold: true),
SizedBox(height: 16.h),
TextInputWidget(
labelText: LocaleKeys.search.tr(context: context),
hintText: "Type any record",
controller: TextEditingController(),
keyboardType: TextInputType.number,
isEnable: true,
prefix: null,
autoFocus: false,
isBorderAllowed: false,
isAllowLeadingIcon: true,
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.h),
leadingIcon: AppAssets.student_card,
hasError: true,
),
SizedBox(height: 16.h),
Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
AppAssets.male_img,
width: 56.h,
height: 56.h,
),
SizedBox(width: 8.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Haroon Amjad".toText18(isBold: true),
SizedBox(height: 4.h),
Row(
children: [
CustomButton(
icon: AppAssets.file_icon,
iconColor: AppColors.blackColor,
iconSize: 12.h,
text: "File no: 3628599",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 4.h),
CustomButton(
icon: AppAssets.checkmark_icon,
iconColor: AppColors.successColor,
iconSize: 13.h,
text: LocaleKeys.verified.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
],
)
],
),
SizedBox(height: 16.h),
Divider(color: AppColors.dividerColor, height: 1.h),
SizedBox(height: 16.h),
Row(
children: [
CustomButton(
text: "30 Years Old",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 4.h),
CustomButton(
icon: AppAssets.blood_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 13.h,
text: "Blood: A+",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 4.h),
CustomButton(
icon: AppAssets.insurance_active_icon,
iconColor: AppColors.successColor,
iconSize: 13.h,
text: "Insurance Active",
onPressed: () {},
backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
borderColor: AppColors.bgGreenColor.withOpacity(0.0),
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
SizedBox(height: 8.h),
],
),
),
)
],
),
),
),
);
}
}
}

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:geolocator/geolocator.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/authentication/models/authenticated_user_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/services/analytics/flows/advance_payments.dart';
import 'package:hmg_patient_app_new/services/analytics/flows/app_nav.dart';
import 'package:hmg_patient_app_new/services/analytics/flows/appointments.dart';

@ -0,0 +1,79 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
abstract class DialogService {
Future<void> showErrorDialog({required String message, Function()? onOkPressed});
}
class DialogServiceImp implements DialogService {
final NavigationService navigationService;
DialogServiceImp({required this.navigationService});
@override
Future<void> showErrorDialog({required String message, Function()? onOkPressed}) async {
final context = navigationService.navigatorKey.currentContext;
if (context == null) return;
await showModalBottomSheet(
context: context,
isScrollControlled: false,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (_) => _ErrorBottomSheet(message: message, onOkPressed: onOkPressed),
);
}
}
class _ErrorBottomSheet extends StatelessWidget {
final String message;
final Function()? onOkPressed;
const _ErrorBottomSheet({required this.message, this.onOkPressed});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.error_outline, color: Colors.red, size: 40),
const SizedBox(height: 12),
Text(
"Error",
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
message,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
if (onOkPressed != null) {
onOkPressed!();
} else {
context.pop();
}
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text("OK"),
),
],
),
);
}
}

@ -0,0 +1,55 @@
import 'dart:io';
import 'package:hmg_patient_app_new/core/exceptions/api_exception.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
abstract class ErrorHandlerService {
Future<void> handleError({required Failure failure, Function() onOkPressed});
}
class ErrorHandlerServiceImp implements ErrorHandlerService {
final DialogService dialogService;
final LoggerService loggerService;
final NavigationService navigationService;
ErrorHandlerServiceImp({
required this.dialogService,
required this.loggerService,
required this.navigationService,
});
@override
Future<void> handleError({required Failure failure, Function()? onOkPressed}) async {
if (failure is APIException) {
loggerService.errorLogs("API Exception: ${failure.message}");
} else if (failure is ServerFailure) {
loggerService.errorLogs("Server Failure: ${failure.message}");
await _showDialog(failure);
} else if (failure is DataParsingFailure) {
loggerService.errorLogs("Data Parsing Failure: ${failure.message}");
await _showDialog(failure, title: "Data Error");
} else if (failure is StatusCodeFailure) {
loggerService.errorLogs("StatusCode Failure: ${failure.message}");
await _showDialog(failure, title: "Status Code Failure Error");
} else if (failure is HttpException) {
loggerService.errorLogs("Http Exception: ${failure.message}");
await _showDialog(failure, title: "Network Error");
} else if (failure is UnknownFailure) {
loggerService.errorLogs("Unknown Failure: ${failure.message}");
await _showDialog(failure, title: "Unknown Error");
} else if (failure is InvalidCredentials) {
loggerService.errorLogs("Invalid Credentials : ${failure.message}");
await _showDialog(failure, title: "Unknown Error");
} else {
loggerService.errorLogs("Unhandled failure type: $failure");
await _showDialog(failure, title: "Error");
}
}
Future<void> _showDialog(Failure failure, {String title = "Error", Function()? onOkPressed}) async {
await dialogService.showErrorDialog(message: failure.message, onOkPressed: onOkPressed);
}
}

@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
BuildContext? get context => navigatorKey.currentContext;
Future<T?> push<T>(Route<T> route) {
return navigatorKey.currentState!.push(route);
}
void pop<T extends Object?>([T? result]) {
navigatorKey.currentState!.pop(result);
}
}

@ -16,8 +16,8 @@ import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
import 'core/consts.dart';
import 'core/utils/LocalNotification.dart';
import 'core/utils/push-notification-handler.dart';
import 'core/utils/local_notifications.dart';
import 'core/utils/push_notification_handler.dart';
class SplashPage extends StatefulWidget {
@override

@ -29,6 +29,7 @@ class AppColors {
static const Color bgGreenColor = Color(0xFF18C273);
static const Color textColor = Color(0xFF2E3039);
static const Color borderOnlyColor = Color(0xFF2E3039);
static const Color dividerColor = Color(0xFFD2D2D2);
static const Color blackBgColor = Color(0xFF2E3039);
static const blackColor = textColor;
static const inputLabelTextColor = Color(0xff898A8D);

@ -20,6 +20,7 @@ class CustomButton extends StatelessWidget {
final bool isDisabled;
final Color iconColor;
final double height;
final double iconSize;
CustomButton({
Key? key,
@ -38,45 +39,56 @@ class CustomButton extends StatelessWidget {
this.icon,
this.iconColor = Colors.white,
this.height = 56,
this.iconSize = 24,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: isDisabled ? null : onPressed,
child: Container(
height: height,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: isDisabled ? Colors.transparent : backgroundColor,
borderRadius: borderRadius,
side: BorderSide(
width: borderWidth,
color: isDisabled ? borderColor.withOpacity(0.5) : borderColor,
)),
child: Padding(
padding: padding,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null)
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled),
onTap: isDisabled ? null : onPressed,
child: Container(
height: height,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: isDisabled ? Colors.transparent : backgroundColor,
borderRadius: borderRadius,
side: BorderSide(
width: borderWidth,
color: isDisabled ? borderColor.withOpacity(0.5) : borderColor,
)),
child: Padding(
padding: padding,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null)
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled, width: iconSize, height: iconSize),
),
Text(
text,
style: context.dynamicTextStyle(
fontSize: fontSize.fSize,
color: isDisabled ? textColor.withOpacity(0.5) : textColor,
letterSpacing: -0.4,
fontWeight: fontWeight,
),
),
Text(
text,
style: context.dynamicTextStyle(
fontSize: fontSize.fSize,
color: isDisabled ? textColor.withOpacity(0.5) : textColor,
letterSpacing: -0.4,
fontWeight: fontWeight,
),
),
],
],
),
),
),
),
);
)
// .toSmoothContainer(
// smoothness: 1,
// side: BorderSide(width: borderWidth, color: backgroundColor),
// borderRadius: BorderRadius.circular(borderRadius * 1.2),
// foregroundDecoration: BoxDecoration(
// color: isDisabled ? backgroundColor.withOpacity(0.5) : Colors.transparent,
// borderRadius: BorderRadius.circular(borderRadius),
// ),
// ),
);
}
}

@ -5,7 +5,7 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
class CustomChipWidget extends StatelessWidget {
final ChipType chipType;
final ChipTypeEnum chipType;
final String chipText;
final String? iconAsset;
final VoidCallback? onTap;
@ -14,7 +14,7 @@ class CustomChipWidget extends StatelessWidget {
final EdgeInsetsGeometry padding;
const CustomChipWidget({
Key? key,
super.key,
required this.chipType,
required this.chipText,
this.iconAsset,
@ -22,7 +22,7 @@ class CustomChipWidget extends StatelessWidget {
this.isSelected = false,
this.borderRadius = 12,
this.padding = const EdgeInsets.all(8),
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

Loading…
Cancel
Save