Merge branch 'feature-ucaf' into 'development'

Feature ucaf

See merge request Cloud_Solution/doctor_app_flutter!253
merge-requests/255/merge
Mohammad Aljammal 4 years ago
commit 40ba189036

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -587,4 +587,20 @@ const Map<String, Map<String, String>> localizedValues = {
'en': "There is no detail for this patient",
'ar': "لا توجد تفاصيل لهذا المريض"
},
"systolic-lng": {
"en": "Systolic",
"ar": "الإنقباض"
},
"diastolic-lng": {
"en": "Diastolic",
"ar": "الإنبساط"
},
"mass": {"en": "Mass", "ar": "كتلة"},
"temp-c": {"en": "°C", "ar": "°س"},
"bpm": {"en": "bpm", "ar": "نبضة"},
"respiration-signs": {"en": "Respiration", "ar": "تنفس"},
"sys-dias": {"en": "SBP/DBP", "ar": "إنقباض/إنبساط"},
"body": {"en": "Body \n Mass", "ar": "كتلة\nالجسم"},
'respirationRate': {'en': 'Respiration Rate', 'ar': 'معدل التنفس'},
'heart': {'en': 'Heart', 'ar': 'قلب'},
};

@ -3,20 +3,20 @@ import 'package:doctor_app_flutter/core/service/base/base_service.dart';
import 'package:doctor_app_flutter/models/patient/PatientArrivalEntity.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_model.dart';
class VitalSignsService extends BaseService {
List<VitalSignResModel> patientVitalSignList = [];
List<VitalSignResModel> patientVitalSignOrderdSubList = [];
VitalSignData patientVitalSigns;
List<VitalSignHistory> patientVitalSignsHistory = [];
Future getPatientVitalSign(PatiantInformtion patient) async {
patientVitalSigns = null;
hasError = false;
Map<String, dynamic> body = Map();
body['PatientMRN'] = 2954208; //patient.patientMRN;
body['AppointmentNo'] = "2016055308"; //patient.appointmentNo;
body['EpisodeID'] = 210011002; //patient.episodeNo;
body['PatientMRN'] = patient.patientMRN;
body['AppointmentNo'] = patient.appointmentNo;
body['EpisodeID'] = patient.episodeNo;
await baseAppClient.post(
GET_PATIENT_VITAL_SIGN_DATA,
onSuccess: (dynamic response, int statusCode) {
@ -35,4 +35,37 @@ class VitalSignsService extends BaseService {
body: body,
);
}
Future getPatientVitalSignsHistory(
PatiantInformtion patient, String fromDate, String toDate) async {
patientVitalSigns = null;
hasError = false;
Map<String, dynamic> body = Map();
body['PatientMRN'] = patient.patientMRN;
body['AppointmentNo'] = patient.appointmentNo;
body['EpisodeID'] = patient.episodeNo;
body['PatientTypeID'] = 1;
body['PatientType'] = 1;
body['DeviceTypeID'] = 1;
body['isDentalAllowedBackend'] = false;
body['From'] = fromDate;
body['To'] = toDate;
await baseAppClient.post(
GET_PATIENT_VITAL_SIGN_DATA,
onSuccess: (dynamic response, int statusCode) {
patientVitalSignsHistory.clear();
if (response['VitalSignsHistory'] != null) {
response['VitalSignsHistory'].forEach((v) {
patientVitalSignsHistory.add(new VitalSignHistory.fromJson(v));
});
}
},
onFailure: (String error, int statusCode) {
hasError = true;
super.error = error.toString();
},
body: body,
);
}
}

@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart';
import 'package:doctor_app_flutter/models/patient/PatientArrivalEntity.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_model.dart';
import '../../locator.dart';
@ -12,6 +13,15 @@ class VitalSignsViewModel extends BaseViewModel {
VitalSignsService _vitalSignService = locator<VitalSignsService>();
VitalSignData get patientVitalSigns => _vitalSignService.patientVitalSigns;
List<VitalSignHistory> get patientVitalSignsHistory => _vitalSignService.patientVitalSignsHistory;
String heightCm = "0";
String weightKg = "0";
String bodyMax = "0";
String temperatureCelcius = "0";
String hartRat = "0";
String respirationBeatPerMinute = "0";
String bloodPressure = "0 / 0";
Future getPatientVitalSign(PatiantInformtion patient) async {
setState(ViewState.Busy);
@ -20,47 +30,51 @@ class VitalSignsViewModel extends BaseViewModel {
error = _vitalSignService.error;
setState(ViewState.Error);
} else {
// if (patientVitalSigns == null) {
// makeVitalSignDemoData();
// }
setState(ViewState.Idle);
}
}
makeVitalSignDemoData(){
_vitalSignService.patientVitalSigns = VitalSignData(
appointmentNo: 2016053265,
bloodPressureCuffLocation: 0,
bloodPressureCuffSize: 0,
bloodPressureHigher: 38,
bloodPressureLower: 32,
bloodPressurePatientPosition: 1,
bodyMassIndex: 31.11,
fio2: 0,
headCircumCm: 0,
heightCm: 150,
idealBodyWeightLbs: -2,
isPainManagementDone: false,
isVitalsRequired: true,
leanBodyWeightLbs: 0,
painCharacter: null,
painDuration: null,
painFrequency: null,
painLocation: null,
painScore: 0,
patientMRN: 3333274,
patientType: 1,
pulseBeatPerMinute: 0,
pulseRhythm: 0,
respirationBeatPerMinute: 0,
respirationPattern: 0,
sao2: 0,
status: 47,
temperatureCelcius: 40,
temperatureCelciusMethod: 1,
waistSizeInch: 39,
weightKg: 70,
);
Future getPatientVitalSignHistory(PatiantInformtion patient, String from, String to) async {
setState(ViewState.Busy);
await _vitalSignService.getPatientVitalSignsHistory(patient, from, to);
if (_vitalSignService.hasError) {
error = _vitalSignService.error;
setState(ViewState.Error);
} else {
patientVitalSignsHistory.forEach((element) {
if (heightCm == "0" || heightCm == null || heightCm == 'null') {
heightCm = element.heightCm.toString();
}
if (weightKg == "0" || weightKg == null || weightKg == 'null') {
weightKg = element.weightKg.toString();
}
if (bodyMax == "0" ||
bodyMax == null ||
bodyMax == 'null') {
bodyMax = element.bodyMassIndex.toString();
}
if (temperatureCelcius == "0" ||
temperatureCelcius == null ||
temperatureCelcius == 'null') {
temperatureCelcius = element.temperatureCelcius.toString();
}
if (hartRat == "0" || hartRat == null || hartRat == 'null') {
hartRat = element.pulseBeatPerMinute.toString();
}
if (respirationBeatPerMinute == "0" ||
respirationBeatPerMinute == null ||
respirationBeatPerMinute == 'null') {
respirationBeatPerMinute =
element.respirationBeatPerMinute.toString();
}
if (bloodPressure == "0 / 0" ||
bloodPressure == null ||
bloodPressure == 'null') {
bloodPressure = element.bloodPressure.toString();
}
});
setState(ViewState.Idle);
}
}
String getBMI(var bodyMassIndex) {

@ -27,11 +27,14 @@ const LOCATIONS = const [
];
enum vitalSignDetails {
bodyMeasurements,
temperature,
pulse,
pespiration,
bloodPressure,
oxygenation,
painScale
BodyMeasurements,
Temperature,
Pulse,
Prescriptions,
BloodPressure,
Respiration,
heart,
PainScale,
Weight,
Height
}

@ -33,36 +33,36 @@ class VitalSignData {
VitalSignData(
{this.appointmentNo,
this.bloodPressureCuffLocation,
this.bloodPressureCuffSize,
this.bloodPressureHigher,
this.bloodPressureLower,
this.bloodPressurePatientPosition,
this.bodyMassIndex,
this.fio2,
this.headCircumCm,
this.heightCm,
this.idealBodyWeightLbs,
this.isPainManagementDone,
this.isVitalsRequired,
this.leanBodyWeightLbs,
this.painCharacter,
this.painDuration,
this.painFrequency,
this.painLocation,
this.painScore,
this.patientMRN,
this.patientType,
this.pulseBeatPerMinute,
this.pulseRhythm,
this.respirationBeatPerMinute,
this.respirationPattern,
this.sao2,
this.status,
this.temperatureCelcius,
this.temperatureCelciusMethod,
this.waistSizeInch,
this.weightKg});
this.bloodPressureCuffLocation,
this.bloodPressureCuffSize,
this.bloodPressureHigher,
this.bloodPressureLower,
this.bloodPressurePatientPosition,
this.bodyMassIndex,
this.fio2,
this.headCircumCm,
this.heightCm,
this.idealBodyWeightLbs,
this.isPainManagementDone,
this.isVitalsRequired,
this.leanBodyWeightLbs,
this.painCharacter,
this.painDuration,
this.painFrequency,
this.painLocation,
this.painScore,
this.patientMRN,
this.patientType,
this.pulseBeatPerMinute,
this.pulseRhythm,
this.respirationBeatPerMinute,
this.respirationPattern,
this.sao2,
this.status,
this.temperatureCelcius,
this.temperatureCelciusMethod,
this.waistSizeInch,
this.weightKg});
VitalSignData.fromJson(Map<String, dynamic> json) {
appointmentNo = json['appointmentNo'];
@ -133,4 +133,5 @@ class VitalSignData {
data['weightKg'] = this.weightKg;
return data;
}
}

@ -0,0 +1,257 @@
class VitalSignHistory {
var transNo;
var projectID;
var weightKg;
var heightCm;
var temperatureCelcius;
var pulseBeatPerMinute;
var respirationBeatPerMinute;
var bloodPressureLower;
var bloodPressureHigher;
var sAO2;
var fIO2;
var painScore;
var bodyMassIndex;
var headCircumCm;
var leanBodyWeightLbs;
var idealBodyWeightLbs;
var temperatureCelciusMethod;
var pulseRhythm;
var respirationPattern;
var bloodPressureCuffLocation;
var bloodPressureCuffSize;
var bloodPressurePatientPosition;
var painLocation;
var painDuration;
var painCharacter;
var painFrequency;
bool isPainManagementDone;
var status;
bool isVitalsRequired;
var patientID;
var createdOn;
var doctorID;
var clinicID;
var triageCategory;
var gCScore;
var lineItemNo;
DateTime vitalSignDate;
var actualTimeTaken;
var sugarLevel;
var fBS;
var rBS;
var observationType;
var heartRate;
var muscleTone;
var reflexIrritability;
var bodyColor;
var isFirstAssessment;
var dateofBirth;
var timeOfBirth;
var bloodPressure;
var bloodPressureCuffLocationDesc;
var bloodPressureCuffSizeDesc;
var bloodPressurePatientPositionDesc;
var clinicName;
var doctorImageURL;
var doctorName;
var painScoreDesc;
var pulseRhythmDesc;
var respirationPatternDesc;
var temperatureCelciusMethodDesc;
var time;
VitalSignHistory(
{this.transNo,
this.projectID,
this.weightKg,
this.heightCm,
this.temperatureCelcius,
this.pulseBeatPerMinute,
this.respirationBeatPerMinute,
this.bloodPressureLower,
this.bloodPressureHigher,
this.sAO2,
this.fIO2,
this.painScore,
this.bodyMassIndex,
this.headCircumCm,
this.leanBodyWeightLbs,
this.idealBodyWeightLbs,
this.temperatureCelciusMethod,
this.pulseRhythm,
this.respirationPattern,
this.bloodPressureCuffLocation,
this.bloodPressureCuffSize,
this.bloodPressurePatientPosition,
this.painLocation,
this.painDuration,
this.painCharacter,
this.painFrequency,
this.isPainManagementDone,
this.status,
this.isVitalsRequired,
this.patientID,
this.createdOn,
this.doctorID,
this.clinicID,
this.triageCategory,
this.gCScore,
this.lineItemNo,
this.vitalSignDate,
this.actualTimeTaken,
this.sugarLevel,
this.fBS,
this.rBS,
this.observationType,
this.heartRate,
this.muscleTone,
this.reflexIrritability,
this.bodyColor,
this.isFirstAssessment,
this.dateofBirth,
this.timeOfBirth,
this.bloodPressure,
this.bloodPressureCuffLocationDesc,
this.bloodPressureCuffSizeDesc,
this.bloodPressurePatientPositionDesc,
this.clinicName,
this.doctorImageURL,
this.doctorName,
this.painScoreDesc,
this.pulseRhythmDesc,
this.respirationPatternDesc,
this.temperatureCelciusMethodDesc,
this.time});
VitalSignHistory.fromJson(Map<String, dynamic> json) {
transNo = json['TransNo'];
projectID = json['ProjectID'];
weightKg = json['WeightKg'];
heightCm = json['HeightCm'];
temperatureCelcius = json['TemperatureCelcius'];
pulseBeatPerMinute = json['PulseBeatPerMinute'];
respirationBeatPerMinute = json['RespirationBeatPerMinute'];
bloodPressureLower = json['BloodPressureLower'];
bloodPressureHigher = json['BloodPressureHigher'];
sAO2 = json['SAO2'];
fIO2 = json['FIO2'];
painScore = json['PainScore'];
bodyMassIndex = json['BodyMassIndex'];
headCircumCm = json['HeadCircumCm'];
leanBodyWeightLbs = json['LeanBodyWeightLbs'];
idealBodyWeightLbs = json['IdealBodyWeightLbs'];
temperatureCelciusMethod = json['TemperatureCelciusMethod'];
pulseRhythm = json['PulseRhythm'];
respirationPattern = json['RespirationPattern'];
bloodPressureCuffLocation = json['BloodPressureCuffLocation'];
bloodPressureCuffSize = json['BloodPressureCuffSize'];
bloodPressurePatientPosition = json['BloodPressurePatientPosition'];
painLocation = json['PainLocation'];
painDuration = json['PainDuration'];
painCharacter = json['PainCharacter'];
painFrequency = json['PainFrequency'];
isPainManagementDone = json['IsPainManagementDone'];
status = json['Status'];
isVitalsRequired = json['IsVitalsRequired'];
patientID = json['PatientID'];
createdOn = json['CreatedOn'];
doctorID = json['DoctorID'];
clinicID = json['ClinicID'];
triageCategory = json['TriageCategory'];
gCScore = json['GCScore'];
lineItemNo = json['LineItemNo'];
vitalSignDate = json['VitalSignDate'];
actualTimeTaken = json['ActualTimeTaken'];
sugarLevel = json['SugarLevel'];
fBS = json['FBS'];
rBS = json['RBS'];
observationType = json['ObservationType'];
heartRate = json['HeartRate'];
muscleTone = json['MuscleTone'];
reflexIrritability = json['ReflexIrritability'];
bodyColor = json['BodyColor'];
isFirstAssessment = json['IsFirstAssessment'];
dateofBirth = json['DateofBirth'];
timeOfBirth = json['TimeOfBirth'];
bloodPressure = json['BloodPressure'];
bloodPressureCuffLocationDesc = json['BloodPressureCuffLocationDesc'];
bloodPressureCuffSizeDesc = json['BloodPressureCuffSizeDesc'];
bloodPressurePatientPositionDesc = json['BloodPressurePatientPositionDesc'];
clinicName = json['ClinicName'];
doctorImageURL = json['DoctorImageURL'];
doctorName = json['DoctorName'];
painScoreDesc = json['PainScoreDesc'];
pulseRhythmDesc = json['PulseRhythmDesc'];
respirationPatternDesc = json['RespirationPatternDesc'];
temperatureCelciusMethodDesc = json['TemperatureCelciusMethodDesc'];
time = json['Time'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['TransNo'] = this.transNo;
data['ProjectID'] = this.projectID;
data['WeightKg'] = this.weightKg;
data['HeightCm'] = this.heightCm;
data['TemperatureCelcius'] = this.temperatureCelcius;
data['PulseBeatPerMinute'] = this.pulseBeatPerMinute;
data['RespirationBeatPerMinute'] = this.respirationBeatPerMinute;
data['BloodPressureLower'] = this.bloodPressureLower;
data['BloodPressureHigher'] = this.bloodPressureHigher;
data['SAO2'] = this.sAO2;
data['FIO2'] = this.fIO2;
data['PainScore'] = this.painScore;
data['BodyMassIndex'] = this.bodyMassIndex;
data['HeadCircumCm'] = this.headCircumCm;
data['LeanBodyWeightLbs'] = this.leanBodyWeightLbs;
data['IdealBodyWeightLbs'] = this.idealBodyWeightLbs;
data['TemperatureCelciusMethod'] = this.temperatureCelciusMethod;
data['PulseRhythm'] = this.pulseRhythm;
data['RespirationPattern'] = this.respirationPattern;
data['BloodPressureCuffLocation'] = this.bloodPressureCuffLocation;
data['BloodPressureCuffSize'] = this.bloodPressureCuffSize;
data['BloodPressurePatientPosition'] = this.bloodPressurePatientPosition;
data['PainLocation'] = this.painLocation;
data['PainDuration'] = this.painDuration;
data['PainCharacter'] = this.painCharacter;
data['PainFrequency'] = this.painFrequency;
data['IsPainManagementDone'] = this.isPainManagementDone;
data['Status'] = this.status;
data['IsVitalsRequired'] = this.isVitalsRequired;
data['PatientID'] = this.patientID;
data['CreatedOn'] = this.createdOn;
data['DoctorID'] = this.doctorID;
data['ClinicID'] = this.clinicID;
data['TriageCategory'] = this.triageCategory;
data['GCScore'] = this.gCScore;
data['LineItemNo'] = this.lineItemNo;
data['VitalSignDate'] = this.vitalSignDate;
data['ActualTimeTaken'] = this.actualTimeTaken;
data['SugarLevel'] = this.sugarLevel;
data['FBS'] = this.fBS;
data['RBS'] = this.rBS;
data['ObservationType'] = this.observationType;
data['HeartRate'] = this.heartRate;
data['MuscleTone'] = this.muscleTone;
data['ReflexIrritability'] = this.reflexIrritability;
data['BodyColor'] = this.bodyColor;
data['IsFirstAssessment'] = this.isFirstAssessment;
data['DateofBirth'] = this.dateofBirth;
data['TimeOfBirth'] = this.timeOfBirth;
data['BloodPressure'] = this.bloodPressure;
data['BloodPressureCuffLocationDesc'] = this.bloodPressureCuffLocationDesc;
data['BloodPressureCuffSizeDesc'] = this.bloodPressureCuffSizeDesc;
data['BloodPressurePatientPositionDesc'] =
this.bloodPressurePatientPositionDesc;
data['ClinicName'] = this.clinicName;
data['DoctorImageURL'] = this.doctorImageURL;
data['DoctorName'] = this.doctorName;
data['PainScoreDesc'] = this.painScoreDesc;
data['PulseRhythmDesc'] = this.pulseRhythmDesc;
data['RespirationPatternDesc'] = this.respirationPatternDesc;
data['TemperatureCelciusMethodDesc'] = this.temperatureCelciusMethodDesc;
data['Time'] = this.time;
return data;
}
}

@ -85,9 +85,9 @@ const String PATIENT_ORDERS = 'patients/patient_orders';
const String PATIENT_INSURANCE_APPROVALS =
'patients/patient_insurance_approvals';
const String VITAL_SIGN_DETAILS = 'patients/vital-sign-details';
const String PATIENT_VITAL_SIGN = 'patients/vital-sign-data';
const String CREATE_EPISODE = 'patients/create-episode';
const String UPDATE_EPISODE = 'patients/update-episode';
const String PATIENT_VITAL_SIGN = 'patients/vital-sign-data';
const String PATIENT_ADMISSION_REQUEST = 'patients/admission-request';
const String PATIENT_ADMISSION_REQUEST_2 = 'patients/admission-request-second';
const String PATIENT_ADMISSION_REQUEST_3 = 'patients/admission-request-third';

@ -676,7 +676,9 @@ class _PatientsScreenState extends State<PatientsScreen> {
PATIENTS_PROFILE,
arguments: {
"patient": item,
"patientType":patientType
"patientType":patientType,
"from" : patient.getFrom,
"to" : patient.getTo,
});
},
),

@ -112,7 +112,7 @@ class MyReferralDetailScreen extends StatelessWidget {
PatientProfileButton(
key: key,
patient: model.patientArrivalList[0],
route: PATIENT_VITAL_SIGN,
route: VITAL_SIGN_DETAILS /*PATIENT_VITAL_SIGN*/,
nameLine1: TranslationBase.of(context).vital,
nameLine2: TranslationBase.of(context).signs,
icon: 'heartbeat.png'),

@ -0,0 +1,217 @@
import 'package:doctor_app_flutter/widgets/charts/app_time_series_chart.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class LineChartCurved extends StatelessWidget {
final String title;
final List<TimeSeriesSales2> timeSeries;
final int indexes;
LineChartCurved({this.title, this.timeSeries, this.indexes});
List<int> xAxixs = List();
List<double> yAxixs = List();
@override
Widget build(BuildContext context) {
getXaxix();
getYaxix();
return AspectRatio(
aspectRatio: 1.1,
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(18)),
// color: Colors.white,
),
child: Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
const SizedBox(
height: 4,
),
Text(
title,
style: TextStyle(
color: Colors.black,
fontSize: 15,
letterSpacing: 2),
textAlign: TextAlign.center,
),
SizedBox(height: 10,),
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 18.0, left: 16.0),
child: LineChart(
sampleData1(context),
swapAnimationDuration: const Duration(milliseconds: 250),
),
),
),
const SizedBox(
height: 10,
),
],
),
],
),
),
);
}
getXaxix() {
for (int index = 0; index < timeSeries.length; index++) {
int mIndex = indexes * index;
if (mIndex < timeSeries.length) {
xAxixs.add(mIndex);
}
}
}
getYaxix() {
int indexess= (timeSeries.length*0.30).toInt();
for (int index = 0; index < timeSeries.length; index++) {
int mIndex = indexess * index;
if (mIndex < timeSeries.length) {
yAxixs.add(timeSeries[mIndex].sales);
}
}
}
LineChartData sampleData1(context) {
return LineChartData(
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
tooltipBgColor: Colors.white,
),
touchCallback: (LineTouchResponse touchResponse) {},
handleBuiltInTouches: true,
),
gridData: FlGridData(
show: true, drawVerticalLine: true, drawHorizontalLine: true),
titlesData: FlTitlesData(
bottomTitles: SideTitles(
showTitles: true,
getTextStyles: (value) => const TextStyle(
color: Colors.black,
fontSize: 10,
),
rotateAngle:-65,
//rotateAngle:-65,
margin: 22,
getTitles: (value) {
if (timeSeries.length < 15) {
if (timeSeries.length > value.toInt()) {
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
} else
return '';
} else {
if (value.toInt() == 0)
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
if (value.toInt() == timeSeries.length - 1)
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
if (xAxixs.contains(value.toInt())) {
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
}
}
return '';
},
),
leftTitles: SideTitles(
showTitles: true,
getTextStyles: (value) => const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 10,
),
getTitles: (value) {
// if (timeSeries.length < 10) {
// return '${value.toInt()}';
// } else {
// if (value == getMinY())
// return '${value.toInt()}';
// if (value == getMaxY())
// return '${value.toInt()}';
// if (yAxixs.contains(value)) {
// return '${value.toInt()}';
// }
// return '';
// }
return '${value.toInt()}';
},
margin: 12,
),
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: Colors.black,
width: 0.5,
),
left: BorderSide(
color: Colors.black,
),
right: BorderSide(
color: Colors.black,
),
top: BorderSide(
color: Colors.transparent,
),
),
),
minX: 0,
maxX: (timeSeries.length - 1).toDouble(),
maxY: getMaxY()+0.3,
minY: getMinY(),
lineBarsData: getData(context),
);
}
double getMaxY() {
double max = 0;
timeSeries.forEach((element) {
double resultValueDouble = element.sales;
if (resultValueDouble > max) max = resultValueDouble;
});
return max.roundToDouble() ;
}
double getMinY() {
double min = timeSeries[0].sales;
timeSeries.forEach((element) {
double resultValueDouble = element.sales;
if (resultValueDouble < min) min = resultValueDouble;
});
int value = min.toInt();
return value.toDouble();
}
List<LineChartBarData> getData(context) {
List<FlSpot> spots = List();
for (int index = 0; index < timeSeries.length; index++) {
spots.add(FlSpot(index.toDouble(), timeSeries[index].sales));
}
final LineChartBarData lineChartBarData1 = LineChartBarData(
spots: spots,
isCurved: true,
colors: [Theme.of(context).primaryColor],
barWidth: 5,
isStrokeCapRound: true,
dotData: FlDotData(
show: false,
),
belowBarData: BarAreaData(
show: false,
),
);
return [
lineChartBarData1,
];
}
}

