Merge branch 'feature-ucaf' into 'development'

Feature ucaf

See merge request Cloud_Solution/doctor_app_flutter!253
merge-requests/255/merge
Mohammad Aljammal 5 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", 'en': "There is no detail for this patient",
'ar': "لا توجد تفاصيل لهذا المريض" '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/PatientArrivalEntity.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.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-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 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_model.dart';
class VitalSignsService extends BaseService { class VitalSignsService extends BaseService {
List<VitalSignResModel> patientVitalSignList = [];
List<VitalSignResModel> patientVitalSignOrderdSubList = [];
VitalSignData patientVitalSigns; VitalSignData patientVitalSigns;
List<VitalSignHistory> patientVitalSignsHistory = [];
Future getPatientVitalSign(PatiantInformtion patient) async { Future getPatientVitalSign(PatiantInformtion patient) async {
patientVitalSigns = null; patientVitalSigns = null;
hasError = false; hasError = false;
Map<String, dynamic> body = Map(); Map<String, dynamic> body = Map();
body['PatientMRN'] = 2954208; //patient.patientMRN; body['PatientMRN'] = patient.patientMRN;
body['AppointmentNo'] = "2016055308"; //patient.appointmentNo; body['AppointmentNo'] = patient.appointmentNo;
body['EpisodeID'] = 210011002; //patient.episodeNo; body['EpisodeID'] = patient.episodeNo;
await baseAppClient.post( await baseAppClient.post(
GET_PATIENT_VITAL_SIGN_DATA, GET_PATIENT_VITAL_SIGN_DATA,
onSuccess: (dynamic response, int statusCode) { onSuccess: (dynamic response, int statusCode) {
@ -35,4 +35,37 @@ class VitalSignsService extends BaseService {
body: body, 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/PatientArrivalEntity.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.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-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 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_model.dart';
import '../../locator.dart'; import '../../locator.dart';
@ -12,6 +13,15 @@ class VitalSignsViewModel extends BaseViewModel {
VitalSignsService _vitalSignService = locator<VitalSignsService>(); VitalSignsService _vitalSignService = locator<VitalSignsService>();
VitalSignData get patientVitalSigns => _vitalSignService.patientVitalSigns; 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 { Future getPatientVitalSign(PatiantInformtion patient) async {
setState(ViewState.Busy); setState(ViewState.Busy);
@ -20,47 +30,51 @@ class VitalSignsViewModel extends BaseViewModel {
error = _vitalSignService.error; error = _vitalSignService.error;
setState(ViewState.Error); setState(ViewState.Error);
} else { } else {
// if (patientVitalSigns == null) {
// makeVitalSignDemoData();
// }
setState(ViewState.Idle); setState(ViewState.Idle);
} }
} }
makeVitalSignDemoData(){ Future getPatientVitalSignHistory(PatiantInformtion patient, String from, String to) async {
_vitalSignService.patientVitalSigns = VitalSignData( setState(ViewState.Busy);
appointmentNo: 2016053265, await _vitalSignService.getPatientVitalSignsHistory(patient, from, to);
bloodPressureCuffLocation: 0, if (_vitalSignService.hasError) {
bloodPressureCuffSize: 0, error = _vitalSignService.error;
bloodPressureHigher: 38, setState(ViewState.Error);
bloodPressureLower: 32, } else {
bloodPressurePatientPosition: 1, patientVitalSignsHistory.forEach((element) {
bodyMassIndex: 31.11, if (heightCm == "0" || heightCm == null || heightCm == 'null') {
fio2: 0, heightCm = element.heightCm.toString();
headCircumCm: 0, }
heightCm: 150, if (weightKg == "0" || weightKg == null || weightKg == 'null') {
idealBodyWeightLbs: -2, weightKg = element.weightKg.toString();
isPainManagementDone: false, }
isVitalsRequired: true, if (bodyMax == "0" ||
leanBodyWeightLbs: 0, bodyMax == null ||
painCharacter: null, bodyMax == 'null') {
painDuration: null, bodyMax = element.bodyMassIndex.toString();
painFrequency: null, }
painLocation: null, if (temperatureCelcius == "0" ||
painScore: 0, temperatureCelcius == null ||
patientMRN: 3333274, temperatureCelcius == 'null') {
patientType: 1, temperatureCelcius = element.temperatureCelcius.toString();
pulseBeatPerMinute: 0, }
pulseRhythm: 0, if (hartRat == "0" || hartRat == null || hartRat == 'null') {
respirationBeatPerMinute: 0, hartRat = element.pulseBeatPerMinute.toString();
respirationPattern: 0, }
sao2: 0, if (respirationBeatPerMinute == "0" ||
status: 47, respirationBeatPerMinute == null ||
temperatureCelcius: 40, respirationBeatPerMinute == 'null') {
temperatureCelciusMethod: 1, respirationBeatPerMinute =
waistSizeInch: 39, element.respirationBeatPerMinute.toString();
weightKg: 70, }
); if (bloodPressure == "0 / 0" ||
bloodPressure == null ||
bloodPressure == 'null') {
bloodPressure = element.bloodPressure.toString();
}
});
setState(ViewState.Idle);
}
} }
String getBMI(var bodyMassIndex) { String getBMI(var bodyMassIndex) {

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

@ -133,4 +133,5 @@ class VitalSignData {
data['weightKg'] = this.weightKg; data['weightKg'] = this.weightKg;
return data; 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 = const String PATIENT_INSURANCE_APPROVALS =
'patients/patient_insurance_approvals'; 'patients/patient_insurance_approvals';
const String VITAL_SIGN_DETAILS = 'patients/vital-sign-details'; 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 CREATE_EPISODE = 'patients/create-episode';
const String UPDATE_EPISODE = 'patients/update-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 = 'patients/admission-request';
const String PATIENT_ADMISSION_REQUEST_2 = 'patients/admission-request-second'; const String PATIENT_ADMISSION_REQUEST_2 = 'patients/admission-request-second';
const String PATIENT_ADMISSION_REQUEST_3 = 'patients/admission-request-third'; const String PATIENT_ADMISSION_REQUEST_3 = 'patients/admission-request-third';

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

@ -112,7 +112,7 @@ class MyReferralDetailScreen extends StatelessWidget {
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: model.patientArrivalList[0], patient: model.patientArrivalList[0],
route: PATIENT_VITAL_SIGN, route: VITAL_SIGN_DETAILS /*PATIENT_VITAL_SIGN*/,
nameLine1: TranslationBase.of(context).vital, nameLine1: TranslationBase.of(context).vital,
nameLine2: TranslationBase.of(context).signs, nameLine2: TranslationBase.of(context).signs,
icon: 'heartbeat.png'), 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) { Widget build(BuildContext context) {
final routeArgs = ModalRoute.of(context).settings.arguments as Map; final routeArgs = ModalRoute.of(context).settings.arguments as Map;
PatiantInformtion patient = routeArgs['patient']; PatiantInformtion patient = routeArgs['patient'];
String from = routeArgs['from'];
String to = routeArgs['to'];
return BaseView<VitalSignsViewModel>( return BaseView<VitalSignsViewModel>(
onModelReady: (model) => model.getPatientVitalSign(patient), onModelReady: (model) => model.getPatientVitalSign(patient),
@ -115,7 +117,7 @@ class PatientVitalSignScreen extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( /*Row(
children: [ children: [
AppText( AppText(
"${TranslationBase.of(context).waistSize} :", "${TranslationBase.of(context).waistSize} :",
@ -133,7 +135,7 @@ class PatientVitalSignScreen extends StatelessWidget {
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
), ),
], ],
), ),*/
Row( Row(
children: [ children: [
AppText( 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,128 +1,78 @@
import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-vital-sign-viewmodel.dart';
import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_req_model.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/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/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 'package:flutter/material.dart';
import '../../../../config/shared_pref_kay.dart'; class VitalSignDetailsScreen extends StatelessWidget {
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';
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 @override
_VitalSignDetailsScreenState createState() => _VitalSignDetailsScreenState(); Widget build(BuildContext context) {
}
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 {
final routeArgs = ModalRoute.of(context).settings.arguments as Map; final routeArgs = ModalRoute.of(context).settings.arguments as Map;
PatiantInformtion patient = routeArgs['patient']; PatiantInformtion patient = routeArgs['patient'];
String token = await sharedPref.getString(TOKEN); String from = routeArgs['from'];
String type = await sharedPref.getString(SLECTED_PATIENT_TYPE); String to = routeArgs['to'];
int inOutpatientType = 1; String imageBasePath = 'assets/images/';
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; return BaseView<VitalSignsViewModel>(
onModelReady: (model) => model.getPatientVitalSignHistory(patient, from, to),
@override builder: (_, mode, widget) => AppScaffold(
Widget build(BuildContext context) { isShowAppBar: true,
final routeArgs = ModalRoute.of(context).settings.arguments as Map; baseViewModel: mode,
vitalSing = routeArgs['vitalSing'];
return BaseView<PatientViewModel>(
onModelReady: (model) => getVitalSignList(context, model),
builder: (_, model, w) => AppScaffold(
baseViewModel: model,
appBarTitle: TranslationBase.of(context).vitalSign, appBarTitle: TranslationBase.of(context).vitalSign,
body: model.patientVitalSignOrderdSubList.length == 0 body: mode.patientVitalSignsHistory.length > 0
? DrAppEmbeddedError( ? Container(
error: 'You don\'t have any vital Sings') child: ListView(
: Container(
child: Column(
children: <Widget>[ children: <Widget>[
Row( Row(
children: <Widget>[ children: <Widget>[
InkWell( InkWell(
onTap: () { onTap: () =>isNotOneAppointment? Navigator.push(
Navigator.of(context).pushNamed( context,
BODY_MEASUREMENTS, FadePage(
arguments: { page: VitalSignItemDetailsScreen(
'title': TranslationBase.of(context) pageKey: vitalSignDetails.Height,
.bodyMeasurements, pageTitle: TranslationBase.of(context).height,
'key': vitalList: mode.patientVitalSignsHistory,
vitalSignDetails.bodyMeasurements ),
}); ),
}, ):null,
child: Container( child: Container(
child: VitalSignItem( child: VitalSignItem(
des: TranslationBase.of(context) des: TranslationBase.of(context).height,
.bodyMeasurements, imagePath: "${imageBasePath}vital_height.png",
url: url + 'heartbeat.png', lastVal: mode.heightCm,
lastVal: model unit: TranslationBase.of(context).cm,
.patientVitalSignOrderdSubList[0]
.heightCm
.toString(),
unit: 'Cm',
), ),
), ),
), ),
InkWell( InkWell(
onTap: () { onTap: () => isNotOneAppointment ? Navigator.push(
Navigator.of(context).pushNamed( context,
BODY_MEASUREMENTS, FadePage(
arguments: { page: VitalSignItemDetailsScreen(
'title': TranslationBase.of(context) pageKey: vitalSignDetails.Weight,
.temperature, pageTitle: TranslationBase.of(context).weight,
'key': vitalSignDetails.temperature, vitalList: mode.patientVitalSignsHistory,
}); ),
},
child: Container(
child: VitalSignItem(
des: TranslationBase.of(context)
.temperature,
url: url + 'heartbeat.png',
lastVal: model
.patientVitalSignOrderdSubList[0]
.temperatureCelcius
.toString(),
unit: 'C',
), ),
):null,
child: VitalSignItem(
des: TranslationBase.of(context).weight,
imagePath: "${imageBasePath}vital_weight.png",
unit: TranslationBase.of(context).kg,
lastVal: mode.weightKg,
), ),
), ),
], ],
@ -130,44 +80,43 @@ class _VitalSignDetailsScreenState extends State<VitalSignDetailsScreen> {
Row( Row(
children: <Widget>[ children: <Widget>[
InkWell( InkWell(
onTap: () { onTap: () => isNotOneAppointment ? Navigator.push(
Navigator.of(context).pushNamed( context,
BODY_MEASUREMENTS, FadePage(
arguments: { page: VitalSignItemDetailsScreen(
'title': pageKey: vitalSignDetails.BodyMeasurements,
TranslationBase.of(context).pulse, pageTitle: TranslationBase.of(context)
'key': vitalSignDetails.pulse .bodyMeasurements,
}); vitalList: mode.patientVitalSignsHistory,
}, ),
),
): null,
child: VitalSignItem( child: VitalSignItem(
des: TranslationBase.of(context).pulse, des: TranslationBase.of(context).body,
url: url + 'heartbeat.png', imagePath: "${imageBasePath}vital_body_mass.png",
lastVal: model lastVal: mode.bodyMax,
.patientVitalSignOrderdSubList[0] unit: TranslationBase.of(context).mass,
.pulseBeatPerMinute
.toString(),
unit: 'M',
), ),
), ),
InkWell( InkWell(
onTap: () { onTap: () => isNotOneAppointment ? Navigator.push(
Navigator.of(context).pushNamed( context,
BODY_MEASUREMENTS, FadePage(
arguments: { page: VitalSignItemDetailsScreen(
'title': TranslationBase.of(context) pageKey: vitalSignDetails.Temperature,
.respiration, pageTitle:
'key': vitalSignDetails.pespiration TranslationBase.of(context).temperature,
}); vitalList: mode.patientVitalSignsHistory,
}, ),
),
):null,
child: Container(
child: VitalSignItem( child: VitalSignItem(
des: des: TranslationBase.of(context).temperature,
TranslationBase.of(context).respiration, imagePath: "${imageBasePath}vital_temperature.png",
url: url + 'heartbeat.png', lastVal: mode.temperatureCelcius,
lastVal: model unit: TranslationBase.of(context).tempC,
.patientVitalSignOrderdSubList[0] ),
.respirationBeatPerMinute
.toString(),
unit: 'M',
), ),
), ),
], ],
@ -175,44 +124,40 @@ class _VitalSignDetailsScreenState extends State<VitalSignDetailsScreen> {
Row( Row(
children: <Widget>[ children: <Widget>[
InkWell( InkWell(
onTap: () { onTap: () => isNotOneAppointment ? Navigator.push(
Navigator.of(context).pushNamed( context,
BODY_MEASUREMENTS, FadePage(
arguments: { page: VitalSignItemDetailsScreen(
'title': TranslationBase.of(context) pageKey: vitalSignDetails.heart,
.bloodPressure, pageTitle: TranslationBase.of(context).heart,
'key': vitalSignDetails.bloodPressure vitalList: mode.patientVitalSignsHistory,
}); ),
}, ),
):null,
child: VitalSignItem( child: VitalSignItem(
des: TranslationBase.of(context) des: TranslationBase.of(context).heart,
.bloodPressure, imagePath: "${imageBasePath}vital_heart_rate.png",
url: url + 'heartbeat.png', lastVal: mode.hartRat,
lastVal: model unit: TranslationBase.of(context).bpm,
.patientVitalSignOrderdSubList[0]
.bloodPressure
.toString(),
unit: '',
), ),
), ),
InkWell( InkWell(
onTap: () { onTap: () => isNotOneAppointment ? Navigator.push(
Navigator.of(context).pushNamed( context,
BODY_MEASUREMENTS, FadePage(
arguments: { page: VitalSignItemDetailsScreen(
'title': TranslationBase.of(context) pageKey: vitalSignDetails.Respiration,
.oxygenation, pageTitle:
'key': vitalSignDetails.oxygenation TranslationBase.of(context).respirationRate,
}); vitalList: mode.patientVitalSignsHistory,
}, ),
),
):null,
child: VitalSignItem( child: VitalSignItem(
des: des: TranslationBase.of(context).respirationRate,
TranslationBase.of(context).oxygenation, imagePath: "${imageBasePath}vital_respiration.png",
url: url + 'heartbeat.png', lastVal: mode.respirationBeatPerMinute,
lastVal: model unit: TranslationBase.of(context).respirationSigns,
.patientVitalSignOrderdSubList[0].fIO2
.toString(),
unit: '',
), ),
), ),
], ],
@ -221,26 +166,32 @@ class _VitalSignDetailsScreenState extends State<VitalSignDetailsScreen> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
InkWell( InkWell(
onTap: () { onTap: () => isNotOneAppointment ? Navigator.push(
Navigator.of(context).pushNamed( context,
BODY_MEASUREMENTS, FadePage(
arguments: { page: VitalSignItemDetailsScreen(
'title': TranslationBase.of(context) pageKey: vitalSignDetails.BloodPressure,
.painScale, pageTitle: TranslationBase.of(context).bloodPressure,
'key': vitalSignDetails.painScale vitalList: mode.patientVitalSignsHistory,
}); ),
}, ),
):null,
child: VitalSignItem( child: VitalSignItem(
des: TranslationBase des: TranslationBase.of(context).bloodPressure,
.of(context) imagePath: "${imageBasePath}vital_blood-pressure.png",
.painScale, lastVal: mode.bloodPressure,
url: url + 'heartbeat.png', 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:flutter/material.dart';
import 'package:hexcolor/hexcolor.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 { class VitalSignItem extends StatelessWidget {
const VitalSignItem( const VitalSignItem(
{Key key, {Key key,
@required this.url,
@required this.des, @required this.des,
this.lastVal = 'N/A', this.lastVal = 'N/A',
this.unit = '', this.unit = '',
this.height, this.height,
this.width}) this.width,
@required this.imagePath})
: super(key: key); : super(key: key);
final String url;
final String des; final String des;
final String lastVal; final String lastVal;
final String unit; final String unit;
final String imagePath;
final double height; final double height;
final double width; final double width;
@ -34,52 +25,70 @@ class VitalSignItem extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return RoundedContainer( return RoundedContainer(
margin: 0.025 * SizeConfig.realScreenWidth, margin: 0.025 * SizeConfig.realScreenWidth,
height: 0.14 * SizeConfig.realScreenHeight, height: 0.15 * SizeConfig.realScreenHeight,
width: 0.45 * SizeConfig.realScreenWidth, width: 0.45 * SizeConfig.realScreenWidth,
child: Container( child: Container(
padding: EdgeInsets.all(5), padding: EdgeInsets.all(5),
child: Row( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 0.10 * SizeConfig.realScreenHeight,
child: Row(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
flex: 2, flex: 2,
child: Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
des, des,
style: TextStyle( style: TextStyle(
fontSize: 1.7 * SizeConfig.textMultiplier, fontSize: 1.7 * SizeConfig.textMultiplier,
color: HexColor('#B8382C'), color: HexColor('#B8382C'),
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold,
),
),
),
), ),
), ),
Expanded( Expanded(
flex: 1, flex: 1,
child: Column( child: Container(
children: <Widget>[
Expanded(
child: Image.asset( child: Image.asset(
url, imagePath,
height: SizeConfig.heightMultiplier * 7, width: 40,
height: 40,
)),
)
],
), ),
), ),
Expanded( Expanded(
child: Container(
width: double.infinity,
child: Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.only(left: 5, right: 5),
child: RichText( child: RichText(
text: TextSpan( text: TextSpan(
style: TextStyle(color: Colors.black), style: TextStyle(color: Colors.black),
children: [ children: [
new TextSpan(text: lastVal), TextSpan(text: "$lastVal "),
new TextSpan( TextSpan(
text: ' ${unit}', text: unit,
style: TextStyle( style: TextStyle(
color: HexColor('#B8382C'), 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/models/patient/vital_sign/patient-vital-sign-data.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-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/app_expandable_notifier.dart';
import 'package:doctor_app_flutter/widgets/shared/charts/app_time_series_chart.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/* import 'package:charts_flutter/flutter.dart' as charts;
*@author: Elham Rababah
*@Date:03/6/2020 import 'LineChartCurved.dart';
*@param:
*@return:
*@desc: VitalSingChartAndDetials
*/
class VitalSingChartAndDetials extends StatelessWidget { class VitalSingChartAndDetials extends StatelessWidget {
VitalSingChartAndDetials({ VitalSingChartAndDetials({
Key key, Key key,
@ -21,30 +19,46 @@ class VitalSingChartAndDetials extends StatelessWidget {
@required this.title2, @required this.title2,
}) : super(key: key); }) : super(key: key);
final List<VitalSignResModel> vitalList; final List<VitalSignHistory> vitalList;
final String name; final String name;
final String viewKey; final String viewKey;
final String title1; final String title1;
final String title2; final String title2;
List<TimeSeriesSales2> timeSeriesData = [];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
generateData();
return Column( return Column(
children: <Widget>[ children: <Widget>[
AppExpandableNotifier( AppExpandableNotifier(
headerWid: AppTimeSeriesChart( // isExpand: true,
headerWid: LineChartCurved(title: name,timeSeries:timeSeriesData,indexes: timeSeriesData.length~/5.5,),
bodyWid: VitalSignDetailsWidget(
vitalList: vitalList, vitalList: vitalList,
chartName: name, title1: title1,
title2: title2,
viewKey: viewKey, 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))); int.parse(str.substring(startIndex + start.length, endIndex)));
return differenceBetweenDateAndCurrent(date); 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 doc => localizedValues['doc'][locale.languageCode];
String get patientNoDetailErrMsg => String get patientNoDetailErrMsg =>
localizedValues['patientNoDetailErrMsg'][locale.languageCode]; 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> { 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; final routeArgs = ModalRoute.of(context).settings.arguments as Map;
patient = routeArgs['patient']; patient = routeArgs['patient'];
String patientType = routeArgs['patientType']; String patientType = routeArgs['patientType'];
String from = routeArgs['from'];
String to = routeArgs['to'];
return Container( return Container(
color: Color(0XFFF2F2F2), color: Color(0XFFF2F2F2),
@ -442,7 +444,7 @@ class PatientProfileWidget extends StatelessWidget {
SliverPadding( SliverPadding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
sliver: ProfileMedicalInfoWidget( 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/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/routes.dart'; import 'package:doctor_app_flutter/routes.dart';
import 'package:doctor_app_flutter/screens/base/base_view.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/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/dr_app_circular_progress_Indeicator.dart';
import 'package:doctor_app_flutter/widgets/shared/network_base_view.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 *@desc: Profile Medical Info Widget
*/ */
class ProfileMedicalInfoWidget extends StatelessWidget { class ProfileMedicalInfoWidget extends StatelessWidget {
ProfileMedicalInfoWidget({Key key, this.patient, this.patientType}); ProfileMedicalInfoWidget(
{Key key, this.patient, this.patientType, this.from, this.to});
PatiantInformtion patient; PatiantInformtion patient;
String patientType; String patientType;
String from;
String to;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<SOAPViewModel>( return BaseView<SOAPViewModel>(
@ -50,32 +56,29 @@ class ProfileMedicalInfoWidget extends StatelessWidget {
patientMRN: patient.patientMRN); patientMRN: patient.patientMRN);
await model.postEpisode(postEpisodeReqModel); await model.postEpisode(postEpisodeReqModel);
patient.episodeNo = model.episodeID; 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, isLoading: model.state == ViewState.BusyLocal,
icon: 'create-episod.png' icon: 'create-episod.png'),
),
if (int.parse(patientType) == 7) if (int.parse(patientType) == 7)
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: patient, patient: patient,
isDisable: patient.episodeNo == 0 ? true : false, isDisable: patient.episodeNo == 0 ? true : false,
nameLine1: TranslationBase nameLine1: TranslationBase.of(context).update,
.of(context) nameLine2: TranslationBase.of(context).episode,
.update,
nameLine2: TranslationBase
.of(context)
.episode,
route: UPDATE_EPISODE, route: UPDATE_EPISODE,
icon: 'modilfy-episode.png'), icon: 'modilfy-episode.png'),
if (int.parse(patientType) == 7)
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: patient, patient: patient,
from: from,
to: to,
nameLine1: TranslationBase.of(context).vital, nameLine1: TranslationBase.of(context).vital,
nameLine2: TranslationBase.of(context).signs, nameLine2: TranslationBase.of(context).signs,
route: (selectedPatientType == 6 || selectedPatientType == 7) ? PATIENT_VITAL_SIGN : VITAL_SIGN_DETAILS, route: VITAL_SIGN_DETAILS /*PATIENT_VITAL_SIGN*/,
icon: 'heartbeat.png'), icon: 'heartbeat.png'),
if (selectedPatientType != 7) if (selectedPatientType != 7)
PatientProfileButton( PatientProfileButton(
@ -85,7 +88,6 @@ class ProfileMedicalInfoWidget extends StatelessWidget {
nameLine1: TranslationBase.of(context).lab, nameLine1: TranslationBase.of(context).lab,
nameLine2: TranslationBase.of(context).result, nameLine2: TranslationBase.of(context).result,
icon: 'lab.png'), icon: 'lab.png'),
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: patient, patient: patient,
@ -93,7 +95,9 @@ class ProfileMedicalInfoWidget extends StatelessWidget {
nameLine1: TranslationBase.of(context).previewHealth, nameLine1: TranslationBase.of(context).previewHealth,
nameLine2: TranslationBase.of(context).summaryReport, nameLine2: TranslationBase.of(context).summaryReport,
icon: 'radiology-1.png'), icon: 'radiology-1.png'),
if (selectedPatientType != 0 && selectedPatientType != 5 && selectedPatientType != 7) if (selectedPatientType != 0 &&
selectedPatientType != 5 &&
selectedPatientType != 7)
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: patient, patient: patient,
@ -128,50 +132,36 @@ class ProfileMedicalInfoWidget extends StatelessWidget {
key: key, key: key,
patient: patient, patient: patient,
route: REFER_PATIENT_TO_DOCTOR, route: REFER_PATIENT_TO_DOCTOR,
nameLine1: TranslationBase nameLine1: TranslationBase.of(context).myReferral,
.of(context) nameLine2: TranslationBase.of(context).patient,
.myReferral,
nameLine2: TranslationBase
.of(context)
.patient,
icon: 'note.png'), icon: 'note.png'),
if (selectedPatientType != 0 && selectedPatientType != 5) if (selectedPatientType != 0 && selectedPatientType != 5)
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: patient, patient: patient,
route: PATIENT_ORDERS, route: PATIENT_ORDERS,
nameLine1: TranslationBase nameLine1: TranslationBase.of(context).orders,
.of(context) nameLine2: TranslationBase.of(context).list,
.orders,
nameLine2: TranslationBase
.of(context)
.list,
icon: 'radiology-1.png'), icon: 'radiology-1.png'),
if (selectedPatientType != 0 && selectedPatientType != 5) if (selectedPatientType != 0 && selectedPatientType != 5)
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: patient, patient: patient,
route: ADD_SICKLEAVE, route: ADD_SICKLEAVE,
nameLine1: TranslationBase nameLine1: TranslationBase.of(context).patientSick,
.of(context) nameLine2: TranslationBase.of(context).leave,
.patientSick,
nameLine2: TranslationBase
.of(context)
.leave,
icon: 'sick_leaves_icons.png'), icon: 'sick_leaves_icons.png'),
if (selectedPatientType == 7) if (selectedPatientType == 7)
PatientProfileButton( PatientProfileButton(
key: key, key: key,
patient: patient, patient: patient,
route: PATIENT_UCAF_REQUEST, route: PATIENT_UCAF_REQUEST,
nameLine1: TranslationBase nameLine1: TranslationBase.of(context).patient,
.of(context) nameLine2: TranslationBase.of(context).ucaf,
.patient,
nameLine2: TranslationBase
.of(context)
.ucaf,
icon: 'lab.png'), icon: 'lab.png'),
],),); ],
),
);
} }
} }
@ -230,18 +220,25 @@ class PatientProfileButton extends StatelessWidget {
final String icon; final String icon;
final dynamic route; final dynamic route;
final PatiantInformtion patient; final PatiantInformtion patient;
String from;
String to;
final String url = "assets/images/"; final String url = "assets/images/";
final bool isDisable; final bool isDisable;
final bool isLoading; final bool isLoading;
final Function onTap; final Function onTap;
PatientProfileButton(
PatientProfileButton({Key key, {Key key,
this.patient, this.patient,
this.nameLine1, this.nameLine1,
this.nameLine2, this.nameLine2,
this.icon, this.icon,
this.route, this.isDisable = false, this.onTap, this.isLoading = false}) this.route,
this.isDisable = false,
this.onTap,
this.isLoading = false,
this.from,
this.to})
: super(key: key); : super(key: key);
@override @override
@ -249,7 +246,11 @@ class PatientProfileButton extends StatelessWidget {
return new Container( return new Container(
margin: new EdgeInsets.symmetric(horizontal: 4.0), margin: new EdgeInsets.symmetric(horizontal: 4.0),
child: InkWell( child: InkWell(
onTap: isDisable?null:onTap != null ? onTap : () { onTap: isDisable
? null
: onTap != null
? onTap
: () {
navigator(context, this.route); navigator(context, this.route);
}, },
child: Column(children: <Widget>[ child: Column(children: <Widget>[
@ -273,8 +274,7 @@ class PatientProfileButton extends StatelessWidget {
textAlign: TextAlign.left, textAlign: TextAlign.left,
fontSize: SizeConfig.textMultiplier * 2, fontSize: SizeConfig.textMultiplier * 2,
), ),
if(isLoading) if (isLoading) DrAppCircularProgressIndeicator()
DrAppCircularProgressIndeicator()
], ],
), ),
), ),
@ -313,6 +313,13 @@ class PatientProfileButton extends StatelessWidget {
} }
void navigator(BuildContext context, route) { 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 name: build
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.0" version: "1.6.1"
build_config: build_config:
dependency: transitive dependency: transitive
description: description:
@ -84,35 +84,35 @@ packages:
name: build_daemon name: build_daemon
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "2.1.6"
build_modules: build_modules:
dependency: transitive dependency: transitive
description: description:
name: build_modules name: build_modules
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.2" version: "3.0.3"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
name: build_resolvers name: build_resolvers
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.1" version: "1.5.2"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.11" version: "1.10.13"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.1.5" version: "6.1.6"
build_web_compilers: build_web_compilers:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -189,7 +189,7 @@ packages:
name: code_builder name: code_builder
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.5.0" version: "3.6.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -281,6 +281,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
equatable:
dependency: transitive
description:
name: equatable
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.5"
eva_icons_flutter: eva_icons_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -351,6 +358,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.10.11" 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: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -496,7 +510,7 @@ packages:
name: js name: js
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.3-nullsafety.1" version: "0.6.2"
json_annotation: json_annotation:
dependency: transitive dependency: transitive
description: description:
@ -581,6 +595,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0-nullsafety.1" 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: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -678,7 +706,7 @@ packages:
name: provider name: provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.3.2+3" version: "4.3.2+4"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
@ -706,7 +734,7 @@ packages:
name: scratch_space name: scratch_space
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4+2" version: "0.0.4+3"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:

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

Loading…
Cancel
Save