Design Updates

pull/89/head
faizatflutter 4 months ago
parent dc5eba7d12
commit b698b74eb5

@ -1,5 +1,5 @@
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:amazon_payfort/amazon_payfort.dart'; import 'package:amazon_payfort/amazon_payfort.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
var MAX_SMALL_SCREEN = 660; var MAX_SMALL_SCREEN = 660;
final OPENTOK_API_KEY = '46209962'; final OPENTOK_API_KEY = '46209962';
@ -570,7 +570,8 @@ var GET_CUSTOMER_INFO = "VerifyCustomer";
//Pharmacy //Pharmacy
var GET_PHARMACY_CATEGORISE = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; var GET_PHARMACY_CATEGORISE =
'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0';
var GET_OFFERS_CATEGORISE = 'discountcategories'; var GET_OFFERS_CATEGORISE = 'discountcategories';
var GET_OFFERS_PRODUCTS = 'offerproducts/'; var GET_OFFERS_PRODUCTS = 'offerproducts/';
var GET_CATEGORISE_PARENT = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; var GET_CATEGORISE_PARENT = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=';
@ -722,14 +723,14 @@ const DEACTIVATE_ACCOUNT = 'Services/Patients.svc/REST/PatientAppleActivation_In
//family Files //family Files
const FAMILY_FILES= 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus'; const FAMILY_FILES = 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus';
var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatbot_SendMedicationInstructionByWhatsApp'; var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatbot_SendMedicationInstructionByWhatsApp';
class ApiConsts { class ApiConsts {
static const maxSmallScreen = 660; static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT
@ -789,7 +790,6 @@ class ApiConsts {
RCBaseUrl = 'https://rc.hmg.com/test/'; RCBaseUrl = 'https://rc.hmg.com/test/';
break; break;
case AppEnvironmentTypeEnum.preProd: case AppEnvironmentTypeEnum.preProd:
baseUrl = "https://webservices.hmg.com/"; baseUrl = "https://webservices.hmg.com/";
payFortEnvironment = FortEnvironment.production; payFortEnvironment = FortEnvironment.production;
applePayMerchantId = "merchant.com.hmgwebservices"; applePayMerchantId = "merchant.com.hmgwebservices";
@ -833,7 +833,7 @@ class ApiConsts {
static final String getUserAgreementContent = 'Services/Patients.svc/REST/GetUsageAgreementText'; static final String getUserAgreementContent = 'Services/Patients.svc/REST/GetUsageAgreementText';
static final String checkPatientForRegistration = 'Services/Authentication.svc/REST/CheckPatientForRegisteration'; static final String checkPatientForRegistration = 'Services/Authentication.svc/REST/CheckPatientForRegisteration';
static final String checkUserStatus= 'Services/NHIC.svc/REST/GetPatientInfo'; static final String checkUserStatus = 'Services/NHIC.svc/REST/GetPatientInfo';
static final String insertPatientDeviceIMEIData = 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI'; static final String insertPatientDeviceIMEIData = 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI';
static final String insertPatientMobileData = 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo'; static final String insertPatientMobileData = 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo';

@ -216,6 +216,7 @@ class SizeUtils {
log("longerSide: $longerSide"); log("longerSide: $longerSide");
log("shorterSide: $shorterSide"); log("shorterSide: $shorterSide");
log("isTablet: $isTablet"); log("isTablet: $isTablet");
log("isFoldable: $isFoldable");
} }
} }

@ -37,9 +37,9 @@ import '../../core/dependencies.dart';
import '../medical_file/widgets/medical_file_card.dart'; import '../medical_file/widgets/medical_file_card.dart';
class AppointmentDetailsPage extends StatefulWidget { class AppointmentDetailsPage extends StatefulWidget {
AppointmentDetailsPage({super.key, required this.patientAppointmentHistoryResponseModel}); const AppointmentDetailsPage({super.key, required this.patientAppointmentHistoryResponseModel});
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel; final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
@override @override
State<AppointmentDetailsPage> createState() => _AppointmentDetailsPageState(); State<AppointmentDetailsPage> createState() => _AppointmentDetailsPageState();
@ -115,7 +115,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Container( Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 20.h, borderRadius: 20.r,
hasShadow: false, hasShadow: false,
), ),
child: Padding( child: Padding(
@ -138,7 +138,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
? Row( ? Row(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 40.h, height: 40.h), Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h), SizedBox(width: 12.w),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -155,7 +155,8 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
children: [ children: [
ClipRRect( ClipRRect(
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
borderRadius: BorderRadius.circular(24), borderRadius: BorderRadius.circular(24.r),
// Todo: what is this???? Api Key??? 😲
child: Image.network( child: Image.network(
"https://maps.googleapis.com/maps/api/staticmap?center=${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&zoom=14&size=350x165&maptype=roadmap&markers=color:red%7C${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&key=AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng", "https://maps.googleapis.com/maps/api/staticmap?center=${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&zoom=14&size=350x165&maptype=roadmap&markers=color:red%7C${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&key=AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng",
fit: BoxFit.contain, fit: BoxFit.contain,
@ -173,19 +174,19 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
double.parse(widget.patientAppointmentHistoryResponseModel.longitude!), double.parse(widget.patientAppointmentHistoryResponseModel.longitude!),
widget.patientAppointmentHistoryResponseModel.projectName); widget.patientAppointmentHistoryResponseModel.projectName);
}, },
backgroundColor: AppColors.textColor.withOpacity(0.8), backgroundColor: AppColors.textColor.withValues(alpha: 0.8),
borderColor: borderColor: AppointmentType.getNextActionButtonColor(
AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction) widget.patientAppointmentHistoryResponseModel.nextAction)
.withOpacity(0.01), .withValues(alpha: 0.01),
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
fontSize: 14.f, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12.r, borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0), padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h, height: 40.h,
icon: AppAssets.directions_icon, icon: AppAssets.directions_icon,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
iconSize: 13.h, iconSize: 14.h,
).paddingAll(12.h), ).paddingAll(12.h),
), ),
), ),
@ -199,7 +200,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Container( Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 20.h, borderRadius: 20.r,
hasShadow: false, hasShadow: false,
), ),
child: Row( child: Row(
@ -211,12 +212,14 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), LocaleKeys.setReminder.tr(context: context).toText13(isBold: true),
"Notify me before the appointment".needTranslation.toText11(color: AppColors.textColorLight, weight: FontWeight.w500), "Notify me before the appointment"
.needTranslation
.toText11(color: AppColors.textColorLight, weight: FontWeight.w500),
], ],
), ),
const Spacer(), const Spacer(),
Switch( Switch(
activeColor: AppColors.successColor, activeThumbColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: .15), activeTrackColor: AppColors.successColor.withValues(alpha: .15),
value: widget.patientAppointmentHistoryResponseModel.hasReminder!, value: widget.patientAppointmentHistoryResponseModel.hasReminder!,
onChanged: (newValue) { onChanged: (newValue) {
@ -237,8 +240,12 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
"Lab & Radiology".needTranslation.toText18(isBold: true), "Lab & Radiology".needTranslation.toText18(isBold: true),
SizedBox(height: 16.h), SizedBox(height: 16.h),
GridView( GridView(
padding: EdgeInsets.zero,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisSpacing: 13.h, mainAxisSpacing: 13.h, childAspectRatio: 7 / 6), crossAxisCount: isTablet || isFoldable ? 3 : 2,
crossAxisSpacing: 13.w,
mainAxisSpacing: 13.w,
),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
children: [ children: [
@ -247,19 +254,36 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.lab_result_icon, svgIcon: AppAssets.lab_result_icon,
iconSize: 40, iconSize: 40.w,
isLargeText: true, isLargeText: true,
), ),
MedicalFileCard( MedicalFileCard(
label: LocaleKeys.radiology.tr(context: context), label: "Radiology Results".needTranslation,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.radiology_icon, svgIcon: AppAssets.radiology_icon,
iconSize: 40, iconSize: 40.w,
isLargeText: true,
),
MedicalFileCard(
label: LocaleKeys.labResults.tr(context: context),
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.lab_result_icon,
iconSize: 40.w,
isLargeText: true,
),
MedicalFileCard(
label: "Radiology Results".needTranslation,
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.radiology_icon,
iconSize: 40.w,
isLargeText: true, isLargeText: true,
), ),
], ],
), ),
SizedBox(height: 16.h),
LocaleKeys.prescriptions.tr().toText18(isBold: true), LocaleKeys.prescriptions.tr().toText18(isBold: true),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) { Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
@ -268,10 +292,10 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
: Container( : Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: Colors.white, color: Colors.white,
borderRadius: 20.h, borderRadius: 20.r,
), ),
child: Padding( child: Padding(
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.w),
child: Column( child: Column(
children: [ children: [
ListView.separated( ListView.separated(
@ -300,7 +324,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Column( Column(
children: [ children: [
SizedBox( SizedBox(
width: 150.h, width: 150.w,
child: prescriptionVM.prescriptionDetailsList[index].itemDescription! child: prescriptionVM.prescriptionDetailsList[index].itemDescription!
.toText12(isBold: true, maxLine: 1)), .toText12(isBold: true, maxLine: 1)),
SizedBox( SizedBox(
@ -309,17 +333,19 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
"Prescribed By: ${widget.patientAppointmentHistoryResponseModel.doctorTitle} ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}" "Prescribed By: ${widget.patientAppointmentHistoryResponseModel.doctorTitle} ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}"
.needTranslation .needTranslation
.toText10( .toText10(
weight: FontWeight.w500, color: AppColors.greyTextColor, letterSpacing: -0.4), weight: FontWeight.w500,
color: AppColors.greyTextColor,
letterSpacing: -0.4),
), ),
], ],
), ),
SizedBox(width: 68.h), SizedBox(width: 68.w),
Transform.flip( Transform.flip(
flipX: appState.isArabic(), flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
width: 18.h, width: 18.w,
height: 13.h, height: 13.h,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
@ -363,6 +389,35 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
// ), // ),
// ), // ),
// SizedBox(width: 16.h), // SizedBox(width: 16.h),
Expanded(
child: CustomButton(
text: "Refill & Delivery".needTranslation,
onPressed: () {
Navigator.of(context)
.push(
CustomPageRoute(
page: PrescriptionsListPage(),
),
)
.then((val) {
prescriptionsViewModel.setPrescriptionsDetailsLoading();
prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel());
});
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
height: 40.h,
icon: AppAssets.requests,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
),
),
SizedBox(width: 16.w),
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: "All Prescriptions".needTranslation, text: "All Prescriptions".needTranslation,
@ -381,9 +436,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
backgroundColor: AppColors.secondaryLightRedColor, backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
fontSize: 14, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12.h, borderRadius: 12.r,
height: 40.h, height: 40.h,
icon: AppAssets.requests, icon: AppAssets.requests,
iconColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor,
@ -400,21 +455,22 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
], ],
), ),
], ],
).paddingSymmetrical(24.h, 24.h), ).paddingAll(24.w),
), ),
), ),
), ),
Container( Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 24.h, borderRadius: 24.r,
hasShadow: true, hasShadow: true,
), ),
child: SizedBox( child: SizedBox(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (widget.patientAppointmentHistoryResponseModel.nextAction == 15 || widget.patientAppointmentHistoryResponseModel.nextAction == 20) if (widget.patientAppointmentHistoryResponseModel.nextAction == 15 ||
widget.patientAppointmentHistoryResponseModel.nextAction == 20)
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -423,7 +479,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
children: [ children: [
"Amount before tax".needTranslation.toText18(isBold: true), "Amount before tax".needTranslation.toText18(isBold: true),
Utils.getPaymentAmountWithSymbol( Utils.getPaymentAmountWithSymbol(
widget.patientAppointmentHistoryResponseModel.patientShare!.toString().toText16(isBold: true), AppColors.blackColor, 13, widget.patientAppointmentHistoryResponseModel.patientShare!.toString().toText16(isBold: true),
AppColors.blackColor,
13,
isSaudiCurrency: true), isSaudiCurrency: true),
], ],
), ),
@ -432,8 +490,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
child: child: LocaleKeys.upcomingPaymentNow
LocaleKeys.upcomingPaymentNow.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)), .tr(context: context)
.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)),
"VAT 15%(${widget.patientAppointmentHistoryResponseModel.patientTaxAmount})" "VAT 15%(${widget.patientAppointmentHistoryResponseModel.patientTaxAmount})"
.needTranslation .needTranslation
.toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -2), .toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -2),
@ -470,10 +529,10 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
fontSize: 16, fontSize: 16.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12, borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0), padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 50.h, height: 50.h,
icon: AppAssets.add_icon, icon: AppAssets.add_icon,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
@ -486,13 +545,14 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction); handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction);
}, },
backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction), backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction),
borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), borderColor:
AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01),
textColor: widget.patientAppointmentHistoryResponseModel.nextAction == 15 ? AppColors.textColor : AppColors.whiteColor, textColor: widget.patientAppointmentHistoryResponseModel.nextAction == 15 ? AppColors.textColor : AppColors.whiteColor,
fontSize: 16, fontSize: 16.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12, borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0), padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 50.h, height: 56.h,
icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
iconSize: 18.h, iconSize: 18.h,

