[auth-payment-login-lockout] Unify auth back button and animate the flow entry
- RegistrationView / LoginEmailView / OtpView: pushed with no nav bar, so they showed the oversized iOS 26 system glass back button. Wrapped each in LCENavigationView with the standard AppBackButtonIcon, matching LoginView and every other screen. Dropped the now-dead colorScheme dark branches and forced .preferredColorScheme(.light) (app has no dark theme). - ContentView: root .auth <-> .main switched with no transition. Added .move transitions on both branches and wrapped enterAuthFlow() / LoginView's back action in withAnimation, so opening auth from Profile's 'Entrar ou Cadastrar' now slides in and back slides out. - ProfileLoggedOutFlowTests: new test asserting the pushed auth screens carry the LCENavigationView back button.
This commit is contained in:
@@ -32,11 +32,13 @@ struct ContentView: View {
|
||||
tokenStore: tokenStore,
|
||||
appState: $appState
|
||||
)
|
||||
.transition(.move(edge: .trailing))
|
||||
case .main:
|
||||
if isBootstrappingSession {
|
||||
sessionBootstrapLoadingView
|
||||
} else {
|
||||
MainTabView(selectedTab: $selectedTab, tokenStore: tokenStore, appState: $appState, enterAuth: enterAuthFlow)
|
||||
.transition(.move(edge: .leading))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -408,7 +410,9 @@ struct ContentView: View {
|
||||
/// decisions/2026-08-27-payment-auth-lockout-clean-intro-screen.md.
|
||||
@MainActor
|
||||
private func enterAuthFlow() {
|
||||
root = .auth
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
root = .auth
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import SwiftUI
|
||||
#if canImport(LCEssentials)
|
||||
import LCEssentials
|
||||
#endif
|
||||
|
||||
struct LoginEmailView: View {
|
||||
@Binding var root: RootFlow
|
||||
@@ -11,7 +14,6 @@ struct LoginEmailView: View {
|
||||
@State var isLoading = false
|
||||
@State var errorMessage: String?
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
|
||||
@ViewBuilder private var logoImage: some View {
|
||||
SwiftUI.Image("pedifoods")
|
||||
@@ -19,8 +21,18 @@ struct LoginEmailView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
LCENavigationView {
|
||||
content
|
||||
}
|
||||
.setLeftButton(image: AnyView(AppBackButtonIcon())) { dismiss() }
|
||||
.setNavigationBarBackgroundColor(AppColors.backgroundLight)
|
||||
.buttonStyle(.plain)
|
||||
.preferredColorScheme(.light)
|
||||
}
|
||||
|
||||
private var content: some View {
|
||||
ZStack {
|
||||
(colorScheme == .dark ? Color.black : AppColors.backgroundLight).ignoresSafeArea()
|
||||
AppColors.backgroundLight.ignoresSafeArea()
|
||||
|
||||
VStack(spacing: 0) {
|
||||
logoImage
|
||||
@@ -29,7 +41,7 @@ struct LoginEmailView: View {
|
||||
|
||||
Text("Boas-vindas!")
|
||||
.font(AppTypography.heading1)
|
||||
.foregroundStyle(colorScheme == .dark ? Color.white : AppColors.textPrimary)
|
||||
.foregroundStyle(AppColors.textPrimary)
|
||||
.padding(Edge.Set.top, 8)
|
||||
.padding(.bottom, 16)
|
||||
|
||||
@@ -66,7 +78,7 @@ struct LoginEmailView: View {
|
||||
|
||||
HStack(spacing: 6) {
|
||||
Text("Novo por aqui?")
|
||||
.foregroundStyle(colorScheme == .dark ? Color.white.opacity(0.8) : Color.gray)
|
||||
.foregroundStyle(Color.gray)
|
||||
Text("Crie sua conta")
|
||||
.foregroundStyle(AppColors.primary)
|
||||
.onTapGesture {
|
||||
|
||||
@@ -16,7 +16,9 @@ struct LoginView: View {
|
||||
LCENavigationView {
|
||||
content
|
||||
}
|
||||
.setLeftButton(image: AnyView(AppBackButtonIcon())) { root = .main }
|
||||
.setLeftButton(image: AnyView(AppBackButtonIcon())) {
|
||||
withAnimation(.easeInOut(duration: 0.3)) { root = .main }
|
||||
}
|
||||
.setTitle(text: Text("Acesse sua conta").font(AppTypography.heading2).foregroundStyle(AppColors.textPrimary))
|
||||
.setNavigationBarBackgroundColor(AppColors.backgroundLight)
|
||||
.buttonStyle(.plain)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
#if canImport(LCEssentials)
|
||||
import LCEssentials
|
||||
#endif
|
||||
|
||||
struct OtpView: View {
|
||||
private let resendDelaySeconds = 45
|
||||
@@ -21,13 +24,23 @@ struct OtpView: View {
|
||||
@Environment(\.dismiss) var dismiss
|
||||
|
||||
var body: some View {
|
||||
LCENavigationView {
|
||||
content
|
||||
}
|
||||
.setLeftButton(image: AnyView(AppBackButtonIcon())) { dismiss() }
|
||||
.setNavigationBarBackgroundColor(AppColors.backgroundLight)
|
||||
.buttonStyle(.plain)
|
||||
.preferredColorScheme(.light)
|
||||
}
|
||||
|
||||
private var content: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 0) {
|
||||
SwiftUI.Image("pedifoods")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 74, height: 74)
|
||||
.padding(.top, 140)
|
||||
.padding(.top, 48)
|
||||
|
||||
Text("Verificação")
|
||||
.font(AppTypography.heading1)
|
||||
@@ -122,7 +135,6 @@ struct OtpView: View {
|
||||
}
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
.background(AppColors.backgroundLight)
|
||||
.ignoresSafeArea()
|
||||
.onAppear {
|
||||
isOtpFocused = true
|
||||
startResendCooldown()
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import SwiftUI
|
||||
#if canImport(LCEssentials)
|
||||
import LCEssentials
|
||||
#endif
|
||||
|
||||
struct RegistrationView: View {
|
||||
@Binding var root: RootFlow
|
||||
@@ -12,7 +15,6 @@ struct RegistrationView: View {
|
||||
@State var isLoading = false
|
||||
@State var errorMessage: String?
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
let navigate: (Route) -> Void
|
||||
|
||||
private var isFormValid: Bool { !name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !email.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !phone.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && acceptedTerms }
|
||||
@@ -23,8 +25,18 @@ struct RegistrationView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
LCENavigationView {
|
||||
content
|
||||
}
|
||||
.setLeftButton(image: AnyView(AppBackButtonIcon())) { dismiss() }
|
||||
.setNavigationBarBackgroundColor(AppColors.backgroundLight)
|
||||
.buttonStyle(.plain)
|
||||
.preferredColorScheme(.light)
|
||||
}
|
||||
|
||||
private var content: some View {
|
||||
ZStack {
|
||||
(colorScheme == .dark ? Color.black : AppColors.backgroundLight).ignoresSafeArea()
|
||||
AppColors.backgroundLight.ignoresSafeArea()
|
||||
|
||||
ScrollView {
|
||||
VStack(spacing: 0) {
|
||||
@@ -34,11 +46,11 @@ struct RegistrationView: View {
|
||||
|
||||
Text("Crie sua conta")
|
||||
.font(AppTypography.heading1)
|
||||
.foregroundStyle(colorScheme == .dark ? Color.white : AppColors.textPrimary)
|
||||
.foregroundStyle(AppColors.textPrimary)
|
||||
|
||||
Text("Preencha os dados abaixo para começar.")
|
||||
.font(AppTypography.body)
|
||||
.foregroundStyle(colorScheme == .dark ? Color.white : AppColors.textPrimary)
|
||||
.foregroundStyle(AppColors.textPrimary)
|
||||
.padding(.top, 8)
|
||||
.padding(.bottom, 20)
|
||||
|
||||
@@ -64,7 +76,7 @@ struct RegistrationView: View {
|
||||
|
||||
Group {
|
||||
Text("Ao se cadastrar, você concorda com nossos [Termos de Uso](app://terms) e [Política de Privacidade](app://policy)")
|
||||
.foregroundStyle(colorScheme == .dark ? Color.white : AppColors.textPrimary)
|
||||
.foregroundStyle(AppColors.textPrimary)
|
||||
.tint(AppColors.primary)
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
guard url.scheme == "app" else { return .handled }
|
||||
@@ -98,7 +110,7 @@ struct RegistrationView: View {
|
||||
|
||||
HStack(spacing: 6) {
|
||||
Text("Já tem uma conta?")
|
||||
.foregroundStyle(colorScheme == .dark ? Color.white.opacity(0.8) : AppColors.textPrimary)
|
||||
.foregroundStyle(AppColors.textPrimary)
|
||||
NavigationLink("Entrar") {
|
||||
LoginEmailView(root: $root, selectedTab: $selectedTab, tokenStore: tokenStore, appState: $appState, navigate: navigate)
|
||||
}
|
||||
@@ -110,7 +122,6 @@ struct RegistrationView: View {
|
||||
Spacer().frame(height: 12)
|
||||
}
|
||||
}
|
||||
.padding(.top, -40)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user