diff --git a/lib/constants/app_constants.dart b/lib/constants/app_constants.dart index 7e73915..8848208 100644 --- a/lib/constants/app_constants.dart +++ b/lib/constants/app_constants.dart @@ -35,6 +35,12 @@ class AppColors { static Color brownColor = const Color(0xFF460707); static Color blackColor = Colors.black54; + static Color nebulizationColor = const Color(0xFF3C86D0); + static Color vitalSignColor = const Color(0xFFD02127); + static Color doctorColor = const Color(0xFF52964F); + static Color vaccinationColor = const Color(0xFFC99609); + static Color procedureColor = const Color(0xFF460707); + //Decoration static BoxDecoration configWidgetDecoration = BoxDecoration( @@ -95,10 +101,16 @@ class AppConstants { static String apiKey = 'EE17D21C7943485D9780223CCE55DCE5'; static String testIP = '12.4.5.1'; // projectID.QlineType.ScreenType.AnyNumber (1 to 10) static int thresholdForListUI = 3; + + static int currentBuildVersion = 1; } class ApiConstants { - static String baseUrl = 'https://ms.hmg.com/nscapi2'; + static String baseUrlLive = 'https://qline.hmg.com'; // LIVE + static String baseUrlUat = 'https://ms.hmg.com/nscapi'; // UAT + static String baseUrlDev = 'https://ms.hmg.com/nscapi2'; // DEV + + static String baseUrl = baseUrlLive; static String baseUrlHub = '$baseUrl/PatientCallingHub'; static String baseUrlApi = '$baseUrl/api'; static String baseUrlApiGen = '$baseUrl/api/Gen'; @@ -148,3 +160,327 @@ class CacheConstants { // "createdBy": 101, // "apiKey": "EE17D21C7943485D9780223CCE55DCE5" // } + +class MockJsonRepo { + static Map globalConfigurationMockResponse = { + "id": 1, + "configType": 2, + "description": "Main Kiosk Config", + "counterStart": 1, + "counterEnd": 10, + "concurrentCallDelaySec": 5, + "voiceType": 1, + "voiceTypeText": "Standard Voice", + "screenLanguage": 1, + "screenLanguageText": "English", + "textDirection": 1, + "voiceLanguage": 1, + "voiceLanguageText": "English", + "screenMaxDisplayPatients": 8, + "isNotiReq": true, + "prioritySMS": 1, + "priorityWhatsApp": 2, + "priorityEmail": 3, + "ticketNoText": "Ticket Number", + "pleaseVisitCounterText": "Please Visit Counter", + "counterText": "Counter", + "roomText": "Room", + "roomNo": 101, + "isRoomNoRequired": true, + "queueNoText": "Queue Number", + "callForText": "Call For", + "currentServeText": "Current Serve", + "maxText": "Max Temp", + "minText": "Min Temp", + "nextPrayerText": "Next Prayer", + "weatherText": "Weather", + "fajarText": "Fajar", + "dhuhrText": "Dhuhr", + "asarText": "Asar", + "maghribText": "Maghrib", + "ishaText": "Isha", + "isActive": true, + "createdBy": 101, + "createdOn": "2025-07-15T08:00:00Z", + "editedBy": 102, + "editedOn": "2025-07-15T10:00:00Z", + "isToneReq": false, + "isVoiceReq": false, + "orientationType": 1, + "isTurnOn": true, + "waitingAreaType": 1, + "gender": 1, + "isWeatherReq": true, + "isPrayerTimeReq": true, + "isRssFeedReq": true, + "qType": 1, + "screenType": 1, + "projectID": 123, + "projectLatitude": 24.722136, + "projectLongitude": 46.774303, + "cityKey": 999, + "kioskQueue": [ + {"id": 1, "name": "General Queue", "code": "GQ", "isActive": true}, + {"id": 2, "name": "VIP Queue", "code": "VIP", "isActive": true} + ], + "kioskConfig": [ + {"id": 1, "languageCode": "en", "languageName": "English", "isDefault": true}, + {"id": 2, "languageCode": "ar", "languageName": "Arabic", "isDefault": false} + ] + }; + + static List> mockPatientTicketResponse = [ + { + "qType": 1, + "screenType": 2, + "connectionID": "abc-123-connection", + "data": [ + { + "id": 101, + "patientID": 202, + "laB_QGroupID": 303, + "queueNo": "A13", + "counterBatchNo": 1, + "calledBy": 404, + "calledOn": "2025-07-15T08:30:00Z", + "servedOn": "2025-07-15T08:45:00Z", + "patientName": "John Doe", + "mobileNo": "+966500000000", + "patientEmail": "john@example.com", + "preferredLang": 1, + "ticketNoText": "Ticket No", + "pleaseVisitCounterText": "Please Visit Counter", + "patientGender": 1, + "roomNo": "R2", + "isActive": true, + "createdBy": 999, + "editedBy": 1000, + "editedOn": "2025-07-15T08:10:00Z", + "createdOn": "2025-07-15T08:00:00Z", + "doctorNameN": "Dr. Smith", + "callType": 2, + "queueNoM": "B45", + "callNoStr": "Call #1001", + "isQueue": true, + "isToneReq": true, + "isVoiceReq": true, + "orientationType": 1, + "isTurnOn": true, + "concurrentCallDelaySec": 3, + "crTypeAckIP": "192.168.1.100", + "voiceLanguage": 1, + "voiceLanguageText": "English", + "vitalSignText": "Vital Sign", + "doctorText": "Doctor", + "procedureText": "Procedure", + "vaccinationText": "Vaccination", + "nebulizationText": "Nebulization", + "callForVitalSignText": "Calling for Vital Sign", + "callForDoctorText": "Calling for Doctor", + "callForProcedureText": "Calling for Procedure", + "callForVaccinationText": "Calling for Vaccination", + "callForNebulizationText": "Calling for Nebulization", + "roomText": "Room", + "queueNoText": "Queue No", + "callForText": "Call For" + }, + { + "id": 101, + "patientID": 202, + "laB_QGroupID": 303, + "queueNo": "B21", + "counterBatchNo": 1, + "calledBy": 404, + "calledOn": "2025-07-15T08:30:00Z", + "servedOn": "2025-07-15T08:45:00Z", + "patientName": "John Doe", + "mobileNo": "+966500000000", + "patientEmail": "john@example.com", + "preferredLang": 1, + "ticketNoText": "Ticket No", + "pleaseVisitCounterText": "Please Visit Counter", + "patientGender": 1, + "roomNo": "R3", + "isActive": true, + "createdBy": 999, + "editedBy": 1000, + "editedOn": "2025-07-15T08:10:00Z", + "createdOn": "2025-07-15T08:00:00Z", + "doctorNameN": "Dr. Smith", + "callType": 3, + "queueNoM": "B45", + "callNoStr": "Call #1001", + "isQueue": true, + "isToneReq": true, + "isVoiceReq": true, + "orientationType": 1, + "isTurnOn": true, + "concurrentCallDelaySec": 3, + "crTypeAckIP": "192.168.1.100", + "voiceLanguage": 1, + "voiceLanguageText": "English", + "vitalSignText": "Vital Sign", + "doctorText": "Doctor", + "procedureText": "Procedure", + "vaccinationText": "Vaccination", + "nebulizationText": "Nebulization", + "callForVitalSignText": "Calling for Vital Sign", + "callForDoctorText": "Calling for Doctor", + "callForProcedureText": "Calling for Procedure", + "callForVaccinationText": "Calling for Vaccination", + "callForNebulizationText": "Calling for Nebulization", + "roomText": "Room", + "queueNoText": "Queue No", + "callForText": "Call For" + }, + { + "id": 101, + "patientID": 202, + "laB_QGroupID": 303, + "queueNo": "C07", + "counterBatchNo": 1, + "calledBy": 404, + "calledOn": "2025-07-15T08:30:00Z", + "servedOn": "2025-07-15T08:45:00Z", + "patientName": "John Doe", + "mobileNo": "+966500000000", + "patientEmail": "john@example.com", + "preferredLang": 1, + "ticketNoText": "Ticket No", + "pleaseVisitCounterText": "Please Visit Counter", + "patientGender": 1, + "roomNo": "R4", + "isActive": true, + "createdBy": 999, + "editedBy": 1000, + "editedOn": "2025-07-15T08:10:00Z", + "createdOn": "2025-07-15T08:00:00Z", + "doctorNameN": "Dr. Smith", + "callType": 4, + "queueNoM": "B45", + "callNoStr": "Call #1001", + "isQueue": true, + "isToneReq": true, + "isVoiceReq": true, + "orientationType": 1, + "isTurnOn": true, + "concurrentCallDelaySec": 3, + "crTypeAckIP": "192.168.1.100", + "voiceLanguage": 1, + "voiceLanguageText": "English", + "vitalSignText": "Vital Sign", + "doctorText": "Doctor", + "procedureText": "Procedure", + "vaccinationText": "Vaccination", + "nebulizationText": "Nebulization", + "callForVitalSignText": "Calling for Vital Sign", + "callForDoctorText": "Calling for Doctor", + "callForProcedureText": "Calling for Procedure", + "callForVaccinationText": "Calling for Vaccination", + "callForNebulizationText": "Calling for Nebulization", + "roomText": "Room", + "queueNoText": "Queue No", + "callForText": "Call For" + }, + { + "id": 101, + "patientID": 202, + "laB_QGroupID": 303, + "queueNo": "D11", + "counterBatchNo": 1, + "calledBy": 404, + "calledOn": "2025-07-15T08:30:00Z", + "servedOn": "2025-07-15T08:45:00Z", + "patientName": "John Doe", + "mobileNo": "+966500000000", + "patientEmail": "john@example.com", + "preferredLang": 1, + "ticketNoText": "Ticket No", + "pleaseVisitCounterText": "Please Visit Counter", + "patientGender": 1, + "roomNo": "R5", + "isActive": true, + "createdBy": 999, + "editedBy": 1000, + "editedOn": "2025-07-15T08:10:00Z", + "createdOn": "2025-07-15T08:00:00Z", + "doctorNameN": "Dr. Smith", + "callType": 5, + "queueNoM": "B45", + "callNoStr": "Call #1001", + "isQueue": true, + "isToneReq": true, + "isVoiceReq": true, + "orientationType": 1, + "isTurnOn": true, + "concurrentCallDelaySec": 3, + "crTypeAckIP": "192.168.1.100", + "voiceLanguage": 1, + "voiceLanguageText": "English", + "vitalSignText": "Vital Sign", + "doctorText": "Doctor", + "procedureText": "Procedure", + "vaccinationText": "Vaccination", + "nebulizationText": "Nebulization", + "callForVitalSignText": "Calling for Vital Sign", + "callForDoctorText": "Calling for Doctor", + "callForProcedureText": "Calling for Procedure", + "callForVaccinationText": "Calling for Vaccination", + "callForNebulizationText": "Calling for Nebulization", + "roomText": "Room", + "queueNoText": "Queue No", + "callForText": "Call For" + }, + { + "id": 101, + "patientID": 202, + "laB_QGroupID": 303, + "queueNo": "E20", + "counterBatchNo": 1, + "calledBy": 404, + "calledOn": "2025-07-15T08:30:00Z", + "servedOn": "2025-07-15T08:45:00Z", + "patientName": "John Doe", + "mobileNo": "+966500000000", + "patientEmail": "john@example.com", + "preferredLang": 1, + "ticketNoText": "Ticket No", + "pleaseVisitCounterText": "Please Visit Counter", + "patientGender": 1, + "roomNo": "R6", + "isActive": true, + "createdBy": 999, + "editedBy": 1000, + "editedOn": "2025-07-15T08:10:00Z", + "createdOn": "2025-07-15T08:00:00Z", + "doctorNameN": "Dr. Smith", + "callType": 6, + "queueNoM": "B45", + "callNoStr": "Call #1001", + "isQueue": true, + "isToneReq": true, + "isVoiceReq": true, + "orientationType": 1, + "isTurnOn": true, + "concurrentCallDelaySec": 3, + "crTypeAckIP": "192.168.1.100", + "voiceLanguage": 1, + "voiceLanguageText": "English", + "vitalSignText": "Vital Sign", + "doctorText": "Doctor", + "procedureText": "Procedure", + "vaccinationText": "Vaccination", + "nebulizationText": "Nebulization", + "callForVitalSignText": "Calling for Vital Sign", + "callForDoctorText": "Calling for Doctor", + "callForProcedureText": "Calling for Procedure", + "callForVaccinationText": "Calling for Vaccination", + "callForNebulizationText": "Calling for Nebulization", + "roomText": "Room", + "queueNoText": "Queue No", + "callForText": "Call For" + } + ] + } + ]; +} diff --git a/lib/models/global_config_model.dart b/lib/models/global_config_model.dart index f68f200..741e6e4 100644 --- a/lib/models/global_config_model.dart +++ b/lib/models/global_config_model.dart @@ -55,7 +55,7 @@ class GlobalConfigurationsModel { bool isWeatherReq = false; bool isPrayerTimeReq = false; bool isRssFeedReq = false; - QTypeEnum qTypeEnum = QTypeEnum.lab; + QTypeEnum qTypeEnum = QTypeEnum.appointment; ScreenTypeEnum screenTypeEnum = ScreenTypeEnum.waitingAreaScreen; int? projectID; double? projectLatitude; @@ -64,6 +64,17 @@ class GlobalConfigurationsModel { List? kioskQueueList; List? kioskLanguageConfigList; + String vitalSignText = "Vital Sign"; + String doctorText = "Doctor"; + String procedureText = "Procedure"; + String vaccinationText = "Vaccination"; + String nebulizationText = "Nebulization"; + String callForVitalSignText = "Call for Vital Sign"; + String callForDoctorText = "Call for Doctor"; + String callForProcedureText = "Call for Procedure"; + String callForVaccinationText = "Call for Vaccination"; + String callForNebulizationText = "Call for Nebulization"; + GlobalConfigurationsModel({ this.id, this.configType, @@ -115,7 +126,7 @@ class GlobalConfigurationsModel { this.isWeatherReq = false, this.isPrayerTimeReq = false, this.isRssFeedReq = false, - this.qTypeEnum = QTypeEnum.lab, + this.qTypeEnum = QTypeEnum.appointment, this.screenTypeEnum = ScreenTypeEnum.waitingAreaScreen, this.projectID, this.projectLatitude, @@ -123,6 +134,16 @@ class GlobalConfigurationsModel { this.cityKey, this.kioskQueueList, this.kioskLanguageConfigList, + this.vitalSignText = "Vital Sign", + this.doctorText = "Doctor", + this.procedureText = "Procedure", + this.vaccinationText = "Vaccination", + this.nebulizationText = "Nebulization", + this.callForVitalSignText = "Call for Vital Sign", + this.callForDoctorText = "Call for Doctor", + this.callForProcedureText = "Call for Procedure", + this.callForVaccinationText = "Call for Vaccination", + this.callForNebulizationText = "Call for Nebulization", }); GlobalConfigurationsModel.fromJson(Map json) { @@ -149,7 +170,7 @@ class GlobalConfigurationsModel { counterText = json['counterText']; roomText = json['roomText']; roomNo = json['roomNo']; - isRoomNoRequired = json['isRoomNoRequired'] ?? true; + isRoomNoRequired = json['isRoomNoReq'] ?? true; queueNoText = json['queueNoText']; callForText = json['callForText']; currentServeText = json['currentServeText']; @@ -169,8 +190,6 @@ class GlobalConfigurationsModel { editedOn = json['editedOn']; isToneReq = json['isToneReq'] ?? false; isVoiceReq = json['isVoiceReq'] ?? false; - // isToneReq = true; - // isVoiceReq = true; orientationTypeEnum = ((json['orientationType'] ?? 1) as int).toScreenOrientationEnum(); isTurnOn = json['isTurnOn']; waitingAreaType = json['waitingAreaType']; @@ -194,6 +213,16 @@ class GlobalConfigurationsModel { } else { kioskLanguageConfigList = []; } + vitalSignText = json['vitalSignText']; + doctorText = json['doctorText']; + procedureText = json['procedureText']; + vaccinationText = json['vaccinationText']; + nebulizationText = json['nebulizationText']; + callForVitalSignText = json['callForVitalSignText']; + callForDoctorText = json['callForDoctorText']; + callForProcedureText = json['callForProcedureText']; + callForVaccinationText = json['callForVaccinationText']; + callForNebulizationText = json['callForNebulizationText']; } } diff --git a/lib/models/kiosk_queue_model.dart b/lib/models/kiosk_queue_model.dart index dc28140..a2fd68d 100644 --- a/lib/models/kiosk_queue_model.dart +++ b/lib/models/kiosk_queue_model.dart @@ -8,7 +8,6 @@ class KioskQueueModel { String? queueNameN; int? kioskID; bool? isPharmacyQueue; - String? kioskName; String? kioskNameN; String? ipAddress; diff --git a/lib/models/room_ticket_model.dart b/lib/models/room_ticket_model.dart index 59a5864..b9edc9c 100644 --- a/lib/models/room_ticket_model.dart +++ b/lib/models/room_ticket_model.dart @@ -1,50 +1,50 @@ -class RoomTicketModel { - int? rowID; - int? id; - int? floorID; - int? buildingID; - int? projectID; - String? roomName; - String? roomNameN; - int? roomNo; - String? roomQScreenIP; - bool? isActive; - int? createdBy; - String? createdOn; - String? editedBy; - String? editedOn; - - RoomTicketModel({ - this.rowID, - this.id, - this.floorID, - this.buildingID, - this.projectID, - this.roomName, - this.roomNameN, - this.roomNo, - this.roomQScreenIP, - this.isActive, - this.createdBy, - this.createdOn, - this.editedBy, - this.editedOn, - }); - - RoomTicketModel.fromJson(Map json) { - rowID = json['rowID']; - id = json['id']; - floorID = json['floorID']; - buildingID = json['buildingID']; - projectID = json['projectID']; - roomName = json['roomName']; - roomNameN = json['roomNameN']; - roomNo = json['roomNo']; - roomQScreenIP = json['roomQScreenIP']; - isActive = json['isActive']; - createdBy = json['createdBy']; - createdOn = json['createdOn']; - editedBy = json['editedBy']; - editedOn = json['editedOn']; - } -} +// class RoomTicketModel { +// int? rowID; +// int? id; +// int? floorID; +// int? buildingID; +// int? projectID; +// String? roomName; +// String? roomNameN; +// int? roomNo; +// String? roomQScreenIP; +// bool? isActive; +// int? createdBy; +// String? createdOn; +// String? editedBy; +// String? editedOn; +// +// RoomTicketModel({ +// this.rowID, +// this.id, +// this.floorID, +// this.buildingID, +// this.projectID, +// this.roomName, +// this.roomNameN, +// this.roomNo, +// this.roomQScreenIP, +// this.isActive, +// this.createdBy, +// this.createdOn, +// this.editedBy, +// this.editedOn, +// }); +// +// RoomTicketModel.fromJson(Map json) { +// rowID = json['rowID']; +// id = json['id']; +// floorID = json['floorID']; +// buildingID = json['buildingID']; +// projectID = json['projectID']; +// roomName = json['roomName']; +// roomNameN = json['roomNameN']; +// roomNo = json['roomNo']; +// roomQScreenIP = json['roomQScreenIP']; +// isActive = json['isActive']; +// createdBy = json['createdBy']; +// createdOn = json['createdOn']; +// editedBy = json['editedBy']; +// editedOn = json['editedOn']; +// } +// } diff --git a/lib/models/ticket_model.dart b/lib/models/ticket_model.dart index 99b972d..2f13b64 100644 --- a/lib/models/ticket_model.dart +++ b/lib/models/ticket_model.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:hmg_qline/utilities/date_utils.dart'; import 'package:hmg_qline/utilities/enums.dart'; import 'package:hmg_qline/utilities/extensions.dart'; @@ -49,6 +47,34 @@ class TicketData { DateTime? editedOn; DateTime? createdOn; + // New fields + String? doctorNameN; + int? callType; + String? queueNoM; + String? callNoStr; + bool? isQueue; + bool? isToneReq; + bool? isVoiceReq; + int? orientationType; + bool? isTurnOn; + int? concurrentCallDelaySec; + String? crTypeAckIP; + int voiceLanguage = 1; + String voiceLanguageText = "English"; + String vitalSignText = "Vital Sign"; + String doctorText = "Doctor"; + String procedureText = "Procedure"; + String vaccinationText = "Vaccination"; + String nebulizationText = "Nebulization"; + String callForVitalSignText = "Call for Vital Sign"; + String callForDoctorText = "Call for Doctor"; + String callForProcedureText = "Call for Procedure"; + String callForVaccinationText = "Call for Vaccination"; + String callForNebulizationText = "Call for Nebulization"; + String roomText = "Room"; + String queueNoText = "Counter"; + String callForText = "Call For"; + TicketData({ this.id, this.patientID, @@ -72,6 +98,31 @@ class TicketData { this.createdOn, this.editedBy, this.editedOn, + this.doctorNameN, + this.callType, + this.queueNoM, + this.callNoStr, + this.isQueue, + this.isToneReq, + this.isVoiceReq, + this.orientationType, + this.isTurnOn, + this.concurrentCallDelaySec, + this.crTypeAckIP, + this.voiceLanguageText = "English", + this.vitalSignText = "Vital Sign", + this.doctorText = "Doctor", + this.procedureText = "Procedure", + this.vaccinationText = "Vaccination", + this.nebulizationText = "Nebulization", + this.callForVitalSignText = "Call for Vital Sign", + this.callForDoctorText = "Call for Doctor", + this.callForProcedureText = "Call for Procedure", + this.callForVaccinationText = "Call for Vaccination", + this.callForNebulizationText = "Call for Nebulization", + this.roomText = "Room", + this.queueNoText = "Counter", + this.callForText = "Call For", }); TicketData.fromJson(Map json, {QTypeEnum? qTypeEnum}) { @@ -86,19 +137,47 @@ class TicketData { patientName = json['patientName']; mobileNo = json['mobileNo']; patientEmail = json['patientEmail']; - preferredLang = (json['preferredLang'] != null && json['preferredLang'].trim() != "") ? int.parse(json['preferredLang']) : 1; - voiceLanguageEnum = (json['preferredLang'] != null && json['preferredLang'].trim() != "") ? (int.parse(json['preferredLang'])).toLanguageEnum() : LanguageEnum.english; + preferredLang = (json['preferredLang'] != null && json['preferredLang'].toString().trim() != "") ? int.parse(json['preferredLang'].toString()) : 1; + voiceLanguageEnum = (json['preferredLang'] != null && json['preferredLang'].toString().trim() != "") ? (int.parse(json['preferredLang'].toString())).toLanguageEnum() : LanguageEnum.english; ticketNoText = json['ticketNoText'] ?? "Ticket Number"; postVoiceText = json['pleaseVisitCounterText'] ?? "Please Visit Counter"; patientGender = json['patientGender'] ?? 1; - roomNo = json['roomNo'].toString(); + roomNo = json['roomNo']?.toString(); if (qTypeEnum != null && qTypeEnum == QTypeEnum.general) { - roomNo = json['counterNo'].toString(); + roomNo = json['counterNo']?.toString(); } isActive = json['isActive']; createdBy = json['createdBy']; editedBy = json['editedBy']; editedOn = json['editedOn'] != null ? (json['editedOn'] as String).toDateTime() : DateTime.now(); createdOn = json['createdOn'] != null ? (json['createdOn'] as String).toDateTime() : DateTime.now(); + + // New fields + doctorNameN = json['doctorNameN']; + callType = json['callType']; + queueNoM = json['queueNoM']; + callNoStr = json['callNoStr']; + isQueue = json['isQueue']; + isToneReq = json['isToneReq']; + isVoiceReq = json['isVoiceReq']; + orientationType = json['orientationType']; + isTurnOn = json['isTurnOn']; + concurrentCallDelaySec = json['concurrentCallDelaySec']; + crTypeAckIP = json['crTypeAckIP']; + voiceLanguage = json['voiceLanguage']; + voiceLanguageText = json['voiceLanguageText']; + vitalSignText = json['vitalSignText']; + doctorText = json['doctorText']; + procedureText = json['procedureText']; + vaccinationText = json['vaccinationText']; + nebulizationText = json['nebulizationText']; + callForVitalSignText = json['callForVitalSignText']; + callForDoctorText = json['callForDoctorText']; + callForProcedureText = json['callForProcedureText']; + callForVaccinationText = json['callForVaccinationText']; + callForNebulizationText = json['callForNebulizationText']; + roomText = json['roomText']; + queueNoText = json['queueNoText']; + callForText = json['callForText']; } } diff --git a/lib/models/widgets_config_model.dart b/lib/models/widgets_config_model.dart index dac5cda..f4da0cf 100644 --- a/lib/models/widgets_config_model.dart +++ b/lib/models/widgets_config_model.dart @@ -1,53 +1,53 @@ -class WidgetsConfigModel { - int? waitingAreaID; - String? waitingAreaName; - int? projectID; - double? projectLatitude; - double? projectLongitude; - int? cityKey; - bool isWeatherReq = false; - bool isPrayerTimeReq = false; - bool isRssFeedReq = false; - - WidgetsConfigModel({ - this.waitingAreaID, - this.waitingAreaName, - this.isWeatherReq = false, - this.isPrayerTimeReq = false, - this.isRssFeedReq = false, - this.projectID, - this.projectLatitude, - this.projectLongitude, - this.cityKey, - }); - - WidgetsConfigModel.fromJson(Map json) { - waitingAreaID = json['waitingAreaID']; - waitingAreaName = json['waitingAreaName']; - isRssFeedReq = json['isRssFeedReq'] ?? false; - isWeatherReq = json['isWeatherReq'] ?? false; - isPrayerTimeReq = json['isPrayerTimeReq'] ?? false; - projectID = json['projectID']; - projectLatitude = json['projectLatitude']; - projectLongitude = json['projectLongitude']; - cityKey = json['cityKey']; - } - - Map toJson() { - final Map data = {}; - data['waitingAreaID'] = waitingAreaID; - data['waitingAreaName'] = waitingAreaName; - data['isWeatherReq'] = isWeatherReq; - data['isPrayerTimeReq'] = isPrayerTimeReq; - data['projectID'] = projectID; - data['projectLatitude'] = projectLatitude; - data['projectLongitude'] = projectLongitude; - data['cityKey'] = cityKey; - return data; - } - - @override - String toString() { - return 'WidgetsConfigModel{waitingAreaID: $waitingAreaID, waitingAreaName: $waitingAreaName, isWeatherReq: $isWeatherReq, isPrayerTimeReq: $isPrayerTimeReq, projectLatitude: $projectLatitude,projectLongitude: $projectLongitude, cityKey: $cityKey}'; - } -} +// class WidgetsConfigModel { +// int? waitingAreaID; +// String? waitingAreaName; +// int? projectID; +// double? projectLatitude; +// double? projectLongitude; +// int? cityKey; +// bool isWeatherReq = false; +// bool isPrayerTimeReq = false; +// bool isRssFeedReq = false; +// +// WidgetsConfigModel({ +// this.waitingAreaID, +// this.waitingAreaName, +// this.isWeatherReq = false, +// this.isPrayerTimeReq = false, +// this.isRssFeedReq = false, +// this.projectID, +// this.projectLatitude, +// this.projectLongitude, +// this.cityKey, +// }); +// +// WidgetsConfigModel.fromJson(Map json) { +// waitingAreaID = json['waitingAreaID']; +// waitingAreaName = json['waitingAreaName']; +// isRssFeedReq = json['isRssFeedReq'] ?? false; +// isWeatherReq = json['isWeatherReq'] ?? false; +// isPrayerTimeReq = json['isPrayerTimeReq'] ?? false; +// projectID = json['projectID']; +// projectLatitude = json['projectLatitude']; +// projectLongitude = json['projectLongitude']; +// cityKey = json['cityKey']; +// } +// +// Map toJson() { +// final Map data = {}; +// data['waitingAreaID'] = waitingAreaID; +// data['waitingAreaName'] = waitingAreaName; +// data['isWeatherReq'] = isWeatherReq; +// data['isPrayerTimeReq'] = isPrayerTimeReq; +// data['projectID'] = projectID; +// data['projectLatitude'] = projectLatitude; +// data['projectLongitude'] = projectLongitude; +// data['cityKey'] = cityKey; +// return data; +// } +// +// @override +// String toString() { +// return 'WidgetsConfigModel{waitingAreaID: $waitingAreaID, waitingAreaName: $waitingAreaName, isWeatherReq: $isWeatherReq, isPrayerTimeReq: $isPrayerTimeReq, projectLatitude: $projectLatitude,projectLongitude: $projectLongitude, cityKey: $cityKey}'; +// } +// } diff --git a/lib/repositories/screen_details_repo.dart b/lib/repositories/screen_details_repo.dart index ede6b03..64a6696 100644 --- a/lib/repositories/screen_details_repo.dart +++ b/lib/repositories/screen_details_repo.dart @@ -6,7 +6,6 @@ import 'package:hmg_qline/models/kiosk_ticket_model.dart'; import 'package:hmg_qline/models/prayers_widget_model.dart'; import 'package:hmg_qline/models/rss_feed_model.dart'; import 'package:hmg_qline/models/weathers_widget_model.dart'; -import 'package:hmg_qline/models/widgets_config_model.dart'; import 'package:hmg_qline/utilities/enums.dart'; import 'package:hmg_qline/utilities/extensions.dart'; import 'package:hmg_qline/views/view_helpers/info_components.dart'; @@ -18,7 +17,7 @@ abstract class ScreenDetailsRepo { Future createTicketFromKiosk({required int projectId, required int queueId, int patientId = 0}); - Future getScreenConfigurationsByIP({required String ipAddress}); + // Future getScreenConfigurationsByIP({required String ipAddress}); Future getWeatherDetailsByCity({required String cityId}); @@ -41,13 +40,13 @@ class ScreenDetailsRepoImp implements ScreenDetailsRepo { "ipAddress": ipAddress.toString(), "apiKey": AppConstants.apiKey.toString(), }; - GenericRespModel adsGenericModel = await apiClientInstance.postJsonForObject( + GenericRespModel genericModel = await apiClientInstance.postJsonForObject( (json) => GenericRespModel.fromJson(json), ApiConstants.commonConfigGet, params, ); - List globalConfigurationsModel = List.generate(adsGenericModel.data.length, (index) => GlobalConfigurationsModel.fromJson(adsGenericModel.data[index])); + List globalConfigurationsModel = List.generate(genericModel.data.length, (index) => GlobalConfigurationsModel.fromJson(genericModel.data[index])); if (globalConfigurationsModel.isNotEmpty) { return globalConfigurationsModel.first; } @@ -71,12 +70,12 @@ class ScreenDetailsRepoImp implements ScreenDetailsRepo { "createdBy": "101", "apiKey": AppConstants.apiKey, }; - GenericRespModel adsGenericModel = await apiClientInstance.postJsonForObject( + GenericRespModel genericModel = await apiClientInstance.postJsonForObject( (json) => GenericRespModel.fromJson(json), ApiConstants.createTicket, params, ); - return adsGenericModel; + return genericModel; } catch (e) { logger.e(e.toString()); InfoComponents.showToast(e.toString()); @@ -110,26 +109,26 @@ class ScreenDetailsRepoImp implements ScreenDetailsRepo { } } - @override - Future getScreenConfigurationsByIP({required String ipAddress}) async { - try { - final body = { - "ipAddress": ipAddress.toString(), - }; - - GenericRespModel genericRespModel = await apiClientInstance.postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConstants.waitingAreaScreenConfigGet, - body, - ); - WidgetsConfigModel widgetsConfigModel = WidgetsConfigModel.fromJson(genericRespModel.data); - return widgetsConfigModel; - } catch (e) { - logger.e(e.toString()); - InfoComponents.showToast(e.toString()); - return null; - } - } + // @override + // Future getScreenConfigurationsByIP({required String ipAddress}) async { + // try { + // final body = { + // "ipAddress": ipAddress.toString(), + // }; + // + // GenericRespModel genericRespModel = await apiClientInstance.postJsonForObject( + // (json) => GenericRespModel.fromJson(json), + // ApiConstants.waitingAreaScreenConfigGet, + // body, + // ); + // WidgetsConfigModel widgetsConfigModel = WidgetsConfigModel.fromJson(genericRespModel.data); + // return widgetsConfigModel; + // } catch (e) { + // logger.e(e.toString()); + // InfoComponents.showToast(e.toString()); + // return null; + // } + // } @override Future getWeatherDetailsByCity({required String cityId}) async { @@ -206,12 +205,12 @@ class ScreenDetailsRepoImp implements ScreenDetailsRepo { "ticketQueueID": ticketQueueID.toString(), "qType": qTypeEnum.getQTypeIDFromEnum().toString(), }; - GenericRespModel adsGenericModel = await apiClientInstance.postJsonForObject( + GenericRespModel genericModel = await apiClientInstance.postJsonForObject( (json) => GenericRespModel.fromJson(json), ApiConstants.ticketAcknowledgementInsert, params, ); - return adsGenericModel; + return genericModel; } catch (e) { logger.e(e.toString()); InfoComponents.showToast(e.toString()); diff --git a/lib/services/audio_service.dart b/lib/services/audio_service.dart index 8d078b8..72be84e 100644 --- a/lib/services/audio_service.dart +++ b/lib/services/audio_service.dart @@ -1,7 +1,7 @@ import 'package:just_audio/just_audio.dart'; abstract class AudioService { - Future playTone({required String path}); + Future playTone({required String path, bool isMute = false}); Future listenAudioPlayerEvents({required Function() onAudioCompleted}); @@ -23,8 +23,11 @@ class AudioServiceImp implements AudioService { } @override - Future playTone({required String path}) async { + Future playTone({required String path, bool isMute = false}) async { audioPlayerInstance.setAsset(path); + if (isMute) { + audioPlayerInstance.setVolume(0.0); + } await audioPlayerInstance.play(); } diff --git a/lib/services/text_to_speech_service.dart b/lib/services/text_to_speech_service.dart index 253c48e..c6a5740 100644 --- a/lib/services/text_to_speech_service.dart +++ b/lib/services/text_to_speech_service.dart @@ -10,6 +10,7 @@ abstract class TextToSpeechService { Future speechText({ required TicketDetailsModel ticket, required GlobalConfigurationsModel globalConfigurationsModel, + bool isMute = false, }); Future speechTextTest(String test); @@ -47,6 +48,7 @@ class TextToSpeechServiceImp implements TextToSpeechService { Future speechText({ required TicketDetailsModel ticket, required GlobalConfigurationsModel globalConfigurationsModel, + bool isMute = false, }) async { const ttsGoogleEngine = 'com.google.android.tts'; // const ttsFlyTecEngine = 'com.iflytek.speechcloud'; @@ -57,8 +59,11 @@ class TextToSpeechServiceImp implements TextToSpeechService { await textToSpeechInstance.setEngine(ttsGoogleEngine); } - textToSpeechInstance.setVolume(1.0); - + if (isMute) { + textToSpeechInstance.setVolume(0.0); + } else { + textToSpeechInstance.setVolume(1.0); + } if (langEnum == LanguageEnum.arabic) { await textToSpeechInstance.setLanguage(LanguageEnum.arabic.enumToString()); textToSpeechInstance.setSpeechRate(0.45); diff --git a/lib/utilities/extensions.dart b/lib/utilities/extensions.dart index 6b9337e..38ff337 100644 --- a/lib/utilities/extensions.dart +++ b/lib/utilities/extensions.dart @@ -1,4 +1,7 @@ -import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:hmg_qline/constants/app_constants.dart'; +import 'package:hmg_qline/models/global_config_model.dart'; import 'package:hmg_qline/utilities/enums.dart'; import 'package:intl/intl.dart'; @@ -69,7 +72,7 @@ extension QTypeEnumExtension on int { case 4: return QTypeEnum.general; default: - return QTypeEnum.lab; + return QTypeEnum.appointment; } } } @@ -146,3 +149,80 @@ extension LanguageEnumToString on LanguageEnum { } } } + +enum CallTypeEnum { vitalSign, doctor, procedure, vaccination, nebulization, none } + +extension XCallType on CallTypeEnum { + Color color() { + if (this == CallTypeEnum.vitalSign) { + return AppColors.vitalSignColor; + } else if (this == CallTypeEnum.doctor) { + return AppColors.doctorColor; + } else if (this == CallTypeEnum.procedure) { + return AppColors.procedureColor; + } else if (this == CallTypeEnum.vaccination) { + return AppColors.vaccinationColor; + } else if (this == CallTypeEnum.nebulization) { + return AppColors.nebulizationColor; + } else { + return Colors.black54; + } + } + + String message(GlobalConfigurationsModel globalConfig, {bool isListView = false}) { + switch (this) { + case CallTypeEnum.vitalSign: + return isListView ? globalConfig.callForVitalSignText : globalConfig.vitalSignText; + case CallTypeEnum.doctor: + return isListView ? globalConfig.callForDoctorText : globalConfig.doctorText; + case CallTypeEnum.procedure: + return isListView ? globalConfig.callForProcedureText : globalConfig.procedureText; + case CallTypeEnum.vaccination: + return isListView ? globalConfig.callForVaccinationText : globalConfig.vaccinationText; + case CallTypeEnum.nebulization: + return isListView ? globalConfig.callForNebulizationText : globalConfig.nebulizationText; + case CallTypeEnum.none: + return isListView ? globalConfig.callForVitalSignText : globalConfig.vitalSignText; + + default: + return globalConfig.callForVitalSignText; + } + } + + SvgPicture icon(double height, {double? width, BoxFit fit = BoxFit.contain}) { + String iconPath = ""; + if (this == CallTypeEnum.vitalSign) { + iconPath = AppAssets.vitalSignIcon; + } else if (this == CallTypeEnum.doctor) { + iconPath = AppAssets.doctorIcon; + } else if (this == CallTypeEnum.procedure) { + iconPath = AppAssets.procedureIcon; + } else if (this == CallTypeEnum.vaccination) { + iconPath = AppAssets.vaccinationIcon; + } else if (this == CallTypeEnum.nebulization) { + iconPath = AppAssets.nebulizationIcon; + } + + return SvgPicture.asset( + iconPath.isEmpty ? "assets/images/wait.svg" : iconPath, + height: height, + width: width, + fit: fit, + ); + } + + String audio(String lang) { + if (this == CallTypeEnum.vitalSign) { + return "visit_nurse.mp3"; + } else if (this == CallTypeEnum.doctor) { + return "visit_doctor.mp3"; + } else if (this == CallTypeEnum.procedure) { + return "visit_doctor.mp3"; + } else if (this == CallTypeEnum.vaccination) { + return "visit_doctor.mp3"; + } else if (this == CallTypeEnum.nebulization) { + return "visit_doctor.mp3"; + } + return ""; + } +} diff --git a/lib/view_models/queuing_view_model.dart b/lib/view_models/queuing_view_model.dart index 59827ef..326c44a 100644 --- a/lib/view_models/queuing_view_model.dart +++ b/lib/view_models/queuing_view_model.dart @@ -67,7 +67,6 @@ class QueuingViewModel extends ChangeNotifier { log("onHubConnected: $response"); ScreenConfigViewModel screenConfigViewModel = getIt.get(); screenConfigViewModel.updateIsHubConnected(true); - log("screenConfigViewModel: ${screenConfigViewModel.isHubConnected}"); screenConfigViewModel.notifyListeners(); } @@ -156,12 +155,13 @@ class QueuingViewModel extends ChangeNotifier { screenConfigViewModel.acknowledgeTicket(ticketQueueID: ticketData.id!.toString()); if (globalConfigurationsModel.isToneReq) { isCallingInProgress = true; - await audioService.playTone(path: AppAssets.callTone); + await audioService.playTone(path: AppAssets.callTone, isMute: false ); } else if (globalConfigurationsModel.isVoiceReq) { isCallingInProgress = true; await textToSpeechService.speechText( globalConfigurationsModel: globalConfigurationsModel, ticket: currentTickets.first, + isMute: false ); } else { waitAndCallNextTicketIfAvailable(); diff --git a/lib/view_models/screen_config_view_model.dart b/lib/view_models/screen_config_view_model.dart index 38ef18e..4d02524 100644 --- a/lib/view_models/screen_config_view_model.dart +++ b/lib/view_models/screen_config_view_model.dart @@ -114,10 +114,9 @@ class ScreenConfigViewModel extends ChangeNotifier { Future getGlobalConfigurationsByIP() async { GlobalConfigurationsModel? response = await screenDetailsRepo.getGlobalScreenConfigurations(ipAddress: currentScreenIP); - if (response == null) { - log("response; $response"); - return; - } + log("response; $response"); + + response ??= GlobalConfigurationsModel.fromJson(MockJsonRepo.globalConfigurationMockResponse); updateGlobalConfigurationsModel(value: response); updateCurrentScreenTypeEnum(globalConfigurationsModel.screenTypeEnum); updateCurrentQTypeEnum(globalConfigurationsModel.qTypeEnum); diff --git a/lib/views/common_widgets/app_footer.dart b/lib/views/common_widgets/app_footer.dart index 340757d..8a853b0 100644 --- a/lib/views/common_widgets/app_footer.dart +++ b/lib/views/common_widgets/app_footer.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:hmg_qline/view_models/queuing_view_model.dart'; import 'package:hmg_qline/view_models/screen_config_view_model.dart'; import 'package:marquee/marquee.dart'; import 'package:provider/provider.dart'; @@ -27,14 +28,19 @@ class AppFooter extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - AppText( - AppStrings.poweredBy, - fontSize: SizeConfig.getWidthMultiplier() * 2, + InkWell( + onTap: () { + context.read().onHubTicketCall(MockJsonRepo.mockPatientTicketResponse); + }, + child: AppText( + AppStrings.poweredBy, + fontSize: SizeConfig.getWidthMultiplier() * 2, + ), ), - Text(screenConfigVM.currentScreenIP, + Text("${screenConfigVM.currentScreenIP}_v${AppConstants.currentBuildVersion}", style: TextStyle( fontWeight: FontWeight.w500, - fontSize: SizeConfig.getWidthMultiplier() * 2.2, + fontSize: SizeConfig.getWidthMultiplier() * 2, )), Row( children: [ diff --git a/lib/views/common_widgets/app_header.dart b/lib/views/common_widgets/app_header.dart index cb2a28a..354c768 100644 --- a/lib/views/common_widgets/app_header.dart +++ b/lib/views/common_widgets/app_header.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hmg_qline/models/global_config_model.dart'; @@ -61,13 +63,14 @@ class AppHeader extends StatelessWidget implements PreferredSizeWidget { return Selector( selector: (context, screenConfigViewModel) => screenConfigViewModel.globalConfigurationsModel, builder: (BuildContext context, GlobalConfigurationsModel globalConfigurationsModel, Widget? child) { + log("globalConfigurationsModel.qTypeEnum: ${globalConfigurationsModel.qTypeEnum}"); return Column( children: [ Container( alignment: Alignment.center, height: SizeConfig.getHeightMultiplier() * 0.6, padding: const EdgeInsets.symmetric(horizontal: 20), - decoration: BoxDecoration(color: AppColors.greenColor), + decoration: BoxDecoration(color: globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? AppColors.redColor : AppColors.greenColor), child: Directionality( textDirection: globalConfigurationsModel.textDirection, child: Row( @@ -81,7 +84,7 @@ class AppHeader extends StatelessWidget implements PreferredSizeWidget { fontFamily: globalConfigurationsModel.screenLanguageEnum == LanguageEnum.arabic ? AppStrings.fontNameCairo : AppStrings.fontNamePoppins, ), SvgPicture.asset( - AppAssets.hmgLogoPharmacy, + globalConfigurationsModel.qTypeEnum == QTypeEnum.appointment ? AppAssets.hmgLogo : AppAssets.hmgLogoPharmacy, height: SizeConfig.getHeightMultiplier() * 0.5, ), ], diff --git a/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart b/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart index 4c191e2..ceb4a5a 100644 --- a/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart +++ b/lib/views/main_queue_screen/components/priority_tickets_sidelist.dart @@ -7,12 +7,12 @@ import 'package:hmg_qline/views/common_widgets/app_texts_widget.dart'; import 'package:hmg_qline/views/main_queue_screen/components/priority_tickets.dart'; import 'package:hmg_qline/views/view_helpers/size_config.dart'; -class PriorityTicketsSidelist extends StatelessWidget { +class PriorityTicketsWithSidelist extends StatelessWidget { final List tickets; final GlobalConfigurationsModel globalConfigurationsModel; final ScreenOrientationEnum screenOrientationEnum; - const PriorityTicketsSidelist({ + const PriorityTicketsWithSidelist({ super.key, required this.tickets, required this.globalConfigurationsModel, diff --git a/lib/views/main_queue_screen/components/ticket_item.dart b/lib/views/main_queue_screen/components/ticket_item.dart index 3af78e6..0d79193 100644 --- a/lib/views/main_queue_screen/components/ticket_item.dart +++ b/lib/views/main_queue_screen/components/ticket_item.dart @@ -34,7 +34,11 @@ class TicketItem extends StatelessWidget { String getFormattedTicket(String ticketNo, bool isClinicAdded) { if (isClinicAdded) { var formattedString = ticketNo.split(" "); - return "${formattedString[0]} ${formattedString[1]}"; + if (formattedString.length > 1) { + return "${formattedString[0]} ${formattedString[1]}"; + } else { + return ticketNo; + } } return ticketNo; } @@ -56,7 +60,6 @@ class TicketItem extends StatelessWidget { ), beginColor: Colors.black, endColor: blink ? Colors.black.withOpacity(0.1) : Colors.black, - // endColor: blink ? AppGlobal.appRedColor : Colors.black, times: 0, duration: const Duration(seconds: 1)), const SizedBox(height: 20), diff --git a/lib/views/main_queue_screen/main_queue_screen.dart b/lib/views/main_queue_screen/main_queue_screen.dart index 3464a3c..d7412bb 100644 --- a/lib/views/main_queue_screen/main_queue_screen.dart +++ b/lib/views/main_queue_screen/main_queue_screen.dart @@ -65,7 +65,7 @@ class MainQueueScreen extends StatelessWidget { ], ); } else if (queuingViewModel.currentTickets.length > AppConstants.thresholdForListUI) { - widget = PriorityTicketsSidelist( + widget = PriorityTicketsWithSidelist( tickets: queuingViewModel.currentTickets, globalConfigurationsModel: screenConfigViewModel.globalConfigurationsModel, screenOrientationEnum: screenConfigViewModel.globalConfigurationsModel.orientationTypeEnum, diff --git a/lib/views/splash_screen/splash_screen.dart b/lib/views/splash_screen/splash_screen.dart index f32cbcb..15e2eab 100644 --- a/lib/views/splash_screen/splash_screen.dart +++ b/lib/views/splash_screen/splash_screen.dart @@ -28,7 +28,7 @@ class SplashScreen extends StatelessWidget { if (snapshot.connectionState == ConnectionState.waiting) { return const Scaffold( body: Center( - child: CircularProgressIndicator(), // Loading indicator + child: CircularProgressIndicator(), ), ); } @@ -48,6 +48,7 @@ class SplashScreen extends StatelessWidget { if (snapshot.connectionState == ConnectionState.done) { Future.delayed(const Duration(seconds: 1)).whenComplete(() { log("context.read().currentScreenTypeEnum: ${context.read().currentScreenTypeEnum}"); + log("context.read().currentQTypeEnum: ${context.read().currentQTypeEnum}"); if (context.read().currentScreenTypeEnum == ScreenTypeEnum.kioskScreen) { context.navigateReplaceTo(AppRoutes.kioskMainScreen); } else {