@ -23,339 +23,313 @@ import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:smooth_corner/smooth_corner.dart';
class AppointmentCard extends StatefulWidget { class AppointmentCard extends StatelessWidget {
AppointmentCard( final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
{super.key, final MyAppointmentsViewModel myAppointmentsViewModel;
required this.patientAppointmentHistoryResponseModel, final bool isLoading;
required this.myAppointmentsViewModel, final bool isFromHomePage;
required this.bookAppointmentsViewModel, final bool isFromMedicalReport;
this.isLoading = false, final MedicalFileViewModel? medicalFileViewModel;
this.isFromHomePage = false, final BookAppointmentsViewModel bookAppointmentsViewModel;
this.isFromMedicalReport = false,
this.medicalFileViewModel});
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel; const AppointmentCard({
MyAppointmentsViewModel myAppointmentsViewModel; super.key,
bool isLoading; required this.patientAppointmentHistoryResponseModel,
bool isFromHomePage; required this.myAppointmentsViewModel,
bool isFromMedicalReport; required this.bookAppointmentsViewModel,
MedicalFileViewModel? medicalFileViewModel; this.isLoading = false,
BookAppointmentsViewModel bookAppointmentsViewModel; this.isFromHomePage = false,
this.isFromMedicalReport = false,
this.medicalFileViewModel,
});
@override
State<AppointmentCard> createState() => _AppointmentCardState();
}
class _AppointmentCardState extends State<AppointmentCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>(); final appState = getIt.get<AppState>();
return InkWell( return InkWell(
onTap: () { onTap: () => _goToDetails(context),
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
),
)
.then((val) {
widget.myAppointmentsViewModel.initAppointmentsViewModel();
widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
},
child: Padding( child: Padding(
padding: EdgeInsets.all(14.h), padding: EdgeInsets.all(14.h),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( _buildHeader(context, appState),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Wrap(
alignment: WrapAlignment.start,
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [
AppCustomChipWidget(
icon: widget.isLoading
? AppAssets.walkin_appointment_icon
: (!widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppAssets.walkin_appointment_icon : AppAssets.small_livecare_icon),
iconColor: widget.isLoading
? AppColors.textColor
: !widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!
? AppColors.textColor
: AppColors.whiteColor,
labelText: widget.isLoading
? "Walk In"
: widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!
? LocaleKeys.livecare.tr(context: context)
: "Walk In".needTranslation,
backgroundColor:
widget.isLoading ? AppColors.greyColor : (!widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor),
textColor: widget.isLoading ? AppColors.textColor : (!widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : AppColors.whiteColor),
).toShimmer2(isShow: widget.isLoading),
AppCustomChipWidget(
labelText: widget.isLoading
? "OutPatient"
: appState.isArabic()
? widget.patientAppointmentHistoryResponseModel.isInOutPatientDescriptionN!
: widget.patientAppointmentHistoryResponseModel.isInOutPatientDescription!,
backgroundColor: AppColors.primaryRedColor.withOpacity(0.1),
textColor: AppColors.primaryRedColor,
).toShimmer2(isShow: widget.isLoading),
AppCustomChipWidget(
labelText: widget.isLoading ? "Booked" : AppointmentType.getAppointmentStatusType(widget.patientAppointmentHistoryResponseModel.patientStatusType!),
backgroundColor: AppColors.successColor.withOpacity(0.1),
textColor: AppColors.successColor,
).toShimmer2(isShow: widget.isLoading),
],
).toShimmer2(isShow: widget.isLoading),
),
// TODO: Implement the logic to enable/disable the switch based on reminder status
// AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
// ? SizedBox().toShimmer2(isShow: widget.isLoading)
// : Switch(
// activeColor: AppColors.successColor,
// activeTrackColor: AppColors.successColor.withValues(alpha: .15),
// thumbIcon: WidgetStateProperty.resolveWith<Icon?>(
// (Set<WidgetState> states) {
// if (states.contains(WidgetState.selected)) {
// return const Icon(Icons.check); // Icon when switch is ON
// }
// return const Icon(Icons.close); // Icon when switch is OFF
// },
// ),
// value: widget.isLoading ? false : widget.patientAppointmentHistoryResponseModel.hasReminder!,
// onChanged: (newValue) {
// setState(() {
// widget.myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel);
// });
// },
// ).toShimmer2(isShow: widget.isLoading),
],
),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( _buildDoctorRow(context),
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.network(
widget.isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : widget.patientAppointmentHistoryResponseModel.doctorImageURL!,
width: 63.h,
height: 63.h,
fit: BoxFit.cover,
).circle(100).toShimmer2(isShow: widget.isLoading),
SizedBox(width: 16.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(widget.isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : widget.patientAppointmentHistoryResponseModel.doctorNameObj!)
.toText16(isBold: true, maxlines: 1)
.toShimmer2(isShow: widget.isLoading),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
widget.isFromHomePage
? SizedBox.shrink()
: AppCustomChipWidget(labelText: widget.isLoading ? "Cardiology" : widget.patientAppointmentHistoryResponseModel.clinicName!).toShimmer2(isShow: widget.isLoading),
widget.isFromHomePage
? SizedBox.shrink()
: AppCustomChipWidget(labelText: widget.isLoading ? "Olaya" : widget.patientAppointmentHistoryResponseModel.projectName!).toShimmer2(isShow: widget.isLoading),
AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText:
widget.isLoading ? "Cardiology" : DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false))
.toShimmer2(isShow: widget.isLoading),
widget.isFromMedicalReport
? SizedBox.shrink()
: AppCustomChipWidget(
icon: AppAssets.appointment_time_icon,
labelText: widget.isLoading
? "Cardiology"
: DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false))
.toShimmer2(isShow: widget.isLoading),
],
),
],
),
),
],
),
SizedBox(height: 16.h), SizedBox(height: 16.h),
widget.isFromMedicalReport _buildActionArea(context, appState),
? CustomButton(
text: "Select appointment".needTranslation,
onPressed: () {
widget.medicalFileViewModel!.setSelectedMedicalReportAppointment(widget.patientAppointmentHistoryResponseModel);
Navigator.pop(context, false);
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppAssets.checkmark_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
)
: Row(
children: [
Expanded(
flex: 6,
child: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? getArrivedAppointmentButton().toShimmer2(isShow: widget.isLoading)
: CustomButton(
text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction),
onPressed: () {
Navigator.of(context)
.push(CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
))
.then((val) {
widget.myAppointmentsViewModel.initAppointmentsViewModel();
widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
},
backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.15),
borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01),
textColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction),
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction),
iconSize: 15.h,
).toShimmer2(isShow: widget.isLoading),
),
SizedBox(width: 8.h),
Expanded(
flex: 1,
child: Container(
height: 40.h,
width: 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor,
borderRadius: 10.h,
),
child: Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.whiteColor,
width: 40.h,
height: 40.h,
fit: BoxFit.cover,
),
),
).toShimmer2(isShow: widget.isLoading).onPress(() {
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
),
)
.then((val) {
widget.myAppointmentsViewModel.initAppointmentsViewModel();
widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
}),
),
],
),
], ],
), ),
), ),
); );
} }
Widget getArrivedAppointmentButton() { Widget _buildHeader(BuildContext context, AppState appState) {
return DateTime.now().difference(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15 return Row(
? CustomButton( mainAxisAlignment: MainAxisAlignment.spaceBetween,
text: LocaleKeys.askDoctor.tr(context: context), children: [
onPressed: () {}, Expanded(child: _buildChips(context, appState)),
backgroundColor: AppColors.secondaryLightRedColor, // Placeholder for future toggle / switch
borderColor: AppColors.secondaryLightRedColor, ],
textColor: AppColors.primaryRedColor, );
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
)
: CustomButton(
text: "Rebook with same doctor".needTranslation,
onPressed: () {
openDoctorScheduleCalendar();
},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppAssets.rebook_appointment_icon,
iconColor: AppColors.blackColor,
iconSize: 16.h,
);
} }
openDoctorScheduleCalendar() async { Widget _buildChips(BuildContext context, AppState appState) {
DoctorsListResponseModel doctor = DoctorsListResponseModel( final isLiveCare = !isLoading && patientAppointmentHistoryResponseModel.isLiveCareAppointment!;
clinicID: widget.patientAppointmentHistoryResponseModel.clinicID,
projectID: widget.patientAppointmentHistoryResponseModel.projectID, return Wrap(
doctorID: widget.patientAppointmentHistoryResponseModel.doctorID, alignment: WrapAlignment.start,
doctorImageURL: widget.patientAppointmentHistoryResponseModel.doctorImageURL, direction: Axis.horizontal,
doctorTitle: widget.patientAppointmentHistoryResponseModel.doctorTitle, spacing: 6.h,
name: widget.patientAppointmentHistoryResponseModel.doctorNameObj, runSpacing: 6.h,
nationalityFlagURL: "https://hmgwebservices.com/Images/flag/SYR.png", children: [
speciality: [], AppCustomChipWidget(
clinicName: widget.patientAppointmentHistoryResponseModel.clinicName, icon: isLoading ? AppAssets.walkin_appointment_icon : (isLiveCare ? AppAssets.small_livecare_icon : AppAssets.walkin_appointment_icon),
projectName: widget.patientAppointmentHistoryResponseModel.projectName, iconColor: isLoading ? AppColors.textColor : (isLiveCare ? AppColors.whiteColor : AppColors.textColor),
labelText: isLoading ? 'Walk In'.needTranslation : (isLiveCare ? LocaleKeys.livecare.tr(context: context) : 'Walk In'.needTranslation),
backgroundColor: isLoading ? AppColors.greyColor : (isLiveCare ? AppColors.successColor : AppColors.greyColor),
textColor: isLoading ? AppColors.textColor : (isLiveCare ? AppColors.whiteColor : AppColors.textColor),
).toShimmer2(isShow: isLoading),
AppCustomChipWidget(
labelText: isLoading
? 'OutPatient'.needTranslation
: (appState.isArabic()
? patientAppointmentHistoryResponseModel.isInOutPatientDescriptionN!
: patientAppointmentHistoryResponseModel.isInOutPatientDescription!),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
textColor: AppColors.primaryRedColor,
).toShimmer2(isShow: isLoading),
AppCustomChipWidget(
labelText: isLoading
? 'Booked'.needTranslation
: AppointmentType.getAppointmentStatusType(patientAppointmentHistoryResponseModel.patientStatusType!),
backgroundColor: AppColors.successColor.withValues(alpha: 0.1),
textColor: AppColors.successColor,
).toShimmer2(isShow: isLoading),
],
).toShimmer2(isShow: isLoading);
}
Widget _buildDoctorRow(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.network(
isLoading
? 'https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png'
: patientAppointmentHistoryResponseModel.doctorImageURL!,
width: 63.h,
height: 63.h,
fit: BoxFit.cover,
).circle(100).toShimmer2(isShow: isLoading),
SizedBox(width: 16.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(isLoading
? 'https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png'
: patientAppointmentHistoryResponseModel.doctorNameObj!)
.toText16(isBold: true, maxlines: 1)
.toShimmer2(isShow: isLoading),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
if (!isFromHomePage)
AppCustomChipWidget(labelText: isLoading ? 'Cardiology' : patientAppointmentHistoryResponseModel.clinicName!)
.toShimmer2(isShow: isLoading),
if (!isFromHomePage)
AppCustomChipWidget(labelText: isLoading ? 'Olaya' : patientAppointmentHistoryResponseModel.projectName!)
.toShimmer2(isShow: isLoading),
AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText: isLoading
? 'Cardiology'
: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false),
).toShimmer2(isShow: isLoading),
if (!isFromMedicalReport)
AppCustomChipWidget(
icon: AppAssets.appointment_time_icon,
labelText: isLoading
? 'Cardiology'
: DateUtil.formatDateToTimeLang(
DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false),
).toShimmer2(isShow: isLoading),
],
),
],
),
),
],
); );
widget.bookAppointmentsViewModel.setSelectedDoctor(doctor); }
LoaderBottomSheet.showLoader();
await widget.bookAppointmentsViewModel.getDoctorFreeSlots( Widget _buildActionArea(BuildContext context, AppState appState) {
isBookingForLiveCare: false, if (isFromMedicalReport) {
onSuccess: (dynamic respData) async { return CustomButton(
LoaderBottomSheet.hideLoader(); text: 'Select appointment'.needTranslation,
showCommonBottomSheetWithoutHeight( onPressed: () {
title: "Pick a Date".needTranslation, medicalFileViewModel!.setSelectedMedicalReportAppointment(patientAppointmentHistoryResponseModel);
context, Navigator.pop(context, false);
child: AppointmentCalendar(),
isFullScreen: false,
isCloseButtonVisible: true,
callBackFunc: () {},
);
}, },
onError: (err) { backgroundColor: AppColors.secondaryLightRedColor,
LoaderBottomSheet.hideLoader(); borderColor: AppColors.secondaryLightRedColor,
showCommonBottomSheetWithoutHeight( textColor: AppColors.primaryRedColor,
context, fontSize: 14.f,
child: Utils.getErrorWidget(loadingText: err), fontWeight: FontWeight.w500,
callBackFunc: () {}, borderRadius: 12.r,
isFullScreen: false, padding: EdgeInsets.symmetric(horizontal: 10.w),
isCloseButtonVisible: true, height: isTablet || isFoldable ? 46.h : 40.h,
); icon: AppAssets.checkmark_icon,
}); iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
);
}
return Row(
children: [
Expanded(
flex: 6,
child: (AppointmentType.isArrived(patientAppointmentHistoryResponseModel)
? _getArrivedButton(context)
: CustomButton(
text: AppointmentType.getNextActionText(patientAppointmentHistoryResponseModel.nextAction),
onPressed: () => _goToDetails(context),
backgroundColor:
AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.15),
borderColor:
AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01),
textColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: isTablet || isFoldable ? 46.h : 40.h,
icon: AppointmentType.getNextActionIcon(patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
iconSize: 15.h,
))
.toShimmer2(isShow: isLoading),
),
SizedBox(width: 8.h),
Expanded(
flex: 1,
child: Container(
height: (isFoldable || isTablet) ? 50.h : 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.textColor, borderRadius: 10.h),
child: Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.whiteColor,
width: 24.w,
height: 24.h,
fit: BoxFit.contain,
),
),
).toShimmer2(isShow: isLoading).onPress(() {
_goToDetails(context);
}),
),
],
);
}
Widget _getArrivedButton(BuildContext context) {
final isRecent = DateTime.now().difference(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15;
if (isRecent) {
return CustomButton(
text: LocaleKeys.askDoctor.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: isTablet || isFoldable ? 46.h : 40.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
);
}
return CustomButton(
text: 'Rebook with same doctor'.needTranslation,
onPressed: () => openDoctorScheduleCalendar(context),
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: isTablet || isFoldable ? 46.h : 40.h,
icon: AppAssets.rebook_appointment_icon,
iconColor: AppColors.blackColor,
iconSize: 16.h,
);
}
void _goToDetails(BuildContext context) {
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel),
),
)
.then((_) {
myAppointmentsViewModel.initAppointmentsViewModel();
myAppointmentsViewModel.getPatientAppointments(true, false);
});
} }
void performAppointmentNextAction(nextAction) {} void openDoctorScheduleCalendar(BuildContext context) async {
final doctor = DoctorsListResponseModel(
clinicID: patientAppointmentHistoryResponseModel.clinicID,
projectID: patientAppointmentHistoryResponseModel.projectID,
doctorID: patientAppointmentHistoryResponseModel.doctorID,
doctorImageURL: patientAppointmentHistoryResponseModel.doctorImageURL,
doctorTitle: patientAppointmentHistoryResponseModel.doctorTitle,
name: patientAppointmentHistoryResponseModel.doctorNameObj,
nationalityFlagURL: 'https://hmgwebservices.com/Images/flag/SYR.png',
speciality: [],
clinicName: patientAppointmentHistoryResponseModel.clinicName,
projectName: patientAppointmentHistoryResponseModel.projectName,
);
bookAppointmentsViewModel.setSelectedDoctor(doctor);
LoaderBottomSheet.showLoader();
await bookAppointmentsViewModel.getDoctorFreeSlots(
isBookingForLiveCare: false,
onSuccess: (respData) async {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: AppointmentCalendar(),
callBackFunc: () {},
title: 'Pick a Date'.needTranslation,
isFullScreen: false,
isCloseButtonVisible: true,
);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
},
);
}
} }

