Merge branch 'master' into haroon_dev

# Conflicts:
#	lib/presentation/emergency_services/call_ambulance/tracking_screen.dart
#	lib/presentation/medical_file/medical_file_page.dart
pull/91/head
haroon amjad 4 weeks ago
commit 8976f4db9d

@ -1,6 +1,6 @@
# HMG Patient App
A comprehensive Flutter-based mobile application for HMG (Hospital Management Group) patients,
A comprehensive Flutter-based mobile application for HMG (Habib Medical Group) patients,
providing seamless healthcare services and patient management features.
## 📱 Features
@ -162,5 +162,4 @@ flutter build ios --release
This project is proprietary software developed for HMG Healthcare Group.
**Built with ❤️ for better healthcare accessibility**

@ -1,5 +1,5 @@
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:amazon_payfort/amazon_payfort.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
var MAX_SMALL_SCREEN = 660;
final OPENTOK_API_KEY = '46209962';
@ -570,7 +570,8 @@ var GET_CUSTOMER_INFO = "VerifyCustomer";
//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_PRODUCTS = 'offerproducts/';
var GET_CATEGORISE_PARENT = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=';
@ -722,7 +723,7 @@ const DEACTIVATE_ACCOUNT = 'Services/Patients.svc/REST/PatientAppleActivation_In
//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';
@ -789,7 +790,6 @@ class ApiConsts {
RCBaseUrl = 'https://rc.hmg.com/test/';
break;
case AppEnvironmentTypeEnum.preProd:
baseUrl = "https://webservices.hmg.com/";
payFortEnvironment = FortEnvironment.production;
applePayMerchantId = "merchant.com.hmgwebservices";
@ -833,7 +833,7 @@ class ApiConsts {
static final String getUserAgreementContent = 'Services/Patients.svc/REST/GetUsageAgreementText';
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 insertPatientMobileData = 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo';

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

@ -37,9 +37,9 @@ import '../../core/dependencies.dart';
import '../medical_file/widgets/medical_file_card.dart';
class AppointmentDetailsPage extends StatefulWidget {
AppointmentDetailsPage({super.key, required this.patientAppointmentHistoryResponseModel});
const AppointmentDetailsPage({super.key, required this.patientAppointmentHistoryResponseModel});
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
@override
State<AppointmentDetailsPage> createState() => _AppointmentDetailsPageState();
@ -115,7 +115,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
borderRadius: 20.r,
hasShadow: false,
),
child: Padding(
@ -138,7 +138,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
? Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
SizedBox(width: 12.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -155,7 +155,8 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
children: [
ClipRRect(
clipBehavior: Clip.hardEdge,
borderRadius: BorderRadius.circular(24),
borderRadius: BorderRadius.circular(24.r),
// Todo: what is this???? Api Key??? 😲
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",
fit: BoxFit.contain,
@ -173,19 +174,19 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
double.parse(widget.patientAppointmentHistoryResponseModel.longitude!),
widget.patientAppointmentHistoryResponseModel.projectName);
},
backgroundColor: AppColors.textColor.withOpacity(0.8),
borderColor:
AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction)
.withOpacity(0.01),
backgroundColor: AppColors.textColor.withValues(alpha: 0.8),
borderColor: AppointmentType.getNextActionButtonColor(
widget.patientAppointmentHistoryResponseModel.nextAction)
.withValues(alpha: 0.01),
textColor: AppColors.whiteColor,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h,
icon: AppAssets.directions_icon,
iconColor: AppColors.whiteColor,
iconSize: 13.h,
iconSize: 14.h,
).paddingAll(12.h),
),
),
@ -199,7 +200,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
borderRadius: 20.r,
hasShadow: false,
),
child: Row(
@ -211,12 +212,14 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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(),
Switch(
activeColor: AppColors.successColor,
activeThumbColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: .15),
value: widget.patientAppointmentHistoryResponseModel.hasReminder!,
onChanged: (newValue) {
@ -237,8 +240,12 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
"Lab & Radiology".needTranslation.toText18(isBold: true),
SizedBox(height: 16.h),
GridView(
padding: EdgeInsets.zero,
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(),
shrinkWrap: true,
children: [
@ -247,19 +254,36 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.lab_result_icon,
iconSize: 40,
iconSize: 40.w,
isLargeText: true,
),
MedicalFileCard(
label: LocaleKeys.radiology.tr(context: context),
label: "Radiology Results".needTranslation,
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
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,
),
],
),
SizedBox(height: 16.h),
LocaleKeys.prescriptions.tr().toText18(isBold: true),
SizedBox(height: 16.h),
Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
@ -268,10 +292,10 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: Colors.white,
borderRadius: 20.h,
borderRadius: 20.r,
),
child: Padding(
padding: EdgeInsets.all(16.h),
padding: EdgeInsets.all(16.w),
child: Column(
children: [
ListView.separated(
@ -300,7 +324,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Column(
children: [
SizedBox(
width: 150.h,
width: 150.w,
child: prescriptionVM.prescriptionDetailsList[index].itemDescription!
.toText12(isBold: true, maxLine: 1)),
SizedBox(
@ -309,17 +333,19 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
"Prescribed By: ${widget.patientAppointmentHistoryResponseModel.doctorTitle} ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}"
.needTranslation
.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(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.blackColor,
width: 18.h,
width: 18.w,
height: 13.h,
fit: BoxFit.contain,
),
@ -363,6 +389,35 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
// ),
// ),
// 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(
child: CustomButton(
text: "All Prescriptions".needTranslation,
@ -381,9 +436,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
borderRadius: 12.r,
height: 40.h,
icon: AppAssets.requests,
iconColor: AppColors.primaryRedColor,
@ -400,21 +455,22 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
],
),
],
).paddingSymmetrical(24.h, 24.h),
).paddingAll(24.w),
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
borderRadius: 24.r,
hasShadow: true,
),
child: SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (widget.patientAppointmentHistoryResponseModel.nextAction == 15 || widget.patientAppointmentHistoryResponseModel.nextAction == 20)
if (widget.patientAppointmentHistoryResponseModel.nextAction == 15 ||
widget.patientAppointmentHistoryResponseModel.nextAction == 20)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -423,7 +479,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
children: [
"Amount before tax".needTranslation.toText18(isBold: true),
Utils.getPaymentAmountWithSymbol(
widget.patientAppointmentHistoryResponseModel.patientShare!.toString().toText16(isBold: true), AppColors.blackColor, 13,
widget.patientAppointmentHistoryResponseModel.patientShare!.toString().toText16(isBold: true),
AppColors.blackColor,
13,
isSaudiCurrency: true),
],
),
@ -432,8 +490,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child:
LocaleKeys.upcomingPaymentNow.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)),
child: LocaleKeys.upcomingPaymentNow
.tr(context: context)
.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)),
"VAT 15%(${widget.patientAppointmentHistoryResponseModel.patientTaxAmount})"
.needTranslation
.toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -2),
@ -470,10 +529,10 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 16,
fontSize: 16.f,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 50.h,
icon: AppAssets.add_icon,
iconColor: AppColors.whiteColor,
@ -486,13 +545,14 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
handleAppointmentNextAction(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,
fontSize: 16,
fontSize: 16.f,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 50.h,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 56.h,
icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppColors.whiteColor,
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/loader/bottomsheet_loader.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 {
AppointmentCard(
{super.key,
required this.patientAppointmentHistoryResponseModel,
required this.myAppointmentsViewModel,
required this.bookAppointmentsViewModel,
this.isLoading = false,
this.isFromHomePage = false,
this.isFromMedicalReport = false,
this.medicalFileViewModel});
class AppointmentCard extends StatelessWidget {
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
final MyAppointmentsViewModel myAppointmentsViewModel;
final bool isLoading;
final bool isFromHomePage;
final bool isFromMedicalReport;
final MedicalFileViewModel? medicalFileViewModel;
final BookAppointmentsViewModel bookAppointmentsViewModel;
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
MyAppointmentsViewModel myAppointmentsViewModel;
bool isLoading;
bool isFromHomePage;
bool isFromMedicalReport;
MedicalFileViewModel? medicalFileViewModel;
BookAppointmentsViewModel bookAppointmentsViewModel;
const AppointmentCard({
super.key,
required this.patientAppointmentHistoryResponseModel,
required this.myAppointmentsViewModel,
required this.bookAppointmentsViewModel,
this.isLoading = false,
this.isFromHomePage = false,
this.isFromMedicalReport = false,
this.medicalFileViewModel,
});
@override
State<AppointmentCard> createState() => _AppointmentCardState();
}
class _AppointmentCardState extends State<AppointmentCard> {
@override
Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>();
final appState = getIt.get<AppState>();
return InkWell(
onTap: () {
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
),
)
.then((val) {
widget.myAppointmentsViewModel.initAppointmentsViewModel();
widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
},
onTap: () => _goToDetails(context),
child: Padding(
padding: EdgeInsets.all(14.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
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),
],
),
_buildHeader(context, appState),
SizedBox(height: 16.h),
Row(
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),
],
),
],
),
),
],
),
_buildDoctorRow(context),
SizedBox(height: 16.h),
widget.isFromMedicalReport
? 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);
});
}),
),
],
),
_buildActionArea(context, appState),
],
),
),
);
}
Widget getArrivedAppointmentButton() {
return DateTime.now().difference(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15
? CustomButton(
text: LocaleKeys.askDoctor.tr(context: context),
onPressed: () {},
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.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,
);
Widget _buildHeader(BuildContext context, AppState appState) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: _buildChips(context, appState)),
// Placeholder for future toggle / switch
],
);
}
openDoctorScheduleCalendar() async {
DoctorsListResponseModel doctor = DoctorsListResponseModel(
clinicID: widget.patientAppointmentHistoryResponseModel.clinicID,
projectID: widget.patientAppointmentHistoryResponseModel.projectID,
doctorID: widget.patientAppointmentHistoryResponseModel.doctorID,
doctorImageURL: widget.patientAppointmentHistoryResponseModel.doctorImageURL,
doctorTitle: widget.patientAppointmentHistoryResponseModel.doctorTitle,
name: widget.patientAppointmentHistoryResponseModel.doctorNameObj,
nationalityFlagURL: "https://hmgwebservices.com/Images/flag/SYR.png",
speciality: [],
clinicName: widget.patientAppointmentHistoryResponseModel.clinicName,
projectName: widget.patientAppointmentHistoryResponseModel.projectName,
Widget _buildChips(BuildContext context, AppState appState) {
final isLiveCare = !isLoading && patientAppointmentHistoryResponseModel.isLiveCareAppointment!;
return Wrap(
alignment: WrapAlignment.start,
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [
AppCustomChipWidget(
icon: isLoading ? AppAssets.walkin_appointment_icon : (isLiveCare ? AppAssets.small_livecare_icon : AppAssets.walkin_appointment_icon),
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(
isBookingForLiveCare: false,
onSuccess: (dynamic respData) async {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
title: "Pick a Date".needTranslation,
context,
child: AppointmentCalendar(),
isFullScreen: false,
isCloseButtonVisible: true,
callBackFunc: () {},
);
}
Widget _buildActionArea(BuildContext context, AppState appState) {
if (isFromMedicalReport) {
return CustomButton(
text: 'Select appointment'.needTranslation,
onPressed: () {
medicalFileViewModel!.setSelectedMedicalReportAppointment(patientAppointmentHistoryResponseModel);
Navigator.pop(context, false);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
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.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';
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;
late Function onRescheduleTap;
late Function onCancelTap;
late Function onAskDoctorTap;
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
final VoidCallback onRescheduleTap;
final VoidCallback onCancelTap;
final VoidCallback onAskDoctorTap;
@override
Widget build(BuildContext context) {
@ -38,11 +43,11 @@ class AppointmentDoctorCard extends StatelessWidget {
children: [
Image.network(
patientAppointmentHistoryResponseModel.doctorImageURL!,
width: 63.h,
width: 63.w,
height: 63.h,
fit: BoxFit.cover,
).circle(100),
SizedBox(width: 16.h),
).circle(100.r),
SizedBox(width: 16.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -50,23 +55,41 @@ class AppointmentDoctorCard extends StatelessWidget {
patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
spacing: 6.w,
runSpacing: 6.h,
children: [
AppCustomChipWidget(labelText: patientAppointmentHistoryResponseModel.clinicName!),
AppCustomChipWidget(labelText: patientAppointmentHistoryResponseModel.projectName!),
AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText:
"${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}, ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}"),
labelText: patientAppointmentHistoryResponseModel.clinicName!,
labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 4.w),
),
AppCustomChipWidget(
labelText: patientAppointmentHistoryResponseModel.projectName!,
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
),
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,
labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? LocaleKeys.livecare.tr(context: context) : "Walk In".needTranslation,
backgroundColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor,
labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment!
? LocaleKeys.livecare.tr(context: context)
: "Walk In".needTranslation,
backgroundColor:
!patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor,
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,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0),
height: 40.h,
iconSize: 16.h,
icon: AppAssets.ask_doctor_icon,
@ -110,10 +133,10 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 14,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0),
height: 40.h,
icon: AppAssets.rebook_appointment_icon,
iconColor: AppColors.blackColor,
@ -129,9 +152,9 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 14,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
borderRadius: 12.r,
height: 40.h,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,
@ -148,9 +171,9 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
borderRadius: 12.r,
height: 40.h,
icon: AppAssets.appointment_calendar_icon,
iconColor: AppColors.primaryRedColor,
@ -167,9 +190,9 @@ class AppointmentDoctorCard extends StatelessWidget {
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 14,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
borderRadius: 12.r,
height: 40.h,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,

@ -1,6 +1,5 @@
import 'package:easy_localization/easy_localization.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_state.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/generated/locale_keys.g.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/theme/colors.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';
class SavedLogin extends StatefulWidget {
const SavedLogin({Key? key}) : super(key: key);
const SavedLogin({super.key});
@override
_SavedLogin createState() => _SavedLogin();
@ -65,248 +63,255 @@ class _SavedLogin extends State<SavedLogin> {
body: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h),
child: appState.getSelectDeviceByImeiRespModelElement != null ? Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
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(
child: appState.getSelectDeviceByImeiRespModelElement != null
? Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Last login info
("${LocaleKeys.lastLoginBy.tr()} ${loginType.displayName}").toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -1),
const Spacer(flex: 2),
// Welcome back text
LocaleKeys.welcomeBack.tr().toText16(color: AppColors.inputLabelTextColor),
SizedBox(height: 16.h),
appState.getSelectDeviceByImeiRespModelElement != null
? (appState.getSelectDeviceByImeiRespModelElement!.createdOn != null
? DateUtil.getFormattedDate(DateUtil.convertStringToDate(appState.getSelectDeviceByImeiRespModelElement!.createdOn!), "d MMMM, y 'at' HH:mm")
: '--')
.toText16(isBold: true, color: AppColors.textColor)
? 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.h, offset: Offset(0, 0), spreadRadius: 5.h),
],
),
child: Column(
children: [
// Last login info
appState.getSelectDeviceByImeiRespModelElement != null
? Container(
margin: EdgeInsets.all(16.h),
child: Utils.buildSvgWithAssets(
icon: getTypeIcons(appState.getSelectDeviceByImeiRespModelElement!.logInType!),
height: 54,
width: 54,
iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor))
: SizedBox(),
// Face ID login button
SizedBox(
height: 45,
child: CustomButton(
text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}",
onPressed: () {
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
authVm.loginWithFingerPrintFace(() {});
} else {
authVm.checkUserAuthentication(otpTypeEnum: loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp);
}
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
icon: getTypeIcons(loginType.toInt),
//loginType == LoginTypeEnum.sms ? AppAssets.sms :AppAssets.whatsapp,
iconColor: loginType != LoginTypeEnum.whatsapp ? Colors.white : null,
("${LocaleKeys.lastLoginBy.tr()} ${loginType.displayName}")
.toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -1),
appState.getSelectDeviceByImeiRespModelElement != null
? (appState.getSelectDeviceByImeiRespModelElement!.createdOn != null
? DateUtil.getFormattedDate(
DateUtil.convertStringToDate(appState.getSelectDeviceByImeiRespModelElement!.createdOn!),
"d MMMM, y 'at' HH:mm")
: '--')
.toText16(isBold: true, color: AppColors.textColor)
: SizedBox(),
appState.getSelectDeviceByImeiRespModelElement != null
? Container(
margin: EdgeInsets.all(16.h),
child: Utils.buildSvgWithAssets(
icon: getTypeIcons(appState.getSelectDeviceByImeiRespModelElement!.logInType!),
height: 54.h,
width: 54.w,
iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor))
: SizedBox(),
// Face ID login button
CustomButton(
text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}",
onPressed: () {
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
authVm.loginWithFingerPrintFace(() {});
} else {
authVm.checkUserAuthentication(otpTypeEnum: loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp);
}
},
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,
),
],
),
),
],
),
),
const SizedBox(height: 24),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
LocaleKeys.oR.tr(),
style: context.dynamicTextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
),
const SizedBox(height: 24),
// OTP login button
loginType.toInt != 1
? Column(
children: [
loginType.toInt != 1
? CustomButton(
text: LocaleKeys.loginByOTP.tr(),
onPressed: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: false,
useSafeArea: true,
backgroundColor: Colors.transparent,
enableDrag: false,
// Prevent dragging to avoid focus conflicts
builder: (bottomSheetContext) => StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) {
return Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom),
child: SingleChildScrollView(
child: GenericBottomSheet(
countryCode: "966",
initialPhoneNumber: "",
textController: TextEditingController(),
isFromSavedLogin: true,
isEnableCountryDropdown: true,
onCountryChange: (value) {},
onChange: (String? value) {},
buttons: [
Padding(
padding: EdgeInsets.only(bottom: 10.h),
child: CustomButton(
text: LocaleKeys.sendOTPSMS.tr(),
onPressed: () {
Navigator.of(context).pop();
loginType = LoginTypeEnum.sms;
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms);
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.sms),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(padding: EdgeInsets.symmetric(horizontal: 8.h), child: (LocaleKeys.oR.tr()).toText16(color: AppColors.textColor)),
],
),
Padding(
padding: const EdgeInsets.only(bottom: 10, top: 10),
child: CustomButton(
text: LocaleKeys.sendOTPWHATSAPP.tr(),
onPressed: () {
Navigator.of(context).pop();
loginType = LoginTypeEnum.whatsapp;
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp);
},
backgroundColor: AppColors.transparent,
borderColor: AppColors.textColor,
textColor: AppColors.textColor,
icon: AppAssets.whatsapp,
iconColor: null,
SizedBox(height: 24.h),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w),
child: Text(
LocaleKeys.oR.tr(),
style: context.dynamicTextStyle(fontSize: 16.f, fontWeight: FontWeight.w500),
),
),
SizedBox(height: 24.h),
// OTP login button
loginType.toInt != 1
? Column(
children: [
loginType.toInt != 1
? CustomButton(
text: LocaleKeys.loginByOTP.tr(),
onPressed: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: false,
useSafeArea: true,
backgroundColor: Colors.transparent,
enableDrag: false,
// Prevent dragging to avoid focus conflicts
builder: (bottomSheetContext) =>
StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) {
return Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom),
child: SingleChildScrollView(
child: GenericBottomSheet(
countryCode: "966",
initialPhoneNumber: "",
textController: TextEditingController(),
isFromSavedLogin: true,
isEnableCountryDropdown: true,
onCountryChange: (value) {},
onChange: (String? value) {},
buttons: [
Padding(
padding: EdgeInsets.only(bottom: 10.h),
child: CustomButton(
text: LocaleKeys.sendOTPSMS.tr(),
onPressed: () {
Navigator.of(context).pop();
loginType = LoginTypeEnum.sms;
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms);
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.sms),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 8.h),
child: (LocaleKeys.oR.tr()).toText16(color: AppColors.textColor)),
],
),
Padding(
padding: EdgeInsets.only(bottom: 10.h, top: 10.h),
child: CustomButton(
text: LocaleKeys.sendOTPWHATSAPP.tr(),
onPressed: () {
Navigator.of(context).pop();
loginType = LoginTypeEnum.whatsapp;
authVm.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp);
},
backgroundColor: AppColors.transparent,
borderColor: AppColors.textColor,
textColor: AppColors.textColor,
icon: AppAssets.whatsapp,
iconColor: null,
),
),
],
),
),
],
),
),
);
}),
);
},
backgroundColor: AppColors.whiteColor,
borderColor: AppColors.borderOnlyColor,
textColor: AppColors.textColor,
borderWidth: 2,
padding: EdgeInsets.fromLTRB(0, 14, 0, 14),
icon: AppAssets.sms,
iconColor: AppColors.textColor,
)
: Container(),
);
}),
);
},
backgroundColor: AppColors.whiteColor,
borderColor: AppColors.borderOnlyColor,
textColor: AppColors.textColor,
borderWidth: 2,
padding: EdgeInsets.fromLTRB(0, 14.h, 0, 14.h),
icon: AppAssets.sms,
iconColor: AppColors.textColor,
)
: Container(),
SizedBox(
height: 20.h,
),
],
)
: 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(
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),
// OR divider
const SizedBox(height: 24),
// 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(),
SizedBox(height: 20.h),
],
)
: 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/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/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/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;
@ -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/search_doctor_by_name.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/widgets/appbar/collapsing_list_view.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/custom_tab_bar.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/transitions/fade_page.dart';
import 'package:provider/provider.dart';
import '../appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
@ -129,7 +127,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
],
),
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(() {
bookAppointmentsViewModel.setIsClinicsListLoading(true);
@ -162,7 +162,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
],
),
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(() {
bookAppointmentsViewModel.setIsDoctorSearchByNameStarted(false);
@ -193,7 +195,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
],
),
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(() {
bookAppointmentsViewModel.setProjectID(null);
@ -213,115 +217,121 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: false,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_clinic_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Immediate Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
"Tap to select clinic".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)),
],
).onPress(() async {
//TODO Implement API to check for existing LiveCare Requests
borderRadius: 24.h,
hasShadow: false,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_clinic_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Immediate Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
"Tap to select clinic".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)),
],
).onPress(() async {
//TODO Implement API to check for existing LiveCare Requests
LoaderBottomSheet.showLoader();
await immediateLiveCareViewModel.getPatientLiveCareHistory();
LoaderBottomSheet.hideLoader();
LoaderBottomSheet.showLoader();
await immediateLiveCareViewModel.getPatientLiveCareHistory();
LoaderBottomSheet.hideLoader();
if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) {
Navigator.of(context).push(
CustomPageRoute(
page: ImmediateLiveCarePendingRequestPage(),
),
);
} else {
Navigator.of(context).push(
CustomPageRoute(
page: SelectImmediateLiveCareClinicPage(),
),
);
}
}),
SizedBox(height: 16.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_doctor_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Scheduled Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
"Tap to select clinic".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)),
],
).onPress(() {
bookAppointmentsViewModel.setIsClinicsListLoading(true);
bookAppointmentsViewModel.setIsLiveCareSchedule(true);
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),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
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)),
],
).onPress(() {
openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
}),
],
),
),
),
],
if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) {
Navigator.of(context).push(
CustomPageRoute(
page: ImmediateLiveCarePendingRequestPage(),
),
);
} else {
Navigator.of(context).push(
CustomPageRoute(
page: SelectImmediateLiveCareClinicPage(),
),
);
}
}),
SizedBox(height: 16.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_doctor_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Scheduled Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
"Tap to select clinic".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)),
],
).onPress(() {
bookAppointmentsViewModel.setIsClinicsListLoading(true);
bookAppointmentsViewModel.setIsLiveCareSchedule(true);
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),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h),
SizedBox(width: 12.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
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)),
],
).onPress(() {
openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
}),
],
),
),
),
],
).paddingSymmetrical(24.h, 0.h)
: getLiveCareNotLoggedInUI();
default:
@ -334,8 +344,10 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
regionalViewModel.flush();
regionalViewModel.setBottomSheetType(type);
// AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
showCommonBottomSheetWithoutHeight(context,
title: "",
titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)),
isDismissible: false, child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
return getRegionalSelectionWidget(data);
}), callBackFunc: () {});
}
@ -394,7 +406,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"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),
],
),
),
@ -426,7 +440,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"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),
],
),
),
@ -442,7 +458,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"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),
],
),
),

