HHC in Progress

pull/98/head
faizatflutter 3 months ago
parent 95bd2a2a7e
commit fe00447483

@ -838,13 +838,19 @@ class ApiConsts {
static final String createAdvancePayments = 'Services/Patients.svc/REST/HIS_CreateAdvancePayment';
static final String addAdvanceNumberRequest = 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest';
// RC CMC ServIces
// RC COMPREHENSIVE MEDICAL CHECKUP ServIces
static final String allCMCOrdersRc = 'api/cmc/list';
static final String allCMCServicesRc = 'api/cmc/getallcmc';
static final String updateCMCOrder = 'api/cmc/update';
static final String addCMCOrder = 'api/cmc/add';
static final String getHospitalsList = 'Services/Lists.svc/REST/GetProject';
// RC HOME HEALTHCARE ServIces
static final String allHHCOrdersRc = 'api/hhc/list';
static final String allHHCServicesRc = 'api/HHC/getallhhc';
static final String updateHHCOrder = 'api/hhc/update';
static final String addHHCOrder = 'api/HHC/add';
// ************ static values for Api ****************
static final double appVersionID = 20.0;
static final int appChannelId = 3;

@ -1,9 +1,8 @@
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/extensions/int_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:shimmer/shimmer.dart';
import 'package:sizer/sizer.dart';
import 'package:smooth_corner/smooth_corner.dart';
@ -19,7 +18,8 @@ extension WidgetExtensions on Widget {
Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this);
Widget paddingSymmetrical(double horizontal, double vertical) => Padding(padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this);
Widget paddingSymmetrical(double horizontal, double vertical) =>
Padding(padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this);
Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) =>
Padding(padding: EdgeInsetsDirectional.only(start: left, end: right, top: top, bottom: bottom), child: this);
@ -99,7 +99,7 @@ extension WidgetExtensions on Widget {
bool disablePadding = false,
double radius = 20,
Color? color,
Color borderColor = AppColors.buttonColor,
Color? borderColor,
bool disableWidth = false,
bool isAlignment = false}) {
return Container(
@ -110,7 +110,7 @@ extension WidgetExtensions on Widget {
),
color: color,
border: Border.all(
color: borderColor,
color: borderColor ?? Colors.transparent,
width: disableWidth ? 2 : 1,
),
),

@ -13,12 +13,18 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class HmgServicesRepo {
Future<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllCmcOrders();
Future<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllComprehensiveCheckupOrders();
Future<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllHomeHealthCareCheckupOrders();
Future<Either<Failure, GenericApiModel<bool>>> updateCmcPresOrder(OrderUpdateRequestModel requestModel);
Future<Either<Failure, GenericApiModel<bool>>> updateHhcPresOrder(OrderUpdateRequestModel requestModel);
Future<Either<Failure, GenericApiModel<List<GetCMCServicesResponseModel>>>> getAllCmcServices({required int patientID});
Future<Either<Failure, GenericApiModel<List<GetCMCServicesResponseModel>>>> getAllHhcServices({required int patientID});
Future<Either<Failure, GenericApiModel<List<HospitalsModel>>>> getHospitalsList();
Future<Either<Failure, GenericApiModel<int>>> addCmcOrder({
@ -26,6 +32,12 @@ abstract class HmgServicesRepo {
required int orderServiceID,
required List<PatientERCMCInsertServicesList> services,
});
Future<Either<Failure, GenericApiModel<int>>> addHhcOrder({
required int projectID,
required int orderServiceID,
required List<PatientERCMCInsertServicesList> services,
});
}
class HmgServicesRepoImp implements HmgServicesRepo {
@ -35,7 +47,7 @@ class HmgServicesRepoImp implements HmgServicesRepo {
HmgServicesRepoImp({required this.apiClient, required this.loggerService});
@override
Future<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllCmcOrders() async {
Future<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllComprehensiveCheckupOrders() async {
Map<String, dynamic> requestBody = {};
try {
@ -93,6 +105,65 @@ class HmgServicesRepoImp implements HmgServicesRepo {
}
}
@override
Future<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllHomeHealthCareCheckupOrders() async {
Map<String, dynamic> requestBody = {};
try {
GenericApiModel<List<GetCMCAllOrdersResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.allHHCOrdersRc,
isRCService: true,
body: requestBody,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
loggerService.logError("HHC Orders API Failed: $error, Status: $statusCode");
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
List<GetCMCAllOrdersResponseModel> cmcOrdersList = [];
// Log the full response for debugging
// Extract MessageStatus and ErrorEndUserMessage from root level
final apiErrorMessage = response['ErrorEndUserMessage'] as String?;
// Parse the response array
if (response['response'] != null && response['response'] is List) {
final ordersList = response['response'] as List;
for (var orderJson in ordersList) {
if (orderJson is Map<String, dynamic>) {
try {
cmcOrdersList.add(GetCMCAllOrdersResponseModel.fromJson(orderJson));
} catch (e) {
loggerService.logError("Error parsing individual order: ${e.toString()}");
}
}
}
}
apiResponse = GenericApiModel<List<GetCMCAllOrdersResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: apiErrorMessage ?? errorMessage,
data: cmcOrdersList,
);
} catch (e) {
loggerService.logError("Error parsing HHC orders: ${e.toString()}");
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
loggerService.logError("Unknown error in getAllHHCOrders: ${e.toString()}");
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<GetCMCServicesResponseModel>>>> getAllCmcServices({required int patientID}) async {
Map<String, dynamic> requestBody = {};
@ -146,6 +217,59 @@ class HmgServicesRepoImp implements HmgServicesRepo {
}
}
@override
Future<Either<Failure, GenericApiModel<List<GetCMCServicesResponseModel>>>> getAllHhcServices({required int patientID}) async {
Map<String, dynamic> requestBody = {};
try {
GenericApiModel<List<GetCMCServicesResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
'${ApiConsts.allHHCServicesRc}?patientID=$patientID',
isRCService: true,
isAllowAny: true,
body: requestBody,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
loggerService.logError("HHC Services API Failed: $error, Status: $statusCode");
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
List<GetCMCServicesResponseModel> hhcServicesList = [];
if (response['response'] != null && response['response'] is List) {
final servicesList = response['response'] as List;
for (var serviceJson in servicesList) {
if (serviceJson is Map<String, dynamic>) {
hhcServicesList.add(GetCMCServicesResponseModel.fromJson(serviceJson));
}
}
}
apiResponse = GenericApiModel<List<GetCMCServicesResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
data: hhcServicesList,
);
} catch (e) {
loggerService.logError("Error parsing HHC services: ${e.toString()}");
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
log("Unknown error in getAllHhcServices: ${e.toString()}");
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<bool>>> updateCmcPresOrder(OrderUpdateRequestModel requestModel) async {
try {
@ -186,6 +310,46 @@ class HmgServicesRepoImp implements HmgServicesRepo {
}
}
@override
Future<Either<Failure, GenericApiModel<bool>>> updateHhcPresOrder(OrderUpdateRequestModel requestModel) async {
try {
GenericApiModel<bool>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.updateHHCOrder,
isRCService: true,
body: requestModel.toJson(),
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
loggerService.logError("Update HHC Order API Failed: $error, Status: $statusCode");
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<bool>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
data: true,
);
loggerService.logInfo("HHC Order updated successfully: PresOrderID=${requestModel.presOrderID}");
} catch (e) {
loggerService.logError("Error processing update HHC order response: ${e.toString()}");
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
loggerService.logError("Unknown error in updateHhcPresOrder: ${e.toString()}");
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<HospitalsModel>>>> getHospitalsList() async {
Map<String, dynamic> requestBody = {};
@ -301,4 +465,58 @@ class HmgServicesRepoImp implements HmgServicesRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<int>>> addHhcOrder({
required int projectID,
required int orderServiceID,
required List<PatientERCMCInsertServicesList> services,
}) async {
try {
GenericApiModel<int>? apiResponse;
Failure? failure;
final requestBody = {
'ProjectID': projectID,
'OrderServiceID': orderServiceID,
'procedures': services.map((service) => service.toJson()).toList(),
};
await apiClient.post(
ApiConsts.addHHCOrder,
isRCService: true,
body: requestBody,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
loggerService.logError("Add HHC Order API Failed: $error, Status: $statusCode");
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
int requestId = 0;
if (response is Map) {
requestId = response['response'];
}
try {
apiResponse = GenericApiModel<int>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
data: requestId,
);
loggerService.logInfo("HHC Order added successfully: ProjectID=$projectID, OrderServiceID=$orderServiceID");
} catch (e) {
loggerService.logError("Error processing add HHC order response: ${e.toString()}");
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
loggerService.logError("Unknown error in addHhcOrder: ${e.toString()}");
return Left(UnknownFailure(e.toString()));
}
}
}

@ -20,17 +20,31 @@ class HmgServicesViewModel extends ChangeNotifier {
bool isUpdatingOrder = false;
bool isHospitalListLoading = false;
// HHC specific loading states
bool isHhcOrdersLoading = false;
bool isHhcServicesLoading = false;
List<GetCMCAllOrdersResponseModel> cmcOrdersList = [];
List<GetCMCServicesResponseModel> cmcServicesList = [];
List<HospitalsModel> hospitalsList = [];
List<HospitalsModel> filteredHospitalsList = [];
HospitalsModel? selectedHospital;
// HHC specific lists
List<GetCMCAllOrdersResponseModel> hhcOrdersList = [];
List<GetCMCServicesResponseModel> hhcServicesList = [];
// CMC order creation state
HospitalsModel? selectedHospitalForOrder;
GetCMCServicesResponseModel? selectedServiceForOrder;
Future<void> getOrdersList() async {
// HHC order creation state (no hospital selection needed for home healthcare)
GetCMCServicesResponseModel? selectedServiceForHhcOrder;
// HHC multiple services selection
List<GetCMCServicesResponseModel> selectedHhcServices = [];
Future<void> getCmcOrdersList() async {
cmcOrdersList.clear();
isCmcOrdersLoading = true;
notifyListeners();
@ -60,7 +74,7 @@ class HmgServicesViewModel extends ChangeNotifier {
isCmcOrdersLoading = true;
notifyListeners();
final result = await hmgServicesRepo.getAllCmcOrders();
final result = await hmgServicesRepo.getAllComprehensiveCheckupOrders();
result.fold(
(failure) async {
@ -290,4 +304,212 @@ class HmgServicesViewModel extends ChangeNotifier {
return requestId;
}
// ******************* HOME HEALTHCARE APIs ********************
Future<void> getHhcOrdersList() async {
hhcOrdersList.clear();
isHhcOrdersLoading = true;
notifyListeners();
await getAllHhcOrders();
}
Future<void> getAllHhcOrders({
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
isHhcOrdersLoading = true;
notifyListeners();
final result = await hmgServicesRepo.getAllHomeHealthCareCheckupOrders();
result.fold(
(failure) async {
isHhcOrdersLoading = false;
notifyListeners();
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
onError(failure.toString());
}
},
(apiResponse) {
isHhcOrdersLoading = false;
if (apiResponse.messageStatus == 1) {
hhcOrdersList = apiResponse.data ?? [];
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? 'Unknown error');
}
}
},
);
}
Future<void> getAllHhcServices({required int patientID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
isHhcServicesLoading = true;
notifyListeners();
final result = await hmgServicesRepo.getAllHhcServices(patientID: patientID);
result.fold(
(failure) async {
isHhcServicesLoading = false;
notifyListeners();
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
onError(failure.toString());
}
},
(apiResponse) {
isHhcServicesLoading = false;
if (apiResponse.messageStatus == 1) {
hhcServicesList = apiResponse.data ?? [];
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? 'Unknown error');
}
}
},
);
}
Future<bool> updateHhcPresOrder({
required OrderUpdateRequestModel requestModel,
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
isUpdatingOrder = true;
notifyListeners();
final result = await hmgServicesRepo.updateHhcPresOrder(requestModel);
bool success = false;
result.fold(
(failure) async {
isUpdatingOrder = false;
notifyListeners();
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
onError(failure.toString());
}
},
(apiResponse) {
isUpdatingOrder = false;
if (apiResponse.messageStatus == 1) {
success = true;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? 'Unknown error');
}
}
},
);
return success;
}
Future<int?> addHhcOrder({
required int projectID,
required int orderServiceID,
required List<PatientERCMCInsertServicesList> services,
Function(int)? onSuccess,
Function(String)? onError,
}) async {
isUpdatingOrder = true;
notifyListeners();
final result = await hmgServicesRepo.addHhcOrder(
projectID: projectID,
orderServiceID: orderServiceID,
services: services,
);
int requestId = 0;
result.fold(
(failure) async {
isUpdatingOrder = false;
notifyListeners();
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
onError(failure.toString());
}
},
(apiResponse) {
isUpdatingOrder = false;
if (apiResponse.messageStatus == 1) {
requestId = apiResponse.data ?? 0;
notifyListeners();
if (onSuccess != null) {
onSuccess(requestId);
}
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? 'Unknown error');
}
}
},
);
return requestId;
}
// HHC Order management methods (no hospital selection for home healthcare)
void setSelectedServiceForHhcOrder(GetCMCServicesResponseModel? service) {
selectedServiceForHhcOrder = service;
notifyListeners();
}
void clearHhcOrderSelection() {
selectedServiceForHhcOrder = null;
selectedHhcServices.clear();
notifyListeners();
}
bool get isHhcOrderReadyToConfirm => selectedServiceForHhcOrder != null;
// Multiple HHC services selection methods
void toggleHhcServiceSelection(GetCMCServicesResponseModel service) {
final index = selectedHhcServices.indexWhere((s) => s.iD == service.iD);
if (index != -1) {
selectedHhcServices.removeAt(index);
} else {
selectedHhcServices.add(service);
}
notifyListeners();
}
bool isHhcServiceSelected(GetCMCServicesResponseModel service) {
return selectedHhcServices.any((s) => s.iD == service.iD);
}
double getHhcSelectedServicesTotal() {
double total = 0.0;
for (var service in selectedHhcServices) {
total += (service.priceTotal ?? 0);
}
return total;
}
void clearHhcServicesSelection() {
selectedHhcServices.clear();
notifyListeners();
}
}

@ -30,7 +30,7 @@ class _CmcOrderDetailPageState extends State<CmcOrderDetailPage> {
super.initState();
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
scheduleMicrotask(() async {
await hmgServicesViewModel.getOrdersList();
await hmgServicesViewModel.getCmcOrdersList();
});
}

@ -31,6 +31,16 @@ class ServicesPage extends StatelessWidget {
textColor: AppColors.blackColor,
route: AppRoutes.comprehensiveCheckupPage,
),
HmgServicesComponentModel(
12,
"Home Health Care".needTranslation,
"".needTranslation,
AppAssets.emergency_services_icon,
true,
bgColor: AppColors.bgGreenColor,
textColor: AppColors.blackColor,
route: AppRoutes.homeHealthCarePage,
),
];
@override

@ -0,0 +1,248 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
import 'package:hmg_patient_app_new/presentation/home_health_care/widgets/hhc_ui_selection_helper.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/chip/app_custom_chip_widget.dart';
import 'package:provider/provider.dart';
class HhcOrderDetailPage extends StatefulWidget {
const HhcOrderDetailPage({super.key});
@override
State<HhcOrderDetailPage> createState() => _HhcOrderDetailPageState();
}
class _HhcOrderDetailPageState extends State<HhcOrderDetailPage> {
@override
void initState() {
super.initState();
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
scheduleMicrotask(() async {
await hmgServicesViewModel.getAllHhcOrders();
});
}
Color _getStatusColor(int? statusId) {
switch (statusId) {
case 1: // Pending
return const Color(0xffCC9B14);
case 2: // Processing
return const Color(0xff2E303A);
case 3: // Completed
return const Color(0xff359846);
case 4: // Cancelled
case 6: // Rejected
case 7: // Rejected
return const Color(0xffD02127);
default:
return AppColors.greyColor;
}
}
String _formatDate(String? dateString) {
if (dateString == null) return '';
try {
final date = DateTime.parse(dateString);
return DateFormat('MMM dd, yyyy').format(date);
} catch (e) {
return dateString;
}
}
Widget _buildLoadingShimmer() {
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 3,
separatorBuilder: (_, __) => SizedBox(height: 12.h),
itemBuilder: (context, index) {
return _buildOrderCard(GetCMCAllOrdersResponseModel(), isLoading: true);
},
);
}
Widget _buildOrderCard(GetCMCAllOrdersResponseModel order, {bool isLoading = false}) {
final statusColor = _getStatusColor(order.statusId);
final canCancel = order.statusId == 1 || order.statusId == 2;
return AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
),
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Status and Date Row
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h),
decoration: BoxDecoration(
color: statusColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8.r),
),
child: (isLoading ? "Processing" : order.statusText ?? '')
.toText12(
color: statusColor,
fontWeight: FontWeight.w600,
)
.toShimmer2(isShow: isLoading),
),
SizedBox(width: 8.w),
(isLoading ? "Jan 15, 2024" : _formatDate(order.created))
.toText12(
color: AppColors.textColorLight,
fontWeight: FontWeight.w500,
)
.toShimmer2(isShow: isLoading),
],
),
SizedBox(height: 16.h),
// Request ID
Row(
children: [
if (!isLoading) ...[
"Request ID:".needTranslation.toText14(
color: AppColors.textColorLight,
weight: FontWeight.w500,
),
SizedBox(width: 4.w),
],
(isLoading ? "12345" : "${order.iD ?? '-'}").toText16(isBold: true).toShimmer2(isShow: isLoading),
],
),
SizedBox(height: 12.h),
// Chips for Hospital, Service, and Amount
Wrap(
spacing: 6.w,
runSpacing: 6.h,
children: [
// Service
if (order.serviceText != null || isLoading)
AppCustomChipWidget(
icon: AppAssets.servicesBottom,
labelText: isLoading ? "Service Name" : order.serviceText ?? '-',
).toShimmer2(isShow: isLoading),
],
),
// Cancel Button
if (canCancel || isLoading) ...[
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: "Cancel Order".needTranslation,
onPressed: isLoading ? () {} : () => HhcUiSelectionHelper.showCancelConfirmationDialog(context: context, order: order),
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 14.f,
fontWeight: FontWeight.w600,
borderRadius: 10.r,
height: 44.h,
).toShimmer2(isShow: isLoading),
),
],
),
]
],
),
),
);
}
Widget _buildEmptyState() {
return Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 40.h),
child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 12.r,
hasShadow: false,
),
child: Utils.getNoDataWidget(
context,
noDataText: "You don't have any Home Health Care orders yet.".needTranslation,
isSmallWidget: true,
width: 62.w,
height: 62.h,
),
),
),
);
}
@override
Widget build(BuildContext context) {
return CollapsingListView(
title: "HHC Orders".needTranslation,
isLeading: true,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Consumer<HmgServicesViewModel>(
builder: (context, viewModel, child) {
if (viewModel.isHhcOrdersLoading) {
return _buildLoadingShimmer();
}
if (viewModel.hhcOrdersList.isEmpty) {
return _buildEmptyState();
}
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: viewModel.hhcOrdersList.length,
separatorBuilder: (_, __) => SizedBox(height: 12.h),
itemBuilder: (context, index) {
final order = viewModel.hhcOrdersList.reversed.toList()[index];
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: _buildOrderCard(order),
),
),
);
},
);
},
),
],
).paddingSymmetrical(24.w, 0),
),
);
}
}

@ -0,0 +1,414 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_order_detail_page.dart';
import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_selection_review_page.dart';
import 'package:hmg_patient_app_new/presentation/home_health_care/widgets/hhc_ui_selection_helper.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/routes/custom_page_route.dart';
import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart';
class HhcProceduresPage extends StatefulWidget {
const HhcProceduresPage({super.key});
@override
State<HhcProceduresPage> createState() => _HhcProceduresPageState();
}
class _HhcProceduresPageState extends State<HhcProceduresPage> {
@override
void initState() {
super.initState();
final HmgServicesViewModel hmgServicesViewModel = context.read<HmgServicesViewModel>();
final AppState appState = getIt.get<AppState>();
scheduleMicrotask(() async {
final user = appState.getAuthenticatedUser();
if (user != null) {
// Clear previous selections when entering the page
hmgServicesViewModel.clearHhcServicesSelection();
await hmgServicesViewModel.getAllHhcOrders();
await hmgServicesViewModel.getAllHhcServices(patientID: user.patientId ?? 0);
}
});
}
GetCMCAllOrdersResponseModel? _getPendingOrder(List<GetCMCAllOrdersResponseModel> orders) {
if (orders.isEmpty) return null;
// Find pending or processing orders (status 1 or 2)
for (var order in orders) {
if (order.statusId == 1 || order.statusId == 2) {
return order;
}
}
return null;
}
Widget _buildPendingOrderCard(GetCMCAllOrdersResponseModel order) {
int status = order.statusId ?? 0;
String statusDisp = order.statusText ?? "";
Color statusColor;
if (status == 1) {
// pending
statusColor = AppColors.statusPendingColor;
} else if (status == 2) {
// processing
statusColor = AppColors.statusProcessingColor;
} else if (status == 3) {
// completed
statusColor = AppColors.statusCompletedColor;
} else {
// cancel / rejected
statusColor = AppColors.statusRejectedColor;
}
final canCancel = order.statusId == 1 || order.statusId == 2;
return Container(
width: double.infinity,
margin: EdgeInsets.all(16.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
),
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Status and Date Row
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h),
decoration: BoxDecoration(
color: statusColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8.r),
),
child: statusDisp.toText12(
color: statusColor,
fontWeight: FontWeight.w600,
),
),
SizedBox(width: 8.w),
if (order.created != null)
DateFormat('MMM dd, yyyy').format(DateTime.parse(order.created!)).toText12(
color: AppColors.textColorLight,
fontWeight: FontWeight.w500,
),
],
),
SizedBox(height: 16.h),
// Request ID
Row(
children: [
"Request ID:".needTranslation.toText14(color: AppColors.textColorLight, weight: FontWeight.w500),
SizedBox(width: 4.w),
"${order.iD ?? '-'}".toText16(isBold: true),
],
),
SizedBox(height: 12.h),
// Info message
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: AppColors.infoBannerBgColor,
borderRadius: BorderRadius.circular(10.r),
border: Border.all(
color: AppColors.infoBannerBorderColor,
width: 1,
),
),
child: Row(
children: [
Icon(
Icons.info_outline,
size: 20.w,
color: AppColors.infoBannerIconColor,
),
SizedBox(width: 8.w),
Expanded(
child: "You have a pending order. Please wait for it to be processed.".needTranslation.toText12(
color: AppColors.infoBannerTextColor,
fontWeight: FontWeight.w500,
),
),
],
),
),
if (canCancel) ...[
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: "Cancel Order".needTranslation,
onPressed: () => HhcUiSelectionHelper.showCancelConfirmationDialog(context: context, order: order),
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 14.f,
fontWeight: FontWeight.w600,
borderRadius: 10.r,
height: 44.h,
),
),
],
),
]
],
),
),
);
}
Widget _buildServiceSelectionList(List<GetCMCServicesResponseModel> services) {
if (services.isEmpty) {
return Center(
child: Padding(
padding: EdgeInsets.all(24.h),
child: Text(
'No services available'.needTranslation,
style: TextStyle(
fontSize: 16.h,
color: AppColors.greyTextColor,
),
),
),
);
}
return Consumer<HmgServicesViewModel>(
builder: (context, viewModel, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 8.h),
if (viewModel.selectedHhcServices.isNotEmpty) ...[
SizedBox(height: 16.h),
Container(
margin: EdgeInsets.symmetric(horizontal: 16.w),
padding: EdgeInsets.all(16.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.primaryRedColor.withValues(alpha: 0.1),
borderRadius: 16.r,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Selected Services".needTranslation.toText12(
color: AppColors.textColorLight,
fontWeight: FontWeight.w600,
),
"${viewModel.selectedHhcServices.length} service(s) selected".toText14(
isBold: true,
weight: FontWeight.bold,
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"Total Amount".needTranslation.toText12(
color: AppColors.textColorLight,
fontWeight: FontWeight.w600,
),
Utils.getPaymentAmountWithSymbol(
viewModel.getHhcSelectedServicesTotal().toStringAsFixed(2).toText16(
isBold: true,
weight: FontWeight.bold,
color: AppColors.primaryRedColor,
),
AppColors.primaryRedColor,
14,
isSaudiCurrency: true,
),
],
),
],
),
),
],
SizedBox(height: 16.h),
Text(
'Select Services'.needTranslation,
style: TextStyle(
fontSize: 20.h,
fontWeight: FontWeight.w700,
color: AppColors.blackColor,
letterSpacing: -0.8,
),
).paddingOnly(left: 16.w, right: 16.w),
SizedBox(height: 12.h),
ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16.w),
itemCount: services.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
final service = services[index];
final isSelected = viewModel.isHhcServiceSelected(service);
final isArabic = getIt.get<AppState>().isArabic();
final serviceName = isArabic ? (service.textN ?? service.text ?? '') : (service.text ?? '');
return AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
margin: EdgeInsets.only(bottom: 12.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 16.r,
hasShadow: true,
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () => viewModel.toggleHhcServiceSelection(service),
borderRadius: BorderRadius.circular(16.r),
child: Container(
padding: EdgeInsets.all(16.w),
child: Row(
children: [
Checkbox(
value: isSelected,
onChanged: (v) => viewModel.toggleHhcServiceSelection(service),
activeColor: AppColors.primaryRedColor,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
),
SizedBox(width: 12.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
serviceName.toText16(
weight: FontWeight.w400,
color: AppColors.blackColor,
maxlines: 2,
),
],
),
),
],
),
),
),
),
);
},
),
// Summary Section
],
);
},
);
}
void _proceedWithSelectedService() {
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
if (hmgServicesViewModel.selectedHhcServices.isNotEmpty) {
hmgServicesViewModel.setSelectedServiceForHhcOrder(hmgServicesViewModel.selectedHhcServices.first);
Navigator.of(context).pushReplacement(
CustomPageRoute(
page: HhcSelectionReviewPage(selectedServices: hmgServicesViewModel.selectedHhcServices),
direction: AxisDirection.left,
),
);
}
}
Widget _buildLoadingShimmer() {
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.all(16.w),
itemCount: 10,
separatorBuilder: (_, __) => SizedBox(height: 12.h),
itemBuilder: (context, index) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
height: 80.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.r),
),
),
);
},
);
}
@override
Widget build(BuildContext context) {
return CollapsingListView(
title: "Home Health Care".needTranslation,
history: () => Navigator.of(context).push(CustomPageRoute(page: HhcOrderDetailPage(), direction: AxisDirection.up)),
bottomChild: Consumer<HmgServicesViewModel>(
builder: (context, hmgServicesViewModel, child) {
if (hmgServicesViewModel.isHhcOrdersLoading || hmgServicesViewModel.isHhcServicesLoading) return SizedBox.shrink();
final pendingOrder = _getPendingOrder(hmgServicesViewModel.hhcOrdersList);
if (pendingOrder == null && hmgServicesViewModel.selectedHhcServices.isNotEmpty) {
return SafeArea(
top: false,
child: Padding(
padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 12.h),
child: CustomButton(
borderWidth: 0,
text: "Next".needTranslation,
onPressed: _proceedWithSelectedService,
textColor: AppColors.whiteColor,
borderRadius: 12.r,
borderColor: Colors.transparent,
padding: EdgeInsets.symmetric(vertical: 14.h),
),
),
);
}
return SizedBox.shrink();
},
),
child: Consumer<HmgServicesViewModel>(
builder: (context, hmgServicesViewModel, child) {
if (hmgServicesViewModel.isHhcOrdersLoading || hmgServicesViewModel.isHhcServicesLoading) {
return _buildLoadingShimmer();
}
final pendingOrder = _getPendingOrder(hmgServicesViewModel.hhcOrdersList);
if (pendingOrder != null) {
return _buildPendingOrderCard(pendingOrder);
} else {
return _buildServiceSelectionList(hmgServicesViewModel.hhcServicesList);
}
},
),
);
}
}