@ -13,12 +13,17 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
class AppointmentDoctorCard extends StatelessWidget { class AppointmentDoctorCard extends StatelessWidget {
AppointmentDoctorCard({super.key, required this.patientAppointmentHistoryResponseModel, required this.onRescheduleTap, required this.onCancelTap, required this.onAskDoctorTap}); AppointmentDoctorCard(
{super.key,
required this.patientAppointmentHistoryResponseModel,
required this.onRescheduleTap,
required this.onCancelTap,
required this.onAskDoctorTap});
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel; final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
late Function onRescheduleTap; final VoidCallback onRescheduleTap;
late Function onCancelTap; final VoidCallback onCancelTap;
late Function onAskDoctorTap; final VoidCallback onAskDoctorTap;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -38,11 +43,11 @@ class AppointmentDoctorCard extends StatelessWidget {
children: [ children: [
Image.network( Image.network(
patientAppointmentHistoryResponseModel.doctorImageURL!, patientAppointmentHistoryResponseModel.doctorImageURL!,
width: 63.h, width: 63.w,
height: 63.h, height: 63.h,
fit: BoxFit.cover, fit: BoxFit.cover,
).circle(100), ).circle(100.r),
SizedBox(width: 16.h), SizedBox(width: 16.w),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -50,23 +55,41 @@ class AppointmentDoctorCard extends StatelessWidget {
patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true), patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true),
Wrap( Wrap(
direction: Axis.horizontal, direction: Axis.horizontal,
spacing: 3.h, spacing: 6.w,
runSpacing: 4.h, runSpacing: 6.h,
children: [ children: [
AppCustomChipWidget(labelText: patientAppointmentHistoryResponseModel.clinicName!),
AppCustomChipWidget(labelText: patientAppointmentHistoryResponseModel.projectName!),
AppCustomChipWidget( AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon, labelText: patientAppointmentHistoryResponseModel.clinicName!,
labelText: labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 4.w),
"${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}, ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}"), ),
AppCustomChipWidget(
labelText: patientAppointmentHistoryResponseModel.projectName!,
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
),
AppCustomChipWidget( AppCustomChipWidget(
icon: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppAssets.walkin_appointment_icon : AppAssets.small_livecare_icon, icon: AppAssets.doctor_calendar_icon,
labelText:
"${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}, ${DateUtil.formatDateToTimeLang(
DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate),
false,
)}",
),
AppCustomChipWidget(
icon: !patientAppointmentHistoryResponseModel.isLiveCareAppointment!
? AppAssets.walkin_appointment_icon
: AppAssets.small_livecare_icon,
iconColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : AppColors.whiteColor, iconColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : AppColors.whiteColor,
labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? LocaleKeys.livecare.tr(context: context) : "Walk In".needTranslation, labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment!
backgroundColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor, ? LocaleKeys.livecare.tr(context: context)
: "Walk In".needTranslation,
backgroundColor:
!patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor,
textColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : AppColors.whiteColor, textColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : AppColors.whiteColor,
), ),
AppCustomChipWidget(icon: AppAssets.rating_icon, iconColor: AppColors.ratingColorYellow, labelText: "Rating: ${patientAppointmentHistoryResponseModel.decimalDoctorRate}"), AppCustomChipWidget(
icon: AppAssets.rating_icon,
iconColor: AppColors.ratingColorYellow,
labelText: "Rating: ${patientAppointmentHistoryResponseModel.decimalDoctorRate}"),
], ],
), ),
], ],
@ -93,10 +116,10 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.secondaryLightRedColor, backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
fontSize: 14, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12, borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0), padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0),
height: 40.h, height: 40.h,
iconSize: 16.h, iconSize: 16.h,
icon: AppAssets.ask_doctor_icon, icon: AppAssets.ask_doctor_icon,
@ -110,10 +133,10 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.greyColor, backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor, borderColor: AppColors.greyColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
fontSize: 14, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12, borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0), padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0),
height: 40.h, height: 40.h,
icon: AppAssets.rebook_appointment_icon, icon: AppAssets.rebook_appointment_icon,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
@ -129,9 +152,9 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
fontSize: 14, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12.h, borderRadius: 12.r,
height: 40.h, height: 40.h,
icon: AppAssets.cancel, icon: AppAssets.cancel,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
@ -148,9 +171,9 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.secondaryLightRedColor, backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
fontSize: 14, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12.h, borderRadius: 12.r,
height: 40.h, height: 40.h,
icon: AppAssets.appointment_calendar_icon, icon: AppAssets.appointment_calendar_icon,
iconColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor,
@ -167,9 +190,9 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
fontSize: 14, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12.h, borderRadius: 12.r,
height: 40.h, height: 40.h,
icon: AppAssets.cancel, icon: AppAssets.cancel,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,