@ -21,6 +21,8 @@ import 'package:provider/provider.dart';
class TrackingScreen extends StatelessWidget {
final OrderTrackingState state = OrderTrackingState.ended;
const TrackingScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
@ -45,7 +47,7 @@ class TrackingScreen extends StatelessWidget {
animationSection(),
Column(
spacing: 16.h,
children: [OrderStatus(context), OrderTrackingId(), ContactSection()],
children: [orderStatus(context), orderTrackingId(), contactSection()],
).paddingAll(16.h),
],
))),
@ -59,12 +61,11 @@ class TrackingScreen extends StatelessWidget {
case OrderTrackingState.returning:
return Lottie.asset(AppAnimations.ambulance, repeat: true, reverse: false, width: 260.h, height: 200.h);
case OrderTrackingState.ended:
default:
return Lottie.asset(AppAnimations.checkmark, repeat: true, width: 260.h, height: 200.h);
}
}
OrderStatus(BuildContext context) {
orderStatus(BuildContext context) {
return Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -137,7 +138,6 @@ class TrackingScreen extends StatelessWidget {
children: [dividerSection, doctorSection(), mapSection(context)],
);
case OrderTrackingState.ended:
default:
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 12.h,
@ -200,16 +200,17 @@ class TrackingScreen extends StatelessWidget {
Widget mapForRequestedCoordinate(BuildContext context) {
// return SizedBox.shrink();
if (context.read<EmergencyServicesViewModel>().isGMSAvailable || Platform.isIOS)
if (context.read<EmergencyServicesViewModel>().isGMSAvailable || Platform.isIOS) {
return GMSMap(
myLocationEnabled: false,
currentLocation: context.read<EmergencyServicesViewModel>().getGMSLocation(),
onCameraMoved: (value) => context.read<EmergencyServicesViewModel>().handleGMSMapCameraMoved(value));
else
} else {
return HMSMap(
myLocationEnabled: false,
currentLocation: context.read<EmergencyServicesViewModel>().getHMSLocation(),
onCameraMoved: (value) => context.read<EmergencyServicesViewModel>().handleHMSMapCameraMoved(value));
}
}
informationRegardingTrackingSection() {
@ -273,12 +274,12 @@ class TrackingScreen extends StatelessWidget {
]),
);
case OrderTrackingState.ended:
default:
return "Arrived".needTranslation.toText21(color: AppColors.textColor, weight: FontWeight.w600);
}
}
OrderTrackingId() {
orderTrackingId() {
return Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -294,17 +295,17 @@ class TrackingScreen extends StatelessWidget {
Row(
spacing: 8.h,
children: [
Chip("location name".needTranslation, AppAssets.location_pickup, AppColors.blackBgColor),
Chip("hotel name ".needTranslation, AppAssets.hospital, AppColors.blackBgColor),
chip("location name".needTranslation, AppAssets.location_pickup, AppColors.blackBgColor),
chip("hotel name ".needTranslation, AppAssets.hospital, AppColors.blackBgColor),
],
),
Chip("hotel name ".needTranslation, AppAssets.hospital, AppColors.blackBgColor),
chip("hotel name ".needTranslation, AppAssets.hospital, AppColors.blackBgColor),
],
),
);
}
Chip(String title, String iconString, Color iconColor) {
chip(String title, String iconString, Color iconColor) {
return AppCustomChipWidget(
labelText: title,
icon: iconString,
@ -313,7 +314,7 @@ class TrackingScreen extends StatelessWidget {
);
}
ContactSection() {
contactSection() {
return Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -371,7 +372,6 @@ class TrackingScreen extends StatelessWidget {
case OrderTrackingState.returning:
return " On The Way To Hospital".needTranslation.toText16(color: AppColors.textColor, weight: FontWeight.w600);
case OrderTrackingState.ended:
default:
return "Arrived at Hospital".needTranslation.toText16(color: AppColors.textColor, weight: FontWeight.w600);
}
}

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

@ -173,7 +173,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
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),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -340,8 +341,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
}),
SizedBox(height: 16.h),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
// Provide an explicit height so the horizontal ListView has a bounded height
return SizedBox(
height: 185.h,
height: 140.h,
child: myAppointmentsVM.isMyAppointmentsLoading
? MedicalFileAppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
@ -353,7 +355,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
? Container(
padding: EdgeInsets.all(12.w),
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(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h),
@ -375,8 +378,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0),
height: isFoldable ? 50.h : 40.h,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: isFoldable || isTablet ? 50.h : 40.h,
icon: AppAssets.add_icon,
iconColor: AppColors.primaryRedColor,
),
@ -499,11 +502,13 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
spacing: 3.w,
runSpacing: 4.w,
children: [
AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!),
AppCustomChipWidget(
labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!),
AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate(
DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate),
DateUtil.convertStringToDate(
prescriptionVM.patientPrescriptionOrders[index].appointmentDate),
false,
),
),
@ -526,7 +531,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
prescriptionVM.setPrescriptionsDetailsLoading();
Navigator.of(context).push(
CustomPageRoute(
page: PrescriptionDetailPage(prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]),
page: PrescriptionDetailPage(
prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]),
),
);
}),
@ -636,7 +642,10 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
fit: BoxFit.cover,
).circle(100).toShimmer2(isShow: true, radius: 50.r),
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
@ -808,10 +817,14 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}",
onPressed: () {
insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true);
insuranceViewModel.getPatientInsuranceDetailsForUpdate(
appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString());
insuranceViewModel.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(),
appState.getAuthenticatedUser()!.patientIdentificationNo.toString());
showCommonBottomSheetWithoutHeight(context,
child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false);
child: PatientInsuranceCardUpdateCard(),
callBackFunc: () {},
title: "",
isCloseButtonVisible: false,
isFullScreen: false);
},
backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
borderColor: AppColors.bgGreenColor.withOpacity(0.0),