@ -0,0 +1,257 @@
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/charts/app_time_series_chart.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class LineChartCurvedBloodPressure extends StatelessWidget {
final String title;
final List<TimeSeriesSales2> timeSeries1;
final List<TimeSeriesSales2> timeSeries2;
final int indexes;
LineChartCurvedBloodPressure(
{this.title, this.timeSeries1, this.indexes, this.timeSeries2});
List<int> xAxixs = List();
List<double> yAxixs = List();
@override
Widget build(BuildContext context) {
getXaxix();
return AspectRatio(
aspectRatio: 1.1,
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(18)),
// color: Colors.white,
),
child: Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
const SizedBox(
height: 15,
),
Text(
title,
style: TextStyle(
color: Colors.black, fontSize: 15, letterSpacing: 2),
textAlign: TextAlign.center,
),
SizedBox(
height: 10,
),
Expanded(
child: Padding(
padding:
const EdgeInsets.only(right: 18.0, left: 16.0, top: 15),
child: LineChart(
sampleData1(context),
swapAnimationDuration: const Duration(milliseconds: 250),
),
),
),
SizedBox(
height: 10,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Theme.of(context).primaryColor),
),
SizedBox(width: 5,),
AppText(TranslationBase.of(context).systolicLng)
],
),
SizedBox(width: 15,),
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.grey),
),
SizedBox(width: 5,),
AppText(TranslationBase.of(context).diastolicLng)
],
),
],
)
],
),
],
),
),
);
}
getXaxix() {
for (int index = 0; index < timeSeries1.length; index++) {
int mIndex = indexes * index;
if (mIndex < timeSeries1.length) {
xAxixs.add(mIndex);
}
}
}
LineChartData sampleData1(context) {
return LineChartData(
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
tooltipBgColor: Colors.white,
),
touchCallback: (LineTouchResponse touchResponse) {},
handleBuiltInTouches: true,
),
gridData: FlGridData(
show: true, drawVerticalLine: true, drawHorizontalLine: true),
titlesData: FlTitlesData(
bottomTitles: SideTitles(
showTitles: true,
getTextStyles: (value) => const TextStyle(
color: Colors.black,
fontSize: 10,
),
rotateAngle: -65,
//rotateAngle:-65,
margin: 22,
getTitles: (value) {
if (timeSeries1.length < 15) {
if (timeSeries1.length > value.toInt()) {
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
} else
return '';
} else {
if (value.toInt() == 0)
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
if (value.toInt() == timeSeries1.length - 1)
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
if (xAxixs.contains(value.toInt())) {
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
}
}
return '';
},
),
leftTitles: SideTitles(
showTitles: true,
getTextStyles: (value) => const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 10,
),
getTitles: (value) {
return '${value.toInt()}';
},
margin: 12,
),
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: Colors.black,
width: 0.5,
),
left: BorderSide(
color: Colors.black,
),
right: BorderSide(
color: Colors.black,
),
top: BorderSide(
color: Colors.transparent,
),
),
),
minX: 0,
maxX: (timeSeries1.length - 1).toDouble(),
maxY: getMaxY() + 0.3,
minY: getMinY(),
lineBarsData: getData(context),
);
}
double getMaxY() {
double max = 0;
timeSeries1.forEach((element) {
double resultValueDouble = element.sales;
if (resultValueDouble > max) max = resultValueDouble;
});
timeSeries2.forEach((element) {
double resultValueDouble = element.sales;
if (resultValueDouble > max) max = resultValueDouble;
});
return max.roundToDouble();
}
double getMinY() {
double min = timeSeries1[0].sales;
timeSeries1.forEach((element) {
double resultValueDouble = element.sales;
if (resultValueDouble < min) min = resultValueDouble;
});
timeSeries2.forEach((element) {
double resultValueDouble = element.sales;
if (resultValueDouble < min) min = resultValueDouble;
});
int value = min.toInt();
return value.toDouble();
}
List<LineChartBarData> getData(context) {
List<FlSpot> spots = List();
for (int index = 0; index < timeSeries1.length; index++) {
spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales));
}
List<FlSpot> spots2 = List();
for (int index = 0; index < timeSeries2.length; index++) {
spots2.add(FlSpot(index.toDouble(), timeSeries2[index].sales));
}
final LineChartBarData lineChartBarData1 = LineChartBarData(
spots: spots,
isCurved: true,
colors: [Theme.of(context).primaryColor],
barWidth: 5,
isStrokeCapRound: true,
dotData: FlDotData(
show: false,
),
belowBarData: BarAreaData(
show: false,
),
);
final LineChartBarData lineChartBarData2 = LineChartBarData(
spots: spots2,
isCurved: true,
colors: [Colors.grey],
barWidth: 5,
isStrokeCapRound: true,
dotData: FlDotData(
show: false,
),
belowBarData: BarAreaData(
show: false,
),
);
return [lineChartBarData1, lineChartBarData2];
}
}