@ -1,6 +1,5 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart';
@ -12,7 +11,6 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/home/landing_page.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart';
@ -21,7 +19,7 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class SavedLogin extends StatefulWidget { class SavedLogin extends StatefulWidget {
const SavedLogin({Key? key}) : super(key: key); const SavedLogin({super.key});
@override @override
_SavedLogin createState() => _SavedLogin(); _SavedLogin createState() => _SavedLogin();
@ -65,248 +63,255 @@ class _SavedLogin extends State<SavedLogin> {
body: SafeArea( body: SafeArea(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h), padding: EdgeInsets.symmetric(horizontal: 24.h),
child: appState.getSelectDeviceByImeiRespModelElement != null ? Column( child: appState.getSelectDeviceByImeiRespModelElement != null
crossAxisAlignment: CrossAxisAlignment.center, ? Column(
children: [ crossAxisAlignment: CrossAxisAlignment.center,
const Spacer(flex: 2),
// Welcome back text
LocaleKeys.welcomeBack.tr().toText16(color: AppColors.inputLabelTextColor),
SizedBox(height: 16.h),
appState.getSelectDeviceByImeiRespModelElement != null
? appState.getSelectDeviceByImeiRespModelElement!.name!.toCamelCase.toText26(isBold: true, height: 26 / 36, color: AppColors.textColor)
: SizedBox(),
SizedBox(height: 24.h),
Container(
padding: EdgeInsets.all(16.h),
decoration: BoxDecoration(
color: AppColors.whiteColor,
border: Border.all(color: AppColors.whiteColor),
borderRadius: BorderRadius.circular(24.h),
boxShadow: [
BoxShadow(color: Color(0x0D000000), blurRadius: 16, offset: Offset(0, 0), spreadRadius: 5),
],
),
child: Column(
children: [ children: [
// Last login info const Spacer(flex: 2),
// Welcome back text
("${LocaleKeys.lastLoginBy.tr()} ${loginType.displayName}").toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -1), LocaleKeys.welcomeBack.tr().toText16(color: AppColors.inputLabelTextColor),
SizedBox(height: 16.h),
appState.getSelectDeviceByImeiRespModelElement != null appState.getSelectDeviceByImeiRespModelElement != null
? (appState.getSelectDeviceByImeiRespModelElement!.createdOn != null ? appState.getSelectDeviceByImeiRespModelElement!.name!.toCamelCase
? DateUtil.getFormattedDate(DateUtil.convertStringToDate(appState.getSelectDeviceByImeiRespModelElement!.createdOn!), "d MMMM, y 'at' HH:mm") .toText26(isBold: true, height: 26 / 36, color: AppColors.textColor)
: '--')
.toText16(isBold: true, color: AppColors.textColor)
: SizedBox(), : SizedBox(),
SizedBox(height: 24.h),
Container(
padding: EdgeInsets.all(16.h),
decoration: BoxDecoration(
color: AppColors.whiteColor,
border: Border.all(color: AppColors.whiteColor),
borderRadius: BorderRadius.circular(24.h),
boxShadow: [
BoxShadow(color: Color(0x0D000000), blurRadius: 16.h, offset: Offset(0, 0), spreadRadius: 5.h),
],
),
child: Column(
children: [
// Last login info
appState.getSelectDeviceByImeiRespModelElement != null ("${LocaleKeys.lastLoginBy.tr()} ${loginType.displayName}")
? Container( .toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -1),
margin: EdgeInsets.all(16.h), appState.getSelectDeviceByImeiRespModelElement != null
child: Utils.buildSvgWithAssets( ? (appState.getSelectDeviceByImeiRespModelElement!.createdOn != null
icon: getTypeIcons(appState.getSelectDeviceByImeiRespModelElement!.logInType!), ? DateUtil.getFormattedDate(
height: 54, DateUtil.convertStringToDate(appState.getSelectDeviceByImeiRespModelElement!.createdOn!),
width: 54, "d MMMM, y 'at' HH:mm")
iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor)) : '--')
: SizedBox(), .toText16(isBold: true, color: AppColors.textColor)
// Face ID login button : SizedBox(),
SizedBox(
height: 45, appState.getSelectDeviceByImeiRespModelElement != null
child: CustomButton( ? Container(
text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}", margin: EdgeInsets.all(16.h),
onPressed: () { child: Utils.buildSvgWithAssets(
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) { icon: getTypeIcons(appState.getSelectDeviceByImeiRespModelElement!.logInType!),
authVm.loginWithFingerPrintFace(() {}); height: 54.h,
} else { width: 54.w,
authVm.checkUserAuthentication(otpTypeEnum: loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp); iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor))
} : SizedBox(),
}, // Face ID login button
backgroundColor: AppColors.primaryRedColor, CustomButton(
borderColor: AppColors.primaryRedColor, text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}",
textColor: Colors.white, onPressed: () {
fontSize: 12, if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
fontWeight: FontWeight.w500, authVm.loginWithFingerPrintFace(() {});
borderRadius: 12, } else {
padding: EdgeInsets.fromLTRB(0, 10, 0, 10), authVm.checkUserAuthentication(otpTypeEnum: loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp);
icon: getTypeIcons(loginType.toInt), }
//loginType == LoginTypeEnum.sms ? AppAssets.sms :AppAssets.whatsapp, },
iconColor: loginType != LoginTypeEnum.whatsapp ? Colors.white : null, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: Colors.white,
fontSize: 12.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
height: 40.h,
padding: EdgeInsets.symmetric(vertical: 10.h),
icon: getTypeIcons(loginType.toInt),
//loginType == LoginTypeEnum.sms ? AppAssets.sms :AppAssets.whatsapp,
iconColor: loginType != LoginTypeEnum.whatsapp ? Colors.white : null,
),
],
), ),
), ),
], SizedBox(height: 24.h),
), Padding(
), padding: EdgeInsets.symmetric(horizontal: 16.w),
const SizedBox(height: 24), child: Text(
Padding( LocaleKeys.oR.tr(),
padding: EdgeInsets.symmetric(horizontal: 16.0), style: context.dynamicTextStyle(fontSize: 16.f, fontWeight: FontWeight.w500),
child: Text( ),
LocaleKeys.oR.tr(), ),
style: context.dynamicTextStyle(fontSize: 16, fontWeight: FontWeight.w500), SizedBox(height: 24.h),
), // OTP login button
), loginType.toInt != 1
const SizedBox(height: 24), ? Column(
// OTP login button children: [
loginType.toInt != 1 loginType.toInt != 1
? Column( ? CustomButton(
children: [ text: LocaleKeys.loginByOTP.tr(),
loginType.toInt != 1 onPressed: () {
? CustomButton( showModalBottomSheet(
text: LocaleKeys.loginByOTP.tr(), context: context,
onPressed: () { isScrollControlled: true,
showModalBottomSheet( isDismissible: false,
context: context, useSafeArea: true,
isScrollControlled: true, backgroundColor: Colors.transparent,
isDismissible: false, enableDrag: false,
useSafeArea: true, // Prevent dragging to avoid focus conflicts
backgroundColor: Colors.transparent, builder: (bottomSheetContext) =>
enableDrag: false, StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) {
// Prevent dragging to avoid focus conflicts return Padding(
builder: (bottomSheetContext) => StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) { padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom),
return Padding( child: SingleChildScrollView(
padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom), child: GenericBottomSheet(
child: SingleChildScrollView( countryCode: "966",
child: GenericBottomSheet( initialPhoneNumber: "",
countryCode: "966", textController: TextEditingController(),
initialPhoneNumber: "", isFromSavedLogin: true,
textController: TextEditingController(), isEnableCountryDropdown: true,
isFromSavedLogin: true, onCountryChange: (value) {},
isEnableCountryDropdown: true, onChange: (String? value) {},
onCountryChange: (value) {}, buttons: [
onChange: (String? value) {}, Padding(
buttons: [ padding: EdgeInsets.only(bottom: 10.h),
Padding( child: CustomButton(
padding: EdgeInsets.only(bottom: 10.h), text: LocaleKeys.sendOTPSMS.tr(),
child: CustomButton( onPressed: () {
text: LocaleKeys.sendOTPSMS.tr(), Navigator.of(context).pop();
onPressed: () { loginType = LoginTypeEnum.sms;
Navigator.of(context).pop(); authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms);
loginType = LoginTypeEnum.sms; },
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms); backgroundColor: AppColors.primaryRedColor,
}, borderColor: AppColors.primaryRedColor,
backgroundColor: AppColors.primaryRedColor, textColor: AppColors.whiteColor,
borderColor: AppColors.primaryRedColor, icon: AppAssets.sms),
textColor: AppColors.whiteColor, ),
icon: AppAssets.sms), Row(
), crossAxisAlignment: CrossAxisAlignment.center,
Row( mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, children: [
mainAxisAlignment: MainAxisAlignment.center, Padding(
children: [ padding: EdgeInsets.symmetric(horizontal: 8.h),
Padding(padding: EdgeInsets.symmetric(horizontal: 8.h), child: (LocaleKeys.oR.tr()).toText16(color: AppColors.textColor)), child: (LocaleKeys.oR.tr()).toText16(color: AppColors.textColor)),
], ],
), ),
Padding( Padding(
padding: const EdgeInsets.only(bottom: 10, top: 10), padding: EdgeInsets.only(bottom: 10.h, top: 10.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.sendOTPWHATSAPP.tr(), text: LocaleKeys.sendOTPWHATSAPP.tr(),
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
loginType = LoginTypeEnum.whatsapp; loginType = LoginTypeEnum.whatsapp;
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp); authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp);
}, },
backgroundColor: AppColors.transparent, backgroundColor: AppColors.transparent,
borderColor: AppColors.textColor, borderColor: AppColors.textColor,
textColor: AppColors.textColor, textColor: AppColors.textColor,
icon: AppAssets.whatsapp, icon: AppAssets.whatsapp,
iconColor: null, iconColor: null,
),
),
],
), ),
), ),
], );
), }),
), );
); },
}), backgroundColor: AppColors.whiteColor,
); borderColor: AppColors.borderOnlyColor,
}, textColor: AppColors.textColor,
backgroundColor: AppColors.whiteColor, borderWidth: 2,
borderColor: AppColors.borderOnlyColor, padding: EdgeInsets.fromLTRB(0, 14.h, 0, 14.h),
textColor: AppColors.textColor, icon: AppAssets.sms,
borderWidth: 2, iconColor: AppColors.textColor,
padding: EdgeInsets.fromLTRB(0, 14, 0, 14), )
icon: AppAssets.sms, : Container(),
iconColor: AppColors.textColor, SizedBox(
) height: 20.h,
: Container(), ),
],
)
: CustomButton(
text: "${LocaleKeys.loginBy.tr()} ${LoginTypeEnum.whatsapp.displayName}",
icon: AppAssets.whatsapp,
iconColor: null,
onPressed: () {
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
authVm.loginWithFingerPrintFace(() {});
} else {
loginType = LoginTypeEnum.whatsapp;
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp);
}
},
backgroundColor: AppColors.whiteColor,
borderColor: Color(0xFF2E3039),
textColor: Color(0xFF2E3039),
borderWidth: 2.w,
padding: EdgeInsets.fromLTRB(0, 14.h, 0, 14.h),
),
const Spacer(flex: 2),
// OR divider
SizedBox(height: 24.h),
// Guest and Switch account
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: SizedBox(
height: 56.h,
child: CustomButton(
text: LocaleKeys.guest.tr(),
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context) => LandingNavigation()),
);
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Color(0xffED1C2B),
fontSize: 16.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(0, 10.h, 0, 10.h),
// icon: "assets/images/svg/apple-finder.svg",
),
),
),
SizedBox( SizedBox(
height: 20, width: MediaQuery.of(context).size.width * 0.05,
),
Expanded(
child: SizedBox(
height: 56.h,
child: CustomButton(
text: LocaleKeys.switchAccount.tr(),
onPressed: () async {
await authVm.clearDefaultInputValues();
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) => LoginScreen()),
);
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Color(0xffED1C2B),
fontSize: 15.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(0, 10.h, 0, 10.h),
// icon: "assets/images/svg/apple-finder.svg",
),
),
), ),
], ],
)
: CustomButton(
text: "${LocaleKeys.loginBy.tr()} ${LoginTypeEnum.whatsapp.displayName}",
icon: AppAssets.whatsapp,
iconColor: null,
onPressed: () {
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
authVm.loginWithFingerPrintFace(() {});
} else {
loginType = LoginTypeEnum.whatsapp;
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp);
}
},
backgroundColor: AppColors.whiteColor,
borderColor: Color(0xFF2E3039),
textColor: Color(0xFF2E3039),
borderWidth: 2,
padding: EdgeInsets.fromLTRB(0, 14, 0, 14),
), ),
const Spacer(flex: 2), SizedBox(height: 20.h),
// OR divider ],
)
const SizedBox(height: 24), : SizedBox.shrink(),
// Guest and Switch account
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: SizedBox(
height: 56,
child: CustomButton(
text: LocaleKeys.guest.tr(),
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context) => LandingNavigation()),
);
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Color(0xffED1C2B),
fontSize: 16,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
// icon: "assets/images/svg/apple-finder.svg",
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.05,
),
Expanded(
child: SizedBox(
height: 56,
child: CustomButton(
text: LocaleKeys.switchAccount.tr(),
onPressed: () async {
await authVm.clearDefaultInputValues();
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) => LoginScreen()),
);
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Color(0xffED1C2B),
fontSize: 15,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
// icon: "assets/images/svg/apple-finder.svg",
),
),
),
],
),
const SizedBox(height: 20),
],
) : SizedBox.shrink(),
), ),
), ),
); );