@ -81,15 +81,15 @@ class _OnboardingScreenState extends State<OnboardingScreen> {
duration: const Duration(milliseconds: 250),
height: 6.h,
width: selectedIndex == 0 ? 18.w : 6.w,
decoration:
BoxDecoration(color: selectedIndex == 0 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)),
decoration: BoxDecoration(
color: selectedIndex == 0 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)),
),
AnimatedContainer(
duration: const Duration(milliseconds: 250),
height: 6.h,
width: selectedIndex == 1 ? 18.w : 6.w,
decoration:
BoxDecoration(color: selectedIndex == 1 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)),
decoration: BoxDecoration(
color: selectedIndex == 1 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)),
),
],
).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,
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back,
width: 32.h,
width: 32.w,
height: 32.h,
),
)
: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back,
width: 32.h,
width: 32.w,
height: 32.h,
),
),
@ -57,11 +57,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
),
// Logo
if (!hideLogoAndLang)
Utils.buildSvgWithAssets(
icon: AppAssets.habiblogo,
height: 24.h,
),
if (!hideLogoAndLang) Utils.buildSvgWithAssets(icon: AppAssets.habiblogo, height: 24.h),
if (!hideLogoAndLang)
Expanded(

@ -110,14 +110,18 @@ class CollapsingListView extends StatelessWidget {
color: AppColors.blackColor,
letterSpacing: -0.5),
).expanded,
if (logout != null) 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 (logout != null)
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)
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)
actionButton(context, t, title: "Instructions".needTranslation, icon: AppAssets.requests).onPress(instructions!),
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 (trailing != null) trailing!,
],
@ -151,7 +155,7 @@ class CollapsingListView extends StatelessWidget {
margin: EdgeInsets.only(right: 24.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.secondaryLightRedColor,
borderRadius: 12.r,
borderRadius: 10.r,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,

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

@ -48,63 +48,62 @@ class AppCustomChipWidget extends StatelessWidget {
final iconS = iconSize ?? 12.w;
return GestureDetector(
onTap: onChipTap,
child: SizedBox(
child: ChipTheme(
data: ChipThemeData(
padding: EdgeInsets.zero,
shape: SmoothRectangleBorder(
side: BorderSide(
width: 10.w,
color: Colors.transparent, // Crucially, set color to transparent
style: BorderStyle.none,
),
borderRadius: BorderRadius.circular(8.r), // Apply a border radius of 16.0
child: ChipTheme(
data: ChipThemeData(
padding: EdgeInsets.zero,
shape: SmoothRectangleBorder(
side: BorderSide(
width: 10.w,
color: Colors.transparent, // Crucially, set color to transparent
style: BorderStyle.none,
),
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(
height: 62.h,
padding: EdgeInsets.all(4.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
@ -87,7 +86,7 @@ class CustomTabBarState extends State<CustomTabBar> {
Widget myTab(CustomTabBarModel tabBar, int currentIndex) {
bool isSelected = selectedIndex == currentIndex;
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),
alignment: Alignment.center,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(

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

Loading…
Cancel
Save