@ -0,0 +1,244 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.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';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:maps_launcher/maps_launcher.dart';
import 'package:provider/provider.dart';
class HhcSelectionReviewPage extends StatefulWidget {
final List<GetCMCServicesResponseModel> selectedServices;
const HhcSelectionReviewPage({super.key, required this.selectedServices});
@override
State<HhcSelectionReviewPage> createState() => _HhcSelectionReviewPageState();
}
class _HhcSelectionReviewPageState extends State<HhcSelectionReviewPage> {
@override
void initState() {
super.initState();
// Initialize ViewModel state with selected services
WidgetsBinding.instance.addPostFrameCallback((_) {
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
if (widget.selectedServices.isNotEmpty) {
hmgServicesViewModel.setSelectedServiceForHhcOrder(widget.selectedServices.first);
}
});
}
@override
Widget build(BuildContext context) {
final appState = getIt.get<AppState>();
final isArabic = appState.isArabic();
return CollapsingListView(
title: "Summary".needTranslation,
bottomChild: _buildBottomButton(),
child: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSelectedServicesCard(isArabic),
SizedBox(height: 16.h),
],
),
),
);
}
Widget _buildSelectedServicesCard(bool isArabic) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 16.r,
),
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Selected Services".needTranslation.toText14(
weight: FontWeight.w600,
color: AppColors.greyTextColor,
letterSpacing: -0.4,
),
SizedBox(height: 12.h),
...widget.selectedServices.map((service) {
final serviceName = isArabic ? (service.textN ?? service.text ?? '') : (service.text ?? '');
final price = service.priceTotal ?? 0.0;
return Padding(
padding: EdgeInsets.only(bottom: 4.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: serviceName.toText14(
weight: FontWeight.w600,
color: AppColors.blackColor,
letterSpacing: -0.5,
maxlines: 2,
),
),
],
),
);
}),
],
),
);
}
Widget _buildBottomButton() {
return SafeArea(
top: false,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
decoration: BoxDecoration(
color: AppColors.whiteColor,
boxShadow: [
BoxShadow(
color: Color.fromARGB(13, 0, 0, 0),
blurRadius: 8,
offset: Offset(0, -2),
),
],
),
child: CustomButton(
text: "Confirm".needTranslation,
onPressed: _handleConfirm,
textColor: AppColors.whiteColor,
backgroundColor: AppColors.successColor,
borderRadius: 12.r,
borderColor: Colors.transparent,
borderWidth: 0,
padding: EdgeInsets.symmetric(vertical: 14.h),
),
),
);
}
void _launchDirections(HospitalsModel selectedHospital) {
final double lat = double.parse(selectedHospital.latitude ?? "0.0");
final double lng = double.parse(selectedHospital.longitude ?? "0.0");
if (lat != 0.0 && lng != 0.0) {
MapsLauncher.launchCoordinates(
lat,
lng,
selectedHospital.name ?? "Hospital",
);
}
}
showSuccessBottomSheet(int requestId, HmgServicesViewModel hmgServicesViewModel) {
return showCommonBottomSheetWithoutHeight(
context,
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
Utils.getSuccessWidget(loadingText: "Your request has been successfully submitted.".needTranslation),
Row(
children: [
"Here is your request #: ".needTranslation.toText14(
color: AppColors.textColorLight,
weight: FontWeight.w500,
),
SizedBox(width: 4.w),
("$requestId").toText16(isBold: true),
],
),
SizedBox(height: 24.h),
Row(
children: [
Expanded(
child: CustomButton(
height: 56.h,
text: LocaleKeys.ok.tr(),
onPressed: () {
context.pop();
context.pop();
hmgServicesViewModel.getAllHhcOrders();
},
textColor: AppColors.whiteColor,
),
),
],
),
],
),
),
isCloseButtonVisible: false,
isDismissible: false,
isFullScreen: false,
);
}
void _handleConfirm() {
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
final appState = getIt.get<AppState>();
return showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: "Are you sure you want to submit this request?".needTranslation,
isShowActionButtons: true,
onCancelTap: () {
Navigator.pop(context);
},
onConfirmTap: () async {
Navigator.pop(context);
LoaderBottomSheet.showLoader();
// Create the services list from all selected services
final servicesList = widget.selectedServices.map((selectedService) {
return PatientERCMCInsertServicesList(
recordID: selectedService.iD,
serviceID: selectedService.serviceID,
selectedServiceName: selectedService.text,
selectedServiceNameAR: selectedService.textN,
price: selectedService.price,
vAT: selectedService.priceVAT,
totalPrice: selectedService.priceTotal,
);
}).toList();
// For HHC, we don't need hospital selection, use a default projectID or 0
await hmgServicesViewModel.addHhcOrder(
projectID: 0,
// HHC doesn't require hospital/project selection
orderServiceID: widget.selectedServices.first.orderServiceID ?? 4,
// HHC service ID
services: servicesList,
onSuccess: (requestId) {
LoaderBottomSheet.hideLoader();
showSuccessBottomSheet(requestId, hmgServicesViewModel);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
},
);
}),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
}