@ -18,6 +18,8 @@ class PatientVitalSignScreen extends StatelessWidget {
Widget build(BuildContext context) {
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
PatiantInformtion patient = routeArgs['patient'];
String from = routeArgs['from'];
String to = routeArgs['to'];
return BaseView<VitalSignsViewModel>(
onModelReady: (model) => model.getPatientVitalSign(patient),
@ -115,7 +117,7 @@ class PatientVitalSignScreen extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
/*Row(
children: [
AppText(
"${TranslationBase.of(context).waistSize} :",
@ -133,7 +135,7 @@ class PatientVitalSignScreen extends StatelessWidget {
fontWeight: FontWeight.normal,
),
],
),
),*/
Row(
children: [
AppText(

@ -0,0 +1,146 @@
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
import 'package:doctor_app_flutter/util/date-utils.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class VitalSignBloodPressureWidget extends StatefulWidget {
final List<VitalSignHistory> vitalList;
final String title1;
final String title2;
final String title3;
final String viewKey1;
final String viewKey2;
VitalSignBloodPressureWidget(
{Key key, this.vitalList, this.title1, this.title2, this.viewKey1, this.title3, this.viewKey2});
@override
_VitalSignDetailsWidgetState createState() => _VitalSignDetailsWidgetState();
}
class _VitalSignDetailsWidgetState extends State<VitalSignBloodPressureWidget> {
@override
Widget build(BuildContext context) {
ProjectViewModel projectViewModel = Provider.of(context);
return Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)),
border: Border.all(color: Colors.grey, width: 1),
),
margin: EdgeInsets.all(20),
child: Container(
color: Colors.transparent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Table(
border: TableBorder.symmetric(
inside: BorderSide(width: 2.0, color: Colors.grey[300]),
),
children: fullData(projectViewModel),
),
],
),
),
);
}
List<TableRow> fullData(ProjectViewModel projectViewModel) {
List<TableRow> tableRow = [];
tableRow.add(TableRow(children: [
Container(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.only(
topLeft:projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
),
),
child: Center(
child: AppText(
TranslationBase.of(context).date,
color: Colors.white,
),
),
height: 60,
),
),
Container(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
),
child: Center(
child: AppText(widget.title2, color: Colors.white),
),
height: 60),
),
Container(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.only(
topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
),
),
child: Center(
child: AppText(widget.title3, color: Colors.white),
),
height: 60),
),
]));
widget.vitalList.forEach((vital) {
var data = vital.toJson()[widget.viewKey1];
if (data != 0)
tableRow.add(TableRow(children: [
Container(
child: Container(
padding: EdgeInsets.all(10),
color: Colors.white,
child: Center(
child: AppText(
'${projectViewModel.isArabic ? DateUtils.getWeekDayArabic(vital.vitalSignDate.weekday) : DateUtils.getWeekDay(vital.vitalSignDate.weekday)}, ${vital.vitalSignDate.day} ${projectViewModel.isArabic ? DateUtils.getMonthArabic(vital.vitalSignDate.month) : DateUtils.getMonth(vital.vitalSignDate.month)}, ${vital.vitalSignDate.year} ',
textAlign: TextAlign.center,
),
),
),
),
Container(
child: Container(
padding: EdgeInsets.all(10),
color: Colors.white,
child: Center(
child: AppText(
'${vital.toJson()[widget.viewKey1]}',
textAlign: TextAlign.center,
),
),
),
),
Container(
child: Container(
padding: EdgeInsets.all(10),
color: Colors.white,
child: Center(
child: AppText(
'${vital.toJson()[widget.viewKey2]}',
textAlign: TextAlign.center,
),
),
),
),
]));
});
return tableRow;
}
}

