This commit is contained in:
Daniel Arantes Loverde
2026-06-03 14:31:11 -03:00
parent 69dd67b8a5
commit 74848192a0
28 changed files with 134 additions and 617 deletions

View File

@@ -17,9 +17,7 @@ struct TermsOfUseView: View {
}
.background((colorScheme == .dark ? Color.black : AppColors.backgroundLight).ignoresSafeArea())
.navigationTitle("Termos de Uso")
#if os(iOS)
.appInlineNavigationTitle()
#endif
}
}
@@ -40,8 +38,6 @@ struct PrivacyPolicyView: View {
}
.background((colorScheme == .dark ? Color.black : AppColors.backgroundLight).ignoresSafeArea())
.navigationTitle("Privacidade")
#if os(iOS)
.appInlineNavigationTitle()
#endif
}
}

View File

@@ -14,13 +14,8 @@ struct LoginEmailView: View {
@Environment(\.colorScheme) var colorScheme
@ViewBuilder private var logoImage: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
#else
SwiftUI.Image("pedifoods")
.resizable()
#endif
}
var body: some View {
@@ -40,9 +35,9 @@ struct LoginEmailView: View {
VStack(spacing: 16) {
VStack(alignment: .leading, spacing: 16) {
LoginField(icon: "envelope", placeholder: "seu@email.com", text: $email)
LoginField(icon: "envelope", placeholder: "seu@email.com", keyboardType: .emailAddress, text: $email)
LoginField(icon: "phone", placeholder: "(00) 00000-0000", text: $phone)
LoginField(icon: "phone", placeholder: "(00) 00000-0000", keyboardType: .numberPad, text: $phone)
.onChange(of: phone) { _, newValue in
let masked = formatPhoneBR(newValue)
if masked != newValue {
@@ -78,6 +73,7 @@ struct LoginEmailView: View {
dismiss()
}
}
.buttonStyle(.plain)
.font(AppTypography.body)
.padding(.top, 8)
@@ -125,6 +121,7 @@ struct LoginEmailView: View {
struct LoginField: View {
let icon: String
let placeholder: String
let keyboardType: UIKeyboardType
@Binding var text: String
var body: some View {
@@ -135,6 +132,7 @@ struct LoginField: View {
TextField(text: $text, prompt: Text(placeholder).foregroundColor(Color.gray)) { }
.appNoAutoCap()
.foregroundColor(.black)
.keyboardType(keyboardType)
}
.padding(.horizontal, 16)
.frame(height: 52)

View File

@@ -15,23 +15,13 @@ struct LoginView: View {
@State var lastAnimatedToken = 0
@ViewBuilder private var logoImage: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
#else
SwiftUI.Image("pedifoods")
.resizable()
#endif
}
@ViewBuilder private var pinHeroImage: some View {
#if os(Android)
SwiftUI.Image(colorScheme == .dark ? "pin_image_app_dark" : "pin_image_app", bundle: .module)
.resizable()
#else
SwiftUI.Image("pin_image_app")
.resizable()
#endif
}
var body: some View {
@@ -43,13 +33,6 @@ struct LoginView: View {
(colorScheme == .dark ? Color.black : AppColors.backgroundLight)
.ignoresSafeArea()
#if os(Android)
pinHeroImage
.scaledToFill()
.frame(height: heroHeight + 80)
.offset(y: heroVisible ? -60 : -(heroHeight + 220))
.opacity(colorScheme == .dark ? 0.08 : 0.15)
#else
pinHeroImage
.scaledToFill()
.frame(height: heroHeight + 80)
@@ -61,7 +44,6 @@ struct LoginView: View {
endPoint: .bottom
)
)
#endif
VStack(spacing: 18) {
Spacer().frame(height: logoTopInset)
@@ -90,6 +72,7 @@ struct LoginView: View {
.tint(AppColors.tertiary)
.offset(y: buttonVisible ? 0 : 140)
.opacity(buttonVisible ? 1.0 : 0.0)
.buttonStyle(.plain)
HStack(spacing: 6) {
Text("Não tem conta ainda?")
@@ -97,6 +80,7 @@ struct LoginView: View {
Button("Criar conta") {
navigate(.registration)
}
.buttonStyle(.plain)
.foregroundStyle(AppColors.primary)
}
.font(AppTypography.body)
@@ -108,36 +92,15 @@ struct LoginView: View {
}
.ignoresSafeArea()
.onAppear {
#if os(Android)
// No Android, rodamos a animação localmente de forma direta
applyHiddenStateWithoutAnimation()
Task {
try? await Task.sleep(nanoseconds: 100_000_000)
withAnimation(.easeOut(duration: 0.5)) {
heroVisible = true
}
try? await Task.sleep(nanoseconds: 150_000_000)
withAnimation(.easeOut(duration: 0.4)) {
textVisible = true
}
try? await Task.sleep(nanoseconds: 150_000_000)
withAnimation(.easeOut(duration: 0.4)) {
buttonVisible = true
}
}
#else
if shouldPrepareEntryAnimation {
applyHiddenStateWithoutAnimation()
} else {
showFinalStateWithoutAnimation()
}
#endif
}
#if os(iOS)
.task(id: authEntryAnimationToken) {
await runEntryAnimationIfNeeded(for: authEntryAnimationToken)
}
#endif
}
}

View File

@@ -25,19 +25,11 @@ struct OtpView: View {
var body: some View {
ScrollView {
VStack(spacing: 0) {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
.scaledToFit()
.frame(width: 74, height: 74)
.padding(.top, 140)
#else
SwiftUI.Image("pedifoods")
.resizable()
.scaledToFit()
.frame(width: 74, height: 74)
.padding(.top, 140)
#endif
Text("Verificação")
.font(AppTypography.heading1)
@@ -72,6 +64,10 @@ struct OtpView: View {
if trimmed != newValue {
otp = trimmed
}
if trimmed.count == 8 && !isLoading {
isOtpFocused = false
validateOtp()
}
}
}
.frame(height: 204)
@@ -92,6 +88,7 @@ struct OtpView: View {
Button(resendButtonTitle) {
resendOtp()
}
.buttonStyle(.plain)
.font(AppTypography.heading3)
.foregroundStyle(AppColors.primary)
.disabled(isResending || !canResend)
@@ -101,6 +98,7 @@ struct OtpView: View {
Button("Colar código") {
pasteOtpFromClipboard()
}
.buttonStyle(.plain)
.font(AppTypography.heading3)
.foregroundStyle(AppColors.primary)
.padding(.top, 22)
@@ -124,6 +122,7 @@ struct OtpView: View {
.padding(.bottom, 18)
}
}
.scrollDismissesKeyboard(.interactively)
.background(AppColors.backgroundLight)
.ignoresSafeArea()
.onAppear {

View File

@@ -18,13 +18,8 @@ struct RegistrationView: View {
private var isFormValid: Bool { !name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !email.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !phone.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && acceptedTerms }
@ViewBuilder private var logoImage: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
#else
SwiftUI.Image("pedifoods")
.resizable()
#endif
}
var body: some View {
@@ -49,9 +44,9 @@ struct RegistrationView: View {
VStack(spacing: 16) {
VStack(alignment: .leading, spacing: 16) {
LoginField(icon: "person", placeholder: "Ex: Maria Silva", text: $name)
LoginField(icon: "envelope", placeholder: "seu@email.com", text: $email)
LoginField(icon: "phone", placeholder: "(00) 00000-0000", text: $phone)
LoginField(icon: "person", placeholder: "Ex: Maria Silva", keyboardType: .default, text: $name)
LoginField(icon: "envelope", placeholder: "seu@email.com", keyboardType: .emailAddress, text: $email)
LoginField(icon: "phone", placeholder: "(00) 00000-0000", keyboardType: .namePhonePad, text: $phone)
.onChange(of: phone) { _, newValue in
let masked = formatPhoneBR(newValue)
if masked != newValue {