Design Updates

pull/86/head
faizatflutter 3 weeks ago
parent eabfaf8182
commit 462f4eba14

@ -15,7 +15,6 @@ import 'package:flutter_ios_voip_kit_karmm/flutter_ios_voip_kit.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:hmg_patient_app_new/core/utils/local_notifications.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:permission_handler/permission_handler.dart';
import '../cache_consts.dart';
@ -355,7 +354,6 @@ class PushNotificationHandler {
}
onToken(String token) async {
print("Push Notification Token: " + token);
await Utils.saveStringFromPrefs(CacheConst.pushToken, token);
}
@ -370,7 +368,9 @@ class PushNotificationHandler {
Future<void> requestPermissions() async {
try {
if (Platform.isIOS) {
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(alert: true, badge: true, sound: true);
} else if (Platform.isAndroid) {
Map<Permission, PermissionStatus> statuses = await [
Permission.notification,

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/get_tamara_installments_details_response_model.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/appointemnet_filters.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/get_tamara_installments_details_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_share_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart';
@ -171,40 +171,36 @@ class MyAppointmentsViewModel extends ChangeNotifier {
getFiltersForSelectedAppointmentList(filteredAppointmentList);
}
void getFiltersForSelectedAppointmentList(
List<PatientAppointmentHistoryResponseModel> filteredAppointmentList) {
void getFiltersForSelectedAppointmentList(List<PatientAppointmentHistoryResponseModel> filteredAppointmentList) {
availableFilters.clear();
if (filteredAppointmentList.isEmpty == true) return;
availableFilters.add(AppointmentListingFilters.DATESELECTION);
if (filteredAppointmentList
.any((element) => element.isLiveCareAppointment == true)) {
if (filteredAppointmentList.any((element) => element.isLiveCareAppointment == true)) {
availableFilters.add(AppointmentListingFilters.LIVECARE);
}
if (filteredAppointmentList
.any((element) => element.isLiveCareAppointment == false)) {
if (filteredAppointmentList.any((element) => element.isLiveCareAppointment == false)) {
availableFilters.add(AppointmentListingFilters.WALKIN);
}
if (filteredAppointmentList
.any((element) => AppointmentType.isArrived(element) == true)) {
if (filteredAppointmentList.any((element) => AppointmentType.isArrived(element) == true)) {
availableFilters.add(AppointmentListingFilters.ARRIVED);
}
if (filteredAppointmentList
.any((element) => AppointmentType.isBooked(element) == true)) {
if (filteredAppointmentList.any((element) => AppointmentType.isBooked(element) == true)) {
availableFilters.add(AppointmentListingFilters.BOOKED);
}
if (filteredAppointmentList
.any((element) => AppointmentType.isConfirmed(element) == true)) {
if (filteredAppointmentList.any((element) => AppointmentType.isConfirmed(element) == true)) {
availableFilters.add(AppointmentListingFilters.CONFIRMED);
}
notifyListeners();
}
Future<void> getPatientShareAppointment(int projectID, int clinicID, String appointmentNo, bool isLiveCareAppointment, {Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.getPatientShareAppointment(projectID: projectID, clinicID: clinicID, appointmentNo: appointmentNo, isLiveCareAppointment: isLiveCareAppointment);
Future<void> getPatientShareAppointment(int projectID, int clinicID, String appointmentNo, bool isLiveCareAppointment,
{Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.getPatientShareAppointment(
projectID: projectID, clinicID: clinicID, appointmentNo: appointmentNo, isLiveCareAppointment: isLiveCareAppointment);
result.fold(
(failure) async {
@ -230,8 +226,13 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
Future<void> addAdvanceNumberRequest(
{required String advanceNumber, required String paymentReference, required String appointmentNo, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.addAdvanceNumberRequest(advanceNumber: advanceNumber, paymentReference: paymentReference, appointmentNo: appointmentNo);
{required String advanceNumber,
required String paymentReference,
required String appointmentNo,
Function(dynamic)? onSuccess,
Function(String)? onError}) async {
final result =
await myAppointmentsRepo.addAdvanceNumberRequest(advanceNumber: advanceNumber, paymentReference: paymentReference, appointmentNo: appointmentNo);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@ -249,8 +250,14 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
Future<void> generateAppointmentQR(
{required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.generateAppointmentQR(clinicID: clinicID, projectID: projectID, appointmentNo: appointmentNo, isFollowUp: isFollowUp);
{required int clinicID,
required int projectID,
required String appointmentNo,
required int isFollowUp,
Function(dynamic)? onSuccess,
Function(String)? onError}) async {
final result =
await myAppointmentsRepo.generateAppointmentQR(clinicID: clinicID, projectID: projectID, appointmentNo: appointmentNo, isFollowUp: isFollowUp);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@ -267,7 +274,8 @@ class MyAppointmentsViewModel extends ChangeNotifier {
);
}
Future<void> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
Future<void> cancelAppointment(
{required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
result.fold(
@ -286,7 +294,8 @@ class MyAppointmentsViewModel extends ChangeNotifier {
);
}
Future<void> confirmAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
Future<void> confirmAppointment(
{required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.confirmAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
result.fold(
@ -347,7 +356,8 @@ class MyAppointmentsViewModel extends ChangeNotifier {
required int checkInType,
Function(dynamic)? onSuccess,
Function(String)? onError}) async {
final result = await myAppointmentsRepo.sendCheckInNfcRequest(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, scannedCode: scannedCode, checkInType: checkInType);
final result = await myAppointmentsRepo.sendCheckInNfcRequest(
patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, scannedCode: scannedCode, checkInType: checkInType);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@ -393,8 +403,12 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
Future<void> insertLiveCareVIDARequest(
{required clientRequestID, required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.insertLiveCareVIDARequest(clientRequestID: clientRequestID, patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
{required clientRequestID,
required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel,
Function(dynamic)? onSuccess,
Function(String)? onError}) async {
final result = await myAppointmentsRepo.insertLiveCareVIDARequest(
clientRequestID: clientRequestID, patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@ -461,14 +475,14 @@ class MyAppointmentsViewModel extends ChangeNotifier {
if (start == null && end == null) {
isDateFilterSelected = false;
filteredAppointmentList.clear();
sourceList.forEach((element) {
for (var element in sourceList) {
if (isUnderFilter(element)) {
filteredAppointmentList.add(element);
}
});
}
} else {
filteredAppointmentList.clear();
sourceList.forEach((element) {
for (var element in sourceList) {
try {
var dateTime = DateUtil.convertStringToDate(element.appointmentDate).provideDateOnly();
@ -486,7 +500,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
}
} catch (e) {}
});
}
}
notifyListeners();
}
@ -496,9 +510,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
bool isUnderFilter(PatientAppointmentHistoryResponseModel element) {
bool isUnderTheFilter = false;
if (selectedFilter == null || selectedFilter!.isEmpty) return true;
int count = 0;
for (var filter in selectedFilter ?? []) {
switch (filter) {
case AppointmentListingFilters.WALKIN:
@ -516,7 +528,6 @@ class MyAppointmentsViewModel extends ChangeNotifier {
if (element.isLiveCareAppointment == true) return true;
case AppointmentListingFilters.DATESELECTION:
}
}
return false;

@ -174,8 +174,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg, width: 56.h, height: 56.h),
SizedBox(width: 8.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,
children: [
@ -184,12 +184,13 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
SizedBox(height: 4.h),
Wrap(
direction: Axis.horizontal,
spacing: 4.h,
runSpacing: 4.h,
spacing: 4.w,
runSpacing: 6.w,
children: [
AppCustomChipWidget(
icon: AppAssets.file_icon,
labelText: "${LocaleKeys.fileNo.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}",
labelPadding: EdgeInsetsDirectional.only(end: 6.w),
onChipTap: () {
navigationService.pushPage(
page: FamilyMedicalScreen(
@ -202,6 +203,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
icon: AppAssets.checkmark_icon,
labelText: LocaleKeys.verified.tr(context: context),
iconColor: AppColors.successColor,
labelPadding: EdgeInsetsDirectional.only(end: 6.w),
),
],
),
@ -341,7 +343,6 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
SizedBox(height: 16.h),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
return SizedBox(
height: 175.h,
child: myAppointmentsVM.isMyAppointmentsLoading
? MedicalFileAppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),

@ -40,7 +40,7 @@ class LabRadCard extends StatelessWidget {
fit: BoxFit.contain,
).toShimmer2(isShow: false, radius: 12.r),
SizedBox(width: 8.w),
labelText.toText14(isBold: true).toShimmer2(isShow: false, radius: 6.r, height: 32.h),
Flexible(child: labelText.toText14(isBold: true).toShimmer2(isShow: false, radius: 6.r, height: 32.h)),
],
),
SizedBox(height: 16.h),

@ -17,16 +17,20 @@ import 'package:hmg_patient_app_new/theme/colors.dart';
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/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
class MedicalFileAppointmentCard extends StatelessWidget {
MedicalFileAppointmentCard({super.key, required this.patientAppointmentHistoryResponseModel, required this.myAppointmentsViewModel, required this.onRescheduleTap, required this.onAskDoctorTap});
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
final MyAppointmentsViewModel myAppointmentsViewModel;
final Function onRescheduleTap;
final Function onAskDoctorTap;
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
MyAppointmentsViewModel myAppointmentsViewModel;
late Function onRescheduleTap;
late Function onAskDoctorTap;
const MedicalFileAppointmentCard({
super.key,
required this.patientAppointmentHistoryResponseModel,
required this.myAppointmentsViewModel,
required this.onRescheduleTap,
required this.onAskDoctorTap,
});
@override
Widget build(BuildContext context) {
@ -36,19 +40,21 @@ class MedicalFileAppointmentCard extends StatelessWidget {
children: [
AppCustomChipWidget(
richText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)
.toText12(color: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor, fontWeight: FontWeight.w500)
.paddingOnly(left: 8.h),
.toText12(
color: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor,
fontWeight: FontWeight.w500)
.paddingOnly(left: 8.w),
icon: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppAssets.appointment_calendar_icon : AppAssets.alarm_clock_icon,
iconColor: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor,
iconSize: 16.h,
iconSize: 16.w,
backgroundColor: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.greyColor : AppColors.secondaryLightRedColor,
textColor: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor,
padding: EdgeInsets.only(top: 12.h, bottom: 12.h, left: 8.h, right: 8.h),
padding: EdgeInsets.only(top: 12.h, bottom: 12.h, left: 8.w, right: 8.w),
).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
SizedBox(height: 16.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
width: 200.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
width: 200.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -56,16 +62,18 @@ class MedicalFileAppointmentCard extends StatelessWidget {
children: [
Image.network(
patientAppointmentHistoryResponseModel.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png",
width: 25.h,
width: 25.w,
height: 27.h,
fit: BoxFit.fill,
).circle(100).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
SizedBox(width: 8.h),
SizedBox(width: 8.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(patientAppointmentHistoryResponseModel.doctorNameObj ?? "").toText14(isBold: true, maxlines: 1).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
(patientAppointmentHistoryResponseModel.doctorNameObj ?? "")
.toText14(isBold: true, maxlines: 1)
.toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
(patientAppointmentHistoryResponseModel.clinicName ?? "")
.toText12(maxLine: 1, fontWeight: FontWeight.w500, color: AppColors.greyTextColor)
.toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
@ -78,7 +86,7 @@ class MedicalFileAppointmentCard extends StatelessWidget {
Row(
children: [
myAppointmentsViewModel.isMyAppointmentsLoading
? Container().toShimmer2(isShow: true, height: 40.h, width: 100.h, radius: 12.h)
? Container().toShimmer2(isShow: true, height: 40.h, width: 100.w, radius: 12.r)
: Expanded(
flex: 6,
child: AppointmentType.isArrived(patientAppointmentHistoryResponseModel)
@ -95,37 +103,38 @@ class MedicalFileAppointmentCard extends StatelessWidget {
// widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
},
backgroundColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.15),
backgroundColor:
AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.15),
borderColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01),
textColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
fontSize: 14,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h,
icon: AppointmentType.getNextActionIcon(patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
iconSize: 14.h,
).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
),
SizedBox(width: 8.h),
SizedBox(width: 8.w),
Expanded(
flex: 2,
child: Container(
height: 40.h,
width: 40.h,
width: 40.w,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor,
borderRadius: 10.h,
borderRadius: 10.r,
),
child: Padding(
padding: EdgeInsets.all(10.h),
padding: EdgeInsets.all(10.w),
child: Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
iconColor: AppColors.whiteColor,
icon: AppAssets.forward_arrow_icon_small,
width: 40.h,
width: 40.w,
height: 40.h,
fit: BoxFit.contain,
),
@ -147,7 +156,7 @@ class MedicalFileAppointmentCard extends StatelessWidget {
],
),
],
).paddingAll(16.h),
).paddingAll(16.w),
),
],
);
@ -163,8 +172,8 @@ class MedicalFileAppointmentCard extends StatelessWidget {
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.primaryRedColor,
@ -178,10 +187,10 @@ class MedicalFileAppointmentCard 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.symmetric(horizontal: 10.w),
height: 40.h,
icon: AppAssets.rebook_appointment_icon,
iconColor: AppColors.blackColor,

@ -69,7 +69,7 @@ class AppCustomChipWidget extends StatelessWidget {
label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: 0, color: textColor),
padding: padding,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
labelPadding: labelPadding ?? EdgeInsetsDirectional.only(start: 5.h, end: deleteIcon?.isNotEmpty == true ? 2.h : 8.h),
labelPadding: labelPadding ?? EdgeInsetsDirectional.only(start: 2.w, end: deleteIcon?.isNotEmpty == true ? 2.w : 8.w),
backgroundColor: backgroundColor,
shape: shape ??
SmoothRectangleBorder(
@ -98,7 +98,7 @@ class AppCustomChipWidget extends StatelessWidget {
smoothness: 10,
side: BorderSide(color: AppColors.transparent, width: 1.5),
),
labelPadding: EdgeInsetsDirectional.only(start: 8.h, end: deleteIcon?.isNotEmpty == true ? -2.h : 8.h),
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,

Loading…
Cancel
Save