@ -1,246 +1,197 @@
import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_req_model.dart';
import 'package:doctor_app_flutter/core/viewModel/patient-vital-sign-viewmodel.dart';
import 'package:doctor_app_flutter/lookups/patient_lookup.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item.dart';
import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/errors/dr_app_embedded_error.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import '../../../../config/shared_pref_kay.dart';
import '../../../../config/size_config.dart';
import '../../../../lookups/patient_lookup.dart';
import '../../../../models/patient/patiant_info_model.dart';
import '../../../../models/patient/vital_sign/vital_sign_res_model.dart';
import '../../../../routes.dart';
import '../../../../screens/patients/profile/vital_sign/vital_sign_item.dart';
import '../../../../util/dr_app_shared_pref.dart';
import '../../../../widgets/shared/app_scaffold_widget.dart';
class VitalSignDetailsScreen extends StatelessWidget {
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
int appointmentNo;
int projectID;
bool isNotOneAppointment;
VitalSignDetailsScreen({this.appointmentNo, this.projectID,this.isNotOneAppointment=true});
class VitalSignDetailsScreen extends StatefulWidget {
// VitalSignDetailsScreen({Key key, this.vitalSing}) : super(key: key);
@override
_VitalSignDetailsScreenState createState() => _VitalSignDetailsScreenState();
}
class _VitalSignDetailsScreenState extends State<VitalSignDetailsScreen> {
VitalSignResModel vitalSing;
String url = "assets/images/";
/*
*@author: Elham Rababah
*@Date:28/4/2020
*@param: context
*@return:
*@desc: getVitalSignList Function
*/
getVitalSignList(BuildContext context, PatientViewModel model) async {
Widget build(BuildContext context) {
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
PatiantInformtion patient = routeArgs['patient'];
String token = await sharedPref.getString(TOKEN);
String type = await sharedPref.getString(SLECTED_PATIENT_TYPE);
int inOutpatientType = 1;
if (type == '0') {
inOutpatientType = 2;
}
print(type);
VitalSignReqModel vitalSignReqModel = VitalSignReqModel(
patientID: patient.patientId,
projectID: patient.projectId,
tokenID: token,
patientTypeID: patient.patientType,
inOutpatientType: inOutpatientType,
languageID: 2,
transNo:
patient.admissionNo != null ? int.parse(patient.admissionNo) : 0);
model.getPatientVitalSign(vitalSignReqModel.toJson());
}
final double contWidth = SizeConfig.realScreenWidth * 0.70;
String from = routeArgs['from'];
String to = routeArgs['to'];
String imageBasePath = 'assets/images/';
@override
Widget build(BuildContext context) {
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
vitalSing = routeArgs['vitalSing'];
return BaseView<PatientViewModel>(
onModelReady: (model) => getVitalSignList(context, model),
builder: (_, model, w) => AppScaffold(
baseViewModel: model,
return BaseView<VitalSignsViewModel>(
onModelReady: (model) => model.getPatientVitalSignHistory(patient, from, to),
builder: (_, mode, widget) => AppScaffold(
isShowAppBar: true,
baseViewModel: mode,
appBarTitle: TranslationBase.of(context).vitalSign,
body: model.patientVitalSignOrderdSubList.length == 0
? DrAppEmbeddedError(
error: 'You don\'t have any vital Sings')
: Container(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
InkWell(
onTap: () {
Navigator.of(context).pushNamed(
BODY_MEASUREMENTS,
arguments: {
'title': TranslationBase.of(context)
.bodyMeasurements,
'key':
vitalSignDetails.bodyMeasurements
});
},
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context)
.bodyMeasurements,
url: url + 'heartbeat.png',
lastVal: model
.patientVitalSignOrderdSubList[0]
.heightCm
.toString(),
unit: 'Cm',
),
),
),
InkWell(
onTap: () {
Navigator.of(context).pushNamed(
BODY_MEASUREMENTS,
arguments: {
'title': TranslationBase.of(context)
.temperature,
'key': vitalSignDetails.temperature,
});
},
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context)
.temperature,
url: url + 'heartbeat.png',
lastVal: model
.patientVitalSignOrderdSubList[0]
.temperatureCelcius
.toString(),
unit: 'C',
),
),
),
],
body: mode.patientVitalSignsHistory.length > 0
? Container(
child: ListView(
children: <Widget>[
Row(
children: <Widget>[
InkWell(
onTap: () =>isNotOneAppointment? Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: vitalSignDetails.Height,
pageTitle: TranslationBase.of(context).height,
vitalList: mode.patientVitalSignsHistory,
),
),
):null,
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context).height,
imagePath: "${imageBasePath}vital_height.png",
lastVal: mode.heightCm,
unit: TranslationBase.of(context).cm,
),
),
),
InkWell(
onTap: () => isNotOneAppointment ? Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: vitalSignDetails.Weight,
pageTitle: TranslationBase.of(context).weight,
vitalList: mode.patientVitalSignsHistory,
),
),
):null,
child: VitalSignItem(
des: TranslationBase.of(context).weight,
imagePath: "${imageBasePath}vital_weight.png",
unit: TranslationBase.of(context).kg,
lastVal: mode.weightKg,
),
),
],
),
Row(
children: <Widget>[
InkWell(
onTap: () => isNotOneAppointment ? Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: vitalSignDetails.BodyMeasurements,
pageTitle: TranslationBase.of(context)
.bodyMeasurements,
vitalList: mode.patientVitalSignsHistory,
),
),
): null,
child: VitalSignItem(
des: TranslationBase.of(context).body,
imagePath: "${imageBasePath}vital_body_mass.png",
lastVal: mode.bodyMax,
unit: TranslationBase.of(context).mass,
),
),
InkWell(
onTap: () => isNotOneAppointment ? Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: vitalSignDetails.Temperature,
pageTitle:
TranslationBase.of(context).temperature,
vitalList: mode.patientVitalSignsHistory,
),
),
):null,
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context).temperature,
imagePath: "${imageBasePath}vital_temperature.png",
lastVal: mode.temperatureCelcius,
unit: TranslationBase.of(context).tempC,
),
Row(
children: <Widget>[
InkWell(
onTap: () {
Navigator.of(context).pushNamed(
BODY_MEASUREMENTS,
arguments: {
'title':
TranslationBase.of(context).pulse,
'key': vitalSignDetails.pulse
});
},
child: VitalSignItem(
des: TranslationBase.of(context).pulse,
url: url + 'heartbeat.png',
lastVal: model
.patientVitalSignOrderdSubList[0]
.pulseBeatPerMinute
.toString(),
unit: 'M',
),
),
InkWell(
onTap: () {
Navigator.of(context).pushNamed(
BODY_MEASUREMENTS,
arguments: {
'title': TranslationBase.of(context)
.respiration,
'key': vitalSignDetails.pespiration
});
},
child: VitalSignItem(
des:
TranslationBase.of(context).respiration,
url: url + 'heartbeat.png',
lastVal: model
.patientVitalSignOrderdSubList[0]
.respirationBeatPerMinute
.toString(),
unit: 'M',
),
),
],
),
),
],
),
Row(
children: <Widget>[
InkWell(
onTap: () => isNotOneAppointment ? Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: vitalSignDetails.heart,
pageTitle: TranslationBase.of(context).heart,
vitalList: mode.patientVitalSignsHistory,
),
),
Row(
children: <Widget>[
InkWell(
onTap: () {
Navigator.of(context).pushNamed(
BODY_MEASUREMENTS,
arguments: {
'title': TranslationBase.of(context)
.bloodPressure,
'key': vitalSignDetails.bloodPressure
});
},
child: VitalSignItem(
des: TranslationBase.of(context)
.bloodPressure,
url: url + 'heartbeat.png',
lastVal: model
.patientVitalSignOrderdSubList[0]
.bloodPressure
.toString(),
unit: '',
),
),
InkWell(
onTap: () {
Navigator.of(context).pushNamed(
BODY_MEASUREMENTS,
arguments: {
'title': TranslationBase.of(context)
.oxygenation,
'key': vitalSignDetails.oxygenation
});
},
child: VitalSignItem(
des:
TranslationBase.of(context).oxygenation,
url: url + 'heartbeat.png',
lastVal: model
.patientVitalSignOrderdSubList[0].fIO2
.toString(),
unit: '',
),
),
],
):null,
child: VitalSignItem(
des: TranslationBase.of(context).heart,
imagePath: "${imageBasePath}vital_heart_rate.png",
lastVal: mode.hartRat,
unit: TranslationBase.of(context).bpm,
),
),
InkWell(
onTap: () => isNotOneAppointment ? Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: vitalSignDetails.Respiration,
pageTitle:
TranslationBase.of(context).respirationRate,
vitalList: mode.patientVitalSignsHistory,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () {
Navigator.of(context).pushNamed(
BODY_MEASUREMENTS,
arguments: {
'title': TranslationBase.of(context)
.painScale,
'key': vitalSignDetails.painScale
});
},
child: VitalSignItem(
des: TranslationBase
.of(context)
.painScale,
url: url + 'heartbeat.png',
),
),
],
):null,
child: VitalSignItem(
des: TranslationBase.of(context).respirationRate,
imagePath: "${imageBasePath}vital_respiration.png",
lastVal: mode.respirationBeatPerMinute,
unit: TranslationBase.of(context).respirationSigns,
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () => isNotOneAppointment ? Navigator.push(
context,
FadePage(
page: VitalSignItemDetailsScreen(
pageKey: vitalSignDetails.BloodPressure,
pageTitle: TranslationBase.of(context).bloodPressure,
vitalList: mode.patientVitalSignsHistory,
),
),
],
):null,
child: VitalSignItem(
des: TranslationBase.of(context).bloodPressure,
imagePath: "${imageBasePath}vital_blood-pressure.png",
lastVal: mode.bloodPressure,
unit: TranslationBase.of(context).sysDias,
),
),
],
),
],
),
)
: Center(
child: AppText('No Data'),
),
),),);
),
);
}
}