@ -13,7 +13,6 @@ import 'package:hmg_patient_app_new/features/authentication/authentication_view_
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart' show RegionBottomSheetBody; import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart' show RegionBottomSheetBody;
@ -21,14 +20,13 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/immed
import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/search_doctor_by_name.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/search_doctor_by_name.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart' show showCommonBottomSheetWithoutHeight; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart' show showCommonBottomSheetWithoutHeight;
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart'; import '../appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
@ -130,7 +128,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
], ],
), ),
Transform.flip( Transform.flip(
flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)), flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
], ],
).onPress(() { ).onPress(() {
bookAppointmentsViewModel.setIsClinicsListLoading(true); bookAppointmentsViewModel.setIsClinicsListLoading(true);
@ -163,7 +163,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
], ],
), ),
Transform.flip( Transform.flip(
flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)), flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
], ],
).onPress(() { ).onPress(() {
bookAppointmentsViewModel.setIsDoctorSearchByNameStarted(false); bookAppointmentsViewModel.setIsDoctorSearchByNameStarted(false);
@ -194,7 +196,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
], ],
), ),
Transform.flip( Transform.flip(
flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)), flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
], ],
).onPress(() { ).onPress(() {
bookAppointmentsViewModel.setProjectID(null); bookAppointmentsViewModel.setProjectID(null);
@ -214,115 +218,121 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Container( Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 24.h, borderRadius: 24.h,
hasShadow: false, hasShadow: false,
), ),
child: Padding( child: Padding(
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( Row(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_clinic_icon, width: 40.h, height: 40.h), Utils.buildSvgWithAssets(icon: AppAssets.search_by_clinic_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h), SizedBox(width: 12.h),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Immediate Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500), "Immediate Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
"Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), "Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
], ],
), ),
Transform.flip( Transform.flip(
flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)), flipX: appState.isArabic(),
], child: Utils.buildSvgWithAssets(
).onPress(() async { icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
//TODO Implement API to check for existing LiveCare Requests ],
).onPress(() async {
//TODO Implement API to check for existing LiveCare Requests
LoaderBottomSheet.showLoader(); LoaderBottomSheet.showLoader();
await immediateLiveCareViewModel.getPatientLiveCareHistory(); await immediateLiveCareViewModel.getPatientLiveCareHistory();
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) { if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) {
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: ImmediateLiveCarePendingRequestPage(), page: ImmediateLiveCarePendingRequestPage(),
), ),
); );
} else { } else {
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: SelectImmediateLiveCareClinicPage(), page: SelectImmediateLiveCareClinicPage(),
), ),
); );
} }
}), }),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( Row(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_doctor_icon, width: 40.h, height: 40.h), Utils.buildSvgWithAssets(icon: AppAssets.search_by_doctor_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h), SizedBox(width: 12.h),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Scheduled Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500), "Scheduled Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
"Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), "Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
], ],
), ),
Transform.flip( Transform.flip(
flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)), flipX: appState.isArabic(),
], child: Utils.buildSvgWithAssets(
).onPress(() { icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
bookAppointmentsViewModel.setIsClinicsListLoading(true); ],
bookAppointmentsViewModel.setIsLiveCareSchedule(true); ).onPress(() {
Navigator.of(context).push( bookAppointmentsViewModel.setIsClinicsListLoading(true);
CustomPageRoute( bookAppointmentsViewModel.setIsLiveCareSchedule(true);
page: SelectClinicPage(), Navigator.of(context).push(
), CustomPageRoute(
); page: SelectClinicPage(),
}), ),
SizedBox(height: 16.h), );
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), }),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
mainAxisAlignment: MainAxisAlignment.spaceBetween, SizedBox(height: 16.h),
children: [ Row(
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h), Row(
SizedBox(width: 12.h), children: [
Column( Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h),
crossAxisAlignment: CrossAxisAlignment.start, SizedBox(width: 12.h),
children: [ Column(
"Pharma LiveCare".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500), crossAxisAlignment: CrossAxisAlignment.start,
"".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), children: [
], "Pharma LiveCare".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
), "".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
Transform.flip( ],
flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)), ),
], Transform.flip(
).onPress(() { flipX: appState.isArabic(),
openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION); child: Utils.buildSvgWithAssets(
}), icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
], ],
), ).onPress(() {
), openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
), }),
], ],
),
),
),
],
).paddingSymmetrical(24.h, 0.h) ).paddingSymmetrical(24.h, 0.h)
: getLiveCareNotLoggedInUI(); : getLiveCareNotLoggedInUI();
default: default:
@ -335,8 +345,10 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
regionalViewModel.flush(); regionalViewModel.flush();
regionalViewModel.setBottomSheetType(type); regionalViewModel.setBottomSheetType(type);
// AppointmentViaRegionViewmodel? viewmodel = null; // AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false, showCommonBottomSheetWithoutHeight(context,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) { title: "",
titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)),
isDismissible: false, child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
return getRegionalSelectionWidget(data); return getRegionalSelectionWidget(data);
}), callBackFunc: () {}); }), callBackFunc: () {});
} }
@ -395,7 +407,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Immediate service".needTranslation.toText18(color: AppColors.textColor, isBold: true), "Immediate service".needTranslation.toText18(color: AppColors.textColor, isBold: true),
"No need to wait, you will get medical consultation immediately via video call".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), "No need to wait, you will get medical consultation immediately via video call"
.needTranslation
.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
), ),
@ -427,7 +441,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Doctor will contact".needTranslation.toText18(color: AppColors.textColor, isBold: true), "Doctor will contact".needTranslation.toText18(color: AppColors.textColor, isBold: true),
"A specialised doctor will contact you and will be able to view your medical history".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), "A specialised doctor will contact you and will be able to view your medical history"
.needTranslation
.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
), ),
@ -443,7 +459,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Free medicine delivery".needTranslation.toText18(color: AppColors.textColor, isBold: true), "Free medicine delivery".needTranslation.toText18(color: AppColors.textColor, isBold: true),
"Offers free medicine delivery for the LiveCare appointment".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), "Offers free medicine delivery for the LiveCare appointment"
.needTranslation
.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
), ),

