177 lines
6.3 KiB
Swift
177 lines
6.3 KiB
Swift
import SwiftUI
|
|
|
|
struct TransferReceiptView: View {
|
|
let receipt: TransferReceiptData
|
|
var onSaveContact: ((BankContact) -> Void)? = nil
|
|
var onDone: () -> Void
|
|
|
|
@State private var contactSaved = false
|
|
|
|
private let primary = Color(red: 0.247, green: 0.396, blue: 0.678)
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
ScrollView {
|
|
VStack(spacing: 0) {
|
|
successHeader
|
|
detailsCard
|
|
Spacer(minLength: 32)
|
|
doneButton
|
|
}
|
|
.padding(.horizontal, 16)
|
|
.padding(.bottom, 32)
|
|
}
|
|
.background(Color(.systemGroupedBackground))
|
|
.navigationTitle("Receipt")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .navigationBarTrailing) {
|
|
Button("Done") { onDone() }
|
|
.foregroundStyle(primary)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Sub-views
|
|
|
|
private var successHeader: some View {
|
|
VStack(spacing: 12) {
|
|
ZStack {
|
|
Circle()
|
|
.fill(Color.green.opacity(0.15))
|
|
.frame(width: 80, height: 80)
|
|
Image(systemName: "checkmark.circle.fill")
|
|
.font(.system(size: 44))
|
|
.foregroundStyle(.green)
|
|
}
|
|
.padding(.top, 32)
|
|
|
|
Text("Transfer Successful")
|
|
.font(.title2.bold())
|
|
|
|
Text(amountText)
|
|
.font(.system(size: 36, weight: .bold, design: .rounded))
|
|
.foregroundStyle(primary)
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.bottom, 24)
|
|
}
|
|
|
|
private var detailsCard: some View {
|
|
VStack(spacing: 0) {
|
|
row(label: "From", value: receipt.fromAccountNumber)
|
|
Divider().padding(.leading, 16)
|
|
row(label: "Bank", value: receipt.fromBankName)
|
|
Divider().padding(.leading, 16)
|
|
row(label: "To Account", value: receipt.toAccountNumber)
|
|
Divider().padding(.leading, 16)
|
|
row(label: "Beneficiary", value: receipt.toAccountName.isEmpty ? "—" : receipt.toAccountName)
|
|
if !receipt.reference.isEmpty {
|
|
Divider().padding(.leading, 16)
|
|
row(label: "Reference", value: receipt.reference)
|
|
}
|
|
if !receipt.date.isEmpty {
|
|
Divider().padding(.leading, 16)
|
|
row(label: "Date", value: receipt.date)
|
|
}
|
|
if !receipt.message.isEmpty && receipt.message != "Transfer successful" {
|
|
Divider().padding(.leading, 16)
|
|
row(label: "Note", value: receipt.message)
|
|
}
|
|
}
|
|
.background(Color(.secondarySystemGroupedBackground))
|
|
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
}
|
|
|
|
private var doneButton: some View {
|
|
VStack(spacing: 12) {
|
|
if let onSave = onSaveContact {
|
|
Button {
|
|
onSave(makeContact())
|
|
contactSaved = true
|
|
} label: {
|
|
Label(contactSaved ? "Contact Saved" : "Save Contact",
|
|
systemImage: contactSaved ? "checkmark.circle.fill" : "person.badge.plus")
|
|
.font(.headline)
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical, 14)
|
|
.background(contactSaved ? Color.green.opacity(0.15) : Color(.secondarySystemGroupedBackground))
|
|
.foregroundStyle(contactSaved ? .green : primary)
|
|
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
}
|
|
.disabled(contactSaved)
|
|
}
|
|
Button(action: onDone) {
|
|
Text("Done")
|
|
.font(.headline)
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical, 14)
|
|
.background(primary)
|
|
.foregroundStyle(.white)
|
|
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
}
|
|
}
|
|
}
|
|
|
|
private func makeContact() -> BankContact {
|
|
let source = receipt.fromBankName.lowercased().contains("islamic") ? "MIB" : "BML"
|
|
let displayName = receipt.toAccountName.isEmpty ? receipt.toAccountNumber : receipt.toAccountName
|
|
return BankContact(
|
|
id: "LOCAL_\(source)_\(receipt.toAccountNumber)",
|
|
benefNo: receipt.toAccountNumber,
|
|
benefName: displayName,
|
|
benefNickName: nil,
|
|
benefAccount: receipt.toAccountNumber,
|
|
benefType: source,
|
|
bankColor: nil,
|
|
benefBankName: nil,
|
|
bankCode: nil,
|
|
benefStatus: "Active",
|
|
transferCyDesc: receipt.currency,
|
|
customerImgHash: nil,
|
|
benefCategoryId: nil,
|
|
profileId: nil,
|
|
source: source
|
|
)
|
|
}
|
|
|
|
private func row(label: String, value: String) -> some View {
|
|
HStack {
|
|
Text(label)
|
|
.font(.subheadline)
|
|
.foregroundStyle(.secondary)
|
|
.frame(width: 110, alignment: .leading)
|
|
Text(value)
|
|
.font(.subheadline)
|
|
.multilineTextAlignment(.trailing)
|
|
.frame(maxWidth: .infinity, alignment: .trailing)
|
|
}
|
|
.padding(.horizontal, 16)
|
|
.padding(.vertical, 12)
|
|
}
|
|
|
|
private var amountText: String {
|
|
let f = NumberFormatter()
|
|
f.numberStyle = .decimal
|
|
f.minimumFractionDigits = 2
|
|
f.maximumFractionDigits = 2
|
|
f.usesGroupingSeparator = true
|
|
return "\(receipt.currency) \(f.string(from: NSNumber(value: receipt.amount)) ?? "0.00")"
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
TransferReceiptView(receipt: TransferReceiptData(
|
|
fromAccountNumber: "7701234567890",
|
|
fromBankName: "Bank of Maldives",
|
|
toAccountNumber: "7709876543210",
|
|
toAccountName: "Ahmed Mohamed",
|
|
amount: 1500.00,
|
|
currency: "MVR",
|
|
reference: "TXN20260607001",
|
|
date: "2026-06-07 14:32:00",
|
|
message: "Transfer successful"
|
|
)) {}
|
|
}
|