@ -0,0 +1,90 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
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/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:provider/provider.dart';
class HhcUiSelectionHelper {
static void showCancelConfirmationDialog({
required BuildContext context,
required GetCMCAllOrdersResponseModel order,
}) {
final HmgServicesViewModel hmgServicesViewModel = context.read<HmgServicesViewModel>();
return showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: "Are you sure you want to cancel this order?".needTranslation,
isShowActionButtons: true,
onCancelTap: () {
Navigator.pop(context);
},
onConfirmTap: () async {
Navigator.pop(context);
LoaderBottomSheet.showLoader();
final requestModel = OrderUpdateRequestModel(
presOrderID: order.iD,
rejectionReason: "Cancelled by user",
presOrderStatus: 4, // Cancelled status
editedBy: 3,
);
await hmgServicesViewModel.updateHhcPresOrder(
requestModel: requestModel,
onSuccess: (_) async {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
Utils.getSuccessWidget(loadingText: "Order has been cancelled successfully".needTranslation),
SizedBox(height: 24.h),
Row(
children: [
Expanded(
child: CustomButton(
height: 56.h,
text: LocaleKeys.ok.tr(),
onPressed: () {
context.pop();
hmgServicesViewModel.getAllHhcOrders();
},
textColor: AppColors.whiteColor,
),
),
],
),
],
),
),
isCloseButtonVisible: false,
isDismissible: false,
isFullScreen: false,
);
},
onError: (error) {
LoaderBottomSheet.hideLoader();
},
);
},
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
}