@ -0,0 +1,122 @@
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
import 'package:doctor_app_flutter/util/date-utils.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:provider/provider.dart';
class VitalSignDetailsWidget extends StatefulWidget {
final List<VitalSignHistory> vitalList;
final String title1;
final String title2;
final String viewKey;
VitalSignDetailsWidget(
{Key key, this.vitalList, this.title1, this.title2, this.viewKey});
@override
_VitalSignDetailsWidgetState createState() => _VitalSignDetailsWidgetState();
}
class _VitalSignDetailsWidgetState extends State<VitalSignDetailsWidget> {
@override
Widget build(BuildContext context) {
ProjectViewModel projectViewModel = Provider.of(context);
return Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)),
border: Border.all(color: Colors.grey, width: 1),
),
margin: EdgeInsets.all(20),
child: Container(
color: Colors.transparent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Table(
border: TableBorder.symmetric(
inside: BorderSide(width: 2.0, color: Colors.grey[300]),
),
children: fullData(projectViewModel),
),
],
),
),
);
}
List<TableRow> fullData(ProjectViewModel projectViewModel) {
List<TableRow> tableRow = [];
tableRow.add(TableRow(children: [
Container(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.only(
topLeft:projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
),
),
child: Center(
child: AppText(
TranslationBase.of(context).date,
color: Colors.white,
),
),
height: 60,
),
),
Container(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.only(
topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
),
),
child: Center(
child: AppText(widget.title2, color: Colors.white),
),
height: 60),
)
]));
widget.vitalList.forEach((vital) {
var data = vital.toJson()[widget.viewKey];
if (data != 0)
tableRow.add(TableRow(children: [
Container(
child: Container(
padding: EdgeInsets.all(10),
color: Colors.white,
child: Center(
child: AppText(
'${projectViewModel.isArabic ? DateUtils.getWeekDayArabic(vital.vitalSignDate.weekday) : DateUtils.getWeekDay(vital.vitalSignDate.weekday)}, ${vital.vitalSignDate.day} ${projectViewModel.isArabic ? DateUtils.getMonthArabic(vital.vitalSignDate.month) : DateUtils.getMonth(vital.vitalSignDate.month)}, ${vital.vitalSignDate.year} ',
textAlign: TextAlign.center,
),
),
),
),
Container(
child: Container(
padding: EdgeInsets.all(10),
color: Colors.white,
child: Center(
child: AppText(
'${vital.toJson()[widget.viewKey]}',
textAlign: TextAlign.center,
),
),
),
),
]));
});
return tableRow;
}
}

