import SwiftUI struct AuthFlowView: View { @Binding var root: RootFlow @Binding var selectedTab: MainTab let tokenStore: TokenStore var body: some View { NavigationStack { LoginView(root: $root, selectedTab: $selectedTab, tokenStore: tokenStore) } } } struct LoginView: View { @Binding var root: RootFlow @Binding var selectedTab: MainTab let tokenStore: TokenStore @State var email = "" @Environment(\.colorScheme) var colorScheme @ViewBuilder private var logoImage: some View { #if os(Android) Image(colorScheme == .dark ? "pedifoods_dark" : "pedifoods", bundle: .module) .resizable() #else SwiftUI.Image("pedifoods") .resizable() #endif } @ViewBuilder private var pinHeroImage: some View { #if os(Android) 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 { ZStack(alignment: .top) { (colorScheme == .dark ? AppColors.backgroundDark : AppColors.backgroundLight) .ignoresSafeArea() pinHeroImage .scaledToFill() .frame(height: 520) .offset(y: -90) .mask( LinearGradient( colors: [.black, .black, .black.opacity(0.0)], startPoint: .top, endPoint: .bottom ) ) VStack(spacing: 20) { Spacer().frame(height: 280) logoImage .scaledToFit() .frame(height: 200) Text("Descubra lorem ipsum ba bla") .font(AppTypography.heading1) .foregroundStyle(colorScheme == .dark ? AppColors.textInverse : AppColors.textPrimary) .multilineTextAlignment(.leading) .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, 28) Spacer() PrimaryButton(title: "ENTRAR") { // TODO: integrar com ApiService e OTP tokenStore.jwt = "demo-token" selectedTab = .home root = .main } .padding(.horizontal, 28) HStack(spacing: 6) { Text("Não tem conta ainda?") .foregroundStyle(colorScheme == .dark ? AppColors.textInverse.opacity(0.9) : AppColors.textPrimary) NavigationLink("Criar conta") { RegistrationView(root: $root, selectedTab: $selectedTab, tokenStore: tokenStore) } .foregroundStyle(AppColors.primary) } .font(AppTypography.body) Spacer().frame(height: 24) } } .ignoresSafeArea() } } struct RegistrationView: View { @Binding var root: RootFlow @Binding var selectedTab: MainTab let tokenStore: TokenStore @State var name = "" @State var email = "" @State var phone = "" var body: some View { ScrollView { VStack(spacing: 20) { Text("Cadastro") .font(AppTypography.heading1) .foregroundStyle(AppColors.textPrimary) VStack(spacing: 12) { TextField("Nome", text: $name) .textFieldStyle(.roundedBorder) TextField("Email", text: $email) .textFieldStyle(.roundedBorder) TextField("Telefone", text: $phone) .textFieldStyle(.roundedBorder) PrimaryButton(title: "Enviar OTP") { // TODO: solicitar OTP } } } .padding(24) } .background(AppColors.backgroundLight) } } struct OtpView: View { let email: String var body: some View { VStack(spacing: 16) { Text("OTP") .font(AppTypography.heading1) .foregroundStyle(AppColors.textPrimary) Text("Enviado para \(email)") .font(.caption) .foregroundStyle(AppColors.secondary) } .padding(24) .background(AppColors.backgroundLight) } }