diff --git a/MobileAcebook.xcodeproj/project.pbxproj b/MobileAcebook.xcodeproj/project.pbxproj index 5506db3b..173677cd 100644 --- a/MobileAcebook.xcodeproj/project.pbxproj +++ b/MobileAcebook.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 10D70DA82AD44C30003B552B /* LogInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10D70DA72AD44C30003B552B /* LogInView.swift */; }; + 9105C5752AD6C3BB00ABFC89 /* Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9105C5742AD6C3BB00ABFC89 /* Post.swift */; }; + 9105C5772AD6C3C600ABFC89 /* PostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9105C5762AD6C3C600ABFC89 /* PostsView.swift */; }; AE5D85B02AC8A221009680C6 /* MobileAcebookApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE5D85AF2AC8A221009680C6 /* MobileAcebookApp.swift */; }; AE5D85B42AC8A224009680C6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AE5D85B32AC8A224009680C6 /* Assets.xcassets */; }; AE5D85B72AC8A224009680C6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AE5D85B62AC8A224009680C6 /* Preview Assets.xcassets */; }; @@ -39,6 +42,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 10D70DA72AD44C30003B552B /* LogInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogInView.swift; sourceTree = ""; }; + 9105C5742AD6C3BB00ABFC89 /* Post.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Post.swift; sourceTree = ""; }; + 9105C5762AD6C3C600ABFC89 /* PostsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostsView.swift; sourceTree = ""; }; AE5D85AC2AC8A221009680C6 /* MobileAcebook.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MobileAcebook.app; sourceTree = BUILT_PRODUCTS_DIR; }; AE5D85AF2AC8A221009680C6 /* MobileAcebookApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileAcebookApp.swift; sourceTree = ""; }; AE5D85B32AC8A224009680C6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -104,6 +110,7 @@ AE5D85AE2AC8A221009680C6 /* MobileAcebook */ = { isa = PBXGroup; children = ( + 9105C5762AD6C3C600ABFC89 /* PostsView.swift */, AE5D85E42AC9B060009680C6 /* Protocols */, AE5D85DF2AC9AF83009680C6 /* Models */, AE5D85DD2AC9AF72009680C6 /* Services */, @@ -111,6 +118,7 @@ AE5D85B32AC8A224009680C6 /* Assets.xcassets */, AE5D85B52AC8A224009680C6 /* Preview Content */, AE5D85D92AC8A337009680C6 /* WelcomePageView.swift */, + 10D70DA72AD44C30003B552B /* LogInView.swift */, ); path = MobileAcebook; sourceTree = ""; @@ -161,6 +169,7 @@ AE5D85DF2AC9AF83009680C6 /* Models */ = { isa = PBXGroup; children = ( + 9105C5742AD6C3BB00ABFC89 /* Post.swift */, AE5D85E72AC9B29A009680C6 /* User.swift */, ); path = Models; @@ -304,10 +313,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 10D70DA82AD44C30003B552B /* LogInView.swift in Sources */, AE5D85E12AC9AFA9009680C6 /* AuthenticationService.swift in Sources */, AE5D85E62AC9B077009680C6 /* AuthenticationServiceProtocol.swift in Sources */, AE5D85B02AC8A221009680C6 /* MobileAcebookApp.swift in Sources */, AE5D85E82AC9B29A009680C6 /* User.swift in Sources */, + 9105C5752AD6C3BB00ABFC89 /* Post.swift in Sources */, + 9105C5772AD6C3C600ABFC89 /* PostsView.swift in Sources */, AE5D85DA2AC8A337009680C6 /* WelcomePageView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/MobileAcebook/LogInView.swift b/MobileAcebook/LogInView.swift new file mode 100644 index 00000000..6c97cf4e --- /dev/null +++ b/MobileAcebook/LogInView.swift @@ -0,0 +1,84 @@ +// +// LogInView.swift +// MobileAcebook +// +// Created by Ami Day on 09/10/2023. +// + +import Foundation +import SwiftUI +import Combine + + +struct LogInView: View { + @State private var userModel = User(email: "", password: "") + @State private var loggedIn = false + + private func onEmailInputChanged(changedEmail: String) { + userModel.email = changedEmail + print("changed email: \(userModel.email)") + } + + private func onPasswordInputChanged(changedPassword: String) { + userModel.password = changedPassword + print("changed password: \(userModel.password)") + } + let authenticationService = AuthenticationService() + var body: some View { + NavigationView { + ZStack { + VStack { + + Spacer() + + Image("makers-logo") + .resizable() + .scaledToFit() + .frame(width: 200, height: 200) + .accessibilityIdentifier("makers-logo") + + Spacer() + LabeledContent { + TextField("Email", text: $userModel.email).textInputAutocapitalization(.never) + } label: { + Text("Email") + }.onChange(of: userModel.email, perform: onEmailInputChanged) + + LabeledContent { + TextField("Password", text: $userModel.password).textInputAutocapitalization(.never) + } label: { + Text("Password") + }.onChange(of: userModel.password, perform: onPasswordInputChanged) + + + Button(action: { + var response = authenticationService.login(user: userModel) { isSuccess in + if isSuccess { + loggedIn = true + } + } + }) { + Text("Login") + } + .accessibilityIdentifier("LoginButton") + + NavigationLink(destination: PostsView().navigationBarBackButtonHidden(true), isActive: $loggedIn) { EmptyView() } + + Button("Sign Up") { + // TODO: sign up logic + } + .accessibilityIdentifier("signUpButton") + + } + + Spacer() + } + } + } + + struct LogInView_Previews: PreviewProvider { + static var previews: some View { + LogInView() + } + } +} diff --git a/MobileAcebook/Models/Post.swift b/MobileAcebook/Models/Post.swift new file mode 100644 index 00000000..b256b217 --- /dev/null +++ b/MobileAcebook/Models/Post.swift @@ -0,0 +1,10 @@ +// +// Post.swift +// MobileAcebook +// +// Created by Jenny Wark on 11/10/2023. +// + +public struct Post { + let message: String +} diff --git a/MobileAcebook/Models/User.swift b/MobileAcebook/Models/User.swift index ea748dd0..c4835094 100644 --- a/MobileAcebook/Models/User.swift +++ b/MobileAcebook/Models/User.swift @@ -5,7 +5,7 @@ // Created by Josué Estévez Fernández on 01/10/2023. // -public struct User { - let username: String - let password: String +public struct User: Encodable { + var email: String + var password: String } diff --git a/MobileAcebook/PostsView.swift b/MobileAcebook/PostsView.swift new file mode 100644 index 00000000..23a47f73 --- /dev/null +++ b/MobileAcebook/PostsView.swift @@ -0,0 +1,59 @@ +// +// PostsView.swift +// MobileAcebook +// +// Created by Jenny Wark on 11/10/2023. +// + +import SwiftUI + +struct PostsView: View { + @State private var authenticationService = AuthenticationService() + @State private var post_content: String = "" + var body: some View { + NavigationView { + VStack { + Spacer() + + Text("Posts") + .font(.largeTitle) + .padding(.bottom, 20) + .accessibilityIdentifier("welcomeText") + + Spacer() + + Image("makers-logo") + .resizable() + .scaledToFit() + .frame(width: 200, height: 200) + .accessibilityIdentifier("makers-logo") + + Spacer() + + TextField("Write a post", text: $post_content) + .textFieldStyle(RoundedBorderTextFieldStyle()) + .padding() + +// Button(action: { +// authenticationService.createPost(post: Post(message: post_content)) +// }) { +// Text("Create Post") +// } +// .accessibilityIdentifier("CreatePostButton") + + Spacer() + +// let Posts = authenticationService.allPosts + + Spacer() + + } + } + } +} + +struct PostsView_Previews: PreviewProvider { + static var previews: some View { + PostsView() + } +} diff --git a/MobileAcebook/Services/AuthenticationService.swift b/MobileAcebook/Services/AuthenticationService.swift index 9f7181c3..e266d6f8 100644 --- a/MobileAcebook/Services/AuthenticationService.swift +++ b/MobileAcebook/Services/AuthenticationService.swift @@ -4,10 +4,117 @@ // // Created by Josué Estévez Fernández on 01/10/2023. // +import Foundation class AuthenticationService: AuthenticationServiceProtocol { + var userToken: String? + + + + func signUp(user: User) -> Bool { // Logic to call the backend API for signing up return true // placeholder } + + func login(user: User, completion: @escaping (Bool) -> Void) { + var request = URLRequest(url: URL(string: "http://localhost:8080/tokens")!) + request.httpMethod = "POST" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + + let jsonEncoder = JSONEncoder() + do { + let jsonData = try jsonEncoder.encode(user) + request.httpBody = jsonData + + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in + // Handling the response data, if any + var isSuccess = false + var token: String? = nil + + if let data = data { + do { + let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] + print("Response: \(jsonResponse)") + + if let message = jsonResponse?["message"] as? String, message == "OK" { + // If the response message is "Email not found", login is unsuccessful + isSuccess = true + if let token = jsonResponse?["token"] as? String { + // Store the token in a variable + self.userToken = token + print(self.userToken) + } + } + + } catch { + // Handle JSON parsing errors, if any + print("Error parsing JSON: \(error)") + } + } + + // Calling the completion handler with the login result (true for successful, false for unsuccessful) + completion(isSuccess) + } + + task.resume() + } catch { + // Handle encoding errors, if any + print("Error encoding user object: \(error)") + completion(false) // Calling the completion handler with false in case of an error + } + } + + +// func login(user: User) -> Bool { +// +// var request = URLRequest(url: URL(string: "http://localhost:8080/tokens")!) +// request.httpMethod = "POST" +// var res: [String: Any]? = ["message": ""] +// request.setValue("application/json", forHTTPHeaderField: "Content-Type") +// var ans = false +// +// let jsonEncoder = JSONEncoder() +// do { +// let jsonData = try jsonEncoder.encode(user) +// request.httpBody = jsonData +// +// let task = URLSession.shared.dataTask(with: request) { (data, response, error) in +// // Handle response here +// +// if let data = data { +// do { +// let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] +// print("Response: \(jsonResponse)") +// res = jsonResponse +// +// +// } catch { +// print("Error parsing JSON: \(error)") +// } +// +// } +// } +// +// task.resume() +// } catch { +// print("Error encoding user object: \(error)") +// +// } +// return ans +// +// if let message = res?["message"] as? String, message == "Email not found" { +// print("yhukh") +// return false +// }else { +// print(res?["message"]) +// print("working") +// return true +// } +// +// +//// +// } +// + } diff --git a/MobileAcebook/WelcomePageView.swift b/MobileAcebook/WelcomePageView.swift index 96006af9..46e32005 100644 --- a/MobileAcebook/WelcomePageView.swift +++ b/MobileAcebook/WelcomePageView.swift @@ -10,28 +10,40 @@ import SwiftUI struct WelcomePageView: View { var body: some View { ZStack { - VStack { - Spacer() - - Text("Welcome to Acebook!") - .font(.largeTitle) - .padding(.bottom, 20) - .accessibilityIdentifier("welcomeText") - - Spacer() - - Image("makers-logo") - .resizable() - .scaledToFit() - .frame(width: 200, height: 200) - .accessibilityIdentifier("makers-logo") - - Spacer() - - Button("Sign Up") { - // TODO: sign up logic + + NavigationView { + VStack { + + Spacer() + + Text("Welcome to Acebook!") + .font(.largeTitle) + .padding(.bottom, 20) + .accessibilityIdentifier("welcomeText") + + Spacer() + + Image("makers-logo") + .resizable() + .scaledToFit() + .frame(width: 200, height: 200) + .accessibilityIdentifier("makers-logo") + + Spacer() + + Button("Sign Up") { + // TODO: sign up logic + } + .accessibilityIdentifier("signUpButton") + + NavigationLink(destination: LogInView()) { + Text("Login") + .padding() + .background(Color.blue) + .foregroundColor(Color.white) + .cornerRadius(10) + } } - .accessibilityIdentifier("signUpButton") Spacer() }