@ -1,32 +1,23 @@
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart';
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import '../../../../config/size_config.dart';
import '../../../../widgets/shared/rounded_container_widget.dart';
/*
*@author: Elham Rababah
*@Date:03/6/2020
*@param:
*@return:
*@desc: VitalSignItem
*/
class VitalSignItem extends StatelessWidget {
const VitalSignItem(
{Key key,
@required this.url,
@required this.des,
this.lastVal = 'N/A',
this.unit = '',
this.height,
this.width})
this.width,
@required this.imagePath})
: super(key: key);
final String url;
final String des;
final String lastVal;
final String unit;
final String imagePath;
final double height;
final double width;
@ -34,52 +25,70 @@ class VitalSignItem extends StatelessWidget {
Widget build(BuildContext context) {
return RoundedContainer(
margin: 0.025 * SizeConfig.realScreenWidth,
height: 0.14 * SizeConfig.realScreenHeight,
height: 0.15 * SizeConfig.realScreenHeight,
width: 0.45 * SizeConfig.realScreenWidth,
child: Container(
padding: EdgeInsets.all(5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Text(
des,
style: TextStyle(
fontSize: 1.7 * SizeConfig.textMultiplier,
color: HexColor('#B8382C'),
fontWeight: FontWeight.bold),
),
),
Expanded(
flex: 1,
child: Column(
Container(
height: 0.10 * SizeConfig.realScreenHeight,
child: Row(
children: <Widget>[
Expanded(
child: Image.asset(
url,
height: SizeConfig.heightMultiplier * 7,
),
),
Expanded(
child: RichText(
text: TextSpan(
style: TextStyle(color: Colors.black),
children: [
new TextSpan(text: lastVal),
new TextSpan(
text: ' ${unit}',
flex: 2,
child: Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
des,
style: TextStyle(
fontSize: 1.7 * SizeConfig.textMultiplier,
color: HexColor('#B8382C'),
fontWeight: FontWeight.bold,
),
),
],
),
),
))
),
Expanded(
flex: 1,
child: Container(
child: Image.asset(
imagePath,
width: 40,
height: 40,
)),
)
],
),
)
),
Expanded(
child: Container(
width: double.infinity,
child: Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.only(left: 5, right: 5),
child: RichText(
text: TextSpan(
style: TextStyle(color: Colors.black),
children: [
TextSpan(text: "$lastVal "),
TextSpan(
text: unit,
style: TextStyle(
color: HexColor('#B8382C'),
),
),
]),
),
),
),
),
),
],
),
),

File diff suppressed because one or more lines are too long

@ -1,16 +1,14 @@
import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_model.dart';
import 'package:doctor_app_flutter/widgets/patients/vital_sign_details_wideget.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_details_wideget.dart';
import 'package:doctor_app_flutter/widgets/charts/app_time_series_chart.dart';
import 'package:doctor_app_flutter/widgets/shared/app_expandable_notifier.dart';
import 'package:doctor_app_flutter/widgets/shared/charts/app_time_series_chart.dart';
import 'package:flutter/material.dart';
/*
*@author: Elham Rababah
*@Date:03/6/2020
*@param:
*@return:
*@desc: VitalSingChartAndDetials
*/
import 'package:charts_flutter/flutter.dart' as charts;
import 'LineChartCurved.dart';
class VitalSingChartAndDetials extends StatelessWidget {
VitalSingChartAndDetials({
Key key,
@ -21,30 +19,46 @@ class VitalSingChartAndDetials extends StatelessWidget {
@required this.title2,
}) : super(key: key);
final List<VitalSignResModel> vitalList;
final List<VitalSignHistory> vitalList;
final String name;
final String viewKey;
final String title1;
final String title2;
List<TimeSeriesSales2> timeSeriesData = [];
@override
Widget build(BuildContext context) {
generateData();
return Column(
children: <Widget>[
AppExpandableNotifier(
headerWid: AppTimeSeriesChart(
// isExpand: true,
headerWid: LineChartCurved(title: name,timeSeries:timeSeriesData,indexes: timeSeriesData.length~/5.5,),
bodyWid: VitalSignDetailsWidget(
vitalList: vitalList,
chartName: name,
title1: title1,
title2: title2,
viewKey: viewKey,
),
bodyWid: VitalSignDetailsWidget(
vitalList: vitalList.reversed.toList(),
title1: '${title1}',
title2: '${title2}',
viewKey: '${viewKey}',
),
),
],
);
}
generateData() {
if (vitalList.length > 0) {
vitalList.reversed.toList().forEach(
(element) {
if( element.toJson()[viewKey]!=null && element.toJson()[viewKey]?.toInt()!=0)
timeSeriesData.add(
TimeSeriesSales2(
new DateTime(element.vitalSignDate.year, element.vitalSignDate.month, element.vitalSignDate.day),
element.toJson()[viewKey].toDouble(),
),
);
},
);
}
return timeSeriesData.reversed.toList();
}
}

@ -0,0 +1,85 @@
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_details_blood_pressurewideget.dart';
import 'package:doctor_app_flutter/widgets/charts/app_time_series_chart.dart';
import 'package:doctor_app_flutter/widgets/shared/app_expandable_notifier.dart';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'LineChartCurved.dart';
import 'LineChartCurvedBloodPressure.dart';
class VitalSingChartBloodPressure extends StatelessWidget {
VitalSingChartBloodPressure({
Key key,
@required this.vitalList,
@required this.name,
@required this.viewKey1,
@required this.viewKey2,
@required this.title1,
@required this.title2,
@required this.title3,
}) : super(key: key);
final List<VitalSignHistory> vitalList;
final String name;
final String viewKey1;
final String viewKey2;
final String title1;
final String title2;
final String title3;
List<TimeSeriesSales2> timeSeriesData1 = [];
List<TimeSeriesSales2> timeSeriesData2 = [];
@override
Widget build(BuildContext context) {
generateData();
return Column(
children: <Widget>[
AppExpandableNotifier(
// isExpand: true,
headerWid: LineChartCurvedBloodPressure(
title: name,
timeSeries1: timeSeriesData1,
timeSeries2: timeSeriesData2,
indexes: timeSeriesData1.length ~/ 5.5,
),
bodyWid: VitalSignBloodPressureWidget(
vitalList: vitalList,
title1: title1,
title2: title2,
title3: title3,
viewKey1: viewKey1,
viewKey2: viewKey2,
),
),
],
);
}
generateData() {
if (vitalList.length > 0) {
vitalList.reversed.toList().forEach(
(element) {
if (element.toJson()[viewKey1]?.toInt() != 0)
timeSeriesData1.add(
TimeSeriesSales2(
new DateTime(element.vitalSignDate.year,
element.vitalSignDate.month, element.vitalSignDate.day),
element.toJson()[viewKey1].toDouble(),
),
);
if (element.toJson()[viewKey2]?.toInt() != 0)
timeSeriesData2.add(
TimeSeriesSales2(
new DateTime(element.vitalSignDate.year,
element.vitalSignDate.month, element.vitalSignDate.day),
element.toJson()[viewKey2].toDouble(),
),
);
},
);
}
}
}

@ -77,5 +77,138 @@ class DateUtils {
int.parse(str.substring(startIndex + start.length, endIndex)));
return differenceBetweenDateAndCurrent(date);
}
/// get month by
/// [weekDay] convert week day in int to week day name
static getWeekDay(int weekDay) {
switch (weekDay) {
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday ";
case 7:
return "Sunday";
}
}
/// get month by
/// [weekDay] convert week day in int to week day name arabic
static getWeekDayArabic(int weekDay) {
switch (weekDay) {
case 1:
return "الاثنين";
case 2:
return "الثلاثاء";
case 3:
return "الاربعاء";
case 4:
return "الخميس";
case 5:
return "الجمعه";
case 6:
return "السبت ";
case 7:
return "الاحد";
}
}
/// get month by
/// [month] convert month number in to month name
static getMonth(int month) {
switch (month) {
case 1:
return "January";
case 2:
return "February";
case 3:
return "March";
case 4:
return "April";
case 5:
return "May";
case 6:
return "June";
case 7:
return "July";
case 8:
return "August";
case 9:
return "September";
case 10:
return "October";
case 11:
return "November";
case 12:
return "December";
}
}
/// get month by
/// [month] convert month number in to month name in Arabic
static getMonthArabic(int month) {
switch (month) {
case 1:
return "يناير";
case 2:
return " فبراير";
case 3:
return "مارس";
case 4:
return "أبريل";
case 5:
return "مايو";
case 6:
return "يونيو";
case 7:
return "يوليو";
case 8:
return "أغسطس";
case 9:
return "سبتمبر";
case 10:
return " اكتوبر";
case 11:
return " نوفمبر";
case 12:
return "ديسمبر";
}
}
static getMonthByName(String month) {
switch (month.toLowerCase()) {
case 'january':
return 1;
case 'february':
return 2;
case 'march':
return 3;
case 'april':
return 4;
case 'may':
return 5;
case 'june':
return 6;
case 'july':
return 7;
case 'august':
return 8;
case 'september':
return 9;
case 'october':
return 10;
case 'november':
return 11;
case 'december':
return 12;
}
}
}