@ -263,15 +263,17 @@ class _LandingPageState extends State<LandingPage> {
) )
: Container( : Container(
width: double.infinity, width: double.infinity,
decoration: decoration: RoundedRectangleBorder()
RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
child: Padding( child: Padding(
padding: EdgeInsets.all(12.h), padding: EdgeInsets.all(12.h),
child: Column( child: Column(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h),
SizedBox(height: 12.h), SizedBox(height: 12.h),
"You do not have any upcoming appointment. Please book an appointment".needTranslation.toText12(isCenter: true), "You do not have any upcoming appointment. Please book an appointment"
.needTranslation
.toText12(isCenter: true),
SizedBox(height: 12.h), SizedBox(height: 12.h),
CustomButton( CustomButton(
text: LocaleKeys.bookAppo.tr(context: context), text: LocaleKeys.bookAppo.tr(context: context),
@ -286,7 +288,7 @@ class _LandingPageState extends State<LandingPage> {
padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0),
icon: AppAssets.add_icon, icon: AppAssets.add_icon,
iconColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor,
height: (isFoldable || isTablet) ? 56.h : 46.h, height: 46.h,
), ),
], ],
), ),

@ -174,7 +174,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Image.asset(appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg, width: 56.w, height: 56.h), Image.asset(appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg,
width: 56.w, height: 56.h),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -343,7 +344,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
}), }),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) { Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
// Provide an explicit height so the horizontal ListView has a bounded height
return SizedBox( return SizedBox(
height: 140.h,
child: myAppointmentsVM.isMyAppointmentsLoading child: myAppointmentsVM.isMyAppointmentsLoading
? MedicalFileAppointmentCard( ? MedicalFileAppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
@ -355,7 +358,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
? Container( ? Container(
padding: EdgeInsets.all(12.w), padding: EdgeInsets.all(12.w),
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: true), decoration:
RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: true),
child: Column( child: Column(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h),
@ -377,8 +381,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
fontSize: 14.f, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
borderRadius: 12.r, borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), padding: EdgeInsets.symmetric(horizontal: 10.w),
height: isFoldable ? 50.h : 40.h, height: isFoldable || isTablet ? 50.h : 40.h,
icon: AppAssets.add_icon, icon: AppAssets.add_icon,
iconColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor,
), ),
@ -501,11 +505,13 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
spacing: 3.w, spacing: 3.w,
runSpacing: 4.w, runSpacing: 4.w,
children: [ children: [
AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), AppCustomChipWidget(
labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!),
AppCustomChipWidget( AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon, icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate( labelText: DateUtil.formatDateToDate(
DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), DateUtil.convertStringToDate(
prescriptionVM.patientPrescriptionOrders[index].appointmentDate),
false, false,
), ),
), ),
@ -528,7 +534,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
prescriptionVM.setPrescriptionsDetailsLoading(); prescriptionVM.setPrescriptionsDetailsLoading();
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: PrescriptionDetailPage(prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]), page: PrescriptionDetailPage(
prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]),
), ),
); );
}), }),
@ -638,7 +645,10 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
fit: BoxFit.cover, fit: BoxFit.cover,
).circle(100).toShimmer2(isShow: true, radius: 50.r), ).circle(100).toShimmer2(isShow: true, radius: 50.r),
SizedBox(height: 8.h), SizedBox(height: 8.h),
("Dr. John Smith Smith Smith").toString().toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2).toShimmer2(isShow: true), ("Dr. John Smith Smith Smith")
.toString()
.toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2)
.toShimmer2(isShow: true),
], ],
) )
: myAppointmentsVM.patientMyDoctorsList.isEmpty : myAppointmentsVM.patientMyDoctorsList.isEmpty
@ -810,10 +820,14 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}",
onPressed: () { onPressed: () {
insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true);
insuranceViewModel.getPatientInsuranceDetailsForUpdate( insuranceViewModel.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(),
appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); appState.getAuthenticatedUser()!.patientIdentificationNo.toString());
showCommonBottomSheetWithoutHeight(context, showCommonBottomSheetWithoutHeight(context,
child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); child: PatientInsuranceCardUpdateCard(),
callBackFunc: () {},
title: "",
isCloseButtonVisible: false,
isFullScreen: false);
}, },
backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
borderColor: AppColors.bgGreenColor.withOpacity(0.0), borderColor: AppColors.bgGreenColor.withOpacity(0.0),

