diff --git a/.gitignore b/.gitignore index 8b1ed09a..9af8aebe 100644 --- a/.gitignore +++ b/.gitignore @@ -77,7 +77,4 @@ Signing/ master.key # PList -# => 전체 plist를 다 제외함. -# **/*.plist -# Support/*.plist GoogleService-Info.plist \ No newline at end of file diff --git a/TnT/.gitignore b/TnT/.gitignore index 8b1ed09a..9af8aebe 100644 --- a/TnT/.gitignore +++ b/TnT/.gitignore @@ -77,7 +77,4 @@ Signing/ master.key # PList -# => 전체 plist를 다 제외함. -# **/*.plist -# Support/*.plist GoogleService-Info.plist \ No newline at end of file diff --git a/TnT/Projects/DIContainer/Sources/DIContainer.swift b/TnT/Projects/DIContainer/Sources/DIContainer.swift index 4ad44f59..e0c12763 100644 --- a/TnT/Projects/DIContainer/Sources/DIContainer.swift +++ b/TnT/Projects/DIContainer/Sources/DIContainer.swift @@ -12,7 +12,11 @@ import Data // MARK: - Swift-Dependencies private enum UserUseCaseKey: DependencyKey { - static let liveValue: UserUseCase = DefaultUserUseCase(userRepository: UserRepositoryImpl()) + static let liveValue: UserUseCase = DefaultUserUseCase(userRepostiory: UserRepositoryImpl()) +} + +private enum UserUseCaseRepoKey: DependencyKey { + static let liveValue: UserRepository = DefaultUserUseCase(userRepostiory: UserRepositoryImpl()) } private enum TraineeUseCaseKey: DependencyKey { @@ -22,6 +26,10 @@ private enum TraineeUseCaseKey: DependencyKey { ) } +private enum SocialUseCaseKey: DependencyKey { + static let liveValue: SocialLoginUseCase = SocialLoginUseCase(socialLoginRepository: SocialLogInRepositoryImpl(loginManager: SNSLoginManager())) +} + // MARK: - DependencyValues public extension DependencyValues { var userUseCase: UserUseCase { @@ -29,8 +37,18 @@ public extension DependencyValues { set { self[UserUseCaseKey.self] = newValue } } + var userUseRepoCase: UserRepository { + get { self[UserUseCaseRepoKey.self] } + set { self[UserUseCaseRepoKey.self] = newValue } + } + var traineeUseCase: TraineeUseCase { get { self[TraineeUseCaseKey.self] } set { self[TraineeUseCaseKey.self] = newValue } } + + var socialLogInUseCase: SocialLoginUseCase { + get { self[SocialUseCaseKey.self] } + set { self[SocialUseCaseKey.self] = newValue } + } } diff --git a/TnT/Projects/Data/Sources/Network/Service/SocialLogin/SocialLogInRepositoryImpl.swift b/TnT/Projects/Data/Sources/Network/Service/SocialLogin/SocialLogInRepositoryImpl.swift new file mode 100644 index 00000000..51adca91 --- /dev/null +++ b/TnT/Projects/Data/Sources/Network/Service/SocialLogin/SocialLogInRepositoryImpl.swift @@ -0,0 +1,40 @@ +// +// SocialLogInRepositoryImpl.swift +// Data +// +// Created by 박서연 on 1/29/25. +// Copyright © 2025 yapp25thTeamTnT. All rights reserved. +// + +import Foundation +import Dependencies + +import Domain + +public enum LoginError: Error { + case invalidCredentials + case networkFailure + case kakaoError + case appleError + case unknown(message: String) +} + +public struct SocialLogInRepositoryImpl: SocialLoginRepository { + + public let loginManager: SNSLoginManager + + public init(loginManager: SNSLoginManager) { + self.loginManager = loginManager + } + + public func appleLogin() async -> AppleLoginInfo? { + let result = await loginManager.appleLogin() + + return result + } + + public func kakaoLogin() async -> KakaoLoginInfo? { + let result = await loginManager.kakaoLogin() + return result + } +} diff --git a/TnT/Projects/Data/Sources/Network/Service/User/UserRepositoryImpl.swift b/TnT/Projects/Data/Sources/Network/Service/User/UserRepositoryImpl.swift index 34ef8b28..251e35ea 100644 --- a/TnT/Projects/Data/Sources/Network/Service/User/UserRepositoryImpl.swift +++ b/TnT/Projects/Data/Sources/Network/Service/User/UserRepositoryImpl.swift @@ -13,7 +13,6 @@ import Domain /// 사용자 관련 네트워크 요청을 처리하는 UserRepository 구현체 public struct UserRepositoryImpl: UserRepository { - private let networkService: NetworkService = .shared public init() {} diff --git a/TnT/Projects/Domain/Sources/Entity/SocailLoginEntity.swift b/TnT/Projects/Domain/Sources/Entity/SocailLoginEntity.swift new file mode 100644 index 00000000..732aa9df --- /dev/null +++ b/TnT/Projects/Domain/Sources/Entity/SocailLoginEntity.swift @@ -0,0 +1,119 @@ +// +// PostSocailEntity.swift +// Domain +// +// Created by 박서연 on 1/31/25. +// Copyright © 2025 yapp25thTeamTnT. All rights reserved. +// + +import Foundation + +/// 소셜 로그인 요청 DTO +public struct PostSocailEntity: Equatable { + /// 소셜 로그인 타입 (KAKAO, APPLE) + let socialType: String + /// FCM 토큰 + let fcmToken: String + /// 소셜 액세스 토큰 + let socialAccessToken: String? + /// 애플 인가 코드 (Apple 로그인 시 필요) + let authorizationCode: String? + /// 애플 ID 토큰 (Apple 로그인 시 필요) + let idToken: String? + + public init( + socialType: String, + fcmToken: String, + socialAccessToken: String?, + authorizationCode: String?, + idToken: String? + ) { + self.socialType = socialType + self.fcmToken = fcmToken + self.socialAccessToken = socialAccessToken + self.authorizationCode = authorizationCode + self.idToken = idToken + } +} + +/// 소셜 로그인 응답 DTO +public struct PostSocialLoginResEntity: Equatable { + /// 세션 ID + public let sessionId: String? + /// 소셜 로그인 ID + public let socialId: String + /// 소셜 이메일 + public let socialEmail: String + /// 소셜 로그인 타입 (KAKAO, APPLE) + public let socialType: String + /// 가입 여부 (`true`: 이미 가입됨, `false`: 미가입) + public let isSignUp: Bool +} + +/// 회원가입 요청 DTO +public struct PostSignUpReqEntity { + /// FCM 토큰 + let fcmToken: String + /// 회원 타입 (trainer, trainee) + let memberType: String + /// 소셜 로그인 타입 (KAKAO, APPLE) + let socialType: String + /// 소셜 로그인 ID + let socialId: String + /// 소셜 로그인 이메일 + let socialEmail: String + /// 서비스 이용 약관 동의 여부 + let serviceAgreement: Bool + /// 개인정보 수집 동의 여부 + let collectionAgreement: Bool + /// 광고성 알림 수신 동의 여부 + let advertisementAgreement: Bool + /// 푸시 알림 수신 동의 여부 + let pushAgreement: Bool + /// 회원 이름 + let name: String + /// 생년월일 (yyyy-MM-dd) + let birthday: String? + /// 키 (cm) + let height: Double? + /// 몸무게 (kg, 소수점 1자리까지 가능) + let weight: Double? + /// 트레이너에게 전달할 주의사항 + let cautionNote: String? + /// PT 목적 (체중 감량, 근력 향상 등) + let goalContents: [String]? + + public init( + fcmToken: String, + memberType: String, + socialType: String, + socialId: String, + socialEmail: String, + serviceAgreement: Bool, + collectionAgreement: Bool, + advertisementAgreement: Bool, + pushAgreement: Bool, + name: String, + birthday: String?, + height: Double?, + weight: Double?, + cautionNote: String?, + goalContents: [String]? + ) { + self.fcmToken = fcmToken + self.memberType = memberType + self.socialType = socialType + self.socialId = socialId + self.socialEmail = socialEmail + self.serviceAgreement = serviceAgreement + self.collectionAgreement = collectionAgreement + self.advertisementAgreement = advertisementAgreement + self.pushAgreement = pushAgreement + self.name = name + self.birthday = birthday + self.height = height + self.weight = weight + self.cautionNote = cautionNote + self.goalContents = goalContents + } +} diff --git a/TnT/Projects/Domain/Sources/Mapper/PostSocialMapper.swift b/TnT/Projects/Domain/Sources/Mapper/PostSocialMapper.swift new file mode 100644 index 00000000..c299a03a --- /dev/null +++ b/TnT/Projects/Domain/Sources/Mapper/PostSocialMapper.swift @@ -0,0 +1,53 @@ +// +// PostSocialMapper.swift +// Domain +// +// Created by 박서연 on 1/31/25. +// Copyright © 2025 yapp25thTeamTnT. All rights reserved. +// + +import Foundation + +public struct PostSocialMapper { + public static func toDTO(from entity: PostSocailEntity) -> PostSocialLoginReqDTO { + return PostSocialLoginReqDTO( + socialType: entity.socialType, + fcmToken: entity.fcmToken, + socialAccessToken: entity.socialAccessToken, + authorizationCode: entity.authorizationCode, + idToken: entity.idToken + ) + } + + public static func toEntity(from dto: PostSocialLoginReqDTO) -> PostSocailEntity { + return PostSocailEntity( + socialType: dto.socialType, + fcmToken: dto.fcmToken, + socialAccessToken: dto.socialAccessToken, + authorizationCode: dto.authorizationCode, + idToken: dto.idToken + ) + } + + /// `PostSocialLoginResDTO` → `PostSocialLoginResEntity` 변환 + public static func toResEntity(from dto: PostSocialLoginResDTO) -> PostSocialLoginResEntity { + return PostSocialLoginResEntity( + sessionId: dto.sessionId, + socialId: dto.socialId, + socialEmail: dto.socialEmail, + socialType: dto.socialType, + isSignUp: dto.isSignUp + ) + } + + /// `PostSocialLoginResEntity` → `PostSocialLoginResDTO` 변환 + public static func toDTO(from entity: PostSocialLoginResEntity) -> PostSocialLoginResDTO { + return PostSocialLoginResDTO( + sessionId: entity.sessionId, + socialId: entity.socialId, + socialEmail: entity.socialEmail, + socialType: entity.socialType, + isSignUp: entity.isSignUp + ) + } +} diff --git a/TnT/Projects/Domain/Sources/Repository/SocialLoginRepository.swift b/TnT/Projects/Domain/Sources/Repository/SocialLoginRepository.swift index 57e0aab0..38abc6d3 100644 --- a/TnT/Projects/Domain/Sources/Repository/SocialLoginRepository.swift +++ b/TnT/Projects/Domain/Sources/Repository/SocialLoginRepository.swift @@ -14,6 +14,4 @@ public protocol SocialLoginRepository { func appleLogin() async -> AppleLoginInfo? /// 카카오 로그인을 수행합니다 func kakaoLogin() async -> KakaoLoginInfo? - /// 카카오 로그아웃을 수행합니다 - func kakaoLogout() async } diff --git a/TnT/Projects/Domain/Sources/UseCase/SocialLoginUseCase.swift b/TnT/Projects/Domain/Sources/UseCase/SocialLoginUseCase.swift new file mode 100644 index 00000000..6eea308b --- /dev/null +++ b/TnT/Projects/Domain/Sources/UseCase/SocialLoginUseCase.swift @@ -0,0 +1,26 @@ +// +// SocialLoginUseCase.swift +// Domain +// +// Created by 박서연 on 1/29/25. +// Copyright © 2025 yapp25thTeamTnT. All rights reserved. +// + +import Foundation + +public struct SocialLoginUseCase { + + private let socialLoginRepository: SocialLoginRepository + + public init(socialLoginRepository: SocialLoginRepository) { + self.socialLoginRepository = socialLoginRepository + } + + public func appleLogin() async -> AppleLoginInfo? { + return await socialLoginRepository.appleLogin() + } + + public func kakaoLogin() async -> KakaoLoginInfo? { + return await socialLoginRepository.kakaoLogin() + } +} diff --git a/TnT/Projects/Domain/Sources/UseCase/UserUseCase.swift b/TnT/Projects/Domain/Sources/UseCase/UserUseCase.swift index 852f9772..e83b8c3d 100644 --- a/TnT/Projects/Domain/Sources/UseCase/UserUseCase.swift +++ b/TnT/Projects/Domain/Sources/UseCase/UserUseCase.swift @@ -7,6 +7,7 @@ // import Dependencies +import Foundation // MARK: - UserUseCase 프로토콜 public protocol UserUseCase { @@ -27,13 +28,15 @@ public protocol UserUseCase { } // MARK: - Default 구현체 -public struct DefaultUserUseCase: UserUseCase { - private let userRepository: UserRepository +public struct DefaultUserUseCase: UserRepository, UserUseCase { - public init(userRepository: UserRepository) { - self.userRepository = userRepository + public let userRepostiory: UserRepository + + public init(userRepostiory: UserRepository) { + self.userRepostiory = userRepostiory } + // MARK: - Usecase public func validateUserName(_ name: String) -> Bool { return !name.isEmpty && UserPolicy.userNameInput.textValidation(name) } @@ -62,3 +65,15 @@ public struct DefaultUserUseCase: UserUseCase { return UserPolicy.maxPrecautionLength } } + +// MARK: - Repository +extension DefaultUserUseCase { + public func postSocialLogin(_ reqDTO: PostSocialLoginReqDTO) async throws -> PostSocialLoginResDTO { + return try await userRepostiory.postSocialLogin(reqDTO) + } + + public func postSignUp(_ reqDTO: PostSignUpReqDTO, profileImage: Data?) async throws -> PostSignUpResDTO { + return try await userRepostiory.postSignUp(reqDTO, profileImage: profileImage) + } +} + diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Common/OnboardingFeature.swift b/TnT/Projects/Presentation/Sources/Onboarding/Common/OnboardingFeature.swift similarity index 65% rename from TnT/Projects/Presentation/Sources/Onbarding/Common/OnboardingFeature.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Common/OnboardingFeature.swift index 7ce8974c..637777d3 100644 --- a/TnT/Projects/Presentation/Sources/Onbarding/Common/OnboardingFeature.swift +++ b/TnT/Projects/Presentation/Sources/Onboarding/Common/OnboardingFeature.swift @@ -9,17 +9,30 @@ import ComposableArchitecture import SwiftUI +import Domain +import DIContainer + @Reducer public struct OnboardingFeature { @ObservableState public struct State: Equatable { public var path = StackState() + public var userType: UserType? + public var nickname: String? = "" + public var socialType: LoginType? + public var termAgree: Bool = true + public var socialEmail: String? = "" + public var postUserEntity: PostSocailEntity? public init(path: StackState = StackState()) { self.path = path } } + @Dependency(\.userUseCase) private var userUseCase: UserUseCase + @Dependency(\.userUseRepoCase) private var userUseCaseRepo: UserRepository + @Dependency(\.socialLogInUseCase) private var socialLoginUseCase: SocialLoginUseCase + public enum Action: ViewAction { /// 뷰에서 일어나는 액션을 처리합니다.(카카오,애플로그인 실행) case view(View) @@ -32,6 +45,9 @@ public struct OnboardingFeature { public enum View: Equatable { case tappedAppleLogin case tappedKakaoLogin + case postSocialLogin(entity: PostSocailEntity) + case postSignUp + case socailLoginFail } @CasePathable @@ -56,6 +72,8 @@ public struct OnboardingFeature { case toRegisterInvitationCode /// 트레이니의 pt 횟수 및 정보 입력화면으로 이동 case toRegisterPtClassInfo + /// 홈으로 이동 + case toHome } } @@ -67,10 +85,51 @@ public struct OnboardingFeature { case let .view(view): switch view { case .tappedAppleLogin: - state.path.append(.term(TermFeature.State())) - return .none + return .run { @Sendable send in + let result = await socialLoginUseCase.appleLogin() + guard let result else { return } + let entity = PostSocailEntity( + socialType: "APPLE", + fcmToken: "", + socialAccessToken: "", + authorizationCode: result.authorizationCode, + idToken: result.identityToken + ) + + await send(.view(.postSocialLogin(entity: entity))) + } + case .tappedKakaoLogin: - state.path.append(.term(TermFeature.State())) + return .run { @Sendable send in + let result = await socialLoginUseCase.kakaoLogin() + guard let result else { return } + + let entity = PostSocailEntity( + socialType: "KAKAO", + fcmToken: "", + socialAccessToken: result.accessToken, + authorizationCode: "", + idToken: "" + ) + + await send(.view(.postSocialLogin(entity: entity))) + } + + case .postSocialLogin(let entity): + let post = PostSocialMapper.toDTO(from: entity) + return .run { send in + do { + let result = try await userUseCaseRepo.postSocialLogin(post) + await send(.move(.toHome)) + } catch { + await send(.move(.toTermview)) + } + } + + case .socailLoginFail: + return .none + + case .postSignUp: return .none } @@ -79,6 +138,7 @@ public struct OnboardingFeature { case .toTermview: state.path.append(.term(TermFeature.State())) return .none + case .toselectRole: state.path.append(.selectRole) return .none @@ -91,6 +151,9 @@ public struct OnboardingFeature { case .toMakeInvitationCode: state.path.append(.makeInvitationCode(MakeInvitationCodeFeature.State())) return .none + case .toHome: + print("post 사인 성공..") + return .none default: return .none } @@ -115,9 +178,6 @@ public struct OnboardingFeature { default: return .none } - - default: - return .none } } .forEach(\.path, action: \.path) @@ -145,5 +205,7 @@ public struct OnboardingFeature { case registerInvitationCode /// 트레이니 수업 정보 입력 case registerPtClassInfo + /// 홈 + case home } } diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Common/OnboardingView.swift b/TnT/Projects/Presentation/Sources/Onboarding/Common/OnboardingView.swift similarity index 94% rename from TnT/Projects/Presentation/Sources/Onbarding/Common/OnboardingView.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Common/OnboardingView.swift index d1b7693f..9bd2ca0e 100644 --- a/TnT/Projects/Presentation/Sources/Onbarding/Common/OnboardingView.swift +++ b/TnT/Projects/Presentation/Sources/Onboarding/Common/OnboardingView.swift @@ -84,10 +84,8 @@ public struct OnboardingView: View { .background(type.background) .clipShape(RoundedRectangle(cornerRadius: 12)) .onTapGesture { - store.send(.move(.toTermview)) -// type == .kakao -// ? store.send(.view(.tappedAppleLogin)) -// : store.send(.view(.tappedAppleLogin)) + type == .kakao ? store.send(.view(.tappedKakaoLogin)) + : store.send(.view(.tappedAppleLogin)) } } } diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Common/TermFeature.swift b/TnT/Projects/Presentation/Sources/Onboarding/Common/TermFeature.swift similarity index 91% rename from TnT/Projects/Presentation/Sources/Onbarding/Common/TermFeature.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Common/TermFeature.swift index 8c4e8ae3..47029d8c 100644 --- a/TnT/Projects/Presentation/Sources/Onbarding/Common/TermFeature.swift +++ b/TnT/Projects/Presentation/Sources/Onboarding/Common/TermFeature.swift @@ -13,13 +13,18 @@ import ComposableArchitecture public struct TermFeature { @ObservableState public struct State: Equatable { - var view_terms: [Term: Bool] = [:] + var view_terms: [Term: Bool] var view_isAllAgreed: Bool { view_terms.values.allSatisfy { $0 } } var isNavigaiton: Bool = false - public init() { } + public init() { + self.view_terms = [ + .term: false, + .personalInfo: false + ] + } } public enum Action: Equatable, ViewAction { diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Common/TermView.swift b/TnT/Projects/Presentation/Sources/Onboarding/Common/TermView.swift similarity index 96% rename from TnT/Projects/Presentation/Sources/Onbarding/Common/TermView.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Common/TermView.swift index 23a1a313..ea24ce83 100644 --- a/TnT/Projects/Presentation/Sources/Onbarding/Common/TermView.swift +++ b/TnT/Projects/Presentation/Sources/Onboarding/Common/TermView.swift @@ -12,7 +12,7 @@ import ComposableArchitecture import DesignSystem @ViewAction(for: TermFeature.self) -struct TermView: View { +public struct TermView: View { public let store: StoreOf @@ -20,7 +20,7 @@ struct TermView: View { self.store = store } - var body: some View { + public var body: some View { VStack { VStack(alignment: .leading, spacing: 0) { Header() @@ -80,7 +80,7 @@ struct TermView: View { term: term, isAgreed: store.view_terms[term] ?? false ) { - send(.toggleTerm(term, $0)) + send(.toggleTerm(term, !$0)) } } } diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Code/MakeInvitationCodeFeature.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Code/MakeInvitationCodeFeature.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Code/MakeInvitationCodeFeature.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Code/MakeInvitationCodeFeature.swift diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Code/MakeInvitationCodeView.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Code/MakeInvitationCodeView.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Code/MakeInvitationCodeView.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Code/MakeInvitationCodeView.swift diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectedTraineeProfileFeature.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectedTraineeProfileFeature.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectedTraineeProfileFeature.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectedTraineeProfileFeature.swift diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectedTraineeProfileView.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectedTraineeProfileView.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectedTraineeProfileView.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectedTraineeProfileView.swift diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectionCompleteFeature.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectionCompleteFeature.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectionCompleteFeature.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectionCompleteFeature.swift diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectionCompleteView.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectionCompleteView.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Connection/ConnectionCompleteView.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Connection/ConnectionCompleteView.swift diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Profile/TrainerSignUpCompleteFeature.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Profile/TrainerSignUpCompleteFeature.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Profile/TrainerSignUpCompleteFeature.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Profile/TrainerSignUpCompleteFeature.swift diff --git a/TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Profile/TrainerSignUpCompleteView.swift b/TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Profile/TrainerSignUpCompleteView.swift similarity index 100% rename from TnT/Projects/Presentation/Sources/Onbarding/Trainer/Login/Profile/TrainerSignUpCompleteView.swift rename to TnT/Projects/Presentation/Sources/Onboarding/Trainer/Login/Profile/TrainerSignUpCompleteView.swift diff --git a/TnT/Projects/TnTApp/Sources/TnTApp.swift b/TnT/Projects/TnTApp/Sources/TnTApp.swift index ca9ab0fc..4f0825b3 100644 --- a/TnT/Projects/TnTApp/Sources/TnTApp.swift +++ b/TnT/Projects/TnTApp/Sources/TnTApp.swift @@ -8,6 +8,8 @@ import SwiftUI +import Presentation +import ComposableArchitecture import DesignSystem @main @@ -19,7 +21,10 @@ struct ToyProjectApp: App { var body: some Scene { WindowGroup { - ContentView() + OnboardingView(store: Store(initialState: OnboardingFeature.State(), reducer: { + OnboardingFeature() + })) +// ContentView() } } } diff --git a/TnT/Projects/TnTApp/TnTApp.entitlements b/TnT/Projects/TnTApp/TnTApp.entitlements new file mode 100644 index 00000000..a812db50 --- /dev/null +++ b/TnT/Projects/TnTApp/TnTApp.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.applesignin + + Default + + + diff --git a/TnT/Tuist/Package.resolved b/TnT/Tuist/Package.resolved index 4e5346f2..b34b640e 100644 --- a/TnT/Tuist/Package.resolved +++ b/TnT/Tuist/Package.resolved @@ -1,5 +1,14 @@ { "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "194a6706acbd25e4ef639bcaddea16e8758a3e27", + "version" : "1.2024011602.0" + } + }, { "identity" : "alamofire", "kind" : "remoteSourceControl", @@ -9,6 +18,15 @@ "version" : "5.10.2" } }, + { + "identity" : "app-check", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/app-check.git", + "state" : { + "revision" : "61b85103a1aeed8218f17c794687781505fbbef5", + "version" : "11.2.0" + } + }, { "identity" : "combine-schedulers", "kind" : "remoteSourceControl", @@ -19,6 +37,69 @@ } }, { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk", + "state" : { + "revision" : "0d885d28250fb1196b614bc9455079b75c531f72", + "version" : "11.7.0" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "be0881ff728eca210ccb628092af400c086abda3", + "version" : "11.7.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "617af071af9aa1d6a091d59a202910ac482128f9", + "version" : "10.1.0" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb", + "version" : "8.0.2" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "f56d8fc3162de9a498377c7b6cea43431f4f5083", + "version" : "1.65.1" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "3cdb78efb79b4a5383c3911488d8025bfc545b5e", + "version" : "4.3.0" + } + }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, + { "identity" : "fscalendar", "kind" : "remoteSourceControl", "location" : "https://github.com/WenchaoD/FSCalendar.git", @@ -36,6 +117,15 @@ "version" : "2.23.0" } }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version" : "1.22.5" + } + }, { "identity" : "lottie-ios", "kind" : "remoteSourceControl", @@ -45,6 +135,24 @@ "version" : "4.5.1" } }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version" : "2.30910.0" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version" : "2.4.0" + } + }, { "identity" : "swift-case-paths", "kind" : "remoteSourceControl", @@ -135,6 +243,15 @@ "version" : "1.4.1" } }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "ebc7251dd5b37f627c93698e4374084d98409633", + "version" : "1.28.2" + } + }, { "identity" : "swift-sharing", "kind" : "remoteSourceControl", diff --git a/TnT/Tuist/Package.swift b/TnT/Tuist/Package.swift index 9ab78b00..c307c82e 100644 --- a/TnT/Tuist/Package.swift +++ b/TnT/Tuist/Package.swift @@ -18,6 +18,7 @@ let package = Package( .package(url: "https://github.com/airbnb/lottie-ios", from: "4.5.0"), .package(url: "https://github.com/kakao/kakao-ios-sdk.git", from: "2.20.0"), .package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.6.3"), + .package(url: "https://github.com/firebase/firebase-ios-sdk", from: "11.7.0"), .package(url: "https://github.com/WenchaoD/FSCalendar.git", from: "2.8.4") ] ) diff --git a/TnT/Tuist/ProjectDescriptionHelpers/Dependency/DependencyInformation.swift b/TnT/Tuist/ProjectDescriptionHelpers/Dependency/DependencyInformation.swift index 6af5c9b2..015c7cf9 100644 --- a/TnT/Tuist/ProjectDescriptionHelpers/Dependency/DependencyInformation.swift +++ b/TnT/Tuist/ProjectDescriptionHelpers/Dependency/DependencyInformation.swift @@ -11,6 +11,8 @@ let dependencyInfo: [DependencyInformation: [DependencyInformation]] = [ .TnTApp: [.Presentation, .Data], .Presentation: [.DIContainer, .DesignSystem, .Domain, .ComposableArchitecture], .Domain: [.SwiftDepedencies], + .Data: [.Domain, .KakaoSDKUser, .SwiftDepedencies, .FirebaseMessaging], + .DesignSystem: [.Lottie], .Data: [.Domain, .KakaoSDKUser, .SwiftDepedencies], .DesignSystem: [.Lottie, .FSCalendar], .DIContainer: [.Domain, .Data] @@ -27,6 +29,7 @@ public enum DependencyInformation: String, CaseIterable, Sendable { case ComposableArchitecture = "ComposableArchitecture" case KakaoSDKUser = "KakaoSDKUser" case SwiftDepedencies = "Dependencies" + case FirebaseMessaging = "FirebaseMessaging" case FSCalendar = "FSCalendar" } diff --git a/TnT/Tuist/ProjectDescriptionHelpers/Dependency/ExternalDependency.swift b/TnT/Tuist/ProjectDescriptionHelpers/Dependency/ExternalDependency.swift index 3ee6f572..bd183d6e 100644 --- a/TnT/Tuist/ProjectDescriptionHelpers/Dependency/ExternalDependency.swift +++ b/TnT/Tuist/ProjectDescriptionHelpers/Dependency/ExternalDependency.swift @@ -12,5 +12,6 @@ let externalDependency: [DependencyInformation] = [ .Lottie, .ComposableArchitecture, .SwiftDepedencies, + .FirebaseMessaging, .FSCalendar ] diff --git a/TnT/Tuist/ProjectDescriptionHelpers/Project/Target+Templates.swift b/TnT/Tuist/ProjectDescriptionHelpers/Project/Target+Templates.swift index 4be59b37..b2629b78 100644 --- a/TnT/Tuist/ProjectDescriptionHelpers/Project/Target+Templates.swift +++ b/TnT/Tuist/ProjectDescriptionHelpers/Project/Target+Templates.swift @@ -68,6 +68,7 @@ public extension Target { infoPlist: .file(path: .relativeToRoot("Tuist/Config/Info.plist")), sources: ["Sources/**"], resources: ["Resources/**"], + entitlements: "\(appName).entitlements", scripts: [.swiftLint], dependencies: dependencies )