@ -612,6 +612,18 @@ class TranslationBase {
String get doc => localizedValues['doc'][locale.languageCode];
String get patientNoDetailErrMsg =>
localizedValues['patientNoDetailErrMsg'][locale.languageCode];
String get systolicLng => localizedValues['systolic-lng'][locale.languageCode];
String get diastolicLng => localizedValues['diastolic-lng'][locale.languageCode];
String get mass => localizedValues['mass'][locale.languageCode];
String get tempC => localizedValues['temp-c'][locale.languageCode];
String get bpm => localizedValues['bpm'][locale.languageCode];
String get respirationSigns =>
localizedValues['respiration-signs'][locale.languageCode];
String get sysDias => localizedValues['sys-dias'][locale.languageCode];
String get body => localizedValues['body'][locale.languageCode];
String get respirationRate =>
localizedValues['respirationRate'][locale.languageCode];
String get heart => localizedValues['heart'][locale.languageCode];
}
class TranslationBaseDelegate extends LocalizationsDelegate<TranslationBase> {

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class AppBarChart extends StatelessWidget {
const AppBarChart({
Key key,
@required this.seriesList,
}) : super(key: key);
final List<charts.Series> seriesList;
@override
Widget build(BuildContext context) {
return Container(
height: 400,
margin: EdgeInsets.only(top: 60),
child: charts.BarChart(
seriesList,
// animate: animate,
/// Customize the primary measure axis using a small tick renderer.
/// Use String instead of num for ordinal domain axis
/// (typically bar charts).
primaryMeasureAxis: new charts.NumericAxisSpec(
renderSpec: new charts.GridlineRendererSpec(
// Display the measure axis labels below the gridline.
//
// 'Before' & 'after' follow the axis value direction.
// Vertical axes draw 'before' below & 'after' above the tick.
// Horizontal axes draw 'before' left & 'after' right the tick.
labelAnchor: charts.TickLabelAnchor.before,
// Left justify the text in the axis.
//
// Note: outside means that the secondary measure axis would right
// justify.
labelJustification:
charts.TickLabelJustification.outside,
)),
),
);
}
}

@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
/// chart line
/// [seriesList] charts series
/// [chartTitle] the charts title
/// [animate] enable and disable animate on create chart
/// [includeArea] chart include Area
/// [stacked] stacked chart over the design
class AppLineChart extends StatelessWidget {
final List<charts.Series> seriesList;
final String chartTitle;
final bool animate;
final bool includeArea;
final bool stacked;
AppLineChart(
{Key key,
@required this.seriesList,
this.chartTitle,
this.animate = true,
this.includeArea = false,
this.stacked = true});
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Text(
chartTitle,
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
Expanded(
child: charts.LineChart(seriesList,
defaultRenderer: charts.LineRendererConfig(
includeArea: false, stacked: true),
animate: animate),
),
],
),
);
}
}

@ -0,0 +1,71 @@
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:charts_flutter/flutter.dart';
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/widgets/data_display/list/flexible_container.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:flutter/material.dart';
/// App Time Series Chart
/// [seriesList] the series list
/// [chartName] the name of the chart
/// [startDate] the start date
/// [endDate] the end date
class AppTimeSeriesChart extends StatelessWidget {
AppTimeSeriesChart({
Key key,
@required this.seriesList,
this.chartName = '',
this.startDate,
this.endDate,
});
final String chartName;
final List<Series<dynamic, DateTime>> seriesList;
final DateTime startDate;
final DateTime endDate;
@override
Widget build(BuildContext context) {
return FlexibleContainer(
heightFactor: 0.47,
child: Column(
children: <Widget>[
AppText(chartName, fontSize: SizeConfig.textMultiplier * 3),
Container(
height: SizeConfig.realScreenHeight * 0.37,
child: Center(
child: Container(
child: charts.TimeSeriesChart(
seriesList,
animate: true,
behaviors: [
charts.RangeAnnotation(
[
charts.RangeAnnotationSegment(startDate, endDate,
charts.RangeAnnotationAxisType.domain ),
],
),
],
),
),
),
),
],
),
);
}
}
class TimeSeriesSales {
final DateTime time;
final int sales;
TimeSeriesSales(this.time, this.sales);
}
class TimeSeriesSales2 {
final DateTime time;
final double sales;
TimeSeriesSales2(this.time, this.sales);
}

@ -0,0 +1,93 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
/// Custom Item widget
/// [startIcon] icon at the start of the widget
/// [startIconSize] icon size of start icon
/// [startIconColor] icon color of start icon
/// [endIcon] icon at the end of the widget
/// [endIconSize] icon size of end icon
/// [endIconColor] icon color of end icon
/// [disabled] disabled on tap function
/// [onTap] opTap function
/// [padding] padding of the widget
/// [child] child of the widget
/// [decoration] decoration of the widget
class CustomItem extends StatelessWidget {
final IconData startIcon;
final double startIconSize;
final Color startIconColor;
final IconData endIcon;
final double endIconSize;
final Color endIconColor;
final bool disabled;
final Function onTap;
final EdgeInsets padding;
final Widget child;
final BoxDecoration decoration;
CustomItem(
{Key key,
this.startIcon,
this.disabled: false,
this.onTap,
this.startIconColor,
this.endIcon = EvaIcons.chevronRight,
this.padding,
this.child,
this.endIconColor,
this.endIconSize = 20,
this.decoration,
this.startIconSize = 19})
: super(key: key);
@override
Widget build(BuildContext context) {
return IgnorePointer(
ignoring: disabled,
child: Container(
decoration: decoration != null ? decoration : BoxDecoration(),
child: InkWell(
onTap: () {
if (onTap != null) onTap();
},
child: Padding(
padding: padding != null
? padding
: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0),
child: Row(
children: <Widget>[
if (startIcon != null)
Expanded(
flex: 1,
child: Icon(
startIcon,
color: startIconColor ?? Theme.of(context).primaryColor,
size: startIconSize,
),
),
if (startIcon != null) SizedBox(width: 18.0),
Expanded(
child: child,
flex: 10,
),
endIcon == null
? Expanded(child: Container())
: Expanded(
flex: 1,
child: Icon(
endIcon,
color: endIconColor != null
? endIconColor
: Colors.grey[500],
size: endIconSize,
),
)
],
),
),
),
),
);
}
}

@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
/// Flexible container widget
/// [widthFactor] If non-null, the fraction of the incoming width given to the child.
/// If non-null, the child is given a tight width constraint that is the max
/// incoming width constraint multiplied by this factor.
/// If null, the incoming width constraints are passed to the child
/// [heightFactor]If non-null, the fraction of the incoming height given to the child.
/// If non-null, the child is given a tight height constraint that is the max
/// incoming height constraint multiplied by this factor.
/// If null, the incoming height constraints are passed to the child
/// [padding] add padding to the container
/// [child] child widget inside the container
class FlexibleContainer extends StatelessWidget {
final double widthFactor;
final double heightFactor;
final EdgeInsets padding;
final Widget child;
FlexibleContainer({
Key key,
this.widthFactor = 0.9,
this.heightFactor = 1,
this.padding,
this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
// widthFactor: widthFactor,
// heightFactor: heightFactor,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Material(
color: Theme.of(context).backgroundColor,
child: Container(
padding: padding,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).dividerColor, width: 2.0),
borderRadius: BorderRadius.circular(8.0)),
child: child,
),
),
),
);
}
}

@ -23,6 +23,8 @@ class PatientProfileWidget extends StatelessWidget {
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
patient = routeArgs['patient'];
String patientType = routeArgs['patientType'];
String from = routeArgs['from'];
String to = routeArgs['to'];
return Container(
color: Color(0XFFF2F2F2),
@ -442,7 +444,7 @@ class PatientProfileWidget extends StatelessWidget {
SliverPadding(
padding: const EdgeInsets.all(16.0),
sliver: ProfileMedicalInfoWidget(
patient: patient, patientType:patientType
patient: patient, patientType:patientType, from: from, to: to,
))
]),
);