@ -81,15 +81,15 @@ class _OnboardingScreenState extends State<OnboardingScreen> {
duration: const Duration(milliseconds: 250), duration: const Duration(milliseconds: 250),
height: 6.h, height: 6.h,
width: selectedIndex == 0 ? 18.w : 6.w, width: selectedIndex == 0 ? 18.w : 6.w,
decoration: decoration: BoxDecoration(
BoxDecoration(color: selectedIndex == 0 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)), color: selectedIndex == 0 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)),
), ),
AnimatedContainer( AnimatedContainer(
duration: const Duration(milliseconds: 250), duration: const Duration(milliseconds: 250),
height: 6.h, height: 6.h,
width: selectedIndex == 1 ? 18.w : 6.w, width: selectedIndex == 1 ? 18.w : 6.w,
decoration: decoration: BoxDecoration(
BoxDecoration(color: selectedIndex == 1 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)), color: selectedIndex == 1 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)),
), ),
], ],
).paddingOnly(left: 24.w, right: 24.w), ).paddingOnly(left: 24.w, right: 24.w),
@ -146,7 +146,7 @@ class _OnboardingScreenState extends State<OnboardingScreen> {
), ),
), ),
], ],
).paddingOnly(bottom: 10.h), ).paddingOnly(bottom: (isFoldable || isTablet) ? 20.h : 10.h),
], ],
), ),
), ),

