WD: lab report changes

merge-update-with-lab-changes
taha.alam 12 months ago
parent 3d2e0a5442
commit 3d27fbdea8

@ -55,7 +55,7 @@ configurations.all {
android {
compileSdkVersion 34
// ndkVersion "24.0.8215888"
namespace = "com.ejada.hmg"
buildFeatures {
viewBinding true
}
@ -98,6 +98,8 @@ android {
debug {
debuggable true
signingConfig signingConfigs.debug
minifyEnabled false
shrinkResources false
// ndk {
// abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64'
// }
@ -130,10 +132,14 @@ android {
compileOptions {
// coreLibraryDesugaringEnabled true
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
}
flutter {
@ -141,7 +147,7 @@ flutter {
}
dependencies {
// coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.firebase:firebase-messaging:21.0.0"

@ -21,8 +21,8 @@ buildscript {
credentials {
username = 'mapbox'
// password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
password = "pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ"
password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
// password = "pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ"
if (password == null || password == "") {
throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.")
}
@ -43,11 +43,13 @@ buildscript {
classpath 'com.google.gms:google-services:4.3.8'
// classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
classpath("com.android.tools:r8:8.2.42")
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12'
classpath "com.mapbox.gradle.plugins:access-token:0.4.0"
}
}
allprojects {
repositories {
google()

@ -5,5 +5,6 @@ android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.suppressUnsupportedCompileSdk=33
MAPBOX_USER_NAME = "mapbox"
kotlin.jvm.target.validation.mode=IGNORE
#MAPBOX_DOWNLOADS_TOKEN="sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
MAPBOX_DOWNLOADS_TOKEN="pk.eyJ1IjoicndhaWQiLCJhIjoiY2x5cGo4aHNjMGNsbTJyc2djempobGQxaSJ9.RCaC6WrUt4A4YnZNfxnONQ"

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

@ -19,7 +19,7 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.7.0' apply false
id "com.android.application" version '8.1.0' apply false
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
id "com.google.protobuf" version "0.9.1" apply false

@ -2114,4 +2114,7 @@ const Map localizedValues = {
"ar":
"لقد قرأت وفهمت وأوافق على الشروط والأحكام المبينة أعلاه وأوافق على الإلتزام بالمتطلبات المذكورة تجاه المستشفى ، لقد قرأت التفاصيل المبينة في نموذج التسجيل الخاص بي وأقر بأنها صحيحة. أنا الموقع ادناه أقر بأنه أتيحت لي الفرصة لطرح الأسئلة والتحفظات بشأن هذه الموافقة، وتلقيت إجابات مرضية على جميع إستفساراتي."
},
"readMore": {"en": "Read More", "ar": "اقرأ أكثر"},
"showLess": {"en": "Show Less", "ar": "عرض أقل"},
"change": {"en": "Change", "ar": "فرق"}
};

@ -18,6 +18,7 @@ class LabOrderResult {
String? uOM;
String? verifiedOn;
String? verifiedOnDateTime;
String? changeResult;
LabOrderResult(
{this.description,
@ -60,6 +61,7 @@ class LabOrderResult {
uOM = json['UOM'];
verifiedOn = json['VerifiedOn'];
verifiedOnDateTime = json['VerifiedOnDateTime'];
changeResult = json['ChangeResult'];
}
Map<String, dynamic> toJson() {
@ -83,6 +85,7 @@ class LabOrderResult {
data['UOM'] = this.uOM;
data['VerifiedOn'] = this.verifiedOn;
data['VerifiedOnDateTime'] = this.verifiedOnDateTime;
data['ChangeResult'] = this.changeResult;
return data;
}
}

@ -1,12 +1,88 @@
import 'package:diplomaticquarterapp/widgets/data_display/medical/LabResult/newUI/labWidgets.dart';
class LabResultList {
String? filterName = "";
String? description = "";
List<LabResult>? patientLabResultList = [];
LabResultList({this.filterName, LabResult? lab}) {
LabResultList({this.filterName, this.description, LabResult? lab}) {
patientLabResultList!.add(lab!);
}
}
enum ResultFlag {
N('normal'),
H('high'),
L('low'),
CL('criticalLow'),
CH('criticalHigh'),
HCH('highCriticalHigh'),
LCL('lowCriticalLow');
final String value;
const ResultFlag(this.value);
static ResultFlag? fromJson(String key) {
switch (key) {
case 'N':
return ResultFlag.N;
case 'H':
return ResultFlag.H;
case 'L':
return ResultFlag.L;
case 'CL':
return ResultFlag.CL;
case 'CH':
return ResultFlag.CH;
case 'HCH':
return ResultFlag.HCH;
case 'LCL':
return ResultFlag.LCL;
default:
return null;
}
}
String toJson() {
switch (this) {
case ResultFlag.N:
return 'N';
case ResultFlag.H:
return 'H';
case ResultFlag.L:
return 'L';
case ResultFlag.CL:
return 'CL';
case ResultFlag.CH:
return 'CH';
case ResultFlag.HCH:
return 'HCH';
case ResultFlag.LCL:
return 'LCL';
}
}
ResultTypes getType() {
switch (this) {
case ResultFlag.N:
return ResultTypes.normal;
case ResultFlag.H:
return ResultTypes.high;
case ResultFlag.L:
return ResultTypes.low;
case ResultFlag.CL:
return ResultTypes.criticalLow;
case ResultFlag.CH:
return ResultTypes.criticalHigh;
case ResultFlag.HCH:
return ResultTypes.highCriticalHigh;
case ResultFlag.LCL:
return ResultTypes.lowCriticalLow;
}
}
}
class LabResult {
String? description;
dynamic femaleInterpretativeData;
@ -31,7 +107,11 @@ class LabResult {
String? testCode;
String? uOM;
String? verifiedOn;
String? packageShortDescription;
String? testShortDescription;
ResultFlag? calculatedResultFlag;
dynamic verifiedOnDateTime;
num? percentage;
LabResult(
{this.description,
@ -59,7 +139,7 @@ class LabResult {
this.verifiedOn,
this.verifiedOnDateTime});
LabResult.fromJson(Map<String, dynamic> json) {
LabResult.fromJson(Map<String, dynamic> json, {String? flag}) {
description = json['Description'];
femaleInterpretativeData = json['FemaleInterpretativeData'];
gender = json['Gender'];
@ -84,6 +164,10 @@ class LabResult {
uOM = json['UOM'];
verifiedOn = json['VerifiedOn'];
verifiedOnDateTime = json['VerifiedOnDateTime'];
packageShortDescription = json['PackageShortDescription'];
testShortDescription = json['TestShortDescription'];
calculatedResultFlag =
ResultFlag.fromJson(flag ?? json['CalculatedResultFlag']);
}
Map<String, dynamic> toJson() {
@ -112,6 +196,10 @@ class LabResult {
data['UOM'] = this.uOM;
data['VerifiedOn'] = this.verifiedOn;
data['VerifiedOnDateTime'] = this.verifiedOnDateTime;
data['PackageShortDescription'] = this.packageShortDescription;
data['TestShortDescription'] = this.testShortDescription;
data['CalculatedResultFlag'] = this.calculatedResultFlag?.toJson() ?? '';
return data;
}
}

@ -202,6 +202,7 @@ class LabsService extends BaseService {
labOrdersResultsList.add(LabOrderResult.fromJson(lab));
});
}, onFailure: (String error, int statusCode) {
labOrdersResultsList.clear();
hasError = true;
super.error = error;
}, body: body);

@ -100,24 +100,50 @@ class LabsViewModel extends BaseViewModel {
} else {
_labsService.labResultList.forEach((element) {
List<LabResultList> patientLabOrdersClinic = labResultLists.where((elementClinic) => elementClinic.filterName == element.testCode).toList();
element.percentage =
getPercentage(element.calculatedResultFlag ?? ResultFlag.N);
if (patientLabOrdersClinic.length != 0) {
// var value = labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])]
// .patientLabResultList!
// .where((e) {
// return e.sampleCollectedOn == element.sampleCollectedOn && e.resultValue == element.resultValue;
// })
// .toList();
// if (value.isEmpty)
labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])].patientLabResultList!.add(element);
} else {
labResultLists.add(LabResultList(filterName: element.testCode, lab: element));
labResultLists.add(LabResultList(
filterName: element.testCode,
description: element.packageShortDescription,
lab: element));
}
});
setState(ViewState.Idle);
}
}
double getPercentage(ResultFlag flag) {
double percentage = 0.0;
final division = 0.2;
switch (flag) {
case ResultFlag.N: //4
percentage = division * 2;
break;
case ResultFlag.H: //5
percentage = division * 3.2;
break;
case ResultFlag.L: //3
percentage = division * .9;
break;
case ResultFlag.CL: //2
case ResultFlag.LCL: //
percentage = division * .3;
break;
case ResultFlag.HCH: //7
case ResultFlag.CH: //6
percentage = division * 3.8;
break;
}
return percentage * 100;
}
getPatientLabOrdersResults({PatientLabOrders? patientLabOrder, String? procedure, bool? isVidaPlus}) async {
setState(ViewState.Busy);
await _labsService.getPatientLabOrdersResults(

@ -4,22 +4,17 @@ import 'dart:io';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart';
import 'package:diplomaticquarterapp/core/model/geofencing/requests/GeoZonesRequestModel.dart';
import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart';
import 'package:diplomaticquarterapp/core/service/geofencing/GeofencingServices.dart';
import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart';
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart';
import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart';
import 'package:diplomaticquarterapp/pages/landing/home_page_2.dart';
import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart';
import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart';
import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart'
@ -40,15 +35,11 @@ import 'package:diplomaticquarterapp/widgets/buttons/floatingActionButton.dart';
import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/others/not_auh_page.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import '../../locator.dart';

@ -6,16 +6,13 @@ import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/core/viewModels/medical/labs_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/LabResult/laboratory_result_widget.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:open_filex/open_filex.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
@ -52,36 +49,28 @@ class _LaboratoryResultPageState extends State<LaboratoryResultPage> {
body: SingleChildScrollView(
child: Column(
children: [
ListView.builder(
addAutomaticKeepAlives: true,
physics: BouncingScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.only(bottom: 12),
itemBuilder: (context, index) => LaboratoryResultWidget(
onTap: () async {
GifLoaderDialogUtils.showMyDialog(context);
await model.sendLabReportEmail(
patientLabOrder: widget.patientLabOrders,
mes: TranslationBase.of(context).sendSuc,
userObj: projectViewModel.user,
isVidaPlus: Utils.isVidaPlusProject(
projectViewModel,
int.parse(widget.patientLabOrders!.projectID!),
),
);
GifLoaderDialogUtils.hideDialog(context);
},
billNo: widget.patientLabOrders!.invoiceNo,
// details: model.patientLabSpecialResult[index].resultDataHTML,
details: model.patientLabSpecialResult.isEmpty ? null : getSpecialResults(model),
orderNo: widget.patientLabOrders!.orderNo,
patientLabOrder: widget.patientLabOrders,
),
itemCount: 1,
LaboratoryResultWidget(
onTap: () async {
GifLoaderDialogUtils.showMyDialog(context);
await model.sendLabReportEmail(
patientLabOrder: widget.patientLabOrders,
mes: TranslationBase.of(context).sendSuc,
userObj: projectViewModel.user,
isVidaPlus: Utils.isVidaPlusProject(
projectViewModel,
int.parse(widget.patientLabOrders!.projectID!),
),
);
GifLoaderDialogUtils.hideDialog(context);
},
billNo: widget.patientLabOrders!.invoiceNo,
// details: model.patientLabSpecialResult[index].resultDataHTML,
details: model.patientLabSpecialResult.isEmpty
? null
: getSpecialResults(model),
orderNo: widget.patientLabOrders!.orderNo,
patientLabOrder: widget.patientLabOrders,
),
SizedBox(
height: 120.0,
)
],
),
),

@ -1,8 +1,6 @@
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
@ -31,7 +29,7 @@ class LocalNotification {
_initialize() async {
try {
var initializationSettingsAndroid = new AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = DarwinInitializationSettings(onDidReceiveLocalNotification: null);
var initializationSettingsIOS = DarwinInitializationSettings();
var initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,

@ -3019,7 +3019,11 @@ class TranslationBase {
String get agreeText => localizedValues["agreeText"][locale.languageCode];
String get ERCheckInSuccess => localizedValues["ERCheckInSuccess"][locale.languageCode];
String get readMore => localizedValues["readMore"][locale.languageCode];
String get showLess => localizedValues["showLess"][locale.languageCode];
String get change => localizedValues["change"][locale.languageCode];
}
class TranslationBaseDelegate extends LocalizationsDelegate<TranslationBase> {

@ -1,18 +1,15 @@
import 'package:diplomaticquarterapp/core/enum/viewstate.dart';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/core/viewModels/medical/labs_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart';
import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'LineChartCurved.dart';
import 'lab_result_chart_and_detials.dart';
class FlowChartPage extends StatelessWidget {
@ -29,63 +26,84 @@ class FlowChartPage extends StatelessWidget {
return BaseView<LabsViewModel>(
onModelReady: (model) =>
model.getPatientLabOrdersResults(patientLabOrder: patientLabOrder, procedure: filterName, isVidaPlus: Utils.isVidaPlusProject(projectViewModel!, int.parse(patientLabOrder!.projectID!))),
builder: (context, model, w) => AppScaffold(
isShowAppBar: true,
appBarTitle: filterName!,
baseViewModel: model,
showNewAppBar: true,
showNewAppBarTitle: true,
backgroundColor: CustomColors.appBackgroudGrey2Color,
body: SingleChildScrollView(
child: model.labOrdersResultsList.isNotEmpty
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: double.infinity,
padding: EdgeInsets.only(left: 17, top: 12, right: 13, bottom: 12),
margin: EdgeInsets.only(left: 21, right: 21, top: 21),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
boxShadow: [
BoxShadow(
color: Color(0xff000000).withOpacity(.05),
//spreadRadius: 5,
blurRadius: 27,
offset: Offset(0, -3),
),
],
),
// child: LineChartCurved(
// title: filterName,
// labResult: model.labOrdersResultsList,
// ),
child: ShowChart(
title: filterName!,
timeSeries: model.timeSeries,
indexes: model.timeSeries.length ~/ 5.5 ?? 0,
builder: (context, model, w) =>
SizedBox(
height: MediaQuery
.sizeOf(context)
.height * .75,
child: (model.state == ViewState.Busy)
? Material(
color: Colors.grey.withOpacity(0.6),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20))),
child: Center(
child: Container(
child: GifLoaderContainer(),
margin: EdgeInsets.only(
bottom: MediaQuery
.of(context)
.size
.height * 0.09)),
),
)
: SingleChildScrollView(
child: model.labOrdersResultsList.isNotEmpty
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: double.infinity,
padding: EdgeInsets.only(
left: 17, top: 12, right: 13, bottom: 12),
margin:
EdgeInsets.only(left: 21, right: 21, top: 21),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
boxShadow: [
BoxShadow(
color: Color(0xff000000).withOpacity(.05),
//spreadRadius: 5,
blurRadius: 27,
offset: Offset(0, -3),
),
],
),
LabResultChartAndDetails(
name: filterName!,
labResult: model.labOrdersResultsList,
),
],
)
: Center(
child: Container(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.32),
child: Center(
child: getNoDataWidget(context),
// child: LineChartCurved(
// title: filterName,
// labResult: model.labOrdersResultsList,
// ),
child: ShowChart(
title: filterName!,
timeSeries: model.timeSeries,
indexes: model.timeSeries.length ~/ 5.5 ?? 0,
),
),
LabResultChartAndDetails(
name: filterName!,
labResult: model.labOrdersResultsList,
),
],
)
: Center(
child: Container(
padding: EdgeInsets.only(
top: MediaQuery
.of(context)
.size
.height * 0.32),
child: Center(
child: getNoDataWidget(context),
),
),
),
),
),
),
);
}

@ -3,7 +3,6 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -26,6 +25,7 @@ class _VitalSignDetailsWidgetState extends State<LabResultDetailsWidget> {
columnWidths: {
0: FlexColumnWidth(2),
1: FlexColumnWidth(1),
2: FlexColumnWidth(1),
},
children: fullData(widget.labResult!, context),
);
@ -38,6 +38,7 @@ class _VitalSignDetailsWidgetState extends State<LabResultDetailsWidget> {
children: [
Utils.tableColumnTitle(TranslationBase.of(context).date),
Utils.tableColumnTitle(TranslationBase.of(context).labResults),
Utils.tableColumnTitle(TranslationBase.of(context).change),
],
),
);
@ -48,9 +49,33 @@ class _VitalSignDetailsWidgetState extends State<LabResultDetailsWidget> {
children: [
Utils.tableColumnValue(DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(labOrderResultList![i].verifiedOnDateTime!)), isLast: i == (labOrderResultList.length - 1)),
Utils.tableColumnValue(labOrderResultList[i].resultValue!, isLast: i == (labOrderResultList.length - 1)),
changeResult(labOrderResultList[i].changeResult ?? '8%')
],
),
);
return tableRow;
}
Widget changeResult(String changeValue) => Padding(
padding: const EdgeInsets.all(4.0),
child: Material(
color: (changeValue.contains("-")) ? Colors.black : Color(0xffcecbcb),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Center(
child: Text(
changeValue,
style: TextStyle(
color: (changeValue.contains("-"))
? Colors.white
: Colors.black,
fontSize: 12,
fontWeight: FontWeight.w500),
),
),
),
),
);
}

@ -1,4 +1,3 @@
import 'dart:convert';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/core/viewModels/medical/labs_view_model.dart';
@ -7,15 +6,13 @@ import 'package:diplomaticquarterapp/models/header_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/LabResult/newUI/LabItem.dart';
import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart';
import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:provider/provider.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/LabResult/newUI/labWidgets.dart';
import 'LabResultWidget.dart';
class LaboratoryResultWidget extends StatefulWidget {
final GestureTapCallback? onTap;
@ -32,14 +29,13 @@ class LaboratoryResultWidget extends StatefulWidget {
class _LaboratoryResultWidgetState extends State<LaboratoryResultWidget> {
bool _isShowMore = true;
bool _isShowMoreGeneral = true;
late ProjectViewModel projectViewModel;
late String labSpecialResult;
late String? labSpecialResult;
@override
void initState() {
super.initState();
labSpecialResult = widget.details ?? TranslationBase.of(context).noDataAvailable;
labSpecialResult = widget.details;
}
@override
@ -51,173 +47,124 @@ class _LaboratoryResultWidgetState extends State<LaboratoryResultWidget> {
builder: (_, model, w) => NetworkBaseView(
baseViewModel: model,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
DoctorHeader(
headerModel: HeaderModel(
widget.patientLabOrder!.doctorName!,
widget.patientLabOrder!.doctorID ?? 0,
widget.patientLabOrder!.doctorImageURL!,
widget.patientLabOrder!.speciality ?? [""],
widget.billNo!,
widget.patientLabOrder!.projectName ?? "",
widget.patientLabOrder!.orderDate!,
"",
widget.patientLabOrder!.nationalityFlagURL ?? "",
widget.patientLabOrder!.doctorRate!,
widget.patientLabOrder!.actualDoctorRate!,
widget.patientLabOrder!.noOfPatientsRate!,
projectViewModel.user.emailAddress!),
onTap: widget.onTap!,
),
mainAxisSize: MainAxisSize.max,
children: [
_buildDoctorHeader(),
SizedBox(height: 10),
if (model.labResultLists.isNotEmpty)
Column(
children: [
Padding(
padding: EdgeInsets.only(left: 21, right: 21),
child: GestureDetector(
onTap: () {
setState(
() {
_isShowMoreGeneral = !_isShowMoreGeneral;
},
);
},
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
TranslationBase.of(context).generalResult,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16),
),
),
Icon(
_isShowMoreGeneral ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
color: Color(0xff575757),
size: 22,
)
],
),
),
),
ItemResultCardWidgetWithParams(
title: "LYMPHOCYTES", subTitle: "0.4", referenceRange: "0.6-4", percentage: 5, note: "", source: "source", buttonText: "Click", type: ResultTypes.criticalLow),
ItemResultCardWidgetWithParams(
title: "Creatinine",
subTitle: "60",
referenceRange: "64-104",
percentage: 20,
note: "Mayoclinic is the source of pediatrics value",
source: "source",
buttonText: "Click",
type: ResultTypes.low),
ItemResultCardWidgetWithParams(
title: "WBC",
subTitle: "5.96",
referenceRange: "4-11",
percentage: 45,
note: "Mayoclinic is the source of pediatrics value",
source: "source",
buttonText: "Click",
type: ResultTypes.normal),
ItemResultCardWidgetWithParams(title: "NEUT%", subTitle: "55", referenceRange: "10-50", percentage: -1, note: "", source: "source", buttonText: "Click", type: ResultTypes.normal),
_isShowMoreGeneral
? Container(
padding: EdgeInsets.only(left: 17, top: 12, right: 13, bottom: 12),
margin: EdgeInsets.only(left: 21, right: 21, top: 12),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
boxShadow: [
BoxShadow(
color: Color(0xff000000).withOpacity(.05),
//spreadRadius: 5,
blurRadius: 27,
offset: Offset(0, -3),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (_isShowMoreGeneral)
...List.generate(model.labResultLists.length, (index) {
print(widget.patientLabOrder);
print(model.labResultLists[index].filterName);
print(jsonEncode(model.labResultLists[0].patientLabResultList));
return LabResultWidget(
patientLabOrder: widget.patientLabOrder,
filterName: model.labResultLists[index].filterName,
patientLabResultList: model.labResultLists[index].patientLabResultList,
);
})
],
),
)
: SizedBox(),
],
Padding(
padding: const EdgeInsets.all(21.0),
child: _buildLabResultsList(model),
),
InkWell(
onTap: () {
setState(() {
_isShowMore = !_isShowMore;
});
},
child: Container(
padding: EdgeInsets.only(left: 17, top: 14, right: 13, bottom: 10),
margin: EdgeInsets.only(left: 21, right: 21, top: 12),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
boxShadow: [
BoxShadow(
color: Color(0xff000000).withOpacity(.05),
//spreadRadius: 5,
blurRadius: 27,
offset: Offset(0, -3),
// Expanded(
// child: _buildLabResultsList(model),
// ),
_buildSpecialResultsToggle(),
SizedBox(height: 16),
],
),
),
);
}
Widget _buildDoctorHeader() {
return DoctorHeader(
headerModel: HeaderModel(
widget.patientLabOrder!.doctorName!,
widget.patientLabOrder!.doctorID ?? 0,
widget.patientLabOrder!.doctorImageURL!,
widget.patientLabOrder!.speciality ?? [""],
widget.billNo!,
widget.patientLabOrder!.projectName ?? "",
widget.patientLabOrder!.orderDate!,
"",
widget.patientLabOrder!.nationalityFlagURL ?? "",
widget.patientLabOrder!.doctorRate!,
widget.patientLabOrder!.actualDoctorRate!,
widget.patientLabOrder!.noOfPatientsRate!,
projectViewModel.user.emailAddress!,
),
onTap: widget.onTap!,
);
}
Widget _buildLabResultsList(LabsViewModel model) {
return ListView.separated(
shrinkWrap: true,
itemCount: model.labResultLists.length,
physics: NeverScrollableScrollPhysics(),
separatorBuilder: (_, __) => SizedBox(
height: 26,
),
itemBuilder: (context, index) {
var data = model.labResultLists[index];
return LabItem(
key: ValueKey(data.filterName),
item: data,
patientLabOrders: widget.patientLabOrder);
},
);
}
Widget _buildSpecialResultsToggle() {
return InkWell(
onTap: () {
setState(() {
_isShowMore = !_isShowMore;
});
},
child: Container(
padding: EdgeInsets.only(left: 17, top: 14, right: 13, bottom: 10),
margin: EdgeInsets.only(left: 21, right: 21, top: 12),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
boxShadow: [
BoxShadow(
color: Color(0xff000000).withOpacity(.05),
blurRadius: 27,
offset: Offset(0, -3),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: <Widget>[
Expanded(
child: Text(
TranslationBase.of(context).specialResult,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color(0xff2E303A),
letterSpacing: -0.64,
height: 25 / 16,
),
],
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: <Widget>[
Expanded(
child: Text(
TranslationBase.of(context).specialResult,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16),
),
),
Icon(
_isShowMore ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
color: Color(0xff575757),
size: 22,
)
],
),
if (_isShowMore)
Container(
width: double.infinity,
// height: 450.0,
child: Html(
// data: widget.details ?? TranslationBase.of(context).noDataAvailable,
data: labSpecialResult,
),
),
],
Icon(
_isShowMore
? Icons.keyboard_arrow_up
: Icons.keyboard_arrow_down,
color: Color(0xff575757),
size: 22,
),
),
],
),
if (_isShowMore)
Container(
width: double.infinity,
child: Html(
data: labSpecialResult ??
TranslationBase.of(context).noDataAvailable,
),
),
],
),
),

@ -0,0 +1,166 @@
import 'package:diplomaticquarterapp/core/model/labs/lab_result.dart';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/LabResult/newUI/labWidgets.dart';
import 'package:flutter/material.dart';
import 'package:readmore/readmore.dart';
import '../FlowChartPage.dart';
class LabItem extends StatefulWidget {
final LabResultList item;
PatientLabOrders? patientLabOrders;
LabItem({super.key, required this.item, this.patientLabOrders});
@override
State<LabItem> createState() => _LabItemState();
}
class _LabItemState extends State<LabItem> {
bool _isShowMoreGeneral = false;
bool showBottomSheet = false;
@override
void initState() {
super.initState();
if (showBottomSheet) {
print('the bottom sheet is showing');
openFlowChart(context, '');
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () {
setState(() {
_isShowMoreGeneral = !_isShowMoreGeneral;
});
},
behavior: HitTestBehavior.opaque,
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
widget.item.filterName ?? '',
style: TextStyle(
fontSize: 21,
fontWeight: FontWeight.bold,
color: Color(0xff2B353E),
letterSpacing: -0.64,
height: 25 / 16),
),
),
Icon(
_isShowMoreGeneral
? Icons.keyboard_arrow_up
: Icons.keyboard_arrow_down,
color: Color(0xff2B353E),
size: 26,
)
],
),
),
SizedBox(
height: 12,
),
ReadMoreText(
widget.item.description ?? '',
trimMode: TrimMode.Line,
trimLines: 3,
style: const TextStyle(color: Color(0xff575757), fontSize: 11),
colorClickableText: CustomColors.accentColor,
trimCollapsedText: '${TranslationBase.of(context).readMore}',
trimExpandedText: ' show less',
),
SizedBox(
height: 8,
),
if (_isShowMoreGeneral)
...List.generate(widget.item.patientLabResultList?.length ?? 0,
(index) {
var data = widget.item.patientLabResultList?[index];
return Column(
children: [
ItemResultCardWidgetWithParams(
title: data?.description ?? '',
subTitle: data?.resultValue ?? '',
referenceRange: data?.referanceRange ?? '',
percentage: data?.percentage ?? 0.0,
note: data?.testShortDescription ?? '',
source: "",
buttonText: "",
type: data?.calculatedResultFlag?.getType() ??
ResultTypes.unknown,
onButtonPressed: () {
openFlowChart(context, data?.description ?? '');
},
),
SizedBox(
height: 13,
),
],
);
})
// Expanded(
// child: ListView.builder(
// itemCount: widget.item.patientLabResultList?.length ?? 0,
// itemBuilder: (context, index) {
// var data = widget.item.patientLabResultList?[index];
// Column(
// children: [
// EllipsisTextWithMore(
// text: data?.packageShortDescription ?? '',
// ),
// SizedBox(
// height: 8,
// ),
// ItemResultCardWidgetWithParams(
// title: data?.description ?? '',
// subTitle: data?.resultValue ?? '',
// referenceRange: data?.referanceRange ?? '',
// percentage: 20,
// note: data?.testShortDescription ?? '',
// source: "",
// buttonText: "",
// type: data?.calculatedResultFlag?.getType() ??
// ResultTypes.unknown),
// ],
// );
// }))
],
);
}
openFlowChart(BuildContext context, String procedure) {
print('openFlowChart: the bottom sheet is showing');
showModalBottomSheet(
backgroundColor: Colors.white,
isScrollControlled: true,
context: context,
scrollControlDisabledMaxHeightRatio: .75,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20))),
builder: (context) {
print('builder: the bottom sheet is showing');
return FlowChartPage(
filterName: procedure,
patientLabOrder: widget.patientLabOrders,
);
}).then((value) {
setState(() {
showBottomSheet = false;
});
});
}
}

@ -4,7 +4,16 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:flutter/material.dart';
enum ResultTypes { criticalLow, low, normal, high, criticalHigh }
enum ResultTypes {
lowCriticalLow,
criticalLow,
low,
normal,
high,
criticalHigh,
highCriticalHigh,
unknown
}
class ItemResultCardWidget extends StatelessWidget {
final Widget child;
@ -30,11 +39,32 @@ class ItemResultCardWidget extends StatelessWidget {
}
class CustomResultProgressBar extends StatelessWidget {
final double percentage;
final num percentage;
final String value;
final ResultTypes type;
const CustomResultProgressBar({Key? key, required this.percentage, required this.value, required this.type}) : super(key: key);
CustomResultProgressBar(
{Key? key,
required this.percentage,
required this.value,
required this.type})
: super(key: key);
final GlobalKey lcl = GlobalKey();
final GlobalKey cl = GlobalKey();
final GlobalKey l = GlobalKey();
final GlobalKey n = GlobalKey();
final GlobalKey h = GlobalKey();
final GlobalKey ch = GlobalKey();
final GlobalKey hch = GlobalKey();
OverlayEntry? overlayEntry;
@override
Widget build(BuildContext context) {
@ -47,61 +77,49 @@ class CustomResultProgressBar extends StatelessWidget {
Row(
children: [
_buildResultBar(
key: cl,
flex: 3,
color: Color(0xFFDE7676),
title: "Critical Low",
),
SizedBox(
width: spacing,
),
_buildResultBar(
key: l,
flex: 2,
color: Color(0xFFEAB157),
title: "Low",
),
SizedBox(
width: spacing,
),
_buildResultBar(
key: n,
flex: 5,
color: Color(0xFF09AA28),
title: "Normal",
),
SizedBox(
width: spacing,
),
_buildResultBar(
key: h,
flex: 2,
color: Color(0xFFEAB157),
title: "High",
),
SizedBox(
width: spacing,
),
_buildResultBar(
key: ch,
flex: 3,
color: Color(0xFFDE7676),
title: "Critical High",
),
],
),
if (!percentage.isNegative) Positioned(
left: tooltipPosition,
top: 33,
if (!percentage.isNegative)
Positioned(
left: tooltipPosition,
top: 33,
child: Column(
children: [
TextCloud(
text: "${value}",
color: type == ResultTypes.criticalLow || type == ResultTypes.criticalHigh
? Color(0xFFDE7676)
: type == ResultTypes.low || type == ResultTypes.high
? Color(0xFFEAB157)
: type == ResultTypes.normal
? Color(0xFF09AA28)
: Color(0xFF09AA28),
width: 60,
height: 20,
padding: EdgeInsets.zero,
color: getColorForResultType(type),
width: 60,
height: 20,
padding: EdgeInsets.zero,
axisDirection: AxisDirection.up,
),
],
@ -112,19 +130,43 @@ class CustomResultProgressBar extends StatelessWidget {
});
}
Color getColorForResultType(ResultTypes type) {
switch (type) {
case ResultTypes.lowCriticalLow:
case ResultTypes.highCriticalHigh:
case ResultTypes.criticalLow:
case ResultTypes.criticalHigh:
return Color(0xFFDE7676);
case ResultTypes.low:
case ResultTypes.high:
return Color(0xFFEAB157);
case ResultTypes.normal:
return Color(0xFF09AA28);
default:
return Color(0xFF09AA28);
}
}
Widget _buildResultBar({
required int flex,
required Color color,
required String title,
}) {
Key? key}) {
return Expanded(
key: key,
flex: flex,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
title,
style: const TextStyle(fontSize: 10, fontFamily: 'Poppins', letterSpacing: -0.24, fontWeight: FontWeight.w500),
style: TextStyle(
fontSize: 10,
fontFamily: 'Poppins',
letterSpacing: -0.24,
color: color,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 5),
@ -258,7 +300,7 @@ class ItemResultCardWidgetWithParams extends StatelessWidget {
final String note;
final String source;
final String referenceRange;
final double percentage;
final num percentage;
final String buttonText;
final ResultTypes type;
final bool isArabic;
@ -283,18 +325,12 @@ class ItemResultCardWidgetWithParams extends StatelessWidget {
final fontFamily = isArabic ? 'Cairo' : 'Poppins';
return Container(
margin: const EdgeInsets.only(left: 21, right: 21, top: 21),
margin: const EdgeInsets.only(top: 21),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(10)),
border: Border(
left: BorderSide(
color: type == ResultTypes.criticalLow || type == ResultTypes.criticalHigh
? Color(0xFFDE7676)
: type == ResultTypes.low || type == ResultTypes.high
? Color(0xFFEAB157)
: type == ResultTypes.normal
? Color(0xFF09AA28)
: Color(0xFF09AA28),
color: getColorForResultType(type),
width: MediaQuery.of(context).size.width * 0.015,
),
),
@ -406,6 +442,23 @@ class ItemResultCardWidgetWithParams extends StatelessWidget {
),
);
}
Color getColorForResultType(ResultTypes type) {
switch (type) {
case ResultTypes.criticalLow:
case ResultTypes.criticalHigh:
case ResultTypes.lowCriticalLow:
case ResultTypes.highCriticalHigh:
return Color(0xFFDE7676);
case ResultTypes.low:
case ResultTypes.high:
return Color(0xFFEAB157);
case ResultTypes.normal:
return Color(0xFF09AA28);
default:
return Color(0xFF09AA28);
}
}
}
class ResultStatusWidget extends StatelessWidget {
@ -423,6 +476,7 @@ class ResultStatusWidget extends StatelessWidget {
switch (type) {
case ResultTypes.criticalLow:
case ResultTypes.lowCriticalLow:
color = const Color(0xFFDE7676);
icon = Icons.arrow_circle_down;
break;
@ -431,6 +485,7 @@ class ResultStatusWidget extends StatelessWidget {
icon = Icons.arrow_circle_down;
break;
case ResultTypes.criticalHigh:
case ResultTypes.highCriticalHigh:
color = const Color(0xFFDE7676);
icon = Icons.arrow_circle_up;
break;
@ -442,6 +497,10 @@ class ResultStatusWidget extends StatelessWidget {
color = const Color(0xFF09AA28);
icon = Icons.check_circle;
break;
case ResultTypes.unknown:
color = const Color(0xFFEAB157);
icon = Icons.arrow_circle_up;
break;
}
// Return the icon if defined, otherwise a placeholder widget

@ -146,7 +146,7 @@ dependencies:
cached_network_image: ^3.3.0
flutter_tts: ^3.6.1
# vibration: ^1.7.3
flutter_nfc_kit: ^3.3.1
flutter_nfc_kit: ^3.3.3
#geofencing: any
speech_to_text: ^6.1.1
@ -155,7 +155,7 @@ dependencies:
in_app_review: ^2.0.3
badges: ^3.1.2
flutter_app_icon_badge: ^2.0.0
# flutter_app_icon_badge: ^2.0.0
# dropdown_search: 5.0.6
youtube_player_flutter: ^9.1.0
@ -183,6 +183,7 @@ dependencies:
win32: ^5.5.4
cloudflare_turnstile: ^2.0.1
readmore: ^3.0.0
dependency_overrides:

Loading…
Cancel
Save