diff --git a/assets/images/vital_blood-pressure.png b/assets/images/vital_blood-pressure.png new file mode 100644 index 00000000..44c9f2e2 Binary files /dev/null and b/assets/images/vital_blood-pressure.png differ diff --git a/assets/images/vital_blood_type.png b/assets/images/vital_blood_type.png new file mode 100644 index 00000000..fbb5296f Binary files /dev/null and b/assets/images/vital_blood_type.png differ diff --git a/assets/images/vital_body_mass.png b/assets/images/vital_body_mass.png new file mode 100644 index 00000000..08476c51 Binary files /dev/null and b/assets/images/vital_body_mass.png differ diff --git a/assets/images/vital_heart_rate.png b/assets/images/vital_heart_rate.png new file mode 100644 index 00000000..e788658b Binary files /dev/null and b/assets/images/vital_heart_rate.png differ diff --git a/assets/images/vital_height.png b/assets/images/vital_height.png new file mode 100644 index 00000000..8c324b2c Binary files /dev/null and b/assets/images/vital_height.png differ diff --git a/assets/images/vital_respiration.png b/assets/images/vital_respiration.png new file mode 100644 index 00000000..7e1b4466 Binary files /dev/null and b/assets/images/vital_respiration.png differ diff --git a/assets/images/vital_signs.png b/assets/images/vital_signs.png new file mode 100644 index 00000000..7b642d6e Binary files /dev/null and b/assets/images/vital_signs.png differ diff --git a/assets/images/vital_temperature.png b/assets/images/vital_temperature.png new file mode 100644 index 00000000..7fe657de Binary files /dev/null and b/assets/images/vital_temperature.png differ diff --git a/assets/images/vital_weight.png b/assets/images/vital_weight.png new file mode 100644 index 00000000..5247e924 Binary files /dev/null and b/assets/images/vital_weight.png differ diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d121dd87..456d8524 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -590,4 +590,34 @@ const Map> localizedValues = { 'allergicTO': {'en': "ALLERGIC TO ", 'ar':" حساس من" }, 'normal': {'en': "Normal", 'ar':"عادي" }, 'abnormal': {'en': "Abnormal", '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': 'قلب'}, + 'medicalReport': {'en': "medical Report", 'ar': "تقرير طبي"}, + 'visitDate': {'en': "Visit Date", 'ar': "تاريخ الزيارة"}, + 'test': {'en': "Procedures/Test", 'ar': "عمليات/تحاليل"}, + 'regular': {'en': "Regular", 'ar': "اعتيادي"}, + 'addMoreProcedure': { + 'en': "Add More Procedures", + 'ar': "اضف المزيد من العمليات" + }, + 'searchProcedures': {'en': "Search Procedures", 'ar': "البحث في العمليات"}, + 'selectProcedures': {'en': "Select procedure", 'ar': "اختر العملية"}, + 'procedureCategorise': { + 'en': "Select Procedure Category", + 'ar': "اختر صنف العمليات " + }, + 'addSelectedProcedures': { + 'en': "add Selected Procedures", + 'ar': "اضافة العمليات المختارة " + }, + 'updateProcedure': {'en': "Update Procedure", 'ar': "تحديث العملية"}, + 'orderProcedure': {'en': "order procedure", 'ar': "طلب العمليات"}, }; diff --git a/lib/core/service/patient-vital-signs-service.dart b/lib/core/service/patient-vital-signs-service.dart index a5e3a107..ed6869f8 100644 --- a/lib/core/service/patient-vital-signs-service.dart +++ b/lib/core/service/patient-vital-signs-service.dart @@ -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 patientVitalSignList = []; - List patientVitalSignOrderdSubList = []; VitalSignData patientVitalSigns; + List patientVitalSignsHistory = []; Future getPatientVitalSign(PatiantInformtion patient) async { patientVitalSigns = null; hasError = false; Map 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 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, + ); + } } diff --git a/lib/core/viewModel/patient-vital-sign-viewmodel.dart b/lib/core/viewModel/patient-vital-sign-viewmodel.dart index 5674030c..4e656d6d 100644 --- a/lib/core/viewModel/patient-vital-sign-viewmodel.dart +++ b/lib/core/viewModel/patient-vital-sign-viewmodel.dart @@ -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(); VitalSignData get patientVitalSigns => _vitalSignService.patientVitalSigns; + List 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) { diff --git a/lib/lookups/patient_lookup.dart b/lib/lookups/patient_lookup.dart index dfcaa305..fa75abaa 100644 --- a/lib/lookups/patient_lookup.dart +++ b/lib/lookups/patient_lookup.dart @@ -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 } diff --git a/lib/models/patient/vital_sign/patient-vital-sign-data.dart b/lib/models/patient/vital_sign/patient-vital-sign-data.dart index c5e503c2..b7fe77cb 100644 --- a/lib/models/patient/vital_sign/patient-vital-sign-data.dart +++ b/lib/models/patient/vital_sign/patient-vital-sign-data.dart @@ -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 json) { appointmentNo = json['appointmentNo']; @@ -133,4 +133,5 @@ class VitalSignData { data['weightKg'] = this.weightKg; return data; } + } diff --git a/lib/models/patient/vital_sign/patient-vital-sign-history.dart b/lib/models/patient/vital_sign/patient-vital-sign-history.dart new file mode 100644 index 00000000..40ff5d00 --- /dev/null +++ b/lib/models/patient/vital_sign/patient-vital-sign-history.dart @@ -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 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 toJson() { + final Map data = new Map(); + 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; + } +} diff --git a/lib/routes.dart b/lib/routes.dart index e57b56a7..8f2b08a4 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -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'; diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 8787eb42..7277bf32 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -116,7 +116,7 @@ class _DashboardScreenState extends State { IsLoginForDoctorApp: true, PatientOutSA: false); return BaseView( - onModelReady: (model) => model.getDashboard(), + //onModelReady: (model) => model.getDashboard(), builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, diff --git a/lib/screens/medical-file/medical_file_details.dart b/lib/screens/medical-file/medical_file_details.dart index e11201e5..d445f471 100644 --- a/lib/screens/medical-file/medical_file_details.dart +++ b/lib/screens/medical-file/medical_file_details.dart @@ -66,7 +66,7 @@ class _MedicalFileDetailsState extends State { (BuildContext context, MedicalFileViewModel model, Widget child) => AppScaffold( isShowAppBar: true, - appBarTitle: 'medical file'.toUpperCase(), + appBarTitle: TranslationBase.of(context).medicalReport.toUpperCase(), body: NetworkBaseView( baseViewModel: model, child: SingleChildScrollView( @@ -141,7 +141,8 @@ class _MedicalFileDetailsState extends State { Row( children: [ AppText( - 'Visit Date : ', + TranslationBase.of(context).visitDate + + ": ", fontWeight: FontWeight.w700, ), if (model.medicalFileList.length != 0 && @@ -174,7 +175,8 @@ class _MedicalFileDetailsState extends State { Row( children: [ AppText( - 'Doctor : '.toUpperCase(), + TranslationBase.of(context).doctorName + + ": ".toUpperCase(), fontWeight: FontWeight.w700, ), if (model.medicalFileList.length != 0 && @@ -203,7 +205,8 @@ class _MedicalFileDetailsState extends State { Row( children: [ AppText( - 'Clinic : ', + TranslationBase.of(context).clinicName + + ": ", fontWeight: FontWeight.w700, ), if (model.medicalFileList.length != 0 && @@ -229,7 +232,8 @@ class _MedicalFileDetailsState extends State { Row( children: [ AppText( - 'Episode Number : ', + TranslationBase.of(context).episode + + ": ", fontWeight: FontWeight.w700, ), if (model.medicalFileList.length != 0 && @@ -277,7 +281,8 @@ class _MedicalFileDetailsState extends State { Row( children: [ Texts( - 'History of present illness' + TranslationBase.of(context) + .historyOfPresentIllness .toUpperCase(), variant: isHistoryExpand ? "bodyText" @@ -376,7 +381,10 @@ class _MedicalFileDetailsState extends State { children: [ Row( children: [ - Texts('assessment'.toUpperCase(), + Texts( + TranslationBase.of(context) + .assessment + .toUpperCase(), variant: isAssessmentExpand ? "bodyText" : '', @@ -554,7 +562,8 @@ class _MedicalFileDetailsState extends State { Row( children: [ Texts( - 'Test / procedures' + TranslationBase.of(context) + .test .toUpperCase(), variant: isProcedureExpand ? "bodyText" @@ -638,18 +647,22 @@ class _MedicalFileDetailsState extends State { ), Row( children: [ - AppText( - model - .medicalFileList[0] - .entityList[0] - .timelines[ - encounterNumber] - .timeLineEvents[0] - .consulations[0] - .lstProcedure[index] - .procName, - fontWeight: - FontWeight.w700, + Expanded( + child: AppText( + model + .medicalFileList[ + 0] + .entityList[0] + .timelines[ + encounterNumber] + .timeLineEvents[0] + .consulations[0] + .lstProcedure[ + index] + .procName, + fontWeight: + FontWeight.w700, + ), ) ], ), @@ -717,7 +730,10 @@ class _MedicalFileDetailsState extends State { children: [ Row( children: [ - Texts('physical exam'.toUpperCase(), + Texts( + TranslationBase.of(context) + .physicalSystemExamination + .toUpperCase(), variant: isPhysicalExam ? "bodyText" : '', diff --git a/lib/screens/medical-file/medical_file_page.dart b/lib/screens/medical-file/medical_file_page.dart index 1e3b4739..069dfbc2 100644 --- a/lib/screens/medical-file/medical_file_page.dart +++ b/lib/screens/medical-file/medical_file_page.dart @@ -27,7 +27,7 @@ class _MedicalFilePageState extends State { (BuildContext context, MedicalFileViewModel model, Widget child) => AppScaffold( isShowAppBar: true, - appBarTitle: 'medical Report'.toUpperCase(), + appBarTitle: TranslationBase.of(context).medicalReport.toUpperCase(), body: NetworkBaseView( baseViewModel: model, child: SingleChildScrollView( @@ -93,6 +93,7 @@ class _MedicalFilePageState extends State { if (model.medicalFileList.length != 0) ListView.builder( //physics: , + physics: NeverScrollableScrollPhysics(), scrollDirection: Axis.vertical, shrinkWrap: true, itemCount: model @@ -108,7 +109,8 @@ class _MedicalFilePageState extends State { Row( children: [ AppText( - 'Branch : ', + TranslationBase.of(context).branch + + ": ", fontWeight: FontWeight.w700, ), AppText(model @@ -121,13 +123,19 @@ class _MedicalFilePageState extends State { Row( children: [ AppText( - 'Doctor : '.toUpperCase(), + TranslationBase.of(context) + .doctorName + .toUpperCase() + + ": ", fontWeight: FontWeight.w700, ), Expanded( child: AppText( - model.medicalFileList[0].entityList[0] - .timelines[index].doctorName, + model + .medicalFileList[0] + .entityList[0] + .timelines[index] + .doctorName, fontWeight: FontWeight.w700, ), ), @@ -136,7 +144,9 @@ class _MedicalFilePageState extends State { Row( children: [ AppText( - 'Clinic : ', + TranslationBase.of(context) + .clinicName + + ": ", fontWeight: FontWeight.w700, ), AppText( diff --git a/lib/screens/patients/patients_screen.dart b/lib/screens/patients/patients_screen.dart index 3083a779..e05c6f04 100644 --- a/lib/screens/patients/patients_screen.dart +++ b/lib/screens/patients/patients_screen.dart @@ -680,7 +680,9 @@ class _PatientsScreenState extends State { PATIENTS_PROFILE, arguments: { "patient": item, - "patientType":patientType + "patientType":patientType, + "from" : patient.getFrom, + "to" : patient.getTo, }); }, ), diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index 77b17e3d..9a59747e 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -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'), diff --git a/lib/screens/patients/profile/vital_sign/LineChartCurved.dart b/lib/screens/patients/profile/vital_sign/LineChartCurved.dart new file mode 100644 index 00000000..2f0eafcb --- /dev/null +++ b/lib/screens/patients/profile/vital_sign/LineChartCurved.dart @@ -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 timeSeries; + final int indexes; + + LineChartCurved({this.title, this.timeSeries, this.indexes}); + + List xAxixs = List(); + List 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: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + 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 getData(context) { + List 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, + ]; + } +} diff --git a/lib/screens/patients/profile/vital_sign/LineChartCurvedBloodPressure.dart b/lib/screens/patients/profile/vital_sign/LineChartCurvedBloodPressure.dart new file mode 100644 index 00000000..e816c145 --- /dev/null +++ b/lib/screens/patients/profile/vital_sign/LineChartCurvedBloodPressure.dart @@ -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 timeSeries1; + final List timeSeries2; + final int indexes; + + LineChartCurvedBloodPressure( + {this.title, this.timeSeries1, this.indexes, this.timeSeries2}); + + List xAxixs = List(); + List 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: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + 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 getData(context) { + List spots = List(); + for (int index = 0; index < timeSeries1.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales)); + } + + List 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]; + } +} diff --git a/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart b/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart index a53a3619..6b2543be 100644 --- a/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart @@ -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( 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( diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_blood_pressurewideget.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_blood_pressurewideget.dart new file mode 100644 index 00000000..693507bb --- /dev/null +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_blood_pressurewideget.dart @@ -0,0 +1,148 @@ +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 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 { + @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: [ + Table( + border: TableBorder.symmetric( + inside: BorderSide(width: 2.0, color: Colors.grey[300]), + ), + children: fullData(projectViewModel), + ), + ], + ), + ), + ); + } + + List fullData(ProjectViewModel projectViewModel) { + List 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]; + DateTime elementDate = + DateUtils.getDateTimeFromServerFormat(vital.createdOn); + 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(elementDate.weekday) : DateUtils.getWeekDay(elementDate.weekday)}, ${elementDate.day} ${projectViewModel.isArabic ? DateUtils.getMonthArabic(elementDate.month) : DateUtils.getMonth(elementDate.month)}, ${elementDate.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; + } +} diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index cf8ee839..ad312625 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -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 { - 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( - onModelReady: (model) => getVitalSignList(context, model), - builder: (_, model, w) => AppScaffold( - baseViewModel: model, + return BaseView( + 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: [ - Row( - children: [ - 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: [ + Row( + children: [ + 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: [ + 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: [ - 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: [ + InkWell( + onTap: () => isNotOneAppointment ? Navigator.push( + context, + FadePage( + page: VitalSignItemDetailsScreen( + pageKey: vitalSignDetails.heart, + pageTitle: TranslationBase.of(context).heart, + vitalList: mode.patientVitalSignsHistory, + ), ), - Row( - children: [ - 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: [ - 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: [ + 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'), ), - ),),); + ), + ); } } diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_wideget.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_wideget.dart new file mode 100644 index 00000000..11a24e42 --- /dev/null +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_wideget.dart @@ -0,0 +1,124 @@ +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 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 { + @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: [ + Table( + border: TableBorder.symmetric( + inside: BorderSide(width: 2.0, color: Colors.grey[300]), + ), + children: fullData(projectViewModel), + ), + ], + ), + ), + ); + } + + List fullData(ProjectViewModel projectViewModel) { + List 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]; + DateTime elementDate = + DateUtils.getDateTimeFromServerFormat(vital.createdOn); + 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(elementDate.weekday) : DateUtils.getWeekDay(elementDate.weekday)}, ${elementDate.day} ${projectViewModel.isArabic ? DateUtils.getMonthArabic(elementDate.month) : DateUtils.getMonth(elementDate.month)}, ${elementDate.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; + } +} diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item.dart index 1e0ce2cf..33b25e82 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item.dart @@ -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: [ - 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: [ 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'), + ), + ), + ]), + ), + ), + ), + ), + ), ], ), ), diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart index 853bec15..bd828138 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart @@ -1 +1,196 @@ -import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.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:flutter/material.dart'; import '../../../../lookups/patient_lookup.dart'; import '../../../../models/patient/vital_sign/vital_sign_res_model.dart'; import '../../../../screens/patients/profile/vital_sign/vital_sing_chart_and_detials.dart'; import '../../../../widgets/shared/app_scaffold_widget.dart'; /* *@author: Elham Rababah *@Date:03/6/2020 *@param: *@return: *@desc: VitalSignItemDetailsScreen */ class VitalSignItemDetailsScreen extends StatelessWidget { VitalSignItemDetailsScreen(); List vitalList = []; String pageTitle; @override Widget build(BuildContext context) { final routeArgs = ModalRoute.of(context).settings.arguments as Map; pageTitle = routeArgs['title']; var pageKey = routeArgs['key']; List VSchart; switch (pageKey) { case vitalSignDetails.bodyMeasurements: VSchart = [ { 'name': 'Highet', 'title1': 'Date', 'title2': 'Cm', 'viewKey': 'HeightCm', }, { 'name': 'Weight Kg', 'title1': 'Date', 'title2': 'Kg', 'viewKey': 'WeightKg', }, { 'name': 'BodyMassIndex', 'title1': 'Date', 'title2': 'BodyMass', 'viewKey': 'BodyMassIndex', }, { 'name': 'HeadCircumCm', 'title1': 'Date', 'title2': 'Cm', 'viewKey': 'HeadCircumCm', }, { 'name': 'Ideal Body Weight (Lbs)', 'title1': 'Date', 'title2': 'Ideal Weight', 'viewKey': 'IdealBodyWeightLbs', }, { 'name': 'LeanBodyWeightLbs (Lbs)', 'title1': 'Date', 'title2': 'Lean Weight', 'viewKey': 'LeanBodyWeightLbs', } ]; break; case vitalSignDetails.temperature: VSchart = [ { 'name': 'Temperature In Celcius', 'title1': 'Date', 'title2': 'C', 'viewKey': 'TemperatureCelcius', }, ]; break; case vitalSignDetails.pulse: VSchart = [ { 'name': 'Pulse Beat Per Minute', 'title1': 'Date', 'title2': 'Minute', 'viewKey': 'PulseBeatPerMinute', }, ]; break; case vitalSignDetails.pespiration: VSchart = [ { 'name': 'Respiration Beat Per Minute', 'title1': 'Date', 'title2': 'Beat Per Minute', 'viewKey': 'RespirationBeatPerMinute', }, ]; break; case vitalSignDetails.bloodPressure: VSchart = [ { 'name': 'Blood Pressure Higher', 'title1': 'Date', 'title2': 'Minute', 'viewKey': 'BloodPressureHigher', }, { 'name': 'Blood Pressure Lower', 'title1': 'Date', 'title2': 'Minute', 'viewKey': 'BloodPressureLower', } ]; break; case vitalSignDetails.oxygenation: VSchart = [ { 'name': 'FIO2', 'title1': 'Date', 'title2': 'Cm', 'viewKey': 'FIO2', }, { 'name': 'SAO2', 'title1': 'Date', 'title2': 'Cm', 'viewKey': 'SAO2', }, ]; break; case vitalSignDetails.painScale: VSchart = [ { 'name': 'PainScore', 'title1': 'Date', 'title2': 'Cm', 'viewKey': 'PainScore', }, ]; break; default: } return BaseView( onModelReady: (model) { vitalList = model.patientVitalSignOrderdSubList; }, builder: (_, model, w) => AppScaffold( baseViewModel: model, appBarTitle: pageTitle, body: ListView( children: VSchart.map((chartInfo) { var vitalListTemp = vitalList.where( (element) => element.toJson()[chartInfo['viewKey']] != null, ); return vitalListTemp.length != 0 ? VitalSingChartAndDetials( vitalList: vitalList, name: chartInfo['name'], title1: chartInfo['title1'], title2: chartInfo['title2'], viewKey: chartInfo['viewKey']) : Center( child: Container( margin: EdgeInsets.only( top: MediaQuery.of(context).size.height * 0.45), child: Center( child: DrAppEmbeddedError( error: TranslationBase.of(context).youDoNotHaveAnyItem), ), )); }).toList(), ), ), ); } } \ No newline at end of file +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/lookups/patient_lookup.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_sing_chart_and_detials.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sing_chart_blood_pressure.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class VitalSignItemDetailsScreen extends StatelessWidget { + final vitalSignDetails pageKey; + final String pageTitle; + List VSchart; + + VitalSignItemDetailsScreen({this.vitalList, this.pageKey, this.pageTitle}); + + final List vitalList; + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + switch (pageKey) { + case vitalSignDetails.BodyMeasurements: + VSchart = [ + { + 'name': 'BMI', + 'nameAr': 'مؤشر الكتلة', + 'title1': 'Date', + 'title2': 'BMI', + 'title2Ar': 'الكتلة', + 'viewKey': 'BodyMassIndex', + }, + + ]; + + break; + + case vitalSignDetails.Temperature: + VSchart = [ + { + 'name': 'Temperature In Celsius', + 'nameAr': 'درجة الحرارة بالدرجة المئوية', + 'title1': 'Date', + 'title2': 'C', + 'title2Ar': 'ْس', + 'viewKey': 'TemperatureCelcius', + }, + ]; + + break; + case vitalSignDetails.Pulse: + VSchart = [ + { + 'name': 'Pulse Beat Per Minute', + 'nameAr': 'نبضة نبضة في الدقيقة', + 'title1': 'Date', + 'title2': 'Minute', + 'title2Ar': 'دقيقة', + 'viewKey': 'PulseBeatPerMinute', + }, + ]; + + break; + case vitalSignDetails.Prescriptions: + VSchart = [ + { + 'name': 'Respiration Beat Per Minute', + 'nameAr': 'ضربات التنفس في الدقيقة', + 'title1': 'Date', + 'title2': 'Beat Per Minute', + 'title2Ar': 'نفس في الدقيقة', + 'viewKey': 'RespirationBeatPerMinute', + }, + ]; + + break; + case vitalSignDetails.BloodPressure: + VSchart = [ + { + 'name': 'Blood Pressure Systolic Diastolic', + 'nameAr': 'ضغط الدم الإنقباض الإنبساط', + 'title1': 'Date', + 'title2': 'systolic', + 'title3': 'Diastolic', + 'title2Ar': 'الإنقباض', + 'title3Ar': 'الإنبساط', + 'viewKey': 'BloodPressure', + }, + + ]; + + break; + case vitalSignDetails.Respiration: + VSchart = [ + { + 'name': 'Respiration Rate', + 'nameAr': 'معدل التنفس', + 'title1': 'Date', + 'title2': 'bpm', + 'title2Ar': 'نفس', + 'viewKey': 'RespirationBeatPerMinute', + }, + ]; + + break; + case vitalSignDetails.heart: + VSchart = [ + { + 'name': 'Heart rate', + 'nameAr': 'معدل النبض بالدقيقة', + 'title1': 'Date', + 'title2': 'bpm', + 'title2Ar': 'نبضة', + 'viewKey': 'PulseBeatPerMinute', + }, + ]; + + break; + case vitalSignDetails.PainScale: + VSchart = [ + { + 'name': 'PainScore', + 'nameAr': 'نقاط الألم', + 'title1': 'Date', + 'title2': 'Cm', + 'title2Ar': 'سم', + 'viewKey': 'PainScore', + }, + ]; + + break; + case vitalSignDetails.Weight: + VSchart = [ + { + 'name': 'Weight Kg', + 'nameAr': 'الوزن كجم', + 'title1': 'Date', + 'title2': 'Kg', + 'title2Ar': 'كجم', + 'viewKey': 'WeightKg', + }, + ]; + + break; + + case vitalSignDetails.Height: + VSchart = [ + { + 'name': 'Height Cm', + 'nameAr': 'الطول سم', + 'title1': 'Date', + 'title2': 'Cm', + 'title2Ar': 'سم', + 'viewKey': 'HeightCm', + }, + ]; + + break; + default: + } + return AppScaffold( + appBarTitle: pageTitle, + isShowAppBar: true, + body: ListView( + children: VSchart.map((chartInfo) { + var vitalListTemp = vitalList.where( + (element) => element.toJson()[chartInfo['viewKey']] != null, + ); + + if(vitalListTemp.length != 0 && chartInfo['viewKey']=='BloodPressure'){ + return VitalSingChartBloodPressure( + vitalList: vitalList, + name:projectViewModel.isArabic? chartInfo['nameAr']:chartInfo['name'], + title1: chartInfo['title1'], + title2:projectViewModel.isArabic?chartInfo['title2Ar']: chartInfo['title2'], + title3:projectViewModel.isArabic?chartInfo['title3Ar']: chartInfo['title3'], + viewKey1: 'BloodPressureHigher', + viewKey2: 'BloodPressureLower', + + ); + } + + return vitalListTemp.length != 0 + ? VitalSingChartAndDetials( + vitalList: vitalList, + name:projectViewModel.isArabic? chartInfo['nameAr']:chartInfo['name'], + title1: chartInfo['title1'], + title2:projectViewModel.isArabic?chartInfo['title2Ar']: chartInfo['title2'], + viewKey: chartInfo['viewKey']) + : Container(); + }).toList(), + ), + ); + } +} diff --git a/lib/screens/patients/profile/vital_sign/vital_sing_chart_and_detials.dart b/lib/screens/patients/profile/vital_sign/vital_sing_chart_and_detials.dart index 7ae4937a..cc93c77b 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sing_chart_and_detials.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sing_chart_and_detials.dart @@ -1,16 +1,15 @@ -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/util/date-utils.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 +20,47 @@ class VitalSingChartAndDetials extends StatelessWidget { @required this.title2, }) : super(key: key); - final List vitalList; + final List vitalList; final String name; final String viewKey; final String title1; final String title2; + List timeSeriesData = []; @override Widget build(BuildContext context) { + generateData(); return Column( children: [ 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) { + DateTime elementDate = DateUtils.getDateTimeFromServerFormat(element.createdOn); + if( element.toJson()[viewKey]!=null && element.toJson()[viewKey]?.toInt()!=0) + timeSeriesData.add( + TimeSeriesSales2( + new DateTime(elementDate.year, elementDate.month, elementDate.day), + element.toJson()[viewKey].toDouble(), + ), + ); + }, + ); + } + return timeSeriesData.reversed.toList(); + } } diff --git a/lib/screens/patients/profile/vital_sign/vital_sing_chart_blood_pressure.dart b/lib/screens/patients/profile/vital_sign/vital_sing_chart_blood_pressure.dart new file mode 100644 index 00000000..dd9f940f --- /dev/null +++ b/lib/screens/patients/profile/vital_sign/vital_sing_chart_blood_pressure.dart @@ -0,0 +1,88 @@ +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/util/date-utils.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 vitalList; + final String name; + final String viewKey1; + final String viewKey2; + final String title1; + final String title2; + final String title3; + List timeSeriesData1 = []; + List timeSeriesData2 = []; + + @override + Widget build(BuildContext context) { + generateData(); + return Column( + children: [ + 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) { + DateTime elementDate = + DateUtils.getDateTimeFromServerFormat(element.createdOn); + if (element.toJson()[viewKey1]?.toInt() != 0) + timeSeriesData1.add( + TimeSeriesSales2( + new DateTime( + elementDate.year, elementDate.month, elementDate.day), + element.toJson()[viewKey1].toDouble(), + ), + ); + if (element.toJson()[viewKey2]?.toInt() != 0) + timeSeriesData2.add( + TimeSeriesSales2( + new DateTime( + elementDate.year, elementDate.month, elementDate.day), + element.toJson()[viewKey2].toDouble(), + ), + ); + }, + ); + } + } +} diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index 8714327d..0b49c257 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -93,6 +93,7 @@ class PrescriptionFormWidget extends StatefulWidget { } class _PrescriptionFormWidgetState extends State { + int selectedType; TextEditingController durationController = TextEditingController(); TextEditingController strengthController = TextEditingController(); TextEditingController routeController = TextEditingController(); @@ -127,6 +128,7 @@ class _PrescriptionFormWidgetState extends State { @override void initState() { super.initState(); + selectedType = 1; referToList = List(); strengthList = List(); routeList = List(); @@ -252,6 +254,12 @@ class _PrescriptionFormWidgetState extends State { referToList.add(urgentOrder); } + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; @@ -344,10 +352,22 @@ class _PrescriptionFormWidgetState extends State { child: Row( children: [ AppText('Order Type'), - Radio(), + Radio( + activeColor: Color(0xFFB9382C), + value: 0, + groupValue: selectedType, + onChanged: (value) { + setSelectedType(value); + }, + ), Text('Regular'), Radio( + activeColor: Color(0xFFB9382C), + groupValue: selectedType, value: 1, + onChanged: (value) { + setSelectedType(value); + }, ), Text('Urgent'), ], diff --git a/lib/screens/prescription/prescription_screen.dart b/lib/screens/prescription/prescription_screen.dart index 45e5173f..df8c0e17 100644 --- a/lib/screens/prescription/prescription_screen.dart +++ b/lib/screens/prescription/prescription_screen.dart @@ -453,6 +453,26 @@ class _NewPrescriptionScreenState extends State { .edit), onTap: () { updatePrescriptionForm( + startDate: + model.prescriptionList[0].entityList[index].startDate + .toString(), + dose: model + .prescriptionList[ + 0] + .entityList[ + index] + .doseTimingID + .toString(), + frequency: + model.prescriptionList[0].entityList[index].frequencyID + .toString(), + rouat: model + .prescriptionList[ + 0] + .entityList[ + index] + .routeID + .toString(), patient: patient, drugId: model @@ -466,17 +486,13 @@ class _NewPrescriptionScreenState extends State { 0] .entityList[ index] - .medicationName, + .doseDetail, remarks: model - .prescriptionList[ - 0] - .entityList[ - index] + .prescriptionList[0] + .entityList[index] .remarks, - model: - model, - context: - context); + model: model, + context: context); //model.postPrescription(); }, ), @@ -577,7 +593,11 @@ class _NewPrescriptionScreenState extends State { int drugId, String remarks, PrescriptionViewModel model, - PatiantInformtion patient}) { + PatiantInformtion patient, + String rouat, + String frequency, + String dose, + String startDate}) { TextEditingController remarksController = TextEditingController(); TextEditingController doseController = TextEditingController(); TextEditingController frequencyController = TextEditingController(); @@ -587,11 +607,11 @@ class _NewPrescriptionScreenState extends State { isScrollControlled: true, builder: (BuildContext bc) { return Container( - height: 600, + height: MediaQuery.of(context).size.height * 0.73, child: Form( child: Padding( padding: - EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), + EdgeInsets.symmetric(horizontal: 20.0, vertical: 12.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -626,7 +646,7 @@ class _NewPrescriptionScreenState extends State { border: Border.all( width: 1.0, color: HexColor("#CCCCCC"))), child: TextFields( - hintText: 'Dose', + hintText: 'Dose Time', controller: doseController, keyboardType: TextInputType.number, ), @@ -649,7 +669,6 @@ class _NewPrescriptionScreenState extends State { SizedBox( height: 12.0, ), - AppText('Remarks'), Container( decoration: BoxDecoration( borderRadius: @@ -667,7 +686,7 @@ class _NewPrescriptionScreenState extends State { height: 12.0, ), SizedBox( - height: 140.0, + height: MediaQuery.of(context).size.height * 0.12, ), Container( margin: @@ -679,6 +698,10 @@ class _NewPrescriptionScreenState extends State { title: 'update prescription'.toUpperCase(), onPressed: () { updatePrescription( + startDate: startDate, + doseId: dose, + frequencyId: frequency, + routeId: rouat, patient: patient, model: model, drugId: drugId, @@ -704,10 +727,14 @@ class _NewPrescriptionScreenState extends State { updatePrescription( {PrescriptionViewModel model, int drugId, + String frequencyId, String remarks, String dose, + String doseId, String frequency, String route, + String routeId, + String startDate, PatiantInformtion patient}) async { //PrescriptionViewModel model = PrescriptionViewModel(); PostPrescriptionReqModel updatePrescriptionReqModel = @@ -722,17 +749,19 @@ class _NewPrescriptionScreenState extends State { "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMDAyIiwianRpIjoiOGFjNDRjZGQtOWE0Mi00M2YxLWE2YTQtMWQ4NzBmZmYwNTUyIiwiZW1haWwiOiIiLCJpZCI6IjEwMDIiLCJOYW1lIjoiVEVNUCAtIERPQ1RPUiIsIkVtcGxveWVlSWQiOiI0NzA5IiwiRmFjaWxpdHlHcm91cElkIjoiMDEwMjY2IiwiRmFjaWxpdHlJZCI6IjE1IiwiUGhhcmFtY3lGYWNpbGl0eUlkIjoiNTUiLCJJU19QSEFSTUFDWV9DT05ORUNURUQiOiJUcnVlIiwiRG9jdG9ySWQiOiI0NzA5IiwiU0VTU0lPTklEIjoiMjE1OTU2NDkiLCJDbGluaWNJZCI6IjEiLCJyb2xlIjpbIkRPQ1RPUlMiLCJIRUFEIERPQ1RPUlMiLCJBRE1JTklTVFJBVE9SUyIsIlJFQ0VQVElPTklTVCIsIkVSIE5VUlNFIiwiRVIgUkVDRVBUSU9OSVNUIiwiUEhBUk1BQ1kgQUNDT1VOVCBTVEFGRiIsIlBIQVJNQUNZIE5VUlNFIiwiSU5QQVRJRU5UIFBIQVJNQUNJU1QiLCJBRE1JU1NJT04gU1RBRkYiLCJBUFBST1ZBTCBTVEFGRiIsIkNPTlNFTlQgIiwiTUVESUNBTCBSRVBPUlQgLSBTSUNLIExFQVZFIE1BTkFHRVIiXSwibmJmIjoxNjA4NzM2NjY5LCJleHAiOjE2MDk2MDA2NjksImlhdCI6MTYwODczNjY2OX0.9EDgYrbe5fQA2CvgLdFT4s_PL7hD5R_Qggfpv4lDtUY"; sss.add(PrescriptionRequestModel( covered: true, - dose: frequency.isNotEmpty ? int.parse(dose) : 1, + dose: 9, //frequency.isNotEmpty ? int.parse(dose) : 1, itemId: drugId, - doseUnitId: 1, - route: frequency.isNotEmpty ? int.parse(route) : 1, - frequency: frequency.isNotEmpty ? int.parse(frequency) : 1, + doseUnitId: 2, + route: route.isNotEmpty ? int.parse(route) : int.parse(routeId), + frequency: frequency.isNotEmpty + ? int.parse(frequency) + : int.parse(frequencyId), remarks: remarks.isEmpty ? '' : remarks, approvalRequired: true, icdcode10Id: "test2", - doseTime: 1, + doseTime: dose.isNotEmpty ? int.parse(dose) : int.parse(doseId), duration: 2, - doseStartDate: "2020-12-20T13:07:41.769Z")); + doseStartDate: startDate)); updatePrescriptionReqModel.prescriptionRequestModel = sss; //postProcedureReqModel.procedures = controlsProcedure; diff --git a/lib/screens/procedures/entity_list_checkbox_search_widget.dart b/lib/screens/procedures/entity_list_checkbox_search_widget.dart index 78f584f6..4f236a4b 100644 --- a/lib/screens/procedures/entity_list_checkbox_search_widget.dart +++ b/lib/screens/procedures/entity_list_checkbox_search_widget.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/Text.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; import 'package:doctor_app_flutter/widgets/shared/app_buttons_widget.dart'; @@ -61,7 +62,7 @@ class _EntityListCheckboxSearchWidgetState child: ListView( children: [ TextFields( - hintText: 'Search ', + hintText: TranslationBase.of(context).searchProcedures, suffixIcon: EvaIcons.search, onChanged: (value) { filterSearchResults(value); diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index 60a04480..31eb99e9 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -33,8 +33,15 @@ class ProcedureScreen extends StatefulWidget { } class _ProcedureScreenState extends State { + int selectedType = 0; int testNum = 1; PatiantInformtion patient; + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + TextEditingController procedureController = TextEditingController(); @override Widget build(BuildContext context) { @@ -45,7 +52,7 @@ class _ProcedureScreenState extends State { builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: true, - appBarTitle: 'ORDER PROCEDURE', + appBarTitle: TranslationBase.of(context).orderProcedure, body: NetworkBaseView( baseViewModel: model, child: SingleChildScrollView( @@ -199,7 +206,8 @@ class _ProcedureScreenState extends State { .spaceBetween, children: [ AppText( - ' Add more procedure', + TranslationBase.of(context) + .addMoreProcedure, fontWeight: FontWeight.w100, fontSize: 12.5, ), @@ -275,7 +283,10 @@ class _ProcedureScreenState extends State { Row( children: [ AppText( - 'Code #: ', + TranslationBase.of( + context) + .codeNo + + " : ", fontWeight: FontWeight .w700, @@ -297,7 +308,10 @@ class _ProcedureScreenState extends State { width: 12.0, ), AppText( - 'Order Type: ', + TranslationBase.of( + context) + .orderType + + " : ", fontWeight: FontWeight .w700, @@ -312,8 +326,8 @@ class _ProcedureScreenState extends State { : 'Urgent', fontSize: 13.0, - color: Colors - .red, + color: Color( + 0xFFB9382C), ), ], ), @@ -342,7 +356,10 @@ class _ProcedureScreenState extends State { Row( children: [ AppText( - 'Price: ', + TranslationBase.of( + context) + .price + + " : ", fontWeight: FontWeight .w700, @@ -409,6 +426,12 @@ class _ProcedureScreenState extends State { onTap: () { updateProcedureForm( context, + remarks: model + .procedureList[ + 0] + .entityList[ + index] + .remarks, procedureName: model .procedureList[ 0] @@ -452,6 +475,109 @@ class _ProcedureScreenState extends State { )), ); } + + void updateProcedureForm(context, + {String procedureName, + PatiantInformtion patient, + String procedureId, + String remarks, + String categoreId}) { + ProcedureViewModel model = ProcedureViewModel(); + TextEditingController remarksController = TextEditingController(); + TextEditingController orderController = TextEditingController(); + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (BuildContext bc) { + return Container( + height: MediaQuery.of(context).size.height * 0.55, + child: Form( + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + procedureName.toUpperCase(), + fontWeight: FontWeight.w700, + ), + SizedBox( + height: 30.0, + ), + Container( + child: Row( + children: [ + AppText(TranslationBase.of(context).orderType), + Radio( + activeColor: Color(0xFFB9382C), + value: 0, + groupValue: selectedType, + onChanged: (value) { + setSelectedType(value); + }, + ), + Text(TranslationBase.of(context).regular), + Radio( + activeColor: Color(0xFFB9382C), + groupValue: selectedType, + value: 1, + onChanged: (value) { + setSelectedType(value); + }, + ), + Text(TranslationBase.of(context).urgent), + ], + ), + ), + SizedBox( + height: 12.0, + ), + Container( + decoration: BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(6.0)), + border: Border.all( + width: 1.0, color: HexColor("#CCCCCC"))), + child: TextFields( + hintText: remarks, + controller: remarksController, + maxLines: 5, + minLines: 3, + ), + ), + SizedBox( + height: 100.0, + ), + Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 2), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: TranslationBase.of(context) + .updateProcedure + .toUpperCase(), + onPressed: () { + Navigator.pop(context); + updateProcedure( + categorieId: categoreId, + procedureId: procedureId, + patient: patient, + model: model, + remarks: remarksController.text); + // authorizationForm(context); + }, + ), + ], + ), + ), + ], + ), + ), + )); + }); + } } postProcedure( @@ -553,6 +679,7 @@ class AddSelectedProcedure extends StatefulWidget { } class _AddSelectedProcedureState extends State { + int selectedType; ProcedureViewModel model; PatiantInformtion patient; _AddSelectedProcedureState({this.patient, this.model}); @@ -560,6 +687,12 @@ class _AddSelectedProcedureState extends State { TextEditingController remarksController = TextEditingController(); List entityList = List(); dynamic selectedCategory; + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; @@ -568,139 +701,172 @@ class _AddSelectedProcedureState extends State { builder: (BuildContext context, ProcedureViewModel model, Widget child) => NetworkBaseView( baseViewModel: model, - child: SingleChildScrollView( - child: Container( - height: 810, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - 'Select Procedure'.toUpperCase(), - fontWeight: FontWeight.w900, - ), - Container( - height: screenSize.height * 0.070, - child: InkWell( - onTap: model.categoryList != null && - model.categoryList.length > 0 - ? () { - ListSelectDialog dialog = ListSelectDialog( - list: model.categoryList, - attributeName: 'categoryName', - attributeValueId: 'categoryId', - okText: TranslationBase.of(context).ok, - okFunction: (selectedValue) { - setState(() { - selectedCategory = selectedValue; - model.getProcedureCategory( - categoryName: - selectedCategory['categoryName']); - }); - }, - ); - showDialog( - barrierDismissible: false, - context: context, - builder: (BuildContext context) { - return dialog; - }, - ); - //model.getProcedureCategory(); - } - : null, - child: TextField( - decoration: textFieldSelectorDecoration( - 'Procedure Categorey', - selectedCategory != null - ? selectedCategory['categoryName'] + child: DraggableScrollableSheet( + minChildSize: 0.90, + initialChildSize: 0.95, + maxChildSize: 1.0, + builder: (BuildContext context, ScrollController scrollController) { + return SingleChildScrollView( + child: Container( + height: MediaQuery.of(context).size.height * 1.20, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .selectProcedures + .toUpperCase(), + fontWeight: FontWeight.w900, + ), + SizedBox( + height: 10.0, + ), + Container( + height: screenSize.height * 0.070, + child: InkWell( + onTap: model.categoryList != null && + model.categoryList.length > 0 + ? () { + ListSelectDialog dialog = ListSelectDialog( + list: model.categoryList, + attributeName: 'categoryName', + attributeValueId: 'categoryId', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() { + selectedCategory = selectedValue; + model.getProcedureCategory( + categoryName: selectedCategory[ + 'categoryName']); + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + //model.getProcedureCategory(); + } : null, - true, - suffixIcon: Icon( - Icons.search, - color: Colors.black, - )), - enabled: false, - ), - ), - ), - if (widget.model.categoriesList.length != 0) - EntityListCheckboxSearchWidget( - model: widget.model, - masterList: widget.model.categoriesList[0].entityList, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => - isEntityListSelected(master), - ), - SizedBox( - height: 15.0, - ), - Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - decoration: BoxDecoration( - borderRadius: - BorderRadius.all(Radius.circular(6.0)), - border: Border.all( - width: 1.0, color: HexColor("#CCCCCC"))), - child: TextFields( - hintText: 'Order Type'.toUpperCase(), - controller: procedureController, + child: TextField( + decoration: textFieldSelectorDecoration( + TranslationBase.of(context) + .procedureCategorise, + selectedCategory != null + ? selectedCategory['categoryName'] + : null, + true, + suffixIcon: Icon( + Icons.search, + color: Colors.black, + )), + enabled: false, + ), + ), ), - ), - SizedBox( - height: 15.0, - ), - TextFields( - hintText: 'Remarks', - controller: remarksController, - minLines: 3, - maxLines: 5, - ), - SizedBox( - height: 50.0, - ), - Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: 'add Selected Procedures'.toUpperCase(), - onPressed: () { - Navigator.pop(context); - postProcedure( - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); + if (widget.model.categoriesList.length != 0) + NetworkBaseView( + baseViewModel: model, + child: EntityListCheckboxSearchWidget( + model: widget.model, + masterList: + widget.model.categoriesList[0].entityList, + removeHistory: (item) { + setState(() { + entityList.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityList.add(history); + }); }, + addSelectedHistories: () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: (master) => + isEntityListSelected(master), ), - ], + ), + SizedBox( + height: 15.0, ), - ), - ], - ) - ], - ), - ), - ), - ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + child: Row( + children: [ + AppText( + TranslationBase.of(context).orderType), + Radio( + activeColor: Color(0xFFB9382C), + value: 0, + groupValue: selectedType, + onChanged: (value) { + setSelectedType(value); + }, + ), + Text(TranslationBase.of(context).regular), + Radio( + activeColor: Color(0xFFB9382C), + groupValue: selectedType, + value: 1, + onChanged: (value) { + setSelectedType(value); + }, + ), + Text(TranslationBase.of(context).urgent), + ], + ), + ), + SizedBox( + height: 15.0, + ), + TextFields( + hintText: TranslationBase.of(context).remarks, + controller: remarksController, + minLines: 3, + maxLines: 5, + ), + SizedBox( + height: 50.0, + ), + Container( + margin: EdgeInsets.all( + SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: TranslationBase.of(context) + .addSelectedProcedures, + onPressed: () { + Navigator.pop(context); + postProcedure( + entityList: entityList, + patient: patient, + model: widget.model, + remarks: remarksController.text); + }, + ), + ], + ), + ), + ], + ) + ], + ), + ), + ), + ); + }), ), ); } @@ -746,86 +912,3 @@ class _AddSelectedProcedureState extends State { ); } } - -void updateProcedureForm(context, - {String procedureName, - PatiantInformtion patient, - String procedureId, - String categoreId}) { - ProcedureViewModel model = ProcedureViewModel(); - TextEditingController remarksController = TextEditingController(); - TextEditingController orderController = TextEditingController(); - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bc) { - return Container( - height: 400, - child: Form( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - procedureName.toUpperCase(), - fontWeight: FontWeight.w700, - ), - SizedBox( - height: 30.0, - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6.0)), - border: Border.all( - width: 1.0, color: HexColor("#CCCCCC"))), - child: TextFields( - hintText: 'Order ', - controller: orderController, - ), - ), - SizedBox( - height: 12.0, - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6.0)), - border: Border.all( - width: 1.0, color: HexColor("#CCCCCC"))), - child: TextFields( - hintText: 'Remarks', - controller: remarksController, - maxLines: 5, - minLines: 3, - ), - ), - SizedBox( - height: 100.0, - ), - Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 2), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: 'Update procedure'.toUpperCase(), - onPressed: () { - Navigator.pop(context); - updateProcedure( - categorieId: categoreId, - procedureId: procedureId, - patient: patient, - model: model, - remarks: remarksController.text); - // authorizationForm(context); - }, - ), - ], - ), - ), - ], - ), - ), - )); - }); -} diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 5d651bad..a624dd2c 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -12,6 +12,12 @@ class DateUtils { } static convertDateFromServerFormat(String str, dateFormat) { + var date = getDateTimeFromServerFormat(str); + + return DateFormat(dateFormat).format(date); + } + + static DateTime getDateTimeFromServerFormat(String str) { const start = "/Date("; const end = "+0300)"; @@ -23,7 +29,7 @@ class DateUtils { var date = new DateTime.fromMillisecondsSinceEpoch( int.parse(str.substring(startIndex + start.length, endIndex))); - return DateFormat(dateFormat).format(date); + return date; } static String differenceBetweenDateAndCurrentInYearMonthDay(DateTime firstDate) { @@ -77,5 +83,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; + } + } } diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index dd72e58a..1f81e8a5 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -616,6 +616,40 @@ class TranslationBase { 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]; + + String get medicalReport => + localizedValues['medicalReport'][locale.languageCode]; + String get visitDate => localizedValues['visitDate'][locale.languageCode]; + String get test => localizedValues['test'][locale.languageCode]; + String get addMoreProcedure => + localizedValues['addMoreProcedure'][locale.languageCode]; + String get regular => localizedValues['regular'][locale.languageCode]; + String get searchProcedures => + localizedValues['searchProcedures'][locale.languageCode]; + String get procedureCategorise => + localizedValues['procedureCategorise'][locale.languageCode]; + String get selectProcedures => + localizedValues['selectProcedures'][locale.languageCode]; + String get addSelectedProcedures => + localizedValues['addSelectedProcedures'][locale.languageCode]; + String get updateProcedure => + localizedValues['updateProcedure'][locale.languageCode]; + String get orderProcedure => + localizedValues['orderProcedure'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/charts/app_bar_chart.dart b/lib/widgets/charts/app_bar_chart.dart new file mode 100644 index 00000000..98ef3cfa --- /dev/null +++ b/lib/widgets/charts/app_bar_chart.dart @@ -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 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, + )), + ), + ); + } +} diff --git a/lib/widgets/charts/app_line_chart.dart b/lib/widgets/charts/app_line_chart.dart new file mode 100644 index 00000000..553afec8 --- /dev/null +++ b/lib/widgets/charts/app_line_chart.dart @@ -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 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: [ + Text( + chartTitle, + style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold), + ), + Expanded( + child: charts.LineChart(seriesList, + defaultRenderer: charts.LineRendererConfig( + includeArea: false, stacked: true), + animate: animate), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/charts/app_time_series_chart.dart b/lib/widgets/charts/app_time_series_chart.dart new file mode 100644 index 00000000..670284a1 --- /dev/null +++ b/lib/widgets/charts/app_time_series_chart.dart @@ -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> seriesList; + final DateTime startDate; + final DateTime endDate; + + @override + Widget build(BuildContext context) { + return FlexibleContainer( + heightFactor: 0.47, + child: Column( + children: [ + 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); +} diff --git a/lib/widgets/data_display/list/custom_Item.dart b/lib/widgets/data_display/list/custom_Item.dart new file mode 100644 index 00000000..c11af999 --- /dev/null +++ b/lib/widgets/data_display/list/custom_Item.dart @@ -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: [ + 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, + ), + ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/widgets/data_display/list/flexible_container.dart b/lib/widgets/data_display/list/flexible_container.dart new file mode 100644 index 00000000..a35fa279 --- /dev/null +++ b/lib/widgets/data_display/list/flexible_container.dart @@ -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, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/patients/profile/patient_profile_widget.dart b/lib/widgets/patients/profile/patient_profile_widget.dart index a58a4a38..11f1572f 100644 --- a/lib/widgets/patients/profile/patient_profile_widget.dart +++ b/lib/widgets/patients/profile/patient_profile_widget.dart @@ -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, )) ]), ); diff --git a/lib/widgets/patients/profile/profile_medical_info_widget.dart b/lib/widgets/patients/profile/profile_medical_info_widget.dart index e9956453..054d3c34 100644 --- a/lib/widgets/patients/profile/profile_medical_info_widget.dart +++ b/lib/widgets/patients/profile/profile_medical_info_widget.dart @@ -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}); + + String from; + String to; + PatiantInformtion patient; - String patientType; + String patientType; @override Widget build(BuildContext context) { return BaseView( @@ -50,42 +56,41 @@ 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 || int.parse(patientType) == 6) - 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 || int.parse(patientType) == 6) + 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, @@ -113,65 +118,51 @@ class ProfileMedicalInfoWidget extends StatelessWidget { key: key, patient: patient, route: ORDER_PRESCRIPTION, - nameLine1: 'Order', - nameLine2: 'Prescription', + nameLine1: TranslationBase.of(context).orders, + nameLine2: TranslationBase.of(context).prescription, icon: 'lab.png'), PatientProfileButton( key: key, patient: patient, route: ORDER_PROCEDURE, - nameLine1: 'Order Test', - nameLine2: 'Or Procedures', + nameLine1: TranslationBase.of(context).orders, + nameLine2: TranslationBase.of(context).procedures, icon: 'lab.png'), - if(selectedPatientType == 7|| int.parse(patientType) == 6) + if (selectedPatientType == 7|| int.parse(patientType) == 6) 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|| int.parse(patientType) == 6) + if (selectedPatientType == 7|| int.parse(patientType) == 6) 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 +221,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 +247,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: [ Container( alignment: Alignment.topLeft, @@ -273,8 +275,7 @@ class PatientProfileButton extends StatelessWidget { textAlign: TextAlign.left, fontSize: SizeConfig.textMultiplier * 2, ), - if(isLoading) - DrAppCircularProgressIndeicator() + if (isLoading) DrAppCircularProgressIndeicator() ], ), ), @@ -313,6 +314,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}); } } diff --git a/lib/widgets/transitions/fade_page.dart b/lib/widgets/transitions/fade_page.dart new file mode 100644 index 00000000..97a37ce1 --- /dev/null +++ b/lib/widgets/transitions/fade_page.dart @@ -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 animation, + Animation secondaryAnimation, + ) => + page, + transitionDuration: Duration(milliseconds: 300), + transitionsBuilder: ( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) { + return FadeTransition( + opacity: animation, + child: child + ); + } + ); +} \ No newline at end of file diff --git a/lib/widgets/transitions/slide_up_page.dart b/lib/widgets/transitions/slide_up_page.dart new file mode 100644 index 00000000..2c138b9e --- /dev/null +++ b/lib/widgets/transitions/slide_up_page.dart @@ -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 animation, + Animation 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 animation, + Animation 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); + }), + ); +} diff --git a/pubspec.lock b/pubspec.lock index 7f3738b5..d49ad4a1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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 @@ -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: diff --git a/pubspec.yaml b/pubspec.yaml index 35afa76a..887ac913 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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