From 47b50e35a1a3a29f8d45c8c82e7f88f30ab56f31 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 11 Mar 2026 16:02:17 +0300 Subject: [PATCH] updates --- assets/images/svg/download.svg | 5 +- lib/core/api/api_client.dart | 20 +-- lib/features/radiology/radiology_repo.dart | 8 +- .../appointments/my_doctors_page.dart | 9 ++ .../book_appointment/doctor_profile_page.dart | 2 +- .../LabResultByClinic.dart | 148 ++++++++++-------- .../lab/lab_results/lab_result_details.dart | 124 +++++++++++---- lib/widgets/appbar/collapsing_list_view.dart | 6 + 8 files changed, 211 insertions(+), 111 deletions(-) diff --git a/assets/images/svg/download.svg b/assets/images/svg/download.svg index 37aef2bd..7bedc456 100644 --- a/assets/images/svg/download.svg +++ b/assets/images/svg/download.svg @@ -1,4 +1,3 @@ - - + + diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 192f6a4a..921e274b 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -195,7 +195,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 2007395; + // body['PatientID'] = 809289; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; @@ -301,14 +301,16 @@ class ApiClientImp implements ApiClient { } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); - } else if (parsed['IsAuthenticated'] == false) { - onFailure( - "User is not Authenticated", - statusCode, - failureType: - UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), - ); - } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { + } + // else if (parsed['IsAuthenticated'] == false) { + // onFailure( + // "User is not Authenticated", + // statusCode, + // failureType: + // UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), + // ); + // } + else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); diff --git a/lib/features/radiology/radiology_repo.dart b/lib/features/radiology/radiology_repo.dart index 5847718d..3ad4e54f 100644 --- a/lib/features/radiology/radiology_repo.dart +++ b/lib/features/radiology/radiology_repo.dart @@ -188,14 +188,16 @@ class RadiologyRepoImp implements RadiologyRepo { failure = failureType; }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { - final radOrders; + List radOrders = []; try { if (response['FinalRadiologyList'] != null && response['FinalRadiologyList'].length != 0) { final list = response['FinalRadiologyList']; radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast(); } else { - final list = response['FinalRadiologyListAPI']; - radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast(); + if (response['FinalRadiologyListAPI'] != null && response['FinalRadiologyListAPI'].length != 0) { + final list = response['FinalRadiologyListAPI']; + radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast(); + } } apiResponse = GenericApiModel>( diff --git a/lib/presentation/appointments/my_doctors_page.dart b/lib/presentation/appointments/my_doctors_page.dart index fc7798f8..d1ea0e98 100644 --- a/lib/presentation/appointments/my_doctors_page.dart +++ b/lib/presentation/appointments/my_doctors_page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -34,6 +36,13 @@ class _MyDoctorsPageState extends State { int? expandedIndex; final Map _groupKeys = {}; + @override + void initState() { + scheduleMicrotask(() { + myAppointmentsViewModel.getPatientMyDoctors(); + }); + super.initState(); + } @override Widget build(BuildContext context) { diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index 4b2d4dbb..549b8b0d 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -41,7 +41,7 @@ class DoctorProfilePage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 24.h), + // SizedBox(height: 24.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart index eed1eedb..af6c97f8 100644 --- a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart +++ b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart @@ -41,21 +41,54 @@ class LabResultByClinic extends StatelessWidget { Expanded( child: CollapsingListView( title: LocaleKeys.labResults.tr(), - aiOverview: () async { - final _dialogService = getIt.get(); - await _dialogService.showCommonBottomSheetWithoutH( - message: LocaleKeys.aiDisclaimer.tr(), - label: LocaleKeys.consent.tr(), - okLabel: LocaleKeys.acceptLbl.tr(), - cancelLabel: LocaleKeys.rejectView.tr(), - onOkPressed: () { - context.pop(); - labViewModel.getAiOverviewLabOrders(labOrder: labOrder, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); - }, - onCancelPressed: () { - context.pop(); - }); + downloadReport: () async { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.generatingReport.tr(context: context)); + await labViewModel + .getLabResultReportPDF( + labOrder: labOrder, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }) + .then((val) async { + LoaderBottomSheet.hideLoader(); + if (labViewModel.patientLabResultReportPDFBase64.isNotEmpty) { + String path = await Utils.createFileFromString(labViewModel.patientLabResultReportPDFBase64, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Cannot open file"), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } + } + }); }, + // aiOverview: () async { + // final _dialogService = getIt.get(); + // await _dialogService.showCommonBottomSheetWithoutH( + // message: LocaleKeys.aiDisclaimer.tr(), + // label: LocaleKeys.consent.tr(), + // okLabel: LocaleKeys.acceptLbl.tr(), + // cancelLabel: LocaleKeys.rejectView.tr(), + // onOkPressed: () { + // context.pop(); + // labViewModel.getAiOverviewLabOrders(labOrder: labOrder, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + // }, + // onCancelPressed: () { + // context.pop(); + // }); + // }, child: SingleChildScrollView( child: Column( spacing: 8.h, @@ -109,53 +142,46 @@ class LabResultByClinic extends StatelessWidget { borderRadius: 24.h, hasShadow: true, ), - child: CustomButton( - text: LocaleKeys.downloadReport.tr(context: context), - onPressed: () async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.generatingReport.tr(context: context)); - await labViewModel - .getLabResultReportPDF( - labOrder: labOrder, - onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }) - .then((val) async { - LoaderBottomSheet.hideLoader(); - if (labViewModel.patientLabResultReportPDFBase64.isNotEmpty) { - String path = await Utils.createFileFromString(labViewModel.patientLabResultReportPDFBase64, "pdf"); - try { - OpenFilex.open(path); - } catch (ex) { - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: "Cannot open file"), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - } - } - }); - }, - backgroundColor: AppColors.successColor, - borderColor: AppColors.successColor, - textColor: Colors.white, - fontSize: 16.f, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 45.h, - icon: AppAssets.download, - iconColor: Colors.white, - iconSize: 20.h, - ).paddingSymmetrical(24.h, 24.h), + child: Container( + height: 56.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.r), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.236, 1.0], // 53.6% and 100% + colors: [ + Color(0xFF8A38F5), // Transparent + Color(0xFFE20BBB), // Solid #F8F8F8 + ], + ), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(right: 4.w, left: 4.w), + child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), + ), + LocaleKeys.generateAiAnalysis.tr(context: context).toText16(isBold: true) + ], + ), + ).paddingSymmetrical(24.h, 24.h).onPress(() async { + final _dialogService = getIt.get(); + await _dialogService.showCommonBottomSheetWithoutH( + message: LocaleKeys.aiDisclaimer.tr(), + label: LocaleKeys.consent.tr(), + okLabel: LocaleKeys.acceptLbl.tr(), + cancelLabel: LocaleKeys.rejectView.tr(), + onOkPressed: () { + context.pop(); + labViewModel.getAiOverviewLabOrders(labOrder: labOrder, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + }, + onCancelPressed: () { + context.pop(); + }); + }), ), ], ), diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index cff9764e..d2c1b524 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -34,41 +34,97 @@ class LabResultDetails extends StatelessWidget { Widget build(BuildContext context) { LabViewModel labViewModel = Provider.of(context, listen: false); final appState = getIt.get(); - return CollapsingListView( - title: LocaleKeys.labResultDetails.tr(context: context), - aiOverview: () async { - final _dialogService = getIt.get(); - await _dialogService.showCommonBottomSheetWithoutH( - message: LocaleKeys.aiDisclaimer.tr(), - label: LocaleKeys.consent.tr(), - okLabel: LocaleKeys.acceptLbl.tr(), - cancelLabel: LocaleKeys.rejectView.tr(), - onOkPressed: () { - context.pop(); - labViewModel.getAiOverviewSingleLabResult(langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); - }, - onCancelPressed: () { - context.pop(); - }); - }, - child: SingleChildScrollView( - child: Column( - spacing: 16.h, - children: [ - LabNameAndStatus(context), - getLabDescription(context), - LabGraph(context), - Selector( - selector: (_, model) => model.labOrderResponseByAi, - builder: (_, aiData, __) { - if (aiData != null) { - return AiAnalysisWidget(data: aiData).paddingOnly(bottom: 16.h); - } - return const SizedBox.shrink(); - }, + return Scaffold( + body: Column( + children: [ + Expanded( + child: CollapsingListView( + title: LocaleKeys.labResultDetails.tr(context: context), + // aiOverview: () async { + // final _dialogService = getIt.get(); + // await _dialogService.showCommonBottomSheetWithoutH( + // message: LocaleKeys.aiDisclaimer.tr(), + // label: LocaleKeys.consent.tr(), + // okLabel: LocaleKeys.acceptLbl.tr(), + // cancelLabel: LocaleKeys.rejectView.tr(), + // onOkPressed: () { + // context.pop(); + // labViewModel.getAiOverviewSingleLabResult(langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + // }, + // onCancelPressed: () { + // context.pop(); + // }); + // }, + child: SingleChildScrollView( + child: Column( + spacing: 16.h, + children: [ + LabNameAndStatus(context), + getLabDescription(context), + LabGraph(context), + Selector( + selector: (_, model) => model.labOrderResponseByAi, + builder: (_, aiData, __) { + if (aiData != null) { + return AiAnalysisWidget(data: aiData).paddingOnly(bottom: 16.h); + } + return const SizedBox.shrink(); + }, + ), + ], + ).paddingAll(24.h), + ), ), - ], - ).paddingAll(24.h), + ), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: true, + ), + child: Container( + height: 56.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.r), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.236, 1.0], // 53.6% and 100% + colors: [ + Color(0xFF8A38F5), // Transparent + Color(0xFFE20BBB), // Solid #F8F8F8 + ], + ), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(right: 4.w, left: 4.w), + child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), + ), + LocaleKeys.generateAiAnalysis.tr(context: context).toText16(isBold: true) + ], + ), + ).paddingSymmetrical(24.h, 24.h).onPress(() async { + final _dialogService = getIt.get(); + await _dialogService.showCommonBottomSheetWithoutH( + message: LocaleKeys.aiDisclaimer.tr(), + label: LocaleKeys.consent.tr(), + okLabel: LocaleKeys.acceptLbl.tr(), + cancelLabel: LocaleKeys.rejectView.tr(), + onOkPressed: () { + context.pop(); + labViewModel.getAiOverviewSingleLabResult( + langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + }, + onCancelPressed: () { + context.pop(); + }); + }), + ), + ], ), ); } diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 25221962..0c32d87d 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -25,6 +25,7 @@ class CollapsingListView extends StatelessWidget { VoidCallback? requests; VoidCallback? sendEmail; VoidCallback? doctorResponse; + VoidCallback? downloadReport; Widget? bottomChild; Widget? trailing; bool isClose; @@ -47,6 +48,7 @@ class CollapsingListView extends StatelessWidget { this.requests, this.sendEmail, this.doctorResponse, + this.downloadReport, this.isLeading = true, this.trailing, this.leadingCallback, @@ -89,6 +91,7 @@ class CollapsingListView extends StatelessWidget { requests: requests, sendEmail: sendEmail, doctorResponse: doctorResponse, + downloadReport: downloadReport, bottomChild: bottomChild, trailing: trailing, aiOverview: aiOverview, @@ -200,6 +203,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget VoidCallback? requests; VoidCallback? sendEmail; VoidCallback? doctorResponse; + VoidCallback? downloadReport; Widget? bottomChild; Widget? trailing; @@ -217,6 +221,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget this.requests, this.sendEmail, this.doctorResponse, + this.downloadReport, this.bottomChild, this.trailing, }); @@ -295,6 +300,7 @@ class _ScrollAnimatedTitleState extends State { if (widget.doctorResponse != null) actionButton(context, t, title: LocaleKeys.doctorResponses.tr(context: context), icon: AppAssets.doctorResponseIcon).onPress(widget.doctorResponse!), if (widget.search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(widget.search!), if (widget.aiOverview != null) actionButton(context, t, title: LocaleKeys.aiOverView.tr(context: context), icon: AppAssets.aiOverView, isAiButton: true).onPress(widget.aiOverview!), + if (widget.downloadReport != null) actionButton(context, t, title: LocaleKeys.downloadReport.tr(context: context), icon: AppAssets.download).onPress(widget.downloadReport!), if (widget.trailing != null) widget.trailing!, ] ],