Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 13 KiB |
@ -0,0 +1,5 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 10.75C0 4.81294 4.81294 0 10.75 0C15.5683 0 19.597 3.1682 20.9655 7.52526C21.037 7.75307 20.9958 8.00133 20.8545 8.19382C20.7133 8.3863 20.4887 8.5 20.25 8.5H17.75C17.3357 8.5 17 8.16421 17 7.75C17 7.33579 17.3357 7 17.75 7H19.1673C17.7335 3.75655 14.5197 1.5 10.75 1.5C5.64137 1.5 1.5 5.64137 1.5 10.75C1.5 15.8586 5.64133 20 10.75 20C11.1642 20 11.5 20.3358 11.5 20.75C11.5 21.1642 11.1642 21.5 10.75 21.5C4.8129 21.5 0 16.6871 0 10.75Z" fill="white"/>
|
||||
<path d="M10.75 6C11.1642 6 11.5 6.33579 11.5 6.75V10.4393L13.2803 12.2197C13.5732 12.5126 13.5732 12.9874 13.2803 13.2803C12.9874 13.5732 12.5125 13.5732 12.2196 13.2803L10.2196 11.2803C10.079 11.1397 9.99996 10.9489 9.99996 10.75V6.75C9.99996 6.33579 10.3357 6 10.75 6Z" fill="white"/>
|
||||
<path d="M15.2803 14.2197C14.9874 13.9268 14.5126 13.9268 14.2197 14.2197C13.9268 14.5126 13.9268 14.9874 14.2197 15.2803L16.6893 17.75L14.2197 20.2197C13.9268 20.5126 13.9268 20.9874 14.2197 21.2803C14.5126 21.5732 14.9874 21.5732 15.2803 21.2803L17.75 18.8107L20.2197 21.2803C20.5126 21.5732 20.9874 21.5732 21.2803 21.2803C21.5732 20.9874 21.5732 20.5126 21.2803 20.2197L18.8107 17.75L21.2803 15.2803C21.5732 14.9874 21.5732 14.5126 21.2803 14.2197C20.9874 13.9268 20.5126 13.9268 20.2197 14.2197L17.75 16.6893L15.2803 14.2197Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,12 @@
|
||||
/// Default configuration values for PayTabs Payment SDK
|
||||
class PaymentSdkDefaultConfig {
|
||||
static const String profileID = "119730";
|
||||
static const String serverKey = "SWJ9LD22MT-JLJZLBKTLK-WGWTLWGTWR";
|
||||
static const String clientKey = "C7K2DQ-PDDN6B-69B2K7-P9GB9T";
|
||||
static const String defaultCurrency = "SAR";
|
||||
static const double defaultAmount = 10.0;
|
||||
static const String defaultMerchantCountryCode = "SA";
|
||||
static const String defaultMerchantName = "Sulaiman Al Habib Medical Group";
|
||||
static const String defaultMerchantAppleBundleID = "merchant.com.hmgwebservices";
|
||||
static const String defaultMerchantAppleBundleIDUAT = "merchant.com.hmgwebservices.uat";
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
class GetPharmacyInvoicesResponseModel {
|
||||
String? setupId;
|
||||
int? projectID;
|
||||
int? pharmacyProjectID;
|
||||
int? patientID;
|
||||
int? appointmentNo;
|
||||
String? appointmentDate;
|
||||
dynamic appointmentDateN;
|
||||
int? clinicID;
|
||||
int? doctorID;
|
||||
int? invoiceNo;
|
||||
int? status;
|
||||
String? arrivedOn;
|
||||
String? doctorName;
|
||||
String? doctorNameN;
|
||||
String? displayInvoiceNo;
|
||||
String? clinicName;
|
||||
num? decimalDoctorRate;
|
||||
String? doctorImageURL;
|
||||
num? doctorRate;
|
||||
num? patientNumber;
|
||||
String? projectName;
|
||||
dynamic locationID;
|
||||
|
||||
GetPharmacyInvoicesResponseModel(
|
||||
{this.setupId,
|
||||
this.projectID,
|
||||
this.pharmacyProjectID,
|
||||
this.patientID,
|
||||
this.appointmentNo,
|
||||
this.appointmentDate,
|
||||
this.appointmentDateN,
|
||||
this.clinicID,
|
||||
this.doctorID,
|
||||
this.invoiceNo,
|
||||
this.status,
|
||||
this.arrivedOn,
|
||||
this.doctorName,
|
||||
this.doctorNameN,
|
||||
this.displayInvoiceNo,
|
||||
this.clinicName,
|
||||
this.decimalDoctorRate,
|
||||
this.doctorImageURL,
|
||||
this.doctorRate,
|
||||
this.patientNumber,
|
||||
this.projectName, this.locationID});
|
||||
|
||||
GetPharmacyInvoicesResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
setupId = json['SetupId'];
|
||||
projectID = json['ProjectID'];
|
||||
pharmacyProjectID = json['PharmacyProjectID'];
|
||||
patientID = json['PatientID'];
|
||||
appointmentNo = json['AppointmentNo'];
|
||||
appointmentDate = json['AppointmentDate'];
|
||||
appointmentDateN = json['AppointmentDateN'];
|
||||
clinicID = json['ClinicID'];
|
||||
doctorID = json['DoctorID'];
|
||||
invoiceNo = json['InvoiceNo'];
|
||||
status = json['Status'];
|
||||
arrivedOn = json['ArrivedOn'];
|
||||
doctorName = json['DoctorName'];
|
||||
doctorNameN = json['DoctorNameN'];
|
||||
displayInvoiceNo = json['DisplayInvoiceNo'];
|
||||
clinicName = json['ClinicName'];
|
||||
decimalDoctorRate = json['DecimalDoctorRate'];
|
||||
doctorImageURL = json['DoctorImageURL'];
|
||||
doctorRate = json['DoctorRate'];
|
||||
patientNumber = json['PatientNumber'];
|
||||
projectName = json['ProjectName'];
|
||||
locationID = json['LocationId'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['SetupId'] = this.setupId;
|
||||
data['ProjectID'] = this.projectID;
|
||||
data['PharmacyProjectID'] = this.pharmacyProjectID;
|
||||
data['PatientID'] = this.patientID;
|
||||
data['AppointmentNo'] = this.appointmentNo;
|
||||
data['AppointmentDate'] = this.appointmentDate;
|
||||
data['AppointmentDateN'] = this.appointmentDateN;
|
||||
data['ClinicID'] = this.clinicID;
|
||||
data['DoctorID'] = this.doctorID;
|
||||
data['InvoiceNo'] = this.invoiceNo;
|
||||
data['Status'] = this.status;
|
||||
data['ArrivedOn'] = this.arrivedOn;
|
||||
data['DoctorName'] = this.doctorName;
|
||||
data['DoctorNameN'] = this.doctorNameN;
|
||||
data['DisplayInvoiceNo'] = this.displayInvoiceNo;
|
||||
data['ClinicName'] = this.clinicName;
|
||||
data['DecimalDoctorRate'] = this.decimalDoctorRate;
|
||||
data['DoctorImageURL'] = this.doctorImageURL;
|
||||
data['DoctorRate'] = this.doctorRate;
|
||||
data['PatientNumber'] = this.patientNumber;
|
||||
data['ProjectName'] = this.projectName;
|
||||
data['LocationId'] = this.locationID;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
class PaytabsTransactionResponseModel {
|
||||
int? tranTotal;
|
||||
String? transactionReference;
|
||||
String? cartCurrency;
|
||||
String? cartDescription;
|
||||
String? cartID;
|
||||
String? tranCurrency;
|
||||
String? payResponseReturn;
|
||||
bool? isPending;
|
||||
bool? isOnHold;
|
||||
String? token;
|
||||
String? transactionType;
|
||||
bool? isAuthorized;
|
||||
String? trace;
|
||||
dynamic cartAmount;
|
||||
int? merchantId;
|
||||
int? profileId;
|
||||
bool? isProcessed;
|
||||
int? serviceId;
|
||||
PaymentInfo? paymentInfo;
|
||||
bool? isSuccess;
|
||||
|
||||
PaytabsTransactionResponseModel(
|
||||
{this.tranTotal,
|
||||
this.transactionReference,
|
||||
this.cartCurrency,
|
||||
this.cartDescription,
|
||||
this.cartID,
|
||||
this.tranCurrency,
|
||||
this.payResponseReturn,
|
||||
this.isPending,
|
||||
this.isOnHold,
|
||||
this.token,
|
||||
this.transactionType,
|
||||
this.isAuthorized,
|
||||
this.trace,
|
||||
this.cartAmount,
|
||||
this.merchantId,
|
||||
this.profileId,
|
||||
this.isProcessed,
|
||||
this.serviceId,
|
||||
this.paymentInfo,
|
||||
this.isSuccess});
|
||||
|
||||
PaytabsTransactionResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
tranTotal = json['tran_total'];
|
||||
transactionReference = json['transactionReference'];
|
||||
cartCurrency = json['cartCurrency'];
|
||||
cartDescription = json['cartDescription'];
|
||||
cartID = json['cartID'];
|
||||
tranCurrency = json['tran_currency'];
|
||||
payResponseReturn = json['payResponseReturn'];
|
||||
isPending = json['isPending'];
|
||||
isOnHold = json['isOnHold'];
|
||||
token = json['token'];
|
||||
transactionType = json['transactionType'];
|
||||
isAuthorized = json['isAuthorized'];
|
||||
trace = json['trace'];
|
||||
cartAmount = json['cartAmount'];
|
||||
merchantId = json['merchantId'];
|
||||
profileId = json['profileId'];
|
||||
isProcessed = json['isProcessed'];
|
||||
serviceId = json['serviceId'];
|
||||
paymentInfo = json['paymentInfo'] != null
|
||||
? PaymentInfo.fromJson(Map<String, dynamic>.from(json['paymentInfo'] as Map))
|
||||
: null;
|
||||
isSuccess = json['isSuccess'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['tran_total'] = this.tranTotal;
|
||||
data['transactionReference'] = this.transactionReference;
|
||||
data['cartCurrency'] = this.cartCurrency;
|
||||
data['cartDescription'] = this.cartDescription;
|
||||
data['cartID'] = this.cartID;
|
||||
data['tran_currency'] = this.tranCurrency;
|
||||
data['payResponseReturn'] = this.payResponseReturn;
|
||||
data['isPending'] = this.isPending;
|
||||
data['isOnHold'] = this.isOnHold;
|
||||
data['token'] = this.token;
|
||||
data['transactionType'] = this.transactionType;
|
||||
data['isAuthorized'] = this.isAuthorized;
|
||||
data['trace'] = this.trace;
|
||||
data['cartAmount'] = this.cartAmount;
|
||||
data['merchantId'] = this.merchantId;
|
||||
data['profileId'] = this.profileId;
|
||||
data['isProcessed'] = this.isProcessed;
|
||||
data['serviceId'] = this.serviceId;
|
||||
if (this.paymentInfo != null) {
|
||||
data['paymentInfo'] = this.paymentInfo!.toJson();
|
||||
}
|
||||
data['isSuccess'] = this.isSuccess;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class PaymentInfo {
|
||||
String? cardScheme;
|
||||
String? cardType;
|
||||
int? expiryMonth;
|
||||
int? expiryYear;
|
||||
String? paymentDescription;
|
||||
String? paymentMethod;
|
||||
|
||||
PaymentInfo(
|
||||
{this.cardScheme,
|
||||
this.cardType,
|
||||
this.expiryMonth,
|
||||
this.expiryYear,
|
||||
this.paymentDescription,
|
||||
this.paymentMethod});
|
||||
|
||||
PaymentInfo.fromJson(Map<String, dynamic> json) {
|
||||
cardScheme = json['cardScheme'];
|
||||
cardType = json['cardType'];
|
||||
expiryMonth = json['expiryMonth'];
|
||||
expiryYear = json['expiryYear'];
|
||||
paymentDescription = json['paymentDescription'];
|
||||
paymentMethod = json['payment_method'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['cardScheme'] = this.cardScheme;
|
||||
data['cardType'] = this.cardType;
|
||||
data['expiryMonth'] = this.expiryMonth;
|
||||
data['expiryYear'] = this.expiryYear;
|
||||
data['paymentDescription'] = this.paymentDescription;
|
||||
data['payment_method'] = this.paymentMethod;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
|
||||
|
||||
abstract class PaytabsService {
|
||||
Future<Either<Failure, dynamic>> getAskDoctorAppointmentsList();
|
||||
|
||||
Future<Either<Failure, dynamic>> getDoctorResponse();
|
||||
}
|
||||
|
||||
class PaytabsServiceImp implements PaytabsService {
|
||||
@override
|
||||
Future<Either<Failure, dynamic>> getAskDoctorAppointmentsList() {
|
||||
// TODO: implement getAskDoctorAppointmentsList
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, dynamic>> getDoctorResponse() {
|
||||
// TODO: implement getDoctorResponse
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_paytabs_bridge/BaseBillingShippingInfo.dart';
|
||||
import 'package:flutter_paytabs_bridge/IOSThemeConfiguration.dart';
|
||||
import 'package:flutter_paytabs_bridge/PaymentSdkConfigurationDetails.dart';
|
||||
import 'package:flutter_paytabs_bridge/PaymentSdkLocale.dart';
|
||||
import 'package:flutter_paytabs_bridge/PaymentSdkTokeniseType.dart';
|
||||
import 'package:flutter_paytabs_bridge/PaymentSdkTransactionType.dart';
|
||||
import 'package:flutter_paytabs_bridge/flutter_paytabs_bridge.dart';
|
||||
import 'package:hmg_patient_app_new/core/api_consts.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_state.dart';
|
||||
import 'package:hmg_patient_app_new/core/enums.dart';
|
||||
import 'package:hmg_patient_app_new/core/paytabs_config.dart';
|
||||
import 'package:hmg_patient_app_new/features/paytabs/models/paytabs_transaction_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
class PayTabsViewModel extends ChangeNotifier {
|
||||
late PaymentSdkConfigurationDetails paymentConfiguration;
|
||||
final AppState appState;
|
||||
late PaytabsTransactionResponseModel paytabsTransactionResponseModel;
|
||||
|
||||
PayTabsViewModel({
|
||||
required this.appState,
|
||||
});
|
||||
|
||||
setPaymentConfiguration(String paymentDescription, num amount) {
|
||||
String cartID = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
paymentConfiguration = PaymentSdkConfigurationDetails(
|
||||
profileId: PaymentSdkDefaultConfig.profileID,
|
||||
serverKey: PaymentSdkDefaultConfig.serverKey,
|
||||
clientKey: PaymentSdkDefaultConfig.clientKey,
|
||||
transactionType: PaymentSdkTransactionType.SALE,
|
||||
cartId: cartID.substring((cartID.length - 5), cartID.length),
|
||||
cartDescription: paymentDescription,
|
||||
merchantName: PaymentSdkDefaultConfig.defaultMerchantName,
|
||||
locale: appState.isArabic() ? PaymentSdkLocale.AR : PaymentSdkLocale.EN,
|
||||
merchantApplePayIndentifier:
|
||||
ApiConsts.appEnvironmentType == AppEnvironmentTypeEnum.uat ? PaymentSdkDefaultConfig.defaultMerchantAppleBundleIDUAT : PaymentSdkDefaultConfig.defaultMerchantAppleBundleID,
|
||||
// merchantApplePayIndentifier: PaymentSdkDefaultConfig.defaultMerchantAppleBundleIDUAT,
|
||||
screentTitle: paymentDescription,
|
||||
amount: amount.toDouble(),
|
||||
showBillingInfo: false,
|
||||
forceShippingInfo: false,
|
||||
currencyCode: PaymentSdkDefaultConfig.defaultCurrency,
|
||||
merchantCountryCode: PaymentSdkDefaultConfig.defaultMerchantCountryCode,
|
||||
billingDetails: BillingDetails(
|
||||
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}" ?? "HMG Patient", "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com",
|
||||
appState.getAuthenticatedUser()!.mobileNumber ?? "0000000000", "Riyadh", "SA", "Riyadh", "Riyadh", "12626"),
|
||||
shippingDetails: ShippingDetails("${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}" ?? "HMG Patient", "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com",
|
||||
appState.getAuthenticatedUser()!.mobileNumber ?? "0000000000", "Riyadh", "SA", "Riyadh", "Riyadh", "12626"),
|
||||
alternativePaymentMethods: [],
|
||||
linkBillingNameWithCardHolderName: true,
|
||||
simplifyApplePayValidation: true);
|
||||
|
||||
paymentConfiguration.iOSThemeConfigurations = IOSThemeConfigurations(
|
||||
// logoImage: "assets/images/png/hmg_logo.png",
|
||||
backgroundColor: "ffffff",
|
||||
backgroundColorDark: "ffffff",
|
||||
secondaryColor: "191919",
|
||||
secondaryColorDark: "191919",
|
||||
primaryColor: "ffffff",
|
||||
primaryColorDark: "ffffff",
|
||||
// primaryFont: "Poppins",
|
||||
titleFontColor: "2E3039",
|
||||
titleFontColorDark: "2E3039",
|
||||
// titleFont: "Poppins",
|
||||
primaryFontColor: "2E3039",
|
||||
primaryFontColorDark: "2E3039",
|
||||
inputFieldBackgroundColor: "ffffff",
|
||||
inputFieldBackgroundColorDark: "ffffff",
|
||||
placeholderColor: "2E3039",
|
||||
placeholderColorDark: "2E3039",
|
||||
buttonColor: "ED1C2B",
|
||||
buttonColorDark: "ED1C2B",
|
||||
// buttonFont: "Poppins",
|
||||
);
|
||||
paymentConfiguration.tokeniseType = PaymentSdkTokeniseType.MERCHANT_MANDATORY;
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
startApplePayPayment({Function(PaytabsTransactionResponseModel)? onSuccess, Function(String)? onError}) {
|
||||
FlutterPaytabsBridge.startApplePayPayment(paymentConfiguration, (event) {
|
||||
final transactionDetails = event["data"] as Map<Object?, Object?>?;
|
||||
if (event["status"] == "success") {
|
||||
// Cast Map<Object?, Object?> to Map<String, dynamic>
|
||||
final data = Map<String, dynamic>.from(event["data"] as Map);
|
||||
paytabsTransactionResponseModel = PaytabsTransactionResponseModel.fromJson(data);
|
||||
if (paytabsTransactionResponseModel.isSuccess!) {
|
||||
onSuccess!(paytabsTransactionResponseModel);
|
||||
} else {
|
||||
// Transaction was processed but failed
|
||||
final reason = transactionDetails?["payResponseReturn"] ?? transactionDetails?["responseMessage"] ?? transactionDetails?["message"] ?? "Unknown error";
|
||||
final responseCode = transactionDetails?["responseCode"] ?? "";
|
||||
final errorMessage = responseCode.toString().isNotEmpty ? "Transaction failed (Code: $responseCode): $reason" : "Transaction failed: $reason";
|
||||
onError!(errorMessage);
|
||||
}
|
||||
} else if (event["status"] == "error") {
|
||||
final errorMessage = event["message"] ?? "An error occurred";
|
||||
debugPrint("Error occurred in transaction: $errorMessage");
|
||||
debugPrint("Full error event: $event");
|
||||
onError!(errorMessage);
|
||||
} else if (event["status"] == "event") {
|
||||
final eventMessage = event["message"] ?? "Event occurred";
|
||||
debugPrint("Event occurred: $eventMessage");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
startCardPayment({Function(PaytabsTransactionResponseModel)? onSuccess, Function(String)? onError}) {
|
||||
FlutterPaytabsBridge.startCardPayment(paymentConfiguration, (event) {
|
||||
final transactionDetails = event["data"] as Map<Object?, Object?>?;
|
||||
if (event["status"] == "success") {
|
||||
// Cast Map<Object?, Object?> to Map<String, dynamic>
|
||||
final data = Map<String, dynamic>.from(event["data"] as Map);
|
||||
paytabsTransactionResponseModel = PaytabsTransactionResponseModel.fromJson(data);
|
||||
if (paytabsTransactionResponseModel.isSuccess!) {
|
||||
onSuccess!(paytabsTransactionResponseModel);
|
||||
} else {
|
||||
// Transaction was processed but failed
|
||||
final reason = transactionDetails?["payResponseReturn"] ?? transactionDetails?["responseMessage"] ?? transactionDetails?["message"] ?? "Unknown error";
|
||||
final responseCode = transactionDetails?["responseCode"] ?? "";
|
||||
final errorMessage = responseCode.toString().isNotEmpty ? "Transaction failed (Code: $responseCode): $reason" : "Transaction failed: $reason";
|
||||
onError!(errorMessage);
|
||||
}
|
||||
} else if (event["status"] == "error") {
|
||||
final errorMessage = event["message"] ?? "An error occurred";
|
||||
debugPrint("Error occurred in transaction: $errorMessage");
|
||||
debugPrint("Full error event: $event");
|
||||
onError!(errorMessage);
|
||||
} else if (event["status"] == "event") {
|
||||
final eventMessage = event["message"] ?? "Event occurred";
|
||||
debugPrint("Event occurred: $eventMessage");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.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';
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.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/my_invoices/models/get_pharmacy_invoices_response_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/chip/app_custom_chip_widget.dart';
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
class PharmacyInvoiceCard extends StatelessWidget {
|
||||
final GetPharmacyInvoicesResponseModel pharmacyInvoice;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const PharmacyInvoiceCard({
|
||||
super.key,
|
||||
required this.pharmacyInvoice,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isArabic = getIt<AppState>().isArabic();
|
||||
|
||||
return Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 20.h,
|
||||
hasShadow: true,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(14.h),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Type chips
|
||||
// Wrap(
|
||||
// alignment: WrapAlignment.start,
|
||||
// direction: Axis.horizontal,
|
||||
// spacing: 6.w,
|
||||
// runSpacing: 6.h,
|
||||
// children: [
|
||||
// AppCustomChipWidget(
|
||||
// icon: AppAssets.pharmacy_icon,
|
||||
// iconColor: AppColors.primaryRedColor,
|
||||
// labelText: LocaleKeys.pharmacy.tr(context: context),
|
||||
// textColor: AppColors.primaryRedColor,
|
||||
// ),
|
||||
// if (pharmacyInvoice.totalAmount != null)
|
||||
// AppCustomChipWidget(
|
||||
// labelText: '${pharmacyInvoice.totalAmount!.toStringAsFixed(2)} ${LocaleKeys.sar.tr(context: context)}',
|
||||
// backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
|
||||
// textColor: AppColors.primaryRedColor,
|
||||
// isEnglishOnly: true,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
// Main content row
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Image.network(
|
||||
pharmacyInvoice.doctorImageURL ?? 'https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png',
|
||||
width: 63.h,
|
||||
height: 63.h,
|
||||
fit: BoxFit.cover,
|
||||
).circle(100.r),
|
||||
Transform.translate(
|
||||
offset: Offset(0.0, -20.h),
|
||||
child: Container(
|
||||
width: 40.w,
|
||||
height: 40.h,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: AppColors.scaffoldBgColor,
|
||||
width: 1.5.w,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h, applyThemeColor: false),
|
||||
SizedBox(height: 2.h),
|
||||
"${pharmacyInvoice.decimalDoctorRate ?? '0.0'}".toText11(isBold: true, color: AppColors.textColor),
|
||||
],
|
||||
),
|
||||
).circle(100),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 16.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
(getIt<AppState>().isArabic()
|
||||
? (pharmacyInvoice.doctorNameN ?? pharmacyInvoice.doctorName ?? LocaleKeys.doctor.tr(context: context))
|
||||
: (pharmacyInvoice.doctorName ?? pharmacyInvoice.doctorNameN ?? LocaleKeys.doctor.tr(context: context))
|
||||
).toText16(isBold: true),
|
||||
SizedBox(height: 8.h),
|
||||
Wrap(
|
||||
direction: Axis.horizontal,
|
||||
spacing: 6.w,
|
||||
runSpacing: 6.h,
|
||||
children: [
|
||||
AppCustomChipWidget(
|
||||
labelText: "${LocaleKeys.invoiceNo.tr(context: context)}: ${pharmacyInvoice.invoiceNo ?? '-'}",
|
||||
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
|
||||
isEnglishOnly: true,
|
||||
),
|
||||
AppCustomChipWidget(
|
||||
labelText: ((pharmacyInvoice.clinicName ?? LocaleKeys.clinic.tr(context: context)).length > 15
|
||||
? '${(pharmacyInvoice.clinicName ?? LocaleKeys.clinic.tr(context: context)).substring(0, 12)}...'
|
||||
: (pharmacyInvoice.clinicName ?? LocaleKeys.clinic.tr(context: context))),
|
||||
labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 4.w),
|
||||
),
|
||||
AppCustomChipWidget(
|
||||
labelText: pharmacyInvoice.projectName ?? LocaleKeys.hospital.tr(context: context),
|
||||
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
|
||||
),
|
||||
if (pharmacyInvoice.appointmentDate != null)
|
||||
Directionality(
|
||||
textDirection: ui.TextDirection.ltr,
|
||||
child: AppCustomChipWidget(
|
||||
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
|
||||
icon: AppAssets.doctor_calendar_icon,
|
||||
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(pharmacyInvoice.appointmentDate), false),
|
||||
isEnglishOnly: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
// Action button
|
||||
CustomButton(
|
||||
text: Utils.isVidaPlusProject(pharmacyInvoice.projectID ?? 0)
|
||||
? LocaleKeys.sendEmail.tr(context: context)
|
||||
: LocaleKeys.downloadInvoice.tr(context: context),
|
||||
onPressed: onTap,
|
||||
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
|
||||
borderColor: AppColors.primaryRedColor.withValues(alpha: 0.01),
|
||||
textColor: AppColors.primaryRedColor,
|
||||
fontSize: 14.f,
|
||||
fontWeight: FontWeight.w600,
|
||||
borderRadius: 12.r,
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
||||
height: 40.h,
|
||||
iconSize: 14.h,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
).paddingOnly(bottom: 16.h);
|
||||
}
|
||||
|
||||
String _formatDate(String? dateString) {
|
||||
if (dateString == null || dateString.isEmpty) return '-';
|
||||
try {
|
||||
final date = DateUtil.convertStringToDate(dateString);
|
||||
return DateUtil.formatDateToDate(date, false);
|
||||
} catch (e) {
|
||||
return dateString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue