Implemented the overall UI of the LoginView view.
This commit is contained in:
parent
4eb373b6ef
commit
3eadc3d602
@ -12,7 +12,7 @@ struct LoginView: View {
|
||||
|
||||
// MARK: States
|
||||
|
||||
@State private var topPadding: CGFloat = 0
|
||||
@State private var containerTopPadding: CGFloat = 0
|
||||
|
||||
// MARK: Body
|
||||
|
||||
@ -21,15 +21,14 @@ struct LoginView: View {
|
||||
.vertical,
|
||||
showsIndicators: false
|
||||
) {
|
||||
Container()
|
||||
LoginContainer()
|
||||
.padding(.horizontal, 24)
|
||||
.padding(.top, topPadding)
|
||||
.padding(.top, containerTopPadding)
|
||||
}
|
||||
.background(Color.red)
|
||||
.ignoresSafeArea()
|
||||
.overlay(ViewHeightGeometry())
|
||||
.onPreferenceChange(ViewHeightPreferenceKey.self) { height in
|
||||
topPadding = height * 0.25
|
||||
containerTopPadding = height * 0.1
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,36 +37,52 @@ struct LoginView: View {
|
||||
// MARK: - Views
|
||||
|
||||
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 password: String = .empty
|
||||
@State private var errorMessage: String?
|
||||
|
||||
// MARK: Body
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 24) {
|
||||
Text("My NFS")
|
||||
VStack(spacing: 32) {
|
||||
Text("login.title.text")
|
||||
.font(.largeTitle)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(.primary)
|
||||
|
||||
LoginForm(
|
||||
username: $username,
|
||||
password: $password,
|
||||
errorMessage: $errorMessage
|
||||
)
|
||||
) {
|
||||
// TODO: login with the username and password.
|
||||
}
|
||||
|
||||
Button {
|
||||
// ...
|
||||
// TODO: login with the username and password.
|
||||
} label: {
|
||||
Text("Log in")
|
||||
.font(.body)
|
||||
.fontWeight(.semibold)
|
||||
.padding(.vertical, 8)
|
||||
.padding(.horizontal, 32)
|
||||
.background(
|
||||
Capsule()
|
||||
.foregroundColor(.white)
|
||||
)
|
||||
Label {
|
||||
Text("login.button.log_in.text")
|
||||
.fontWeight(.semibold)
|
||||
} icon: {
|
||||
if isAuthenticating {
|
||||
ProgressView()
|
||||
} else {
|
||||
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
|
||||
|
||||
struct ViewHeightPreferenceKey: PreferenceKey {
|
||||
|
Loading…
x
Reference in New Issue
Block a user