feat: 样式。。。
This commit is contained in:
parent
a8f6be62e1
commit
cd9af65019
Binary file not shown.
@ -7,5 +7,25 @@
|
|||||||
<string>Quicksand x.ttf</string>
|
<string>Quicksand x.ttf</string>
|
||||||
<string>SankeiCutePopanime.ttf</string>
|
<string>SankeiCutePopanime.ttf</string>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
|
<!-- Apple Sign In Configuration -->
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<key>ASAuthorizationAppleIDProvider</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
|
||||||
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>appleid</string>
|
||||||
|
<string>appleauth</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import AuthenticationServices
|
||||||
import Alamofire
|
import Alamofire
|
||||||
|
|
||||||
struct Post: Codable {
|
struct Post: Codable {
|
||||||
@ -16,88 +17,146 @@ struct Login: Encodable {
|
|||||||
struct LoginView: View {
|
struct LoginView: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
@State private var showModal = false
|
@State private var showModal = false
|
||||||
@State private var username = ""
|
|
||||||
@State private var password = ""
|
|
||||||
@State private var isLoading = false
|
@State private var isLoading = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
ZStack {
|
ZStack {
|
||||||
VStack {
|
VStack {
|
||||||
// Back button and settings
|
// App logo or title
|
||||||
HStack {
|
VStack {
|
||||||
Button(action: { dismiss() }) {
|
Image(systemName: "person.circle.fill")
|
||||||
HStack {
|
.resizable()
|
||||||
Image(systemName: "chevron.left")
|
.frame(width: 80, height: 80)
|
||||||
Text("返回")
|
.foregroundColor(.blue)
|
||||||
}
|
.padding(.bottom, 20)
|
||||||
.padding()
|
|
||||||
}
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
Button(action: { showModal = true }) {
|
Text("Welcome")
|
||||||
Image(systemName: "gearshape")
|
.font(.largeTitle)
|
||||||
.font(.title2)
|
.fontWeight(.bold)
|
||||||
.padding()
|
.padding(.bottom, 40)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login form
|
// Apple Sign In Button
|
||||||
VStack(spacing: 20) {
|
SignInWithAppleButton(
|
||||||
Text("邮箱登录").font(.title)
|
onRequest: { request in
|
||||||
|
request.requestedScopes = [.fullName, .email]
|
||||||
|
},
|
||||||
|
onCompletion: { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let authResults):
|
||||||
|
print("Authorization successful: \(authResults)")
|
||||||
|
// Handle successful authentication
|
||||||
|
// You can get user details from authResults.credential
|
||||||
|
if let appleIDCredential = authResults.credential as? ASAuthorizationAppleIDCredential {
|
||||||
|
let userId = appleIDCredential.user
|
||||||
|
let email = appleIDCredential.email
|
||||||
|
let fullName = appleIDCredential.fullName
|
||||||
|
|
||||||
// Username field
|
print("User ID: \(userId)")
|
||||||
TextField("请输入用户名", text: $username)
|
print("Email: \(email ?? "No email")")
|
||||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
print("Name: \(fullName?.givenName ?? "") \(fullName?.familyName ?? "")")
|
||||||
.padding(.horizontal)
|
|
||||||
|
|
||||||
// Password field
|
// TODO: Send this information to your backend
|
||||||
SecureField("请输入密码", text: $password)
|
// For example:
|
||||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
// loginWithApple(userId: userId, email: email, name: "\(fullName?.givenName ?? "") \(fullName?.familyName ?? "")")
|
||||||
.padding(.horizontal)
|
|
||||||
|
|
||||||
// Login button
|
// Dismiss the login view after successful login
|
||||||
Button(action: handleLogin) {
|
DispatchQueue.main.async {
|
||||||
if isLoading {
|
self.dismiss()
|
||||||
ProgressView()
|
}
|
||||||
} else {
|
}
|
||||||
Text("登录")
|
|
||||||
|
case .failure(let error):
|
||||||
|
print("Authorization failed: \(error.localizedDescription)")
|
||||||
|
// Handle error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.borderedProminent)
|
)
|
||||||
.disabled(isLoading)
|
.signInWithAppleButtonStyle(.black) // or .white, .whiteOutline
|
||||||
.padding()
|
.frame(height: 50)
|
||||||
|
.padding(.horizontal, 40)
|
||||||
|
.padding(.bottom, 20)
|
||||||
|
|
||||||
|
// Terms and Privacy Policy
|
||||||
|
VStack(spacing: 8) {
|
||||||
|
Text("By continuing, you agree to our")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
|
||||||
|
HStack(spacing: 16) {
|
||||||
|
Button("Terms of Service") {
|
||||||
|
// Open terms URL
|
||||||
|
if let url = URL(string: "https://yourwebsite.com/terms") {
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.blue)
|
||||||
|
|
||||||
|
Text("•")
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
|
||||||
|
Button("Privacy Policy") {
|
||||||
|
// Open privacy policy URL
|
||||||
|
if let url = URL(string: "https://yourwebsite.com/privacy") {
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.blue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.bottom, 40)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
|
.padding()
|
||||||
.navigationBarHidden(true)
|
.navigationBarHidden(true)
|
||||||
.navigationBarBackButtonHidden(true)
|
.navigationBarBackButtonHidden(true)
|
||||||
|
|
||||||
// Modal view
|
// Loading indicator
|
||||||
if showModal {
|
if isLoading {
|
||||||
Color.black.opacity(0.4)
|
Color.black.opacity(0.4)
|
||||||
.edgesIgnoringSafeArea(.all)
|
.edgesIgnoringSafeArea(.all)
|
||||||
.onTapGesture { showModal = false }
|
|
||||||
|
|
||||||
// Your modal content here
|
ProgressView()
|
||||||
VStack {
|
.scaleEffect(1.5)
|
||||||
Text("Settings")
|
.progressViewStyle(CircularProgressViewStyle(tint: .white))
|
||||||
Button("Close") { showModal = false }
|
|
||||||
}
|
|
||||||
.frame(width: 300, height: 200)
|
|
||||||
.background(Color.white)
|
|
||||||
.cornerRadius(20)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLogin() {
|
// Example function to handle login with your backend
|
||||||
|
private func loginWithApple(userId: String, email: String?, name: String) {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
// Your login logic here
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
// Replace with your actual API endpoint
|
||||||
isLoading = false
|
let url = "https://your-api-endpoint.com/auth/apple"
|
||||||
}
|
let parameters: [String: Any] = [
|
||||||
|
"appleUserId": userId,
|
||||||
|
"email": email ?? "",
|
||||||
|
"name": name,
|
||||||
|
// Add any other required parameters
|
||||||
|
]
|
||||||
|
|
||||||
|
AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default)
|
||||||
|
.validate()
|
||||||
|
.responseJSON { response in
|
||||||
|
isLoading = false
|
||||||
|
|
||||||
|
switch response.result {
|
||||||
|
case .success(let value):
|
||||||
|
print("Login successful: \(value)")
|
||||||
|
// Handle successful login (e.g., save auth token, navigate to home screen)
|
||||||
|
dismiss()
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
print("Login failed: \(error.localizedDescription)")
|
||||||
|
// Show error message to user
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user