Implemented the overall UI of the LoginView view.

This commit is contained in:
Javier Cicchelli 2022-12-02 19:27:21 +01:00
parent 4eb373b6ef
commit 3eadc3d602

View File

@ -12,7 +12,7 @@ struct LoginView: View {
// MARK: States // MARK: States
@State private var topPadding: CGFloat = 0 @State private var containerTopPadding: CGFloat = 0
// MARK: Body // MARK: Body
@ -21,15 +21,14 @@ struct LoginView: View {
.vertical, .vertical,
showsIndicators: false showsIndicators: false
) { ) {
Container() LoginContainer()
.padding(.horizontal, 24) .padding(.horizontal, 24)
.padding(.top, topPadding) .padding(.top, containerTopPadding)
} }
.background(Color.red) .background(Color.red)
.ignoresSafeArea()
.overlay(ViewHeightGeometry()) .overlay(ViewHeightGeometry())
.onPreferenceChange(ViewHeightPreferenceKey.self) { height in .onPreferenceChange(ViewHeightPreferenceKey.self) { height in
topPadding = height * 0.25 containerTopPadding = height * 0.1
} }
} }
@ -38,36 +37,52 @@ struct LoginView: View {
// MARK: - Views // MARK: - Views
fileprivate extension LoginView { fileprivate extension LoginView {
struct Container: View { struct LoginContainer: View {
// MARK: States
@State private var isAuthenticating: Bool = false
@State private var username: String = .empty @State private var username: String = .empty
@State private var password: String = .empty @State private var password: String = .empty
@State private var errorMessage: String? @State private var errorMessage: String?
// MARK: Body
var body: some View { var body: some View {
VStack(spacing: 24) { VStack(spacing: 32) {
Text("My NFS") Text("login.title.text")
.font(.largeTitle) .font(.largeTitle)
.fontWeight(.bold) .fontWeight(.bold)
.foregroundColor(.primary)
LoginForm( LoginForm(
username: $username, username: $username,
password: $password, password: $password,
errorMessage: $errorMessage errorMessage: $errorMessage
) ) {
// TODO: login with the username and password.
}
Button { Button {
// ... // TODO: login with the username and password.
} label: { } label: {
Text("Log in") Label {
.font(.body) Text("login.button.log_in.text")
.fontWeight(.semibold) .fontWeight(.semibold)
.padding(.vertical, 8) } icon: {
.padding(.horizontal, 32) if isAuthenticating {
.background( ProgressView()
Capsule() } else {
.foregroundColor(.white) EmptyView()
) }
}
.labelStyle(LogInLabelStyle())
} }
.tint(.orange)
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle(radius: 8))
.controlSize(.large)
.disabled(isLoginDisabled)
} }
} }
} }
@ -84,6 +99,35 @@ fileprivate extension LoginView {
} }
} }
// MARK: - Label styles
private extension LoginView.LoginContainer {
struct LogInLabelStyle: LabelStyle {
func makeBody(configuration: Configuration) -> some View {
HStack(spacing: 8) {
Spacer()
configuration.title
.font(.body)
.foregroundColor(.primary)
configuration.icon
.tint(.primary)
Spacer()
}
}
}
}
// MARK: - Helpers
private extension LoginView.LoginContainer {
var isLoginDisabled: Bool {
username.isEmpty || password.isEmpty
}
}
// MARK: - Preference keys // MARK: - Preference keys
struct ViewHeightPreferenceKey: PreferenceKey { struct ViewHeightPreferenceKey: PreferenceKey {