You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
PadelClub/PadelClub/Views/User/LoginView.swift

178 lines
5.0 KiB

//
// LoginView.swift
// PadelClub
//
// Created by Laurent Morvillier on 19/02/2024.
//
import SwiftUI
import LeStorage
struct LoginView: View {
@EnvironmentObject var dataStore: DataStore
@State var username: String = ""
@State var password: String = ""
@State var isLoading: Bool = false
@State var showEmailPopup: Bool = false
@State var errorText: String? = nil
var showEmailValidationMessage: Bool = false
var handler: (User) -> ()
var body: some View {
Form {
Section {
TextField("Nom d'utilisateur", text: self.$username)
.autocorrectionDisabled()
.textInputAutocapitalization(.never)
SecureField("Mot de passe", text: self.$password)
} header: {
if self.showEmailValidationMessage {
Text("Vous pouvez maintenant ouvrir votre boîte mail pour valider votre compte. Vous pourrez ensuite vous connecter ici.")
}
}
Section {
Button(action: {
self._login()
}, label: {
if self.isLoading {
HStack {
Spacer()
ProgressView()
Spacer()
}
} else {
Text("Connexion")
.buttonStyle(.borderedProminent)
.tint(.orange)
.listRowBackground(Color.clear)
.frame(maxWidth: .infinity)
}
})
if let error = self.errorText {
Text(error).font(.callout).foregroundStyle(.red)
}
}
if !self.showEmailValidationMessage {
Section {
NavigationLink("Créer un compte") {
UserCreationView()
}
Button(action: {
self.showEmailPopup = true
}, label: {
Text("Mot passe oublié")
})
.alert(
Text("Changer de mot de passe")
,
isPresented: self.$showEmailPopup
) {
EmailConfirmationView()
} message: {
Text("Veuillez entrer votre email")
}
}
}
}
.navigationTitle("Connexion")
.onAppear {
#if DEBUG
if let username = PListReader.readString(plist: "local", key: "username") {
self.username = username
}
if let password = PListReader.readString(plist: "local", key: "password") {
self.password = password
}
#endif
}
}
fileprivate func _login() {
self.errorText = nil // reset error
self.isLoading = true
Task {
do {
let service = try Store.main.service()
let user: User = try await service.login(
username: self.username,
password: self.password)
self.dataStore.user = user
self.isLoading = false
self.handler(user)
} catch {
self.isLoading = false
switch error {
case ServiceError.responseError(let reason):
self.errorText = reason
default:
self.errorText = error.localizedDescription
}
Logger.error(error)
}
}
}
}
struct EmailConfirmationView: View {
@State var email: String = ""
@State var errorMessage: String = ""
var body: some View {
VStack {
TextField("Email", text: self.$email)
.keyboardType(.emailAddress)
Button {
self._forgottenPassword()
} label: {
Text("Envoyer l'email")
}
}
}
fileprivate func _forgottenPassword() {
Task {
do {
let service = try Store.main.service()
try await service.forgotPassword(email: self.email)
} catch {
Logger.error(error)
switch error {
case ServiceError.responseError(let reason):
self.errorMessage = reason
default:
self.errorMessage = error.localizedDescription
}
Logger.log(self.errorMessage)
}
}
}
}
#Preview {
NavigationStack {
LoginView(handler: { _ in })
}
}
#Preview {
EmailConfirmationView()
}