@ -43,13 +43,13 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
quarterTurns: 90, quarterTurns: 90,
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back, icon: AppAssets.arrow_back,
width: 32.h, width: 32.w,
height: 32.h, height: 32.h,
), ),
) )
: Utils.buildSvgWithAssets( : Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back, icon: AppAssets.arrow_back,
width: 32.h, width: 32.w,
height: 32.h, height: 32.h,
), ),
), ),
@ -57,11 +57,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
), ),
// Logo // Logo
if (!hideLogoAndLang) if (!hideLogoAndLang) Utils.buildSvgWithAssets(icon: AppAssets.habiblogo, height: 24.h),
Utils.buildSvgWithAssets(
icon: AppAssets.habiblogo,
height: 24.h,
),
if (!hideLogoAndLang) if (!hideLogoAndLang)
Expanded( Expanded(

@ -110,14 +110,18 @@ class CollapsingListView extends StatelessWidget {
color: AppColors.blackColor, color: AppColors.blackColor,
letterSpacing: -0.5), letterSpacing: -0.5),
).expanded, ).expanded,
if (logout != null) actionButton(context, t, title: "Logout".needTranslation, icon: AppAssets.logout).onPress(logout!), if (logout != null)
if (report != null) actionButton(context, t, title: "Report".needTranslation, icon: AppAssets.report_icon).onPress(report!), actionButton(context, t, title: "Logout".needTranslation, icon: AppAssets.logout).onPress(logout!),
if (report != null)
actionButton(context, t, title: "Report".needTranslation, icon: AppAssets.report_icon).onPress(report!),
if (history != null) if (history != null)
actionButton(context, t, title: "History".needTranslation, icon: AppAssets.insurance_history_icon).onPress(history!), actionButton(context, t, title: "History".needTranslation, icon: AppAssets.insurance_history_icon)
.onPress(history!),
if (instructions != null) if (instructions != null)
actionButton(context, t, title: "Instructions".needTranslation, icon: AppAssets.requests).onPress(instructions!), actionButton(context, t, title: "Instructions".needTranslation, icon: AppAssets.requests).onPress(instructions!),
if (requests != null) if (requests != null)
actionButton(context, t, title: "Requests".needTranslation, icon: AppAssets.insurance_history_icon).onPress(requests!), actionButton(context, t, title: "Requests".needTranslation, icon: AppAssets.insurance_history_icon)
.onPress(requests!),
if (search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(search!).paddingOnly(right: 24), if (search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(search!).paddingOnly(right: 24),
if (trailing != null) trailing!, if (trailing != null) trailing!,
], ],
@ -151,7 +155,7 @@ class CollapsingListView extends StatelessWidget {
margin: EdgeInsets.only(right: 24.w), margin: EdgeInsets.only(right: 24.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.secondaryLightRedColor, color: AppColors.secondaryLightRedColor,
borderRadius: 12.r, borderRadius: 10.r,
), ),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,

@ -56,7 +56,11 @@ class CustomButton extends StatelessWidget {
return GestureDetector( return GestureDetector(
onTap: isDisabled ? null : onPressed, onTap: isDisabled ? null : onPressed,
child: Container( child: Container(
height: height ?? (56.h), height: height == null
? 56.h
: (isFoldable || isTablet)
? height! + 10.h
: height,
width: width, width: width,
padding: padding, padding: padding,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(

@ -48,63 +48,62 @@ class AppCustomChipWidget extends StatelessWidget {
final iconS = iconSize ?? 12.w; final iconS = iconSize ?? 12.w;
return GestureDetector( return GestureDetector(
onTap: onChipTap, onTap: onChipTap,
child: SizedBox( child: ChipTheme(
child: ChipTheme( data: ChipThemeData(
data: ChipThemeData( padding: EdgeInsets.zero,
padding: EdgeInsets.zero, shape: SmoothRectangleBorder(
shape: SmoothRectangleBorder( side: BorderSide(
side: BorderSide( width: 10.w,
width: 10.w, color: Colors.transparent, // Crucially, set color to transparent
color: Colors.transparent, // Crucially, set color to transparent style: BorderStyle.none,
style: BorderStyle.none,
),
borderRadius: BorderRadius.circular(8.r), // Apply a border radius of 16.0
), ),
borderRadius: BorderRadius.circular(isFoldable || isTablet ? 6.r : 8.r),
), ),
child: icon.isNotEmpty
? Chip(
avatar: icon.isNotEmpty
? Utils.buildSvgWithAssets(icon: icon, width: iconS, height: iconS, iconColor: iconHasColor ? iconColor : null, fit: BoxFit.contain)
: SizedBox.shrink(),
label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: 0, color: textColor),
padding: padding,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
labelPadding: labelPadding ?? EdgeInsetsDirectional.only(start: 2.w, end: deleteIcon?.isNotEmpty == true ? 2.w : 8.w),
backgroundColor: backgroundColor,
shape: shape ??
SmoothRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
smoothness: 10,
side: BorderSide(color: AppColors.transparent, width: 1.5),
),
deleteIcon: deleteIcon?.isNotEmpty == true
? Utils.buildSvgWithAssets(
icon: deleteIcon!,
width: iconS,
height: iconS,
iconColor: deleteIconHasColor ? deleteIconColor : null,
)
: null,
onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null,
)
: Chip(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: 0, color: textColor),
padding: EdgeInsets.zero,
backgroundColor: backgroundColor,
shape: shape ??
SmoothRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
smoothness: 10,
side: BorderSide(color: AppColors.transparent, width: 1.5),
),
labelPadding: labelPadding ?? EdgeInsetsDirectional.only(start: 2.w, end: deleteIcon?.isNotEmpty == true ? 2.w : 8.w),
deleteIcon: deleteIcon?.isNotEmpty == true
? Utils.buildSvgWithAssets(icon: deleteIcon!, width: iconS, height: iconS, iconColor: deleteIconHasColor ? deleteIconColor : null)
: null,
onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null,
),
), ),
child: icon.isNotEmpty
? Chip(
avatar: icon.isNotEmpty
? Utils.buildSvgWithAssets(
icon: icon, width: iconS, height: iconS, iconColor: iconHasColor ? iconColor : null, fit: BoxFit.contain)
: SizedBox.shrink(),
label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: 0, color: textColor),
padding: padding,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
labelPadding: labelPadding ?? EdgeInsetsDirectional.only(start: 2.w, end: deleteIcon?.isNotEmpty == true ? 2.w : 8.w),
backgroundColor: backgroundColor,
shape: shape ??
SmoothRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
smoothness: 10,
side: BorderSide(color: AppColors.transparent, width: 1.5),
),
deleteIcon: deleteIcon?.isNotEmpty == true
? Utils.buildSvgWithAssets(
icon: deleteIcon!,
width: iconS,
height: iconS,
iconColor: deleteIconHasColor ? deleteIconColor : null,
)
: null,
onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null,
)
: Chip(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: 0, color: textColor),
padding: EdgeInsets.zero,
backgroundColor: backgroundColor,
shape: shape ??
SmoothRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
smoothness: 10,
side: BorderSide(color: AppColors.transparent, width: 1.5),
),
labelPadding: labelPadding ?? EdgeInsetsDirectional.only(start: 2.w, end: deleteIcon?.isNotEmpty == true ? 2.w : 8.w),
deleteIcon: deleteIcon?.isNotEmpty == true
? Utils.buildSvgWithAssets(icon: deleteIcon!, width: iconS, height: iconS, iconColor: deleteIconHasColor ? deleteIconColor : null)
: null,
onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null,
),
), ),
); );
} }

@ -75,7 +75,6 @@ class CustomTabBarState extends State<CustomTabBar> {
} }
return Container( return Container(
height: 62.h,
padding: EdgeInsets.all(4.w), padding: EdgeInsets.all(4.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
@ -87,7 +86,7 @@ class CustomTabBarState extends State<CustomTabBar> {
Widget myTab(CustomTabBarModel tabBar, int currentIndex) { Widget myTab(CustomTabBarModel tabBar, int currentIndex) {
bool isSelected = selectedIndex == currentIndex; bool isSelected = selectedIndex == currentIndex;
return Container( return Container(
height: 54.h, height: (isTablet || isFoldable) ? 60.h : 54.h,
padding: EdgeInsets.only(top: 4.h, bottom: 4.h, left: 14.w, right: 14.w), padding: EdgeInsets.only(top: 4.h, bottom: 4.h, left: 14.w, right: 14.w),
alignment: Alignment.center, alignment: Alignment.center,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(

@ -42,7 +42,7 @@ class _LanguageSelectorState extends State<LanguageSelector> {
return Stack(clipBehavior: Clip.none, children: [ return Stack(clipBehavior: Clip.none, children: [
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular((12.r)), borderRadius: BorderRadius.circular((10.r)),
color: AppColors.secondaryLightRedColor, color: AppColors.secondaryLightRedColor,
), ),
child: InkWell( child: InkWell(

Loading…
Cancel
Save