Skip to content

Commit

Permalink
๐ŸŽจ :: [#44] Tuist ๋ฒ„์ „ ๋ณ€๊ฒฝ / ์ „์ฒด์ ์ธ ์ฝ”๋“œ ์ˆ˜์ • / ๊ฐ์ข… ์˜ค๋ฅ˜ ํ•ด๊ฒฐ
Browse files Browse the repository at this point in the history
  • Loading branch information
Xixn2 committed Dec 30, 2024
1 parent c3617a4 commit 6dc5245
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .mise.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[tools]
tuist = "4.32.0"
tuist = "4.9.0"

Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,40 @@ struct LoginView: View {
@StateObject var userInfoViewModel: UserInfoViewModel

var body: some View {
NavigationStack {
ZStack {
GPleAsset.Color.back.swiftUIColor
.ignoresSafeArea()
VStack(spacing: 0) {
Spacer()

GPleAsset.Assets.gpleLogo.swiftUIImage
.padding(.bottom, 20)

Text("GSM ์‚ฌ์ง„ ๊ณต์œ  ์„œ๋น„์Šค")
.foregroundStyle(GPleAsset.Color.gray400.swiftUIColor)
.font(GPleFontFamily.Pretendard.semiBold.swiftUIFont(size: 20))
.padding(.bottom, 90)

Spacer()

GPleAsset.Assets.map.swiftUIImage
.resizable()
.ignoresSafeArea()
.frame(width: 410, height: 500)
}

VStack {
Spacer()

LoginButton(loginViewModel: viewModel)
.padding(.bottom, 40)
}
}
}
.fullScreenCover(isPresented: $viewModel.isSignedIn) {
UserInfoView(viewModel: UserInfoViewModel())
}
.navigationBarBackButtonHidden(true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Domain
final class LoginViewModel: ObservableObject {
@Published var isSignedIn: Bool = false
@Published var errorMessage: String?

private let provider = MoyaProvider<AuthAPI>()

private func getGoogleClientID() -> String? {
Expand All @@ -25,7 +25,6 @@ final class LoginViewModel: ObservableObject {
print("Google Client ID is missing.")
return
}


let configuration = GIDConfiguration(clientID: clientID)
GIDSignIn.sharedInstance.configuration = configuration
Expand All @@ -50,70 +49,87 @@ final class LoginViewModel: ObservableObject {

print("CILENT_ID: \(clientID)")
print("ID Token: \(idToken)")
self?.sendIdTokenToServer(idToken)
self?.sendIdTokenToServer(idToken) { success in
if success {
print("ํ† ํฐ ์ €์žฅ ์„ฑ๊ณต!")
} else {
print("ํ† ํฐ ์ €์žฅ ์‹คํŒจ.")
}
}

}
}

@MainActor
private func sendIdTokenToServer(_ idToken: String) {
public func sendIdTokenToServer(_ idToken: String, completion: @escaping (Bool) -> Void) {
provider.request(.login(idToken: idToken)) { [weak self] result in
switch result {
case let .success(res):
do {

let loginResponse = try JSONDecoder().decode(Token.self, from: res.data)

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

if let accessTokenExpirationDate = dateFormatter.date(from: loginResponse.accessExpiredAt),
let refreshTokenExpirationDate = dateFormatter.date(from: loginResponse.refreshExpiredAt) {
let accessTokenExpirationDate = dateFormatter.date(from: loginResponse.accessExpiredAt)
let refreshTokenExpirationDate = dateFormatter.date(from: loginResponse.refreshExpiredAt)

let accessTokenExpirationInterval = accessTokenExpirationDate.timeIntervalSinceNow
let refreshTokenExpirationInterval = refreshTokenExpirationDate.timeIntervalSinceNow
if accessTokenExpirationDate == nil {
print("Access Token ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ๋ณ€ํ™˜ ์‹คํŒจ: ํ˜•์‹์ด ๋งž์ง€ ์•Š์Œ, ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ์ฒ˜๋ฆฌ๋จ.")
}
if refreshTokenExpirationDate == nil {
print("Refresh Token ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ๋ณ€ํ™˜ ์‹คํŒจ: ํ˜•์‹์ด ๋งž์ง€ ์•Š์Œ, ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ์ฒ˜๋ฆฌ๋จ.")
}

KeyChain.shared.saveTokenWithExpiration(
key: Const.KeyChainKey.accessToken,
token: loginResponse.accessToken,
expiresIn: accessTokenExpirationInterval
)
let accessTokenExpirationInterval = accessTokenExpirationDate?.timeIntervalSinceNow ?? 0
let refreshTokenExpirationInterval = refreshTokenExpirationDate?.timeIntervalSinceNow ?? 0

KeyChain.shared.saveTokenWithExpiration(
key: Const.KeyChainKey.refreshToken,
token: loginResponse.refreshToken,
expiresIn: refreshTokenExpirationInterval
)
UserDefaults.standard.set(loginResponse.accessToken, forKey: "accessToken")
UserDefaults.standard.set(loginResponse.refreshToken, forKey: "refreshToken")

print("Access Token ๋งŒ๋ฃŒ ๋‚ ์งœ: \(accessTokenExpirationDate)")
print("Refresh Token ๋งŒ๋ฃŒ ๋‚ ์งœ: \(refreshTokenExpirationDate)")
print("ํ† ํฐ ์ €์žฅ ์™„๋ฃŒ")
if let savedAccessToken = UserDefaults.standard.string(forKey: "accessToken") {
print("Access Token ์ €์žฅ ์™„๋ฃŒ: \(savedAccessToken)")
} else {
print("๋งŒ๋ฃŒ ์‹œ๊ฐ„ ๋ณ€ํ™˜ ์˜ค๋ฅ˜: ์œ ํšจํ•œ ๋‚ ์งœ ํ˜•์‹์ด ์•„๋‹˜.")
print("Access Token ์ €์žฅ ์‹คํŒจ")
}
print("------------------------------------------------------------")


if let savedRefreshToken = UserDefaults.standard.string(forKey: "refreshToken") {
print("Refresh Token ์ €์žฅ ์™„๋ฃŒ: \(savedRefreshToken)")
} else {
print("Refresh Token ์ €์žฅ ์‹คํŒจ")
}

print("Access Token ๋งŒ๋ฃŒ ๋‚ ์งœ: \(accessTokenExpirationDate ?? Date())")
print("Refresh Token ๋งŒ๋ฃŒ ๋‚ ์งœ: \(refreshTokenExpirationDate ?? Date())")
print("ํ† ํฐ ์ €์žฅ ์™„๋ฃŒ")

DispatchQueue.main.async {
print("Access Token: \(loginResponse.accessToken)")
print("Refresh Token: \(loginResponse.refreshToken)")
print("Access Token Expiry: \(loginResponse.accessExpiredAt)")
print("Refresh Token Expiry: \(loginResponse.refreshExpiredAt)")
self?.isSignedIn = true
}

completion(true)

} catch {
DispatchQueue.main.async {
self?.errorMessage = "Failed to parse response: \(error.localizedDescription)"
}

completion(false)
}

case .failure(let error):
DispatchQueue.main.async {
self?.errorMessage = "Request failed: \(error.localizedDescription)"
}

completion(false)
}
}
}




func signOut() {
GIDSignIn.sharedInstance.signOut()
DispatchQueue.main.async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Foundation

final class LocationPostViewModel: ObservableObject {
private let authProvider = MoyaProvider<MainAPI>()
private var accessToken: String = "Bearer eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiIyIiwiaWF0IjoxNzM0NjYyNTg4LCJleHAiOjE3NDQ2NjI1ODh9.FG4FVQ4oikC4HNy5h7gq0QyCIjVZtceIOKwAMnkULAt4y0lX5gGIF1s2Mdj9qr1H"
private var accessToken: String = UserDefaults.standard.string(forKey: "accessToken") ?? ""

@Published public var gymPostList: [Post] = []
@Published public var homePostList: [Post] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ struct MainView: View {
}
}
}
.navigationBarBackButtonHidden(true)
}

@ViewBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Foundation

public final class MainViewModel: ObservableObject {
private let authProvider = MoyaProvider<MainAPI>()
private var accessToken: String = "Bearer eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiIyIiwiaWF0IjoxNzM0NjYyNTg4LCJleHAiOjE3NDQ2NjI1ODh9.FG4FVQ4oikC4HNy5h7gq0QyCIjVZtceIOKwAMnkULAt4y0lX5gGIF1s2Mdj9qr1H"
private var accessToken: String = UserDefaults.standard.string(forKey: "accessToken") ?? ""

@Published public var allPostList: [Post] = []
@Published public var gymPostList: [Post] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ struct MyPageView: View {
@State private var topNavigationState = false
@StateObject var postViewModel: PostViewModel
@Environment(\.dismiss) private var dismiss
@State private var navigateToUserInfo = false
@State private var navigateToLogin = false

var body: some View {
NavigationStack {
Expand Down Expand Up @@ -49,18 +51,31 @@ struct MyPageView: View {
Spacer()

Menu {
Button("ํ”„๋กœํ•„ ๋ณ€๊ฒฝ", action: {
})
Button("ํ”„๋กœํ•„ ๋ณ€๊ฒฝ", action: { navigateToUserInfo = true })
.font(GPleFontFamily.Pretendard.regular.swiftUIFont(size: 16))
Button("๋กœ๊ทธ์•„์›ƒ", action: { /* ์•ก์…˜ */ })
Button("๋กœ๊ทธ์•„์›ƒ", action: { navigateToLogin = true })
.font(GPleFontFamily.Pretendard.regular.swiftUIFont(size: 16))
.foregroundStyle(GPleAsset.Color.system.swiftUIColor)

} label: {
GPleAsset.Assets.point3.swiftUIImage
.padding(.trailing, 20)
.padding(.top, 8)
}

NavigationLink(
destination: UserInfoView(viewModel: UserInfoViewModel()),
isActive: $navigateToUserInfo
) {
EmptyView()
}

// ๋กœ๊ทธ์•„์›ƒ ํ™”๋ฉด ๋„ค๋น„๊ฒŒ์ด์…˜
NavigationLink(
destination: LoginView(viewModel: LoginViewModel(), userInfoViewModel: UserInfoViewModel()),
isActive: $navigateToLogin
) {
EmptyView()
}
}

VStack(alignment: topNavigationState ? .trailing : .leading, spacing: 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ struct PostCreateView: View {
ForEach(filteredUsers.indices, id: \.self) { index in
let student = filteredUsers[index]
searchUserList(
userProfileImage: student.profileImage,
userProfileImage: student.profileImage ?? "",
userName: student.name,
userYear: student.grade,
userId: student.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public final class PostViewModel: ObservableObject {
)
private let userProvider = MoyaProvider<UserAPI>()
private var title: String = ""
private var accessToken: String = "Bearer eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiIyIiwiaWF0IjoxNzM0NjYyNTg4LCJleHAiOjE3NDQ2NjI1ODh9.FG4FVQ4oikC4HNy5h7gq0QyCIjVZtceIOKwAMnkULAt4y0lX5gGIF1s2Mdj9qr1H"
private var accessToken: String = UserDefaults.standard.string(forKey: "accessToken") ?? ""
private var userList: [Int] = []
private var imageUrl: [String] = []
private var imageUrlString: [String] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import SwiftUI

struct UserInfoView: View {
@Environment(\.dismiss) private var dismiss
@State private var isSuccess: Bool = false
@StateObject var viewModel: UserInfoViewModel

var body: some View {
NavigationStack {
ZStack(alignment: .leading) {
GPleAsset.Color.back.swiftUIColor
.ignoresSafeArea()

VStack(alignment: .leading, spacing: 0) {
ZStack {
HStack {
Expand All @@ -19,74 +21,90 @@ struct UserInfoView: View {
}
Spacer()
}

Text("์ •๋ณด ์ž…๋ ฅ")
.foregroundStyle(.white)
.font(GPleFontFamily.Pretendard.semiBold.swiftUIFont(size: 18))
}
.padding(.bottom, 16)
.padding(.top, 8)
.padding(.horizontal, 20)

VStack(spacing: 0) {
HStack {
Text("์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”")
.font(GPleFontFamily.Pretendard.semiBold.swiftUIFont(size: 24))
.foregroundStyle(GPleAsset.Color.white.swiftUIColor)

Spacer()
}
.padding(.top, 20)
.padding(.bottom, 8)

HStack {
Text("์›ํ™œํ•œ ์„œ๋น„์Šค๋ฅผ ์œ„ํ•ด ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”")
.font(GPleFontFamily.Pretendard.regular.swiftUIFont(size: 16))
.foregroundStyle(GPleAsset.Color.white.swiftUIColor)

Spacer()
}
.padding(.bottom, 20)

HStack {
Text("์ด๋ฆ„")
.font(GPleFontFamily.Pretendard.regular.swiftUIFont(size: 14))
.foregroundStyle(GPleAsset.Color.white.swiftUIColor)

Spacer()
}
.padding(.bottom, 4)
}
.padding(.horizontal, 20)

GPleTextField("์ด๋ฆ„์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”", text: $viewModel.name)

HStack {
Text("ํ•™๋ฒˆ")
.font(GPleFontFamily.Pretendard.regular.swiftUIFont(size: 14))
.foregroundStyle(GPleAsset.Color.white.swiftUIColor)

Spacer()
}
.padding(.horizontal, 20)
.padding(.top, 20)
.padding(.bottom, 4)

GPleTextField("ํ•™๋ฒˆ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”", text: $viewModel.number)

Spacer()

GPleButton(text: "์™„๋ฃŒ",
horizontalPadding: 20,
verticalPadding: 16,
backColor: GPleAsset.Color.gray1000.swiftUIColor,
buttonState: viewModel.name.isEmpty == false && viewModel.number.isEmpty == false,
buttonOkColor: GPleAsset.Color.main.swiftUIColor
) {
viewModel.submitUserInfo()
viewModel.submitUserInfo { success in
if success {
isSuccess = true
print("์ •๋ณด ์ „์†ก ์„ฑ๊ณต!!")
} else {
print("์ •๋ณด ์ „์†ก ์‹คํŒจ!!")
}
}
}
.padding(.bottom, 12)

NavigationLink(
destination: MainView(viewModel: MainViewModel(), postViewModel: PostViewModel()),
isActive: $isSuccess
) {
EmptyView()
}
}
}
}
.navigationBarBackButtonHidden(true)
}
}
Loading

0 comments on commit 6dc5245

Please sign in to comment.