Skip to content

Commit 00ce58c

Browse files
committed
chore: improve login form styling
1 parent 84936d0 commit 00ce58c

File tree

1 file changed

+79
-75
lines changed

1 file changed

+79
-75
lines changed

Coder Desktop/Coder Desktop/Views/LoginForm.swift

+79-75
Original file line numberDiff line numberDiff line change
@@ -15,48 +15,46 @@ struct LoginForm<S: Session>: View {
1515
let inspection = Inspection<Self>()
1616

1717
var body: some View {
18-
VStack {
19-
VStack {
20-
switch currentPage {
21-
case .serverURL:
22-
serverURLPage
23-
.transition(.move(edge: .leading))
24-
.onAppear {
25-
DispatchQueue.main.async {
26-
focusedField = .baseAccessURL
27-
}
18+
Group {
19+
switch currentPage {
20+
case .serverURL:
21+
serverURLPage
22+
.transition(.move(edge: .leading))
23+
.onAppear {
24+
DispatchQueue.main.async {
25+
focusedField = .baseAccessURL
2826
}
29-
case .sessionToken:
30-
sessionTokenPage
31-
.transition(.move(edge: .trailing))
32-
.onAppear {
33-
DispatchQueue.main.async {
34-
focusedField = .sessionToken
35-
}
27+
}
28+
case .sessionToken:
29+
sessionTokenPage
30+
.transition(.move(edge: .trailing))
31+
.onAppear {
32+
DispatchQueue.main.async {
33+
focusedField = .sessionToken
3634
}
37-
}
38-
}
39-
.animation(.easeInOut, value: currentPage)
40-
.onAppear {
41-
baseAccessURL = session.baseAccessURL?.absoluteString ?? baseAccessURL
42-
sessionToken = ""
43-
}.padding(.vertical, 35)
44-
.alert("Error", isPresented: Binding(
45-
get: { loginError != nil },
46-
set: { isPresented in
47-
if !isPresented {
48-
loginError = nil
4935
}
36+
}
37+
}
38+
.animation(.easeInOut, value: currentPage)
39+
.onAppear {
40+
baseAccessURL = session.baseAccessURL?.absoluteString ?? baseAccessURL
41+
sessionToken = ""
42+
}
43+
.alert("Error", isPresented: Binding(
44+
get: { loginError != nil },
45+
set: { isPresented in
46+
if !isPresented {
47+
loginError = nil
5048
}
51-
)) {
52-
Button("OK", role: .cancel) {}.keyboardShortcut(.defaultAction)
53-
} message: {
54-
Text(loginError?.description ?? "")
5549
}
56-
}.padding()
57-
.frame(width: 450, height: 220)
58-
.disabled(loading)
59-
.onReceive(inspection.notice) { self.inspection.visit(self, $0) } // ViewInspector
50+
)) {
51+
Button("OK", role: .cancel) {}.keyboardShortcut(.defaultAction)
52+
} message: {
53+
Text(loginError?.description ?? "")
54+
}.disabled(loading)
55+
.frame(width: 550)
56+
.fixedSize()
57+
.onReceive(inspection.notice) { self.inspection.visit(self, $0) } // ViewInspector
6058
}
6159

6260
func submit() async {
@@ -82,63 +80,69 @@ struct LoginForm<S: Session>: View {
8280
}
8381

8482
private var serverURLPage: some View {
85-
VStack(spacing: 15) {
86-
Text("Coder Desktop").font(.title).padding(.bottom, 15)
87-
VStack(alignment: .leading) {
88-
HStack(alignment: .firstTextBaseline) {
89-
Text("Server URL")
90-
Spacer()
91-
TextField("https://coder.example.com", text: $baseAccessURL)
92-
.textFieldStyle(RoundedBorderTextFieldStyle())
93-
.disableAutocorrection(true)
94-
.frame(width: 290, alignment: .leading)
83+
VStack(spacing: 0) {
84+
Spacer()
85+
Text("Coder Desktop").font(.title).padding(.top, 10)
86+
Form {
87+
Section {
88+
TextField(
89+
"Server URL",
90+
text: $baseAccessURL,
91+
prompt: Text("https://coder.example.com")
92+
).autocorrectionDisabled()
9593
.focused($focusedField, equals: .baseAccessURL)
9694
}
97-
}
95+
}.formStyle(.grouped).scrollDisabled(true).padding()
96+
Divider()
9897
HStack {
98+
Spacer()
9999
Button("Next", action: next)
100-
.buttonStyle(.borderedProminent)
101100
.keyboardShortcut(.defaultAction)
102101
}
103-
.padding(.top, 10)
104-
}.padding(.horizontal, 15)
102+
.padding(20)
103+
}
104+
}
105+
106+
private var cliAuthURL: URL {
107+
URL(string: baseAccessURL)!.appendingPathComponent("cli-auth")
105108
}
106109

107110
private var sessionTokenPage: some View {
108-
VStack {
109-
VStack(alignment: .leading) {
110-
HStack(alignment: .firstTextBaseline) {
111-
Text("Server URL")
112-
Spacer()
113-
TextField("https://coder.example.com", text: $baseAccessURL)
114-
.textFieldStyle(RoundedBorderTextFieldStyle())
115-
.disableAutocorrection(true)
116-
.frame(width: 290, alignment: .leading)
117-
.disabled(true)
111+
VStack(alignment: .leading, spacing: 0) {
112+
Form {
113+
Section {
114+
TextField(
115+
"Server URL",
116+
text: $baseAccessURL,
117+
prompt: Text("https://coder.example.com")
118+
).disabled(true)
118119
}
119-
HStack(alignment: .firstTextBaseline) {
120-
Text("Session Token")
121-
Spacer()
122-
SecureField("", text: $sessionToken)
123-
.textFieldStyle(RoundedBorderTextFieldStyle())
124-
.disableAutocorrection(true)
125-
.frame(width: 290, alignment: .leading)
120+
Section {
121+
SecureField("Session Token", text: $sessionToken, prompt: Text("●●●●●●●●"))
122+
.autocorrectionDisabled()
126123
.privacySensitive()
127124
.focused($focusedField, equals: .sessionToken)
125+
HStack(spacing: 0) {
126+
Text("Generate a session token at ")
127+
.font(.subheadline)
128+
.foregroundColor(.secondary)
129+
Link(cliAuthURL.absoluteString, destination: cliAuthURL)
130+
.font(.subheadline)
131+
.foregroundColor(.blue)
132+
}
128133
}
129-
Link(
130-
"Generate a token via the Web UI",
131-
destination: URL(string: baseAccessURL)!.appendingPathComponent("cli-auth")
132-
).font(.callout).foregroundColor(.blue).underline()
133-
}.padding()
134+
}.formStyle(.grouped).scrollDisabled(true).padding()
135+
Divider()
134136
HStack {
135-
Button("Back", action: back)
137+
Spacer()
138+
Button("Back", action: back).keyboardShortcut(.cancelAction)
136139
Button("Sign In") {
137140
Task { await submit() }
138141
}
139142
.buttonStyle(.borderedProminent)
140143
.keyboardShortcut(.defaultAction)
141-
}.padding(.top, 5)
144+
}
145+
.padding(20)
142146
}
143147
}
144148

0 commit comments

Comments
 (0)