diff --git a/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate b/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate index 4d3fbc5..39fe2f5 100644 Binary files a/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate and b/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/wake/Info.plist b/wake/Info.plist index efad56b..3a0d680 100644 --- a/wake/Info.plist +++ b/wake/Info.plist @@ -7,5 +7,25 @@ Quicksand x.ttf SankeiCutePopanime.ttf + + + CFBundleURLTypes + + + CFBundleURLSchemes + + $(PRODUCT_BUNDLE_IDENTIFIER) + + + + + ASAuthorizationAppleIDProvider + $(PRODUCT_BUNDLE_IDENTIFIER) + + LSApplicationQueriesSchemes + + appleid + appleauth + diff --git a/wake/View/Login/Login.swift b/wake/View/Login/Login.swift index 72b526f..d9d4dde 100644 --- a/wake/View/Login/Login.swift +++ b/wake/View/Login/Login.swift @@ -1,4 +1,5 @@ import SwiftUI +import AuthenticationServices import Alamofire struct Post: Codable { @@ -16,88 +17,146 @@ struct Login: Encodable { struct LoginView: View { @Environment(\.dismiss) private var dismiss @State private var showModal = false - @State private var username = "" - @State private var password = "" @State private var isLoading = false var body: some View { NavigationView { ZStack { VStack { - // Back button and settings - HStack { - Button(action: { dismiss() }) { - HStack { - Image(systemName: "chevron.left") - Text("返回") - } - .padding() - } - Spacer() + // App logo or title + VStack { + Image(systemName: "person.circle.fill") + .resizable() + .frame(width: 80, height: 80) + .foregroundColor(.blue) + .padding(.bottom, 20) - Button(action: { showModal = true }) { - Image(systemName: "gearshape") - .font(.title2) - .padding() - } + Text("Welcome") + .font(.largeTitle) + .fontWeight(.bold) + .padding(.bottom, 40) } - // Login form - VStack(spacing: 20) { - Text("邮箱登录").font(.title) - - // Username field - TextField("请输入用户名", text: $username) - .textFieldStyle(RoundedBorderTextFieldStyle()) - .padding(.horizontal) - - // Password field - SecureField("请输入密码", text: $password) - .textFieldStyle(RoundedBorderTextFieldStyle()) - .padding(.horizontal) - - // Login button - Button(action: handleLogin) { - if isLoading { - ProgressView() - } else { - Text("登录") + // Apple Sign In Button + SignInWithAppleButton( + 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 + + print("User ID: \(userId)") + print("Email: \(email ?? "No email")") + print("Name: \(fullName?.givenName ?? "") \(fullName?.familyName ?? "")") + + // TODO: Send this information to your backend + // For example: + // loginWithApple(userId: userId, email: email, name: "\(fullName?.givenName ?? "") \(fullName?.familyName ?? "")") + + // Dismiss the login view after successful login + DispatchQueue.main.async { + self.dismiss() + } + } + + case .failure(let error): + print("Authorization failed: \(error.localizedDescription)") + // Handle error } } - .buttonStyle(.borderedProminent) - .disabled(isLoading) - .padding() + ) + .signInWithAppleButtonStyle(.black) // or .white, .whiteOutline + .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() } + .padding() .navigationBarHidden(true) .navigationBarBackButtonHidden(true) - // Modal view - if showModal { + // Loading indicator + if isLoading { Color.black.opacity(0.4) .edgesIgnoringSafeArea(.all) - .onTapGesture { showModal = false } - // Your modal content here - VStack { - Text("Settings") - Button("Close") { showModal = false } - } - .frame(width: 300, height: 200) - .background(Color.white) - .cornerRadius(20) + ProgressView() + .scaleEffect(1.5) + .progressViewStyle(CircularProgressViewStyle(tint: .white)) } } } } - func handleLogin() { + // Example function to handle login with your backend + private func loginWithApple(userId: String, email: String?, name: String) { isLoading = true - // Your login logic here - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - isLoading = false - } + + // Replace with your actual API endpoint + 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 + } + } } }