From abd58ac36de60ef2961f2940b96d607691254456 Mon Sep 17 00:00:00 2001 From: Daniel Arantes Loverde Date: Wed, 3 Jun 2026 17:58:44 -0300 Subject: [PATCH] feat(cards): add input masks and char limits to card form fields - Card number: groups of 4 digits (0000 0000 0000 0000), max 16 digits - Expiry: MM/AAAA mask, max 6 digits - CVV: digits only, max 4 - CPF: 000.000.000-00 mask, max 11 digits - canSubmit validates stripped digit counts --- .../PediFoods/Views/Main/CheckoutView.swift | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/pedi-foods/Sources/PediFoods/Views/Main/CheckoutView.swift b/pedi-foods/Sources/PediFoods/Views/Main/CheckoutView.swift index 8103fd4..d43053e 100644 --- a/pedi-foods/Sources/PediFoods/Views/Main/CheckoutView.swift +++ b/pedi-foods/Sources/PediFoods/Views/Main/CheckoutView.swift @@ -997,10 +997,10 @@ struct PaymentCardView: View { } var canSubmit: Bool { - holderName.isEmpty == false && + holderName.trimmingCharacters(in: .whitespaces).isEmpty == false && cardNumber.filter(\.isNumber).count >= 13 && - expiry.count >= 4 && - cvv.count >= 3 && + expiry.filter(\.isNumber).count == 6 && + cvv.filter(\.isNumber).count >= 3 && cpf.filter(\.isNumber).count == 11 } @@ -1051,15 +1051,49 @@ struct PaymentCardView: View { VStack(spacing: 10) { labeledField("Número do Cartão", placeholder: "0000 0000 0000 0000", text: $cardNumber) .keyboardType(.numberPad) + .onChange(of: cardNumber) { _, v in + let d = String(v.filter(\.isNumber).prefix(16)) + let masked = stride(from: 0, to: d.count, by: 4) + .map { i -> String in + let start = d.index(d.startIndex, offsetBy: i) + let end = d.index(start, offsetBy: min(4, d.count - i)) + return String(d[start..