@ -5,6 +5,7 @@ import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/routes.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/util/date-utils.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/dr_app_circular_progress_Indeicator.dart';
import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart';
@ -23,9 +24,14 @@ import '../../shared/app_texts_widget.dart';
*@desc: Profile Medical Info Widget
*/
class ProfileMedicalInfoWidget extends StatelessWidget {
ProfileMedicalInfoWidget({Key key, this.patient, this.patientType});
ProfileMedicalInfoWidget(
{Key key, this.patient, this.patientType, this.from, this.to});
PatiantInformtion patient;
String patientType;
String patientType;
String from;
String to;
@override
Widget build(BuildContext context) {
return BaseView<SOAPViewModel>(
@ -50,42 +56,38 @@ class ProfileMedicalInfoWidget extends StatelessWidget {
patientMRN: patient.patientMRN);
await model.postEpisode(postEpisodeReqModel);
patient.episodeNo = model.episodeID;
Navigator.of(context).pushNamed(CREATE_EPISODE, arguments: {'patient': patient});
Navigator.of(context).pushNamed(CREATE_EPISODE,
arguments: {'patient': patient});
},
isLoading: model.state == ViewState.BusyLocal,
icon: 'create-episod.png'
),
if(int.parse(patientType) ==7)
PatientProfileButton(
key: key,
patient: patient,
isDisable: patient.episodeNo == 0 ? true : false,
nameLine1: TranslationBase
.of(context)
.update,
nameLine2: TranslationBase
.of(context)
.episode,
route: UPDATE_EPISODE,
icon: 'modilfy-episode.png'),
PatientProfileButton(
key: key,
patient: patient,
nameLine1: TranslationBase.of(context).vital,
nameLine2: TranslationBase.of(context).signs,
route: (selectedPatientType == 6 || selectedPatientType == 7) ? PATIENT_VITAL_SIGN : VITAL_SIGN_DETAILS,
icon: 'heartbeat.png'),
if(selectedPatientType != 7)
PatientProfileButton(
key: key,
patient: patient,
route: LAB_ORDERS,
nameLine1: TranslationBase.of(context).lab,
nameLine2: TranslationBase.of(context).result,
icon: 'lab.png'),
isLoading: model.state == ViewState.BusyLocal,
icon: 'create-episod.png'),
if (int.parse(patientType) == 7)
PatientProfileButton(
key: key,
patient: patient,
isDisable: patient.episodeNo == 0 ? true : false,
nameLine1: TranslationBase.of(context).update,
nameLine2: TranslationBase.of(context).episode,
route: UPDATE_EPISODE,
icon: 'modilfy-episode.png'),
if (int.parse(patientType) == 7)
PatientProfileButton(
key: key,
patient: patient,
from: from,
to: to,
nameLine1: TranslationBase.of(context).vital,
nameLine2: TranslationBase.of(context).signs,
route: VITAL_SIGN_DETAILS /*PATIENT_VITAL_SIGN*/,
icon: 'heartbeat.png'),
if (selectedPatientType != 7)
PatientProfileButton(
key: key,
patient: patient,
route: LAB_ORDERS,
nameLine1: TranslationBase.of(context).lab,
nameLine2: TranslationBase.of(context).result,
icon: 'lab.png'),
PatientProfileButton(
key: key,
patient: patient,
@ -93,7 +95,9 @@ class ProfileMedicalInfoWidget extends StatelessWidget {
nameLine1: TranslationBase.of(context).previewHealth,
nameLine2: TranslationBase.of(context).summaryReport,
icon: 'radiology-1.png'),
if (selectedPatientType != 0 && selectedPatientType != 5 && selectedPatientType != 7)
if (selectedPatientType != 0 &&
selectedPatientType != 5 &&
selectedPatientType != 7)
PatientProfileButton(
key: key,
patient: patient,
@ -123,55 +127,41 @@ class ProfileMedicalInfoWidget extends StatelessWidget {
nameLine1: 'Order Test',
nameLine2: 'Or Procedures',
icon: 'lab.png'),
if(selectedPatientType == 7)
if (selectedPatientType == 7)
PatientProfileButton(
key: key,
patient: patient,
route: REFER_PATIENT_TO_DOCTOR,
nameLine1: TranslationBase
.of(context)
.myReferral,
nameLine2: TranslationBase
.of(context)
.patient,
nameLine1: TranslationBase.of(context).myReferral,
nameLine2: TranslationBase.of(context).patient,
icon: 'note.png'),
if(selectedPatientType != 0 && selectedPatientType != 5)
if (selectedPatientType != 0 && selectedPatientType != 5)
PatientProfileButton(
key: key,
patient: patient,
route: PATIENT_ORDERS,
nameLine1: TranslationBase
.of(context)
.orders,
nameLine2: TranslationBase
.of(context)
.list,
nameLine1: TranslationBase.of(context).orders,
nameLine2: TranslationBase.of(context).list,
icon: 'radiology-1.png'),
if(selectedPatientType != 0 && selectedPatientType != 5)
if (selectedPatientType != 0 && selectedPatientType != 5)
PatientProfileButton(
key: key,
patient: patient,
route: ADD_SICKLEAVE,
nameLine1: TranslationBase
.of(context)
.patientSick,
nameLine2: TranslationBase
.of(context)
.leave,
nameLine1: TranslationBase.of(context).patientSick,
nameLine2: TranslationBase.of(context).leave,
icon: 'sick_leaves_icons.png'),
if( selectedPatientType == 7)
if (selectedPatientType == 7)
PatientProfileButton(
key: key,
patient: patient,
route: PATIENT_UCAF_REQUEST,
nameLine1: TranslationBase
.of(context)
.patient,
nameLine2: TranslationBase
.of(context)
.ucaf,
nameLine1: TranslationBase.of(context).patient,
nameLine2: TranslationBase.of(context).ucaf,
icon: 'lab.png'),
],),);
],
),
);
}
}
@ -230,18 +220,25 @@ class PatientProfileButton extends StatelessWidget {
final String icon;
final dynamic route;
final PatiantInformtion patient;
String from;
String to;
final String url = "assets/images/";
final bool isDisable;
final bool isLoading;
final Function onTap;
PatientProfileButton({Key key,
this.patient,
this.nameLine1,
this.nameLine2,
this.icon,
this.route, this.isDisable = false, this.onTap, this.isLoading = false})
PatientProfileButton(
{Key key,
this.patient,
this.nameLine1,
this.nameLine2,
this.icon,
this.route,
this.isDisable = false,
this.onTap,
this.isLoading = false,
this.from,
this.to})
: super(key: key);
@override
@ -249,9 +246,13 @@ class PatientProfileButton extends StatelessWidget {
return new Container(
margin: new EdgeInsets.symmetric(horizontal: 4.0),
child: InkWell(
onTap: isDisable?null:onTap != null ? onTap : () {
navigator(context, this.route);
},
onTap: isDisable
? null
: onTap != null
? onTap
: () {
navigator(context, this.route);
},
child: Column(children: <Widget>[
Container(
alignment: Alignment.topLeft,
@ -273,8 +274,7 @@ class PatientProfileButton extends StatelessWidget {
textAlign: TextAlign.left,
fontSize: SizeConfig.textMultiplier * 2,
),
if(isLoading)
DrAppCircularProgressIndeicator()
if (isLoading) DrAppCircularProgressIndeicator()
],
),
),
@ -313,6 +313,13 @@ class PatientProfileButton extends StatelessWidget {
}
void navigator(BuildContext context, route) {
Navigator.of(context).pushNamed(route, arguments: {'patient': patient});
if (from == null) {
from = DateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd');
}
if (to == null) {
to = DateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd');
}
Navigator.of(context).pushNamed(route,
arguments: {'patient': patient, 'from': from, 'to': to});
}
}

@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
/// FadePage animation
/// [page]
class FadePage extends PageRouteBuilder {
final Widget page;
FadePage({this.page})
: super(
opaque: false,
fullscreenDialog: true,
barrierDismissible: true,
barrierColor: Colors.black.withOpacity(0.8),
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
page,
transitionDuration: Duration(milliseconds: 300),
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return FadeTransition(
opacity: animation,
child: child
);
}
);
}

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
///Slide Up Page Route
/// [widget] widget we need to slide up
/// [fullscreenDialog] show the widget as full screen dialog
/// [opaque] When an opaque route's entrance transition is complete, the routes behind the opaque route will not be built to save resources.
class SlideUpPageRoute extends PageRouteBuilder {
final Widget widget;
final bool fullscreenDialog;
final bool opaque;
SlideUpPageRoute(
{this.widget, this.fullscreenDialog = false, this.opaque = true})
: super(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return widget;
},
fullscreenDialog: fullscreenDialog,
opaque: opaque,
barrierColor: Color.fromRGBO(0, 0, 0, 0.5),
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 800),
transitionsBuilder: ((BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
var begin = Offset(0.0, 1.0);
var end = Offset.zero;
var curve = Curves.easeInOutQuint;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween), child: child);
}),
);
}

@ -70,7 +70,7 @@ packages:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
version: "1.6.1"
build_config:
dependency: transitive
description:
@ -84,35 +84,35 @@ packages:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
version: "2.1.6"
build_modules:
dependency: transitive
description:
name: build_modules
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
version: "3.0.3"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
version: "1.5.2"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.11"
version: "1.10.13"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.5"
version: "6.1.6"
build_web_compilers:
dependency: "direct dev"
description:
@ -189,7 +189,7 @@ packages:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "3.5.0"
version: "3.6.0"
collection:
dependency: transitive
description:
@ -281,6 +281,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
equatable:
dependency: transitive
description:
name: equatable
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.5"
eva_icons_flutter:
dependency: "direct main"
description:
@ -351,6 +358,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.11"
fl_chart:
dependency: "direct main"
description:
name: fl_chart
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.2"
flutter:
dependency: "direct main"
description: flutter
@ -496,7 +510,7 @@ packages:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3-nullsafety.1"
version: "0.6.2"
json_annotation:
dependency: transitive
description:
@ -581,6 +595,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.1"
path_drawing:
dependency: transitive
description:
name: path_drawing
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.1+1"
path_parsing:
dependency: transitive
description:
name: path_parsing
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
path_provider_linux:
dependency: transitive
description:
@ -678,7 +706,7 @@ packages:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.2+3"
version: "4.3.2+4"
pub_semver:
dependency: transitive
description:
@ -706,7 +734,7 @@ packages:
name: scratch_space
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+2"
version: "0.0.4+3"
shared_preferences:
dependency: "direct main"
description:

@ -59,6 +59,9 @@ dependencies:
#Dependency Injection
get_it: ^4.0.2
#chart
fl_chart: ^0.12.1
#firebase
firebase_messaging: ^7.0.0
#GIF image

Loading…
Cancel
Save