@ -1,23 +0,0 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class ServicesPage extends StatelessWidget {
const ServicesPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
appBar: AppBar(
title: const Text('Appointments'),
backgroundColor: AppColors.bgScaffoldColor,
),
body: const Center(
child: Text(
'Appointments Page',
style: TextStyle(fontSize: 24),
),
),
);
}
}

@ -5,6 +5,7 @@ import 'package:hmg_patient_app_new/presentation/authentication/register_step2.d
import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/comprehensive_checkup_page.dart';
import 'package:hmg_patient_app_new/presentation/e_referral/e_referral_page_home.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_procedures_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/splashPage.dart';
@ -17,6 +18,7 @@ class AppRoutes {
static const String medicalFilePage = '/medicalFilePage';
static const String eReferralPage = '/erReferralPage';
static const String comprehensiveCheckupPage = '/comprehensiveCheckupPage';
static const String homeHealthCarePage = '/homeHealthCarePage';
static Map<String, WidgetBuilder> get routes => {
initialRoute: (context) => SplashPage(),
@ -26,6 +28,7 @@ class AppRoutes {
registerStepTwo: (context) => RegisterNewStep2(),
medicalFilePage: (context) => MedicalFilePage(),
eReferralPage: (context) => EReferralPage(),
comprehensiveCheckupPage: (context) => ComprehensiveCheckupPage()
comprehensiveCheckupPage: (context) => ComprehensiveCheckupPage(),
homeHealthCarePage: (context) => HhcProceduresPage()
};
}

@ -3,21 +3,12 @@ import 'package:flutter/material.dart';
class AppColors {
static const transparent = Colors.transparent;
static const mainPurple = Color(0xFF7954F7);
static const purpleBg = Color(0xFFAEA4FC);
static const deepPurple = Color(0xFF7C65E7);
static const logoColor = Color(0xFF7C65E7);
static const buttonColor = Color(0xFF6A46F5);
static const splashBgColor = Color(0xFF3C355D);
static const lightGray = Color(0xFFF4F5F7);
static const lightPurple = Color(0xFFB7A3E6);
static const scaffoldBgColor = Color(0xFFF8F8F8);
static const bottomSheetBgColor = Color(0xFFF8F8FA);
static const lightGreyEFColor = Color(0xffeaeaff);
static const greyF7Color = Color(0xffF7F7F7);
static const lightGrayColor = Color(0xff808080);
static const buttonGrayColor = Color(0xffF1F1F1);
static const lightPurpleAlpha = Color(0x5AB7A3E6);
// New UI Colors
static const whiteColor = Color(0xFFffffff);

@ -1,7 +1,6 @@
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
extension WithContainer on Widget {
Widget get insideContainer => Container(
@ -26,20 +25,22 @@ class DefaultButton extends StatelessWidget {
final double height;
final double borderRadius;
const DefaultButton(this.text, this.onPress,
{Key? key,
this.color,
this.isTextExpanded = true,
this.svgIcon,
this.disabledColor,
this.count = 0,
this.textColor = Colors.white,
this.iconData,
this.fontSize,
this.colors,
this.height = 50,
this.borderRadius = 100})
: super(key: key);
const DefaultButton(
this.text,
this.onPress, {
super.key,
this.color,
this.isTextExpanded = true,
this.svgIcon,
this.disabledColor,
this.count = 0,
this.textColor = Colors.white,
this.iconData,
this.fontSize,
this.colors,
this.height = 50,
this.borderRadius = 100,
});
@override
Widget build(BuildContext context) {
@ -48,30 +49,20 @@ class DefaultButton extends StatelessWidget {
child: Container(
height: height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
gradient: onPress == null
? LinearGradient(
colors: <Color>[
disabledColor ?? const Color(0xffEAEAEA),
disabledColor ?? const Color(0xffEAEAEA),
],
)
: LinearGradient(
transform: const GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: colors ??
<Color>[
AppColors.buttonColor,
AppColors.buttonColor,
],
),
),
borderRadius: BorderRadius.circular(borderRadius),
gradient: onPress == null
? LinearGradient(
colors: <Color>[
disabledColor ?? const Color(0xffEAEAEA),
disabledColor ?? const Color(0xffEAEAEA),
],
)
: null),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (iconData != null) Icon(iconData, color: textColor),
if (svgIcon != null) SvgPicture.asset(svgIcon ?? "", color: textColor),
if (svgIcon != null) SvgPicture.asset(svgIcon ?? ""),
if (!isTextExpanded)
Padding(
padding: EdgeInsets.only(

@ -15,7 +15,7 @@ class ConfirmDialog extends StatelessWidget {
final VoidCallback? onTap;
final VoidCallback? onCloseTap;
const ConfirmDialog({Key? key, this.title, required this.message, this.okTitle, this.onTap, this.onCloseTap}) : super(key: key);
const ConfirmDialog({super.key, this.title, required this.message, this.okTitle, this.onTap, this.onCloseTap});
@override
Widget build(BuildContext context) {

Loading…
Cancel
Save