Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TNT-158] 트레이너 회원가입 UI 및 네비게이션 구현 #30

Merged
merged 12 commits into from
Jan 26, 2025

Conversation

syss220211
Copy link
Member

@syss220211 syss220211 commented Jan 24, 2025

📌 What is the PR?

  • 회원가입 피처 중 트레이너의 회원가입 플로우를 구현하였습니다.
  • 네비게이션을 구현해보았습니다...

🪄 Changes

  • 트레이너 회원가입 플로우 중 트레이너 단독 화면들의 플로우를 구현하였습니다.
  • API 연결 전, 기본 네비게이션 작업은 완료하였고, 해당 PR 머지 후 트레이니 화면과 네트워크 코드 풀 받아서 이어서 작업할 예정입니다!
  • Button 관련하여 변경사항 팔로업 (있었는데 제가 확인을 못했던거 같아요. 사이즈 및 padding값이 변경되었더라구요)
  • TNavigation에 새로운 케이스 추가 (RTitleButton+CenterTitle)

초기 온보딩(로그인)화면을 구현하였습니다.
이용 약관 화면을 구현하였습니다.
트레이너 프로필 생성 완료, 트레이너 초대코드 생성, 트레이너 연결 완료 화면의 UI를 구현하였습니다.
화면 별 Feature는 아직 틀만 만들었습니다.
제가 작업한 뷰에서 트레이너, 트레이니가 공통적으로 사용하는 화면은 Presentation하위 Sources > Onboarding > Common에 추가하였습니다.
온보딩의 네비게이션을 작업하였습니다.(SignFeature) 우선은 TCA 튜토리얼 기반으로 학습한 내용으로 구현해보았는데 이런 방향성과 해당 방법이 맞는지 확인부탁드립니다 ㅎ.ㅎ...

🌐 Common Changes

🔥 PR Point

public enum Action: ViewAction {
        case view(View)
        case move(MoveAction)
        case path(StackActionOf<Path>)
        
        @CasePathable
        public enum View: Equatable {
            case tappedAppleLogin
            case tappedKakaoLogin
        }
        
        @CasePathable
        public enum MoveAction: Equatable {
            case toTermview // 약관 동의 화면으로 이동
            case toselectRole // 역할 선택화면으로 이동
            
            /// 트레이너
            case toRegisterNickname
            case toCompleteSignup
            case toMakeInvitationCode
            
            /// 트레이니
            case toRegisterUserInfo
            case toRegisterPtPurpose
            case toRegisterprecautions
            case toRegisterInvitationCode
            case toRegisterPtClassInfo
        }
        
case let .view(view):
                switch view {
                case .tappedAppleLogin:
                    return .none
                case .tappedKakaoLogin:
                    return .none
                }
            case let .move(move):
                switch move {
                case .toTermview:
                    state.path.append(.term)
                    return .none
                case .toselectRole:
                    state.path.append(.selectRole)
                    return .none
                case .toRegisterNickname:
                    state.path.append(.registerNickname)
                    return .none
                case .toCompleteSignup:
                    state.path.append(.completeSignup(TrainerSignUpCompleteFeature.State()))
                    return .none
                case .toMakeInvitationCode:
                    state.path.append(.makeInvitationCode(MakeInvitationCodeFeature.State()))
                    return .none
                default:
                    return .none
                }

📸 Screenshot

기능 스크린샷
GIF

🙆🏻 To Reviewers

  • TCA와 관련하여.. 많은 피드백 미리 감사드립니다 ...
  • Feature 를 컨벤션에 맞춰서 수정했습니다만.. 잘못 정의한 부분이 있는지 한번 확인 부탁드립니다!

💭 Related Issues

@syss220211 syss220211 requested a review from FpRaArNkK January 24, 2025 10:23
@FpRaArNkK FpRaArNkK self-assigned this Jan 25, 2025
@FpRaArNkK FpRaArNkK added the ✨Feat 새로운 기능 구현 (새로운 로직 추가, UI 구현 등) label Jan 25, 2025
@FpRaArNkK FpRaArNkK assigned syss220211 and unassigned FpRaArNkK Jan 25, 2025
syss220211 and others added 5 commits January 25, 2025 12:02
- UI 수정 부분 반영
- Button 관련하여 변경사항 팔로업 (있었는데 제가 확인을 못했나봄)
- TNavigation에 새로운 케이스 추가 (RTitleButton+CenterTitle)
- 복사 후 ToastMessag 적용 전, API 연결 전
Copy link
Contributor

@FpRaArNkK FpRaArNkK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생많으셨습니다!
몇가지 코멘트 남겨놓았는데 확인 부탁드려요!

Comment on lines +27 to +28
/// 기존 ViewAction을 Root임을 고려하여 MoveAction으로 구현하였습니다.
case move(MoveAction)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋네요! 👍👍


Spacer()

Image(.imgOnboardingLogin)
Copy link
Contributor

@FpRaArNkK FpRaArNkK Jan 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 이미지는 별도 설정 없어도 괜찮을까요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

있는게 맞는것 같습니다. 추가할게요!!

Comment on lines 113 to 143
public enum Term: CaseIterable {
case term
case personalInfo

var id: Int {
switch self {
case .term:
return 0
case .personalInfo:
return 1
}
}

var title: String {
switch self {
case .term:
return "(필수)서비스 이용약관 동의"
case .personalInfo:
return "(필수)개인정보 처리방침 동의"
}
}

var url: String {
switch self {
case .term:
return ""
case .personalInfo:
return ""
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reducer에서도 같이 사용되는 개념인데, 위치를 바꿔주면 더 좋을 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵!

Comment on lines 88 to 111
private func termList(term: Term, isAgreed: Bool, toggle: @escaping (Bool) -> Void) -> some View {
HStack(spacing: 8) {
Image(isAgreed ? .icnCheckButtonSelected : .icnCheckButtonUnselected)
.resizable()
.frame(width: 24, height: 24)
.onTapGesture {
toggle(isAgreed)
}

Text(term.title)
.typographyStyle(.body2Medium, with: .neutral500)

Spacer()

Text("보기")
.typographyStyle(.body2Medium, with: .neutral300)
.onTapGesture {
if let url = URL(string: term.url) {
UIApplication.shared.open(url)
}
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 뷰아이템에 대해서 ForEach로 추가되는 아이템이니
섹션의 느낌이 나는 TermList보다는 TermListItem의 네이밍은 어떨까요?
TermListItem ∈ TermList 처럼요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굿굿 애매하다 싶었는데 바꿔놓겠습니다

Comment on lines 9 to 11
import SwiftUI
import DesignSystem
import ComposableArchitecture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모듈 친구는 한줄 띄워서 아래로 맞춰주세요!
뷰 작성 컨벤션

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 43 to 44
static let icKakao: ImageResource = DesignSystemAsset.icnKakao.imageResource
static let icApple: ImageResource = DesignSystemAsset.icnApple.imageResource
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

icn 컨벤션 맞춰주세요!
asset 컨벤션

Comment on lines +96 to +121
@ViewBuilder
private func traineeProfileView(title: String, content: String) -> some View {
HStack(spacing: 12) {
Text(title)
.typographyStyle(.body2Bold, with: .neutral950)
Text(content)
.typographyStyle(.body2Medium, with: .neutral500)
}
}

@ViewBuilder
private func traineeInfoView(content: String, type: Info) -> some View {
VStack(spacing: 7) {
Text(type.rawValue)
.typographyStyle(.body1Bold, with: .neutral900)
.frame(maxWidth: .infinity, alignment: .leading)

Text(content)
.typographyStyle(.label1Medium, with: .neutral800)
.frame(height: type == .caution ? 128 : nil)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.init(top: 10, leading: 16, bottom: 10, trailing: 16))
.background(Color.neutral100)
.clipShape(RoundedRectangle(cornerRadius: 8))
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

섹션을 담당하지 않는 친구들은 extension으로 빼서, struct로 만들어주세요!
해당 코드에서 Item이란 의미를 확실하게 줄거에요.
뷰 작성 컨벤션

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +59 to +73
@ViewBuilder
private func userProfileView(imgae: ImageResource, name: String) -> some View {
VStack(spacing: 12) {
Image(imgae)
.resizable()
.frame(width: 100, height: 100)
.scaledToFill()
.clipShape(Circle())

Text(name)
.typographyStyle(.body2Medium, with: .neutral300)
.frame(maxWidth: .infinity)
}
.frame(width: 100)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 친구도 섹션을 담당하는 것이 아닌 섹션을 구성하는 아이템이니 struct로 빼주세요!

import DesignSystem
import ComposableArchitecture

public struct ConnectionCompleteView: View {
Copy link
Contributor

@FpRaArNkK FpRaArNkK Jan 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View 상단에

@ViewAction(for: ConnectionCompleteFeature.self)
public struct ConnectionCompleteView: View {

처럼 작성해주시고,

아래 내용들에서
store.send(.view(.tappedNextButton)) 대신
send(.tappedNextButton)으로 보내주세요!

훨씬 간단하면서, viewAction에 선언된 액션만 호출하게 제한할 수 있겠죠?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인이요!

Comment on lines 39 to 50
Spacer().frame(height: 80.5)

Text("만나서 반가워요\n김헬짱 트레이너님!")
.typographyStyle(.heading1, with: .neutral950)
.frame(maxWidth: .infinity)
.multilineTextAlignment(.center)
.padding(.horizontal, 24)

Text("트레이니와 함께\n케미를 터뜨려보세요! 🧨")
.multilineTextAlignment(.center)

Spacer().frame(height: 18)
Copy link
Contributor

@FpRaArNkK FpRaArNkK Jan 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단일 아이템으로 구성되지 않는 섹션의 경우,
VStack, HStack, ZStack, Group과 같이 묶어 해당 섹션이 어떤 레이아웃으로 아이템들이 표현되는지 작성해주시면
한 눈에 레이아웃을 파악하기 좋을 것 같아요!

Copy link
Member Author

@syss220211 syss220211 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뷰컨벤션 관련해서 일괄 확인완료했습니다. 수정해서 반영해놓을게요!

Comment on lines +96 to +121
@ViewBuilder
private func traineeProfileView(title: String, content: String) -> some View {
HStack(spacing: 12) {
Text(title)
.typographyStyle(.body2Bold, with: .neutral950)
Text(content)
.typographyStyle(.body2Medium, with: .neutral500)
}
}

@ViewBuilder
private func traineeInfoView(content: String, type: Info) -> some View {
VStack(spacing: 7) {
Text(type.rawValue)
.typographyStyle(.body1Bold, with: .neutral900)
.frame(maxWidth: .infinity, alignment: .leading)

Text(content)
.typographyStyle(.label1Medium, with: .neutral800)
.frame(height: type == .caution ? 128 : nil)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.init(top: 10, leading: 16, bottom: 10, trailing: 16))
.background(Color.neutral100)
.clipShape(RoundedRectangle(cornerRadius: 8))
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import DesignSystem
import ComposableArchitecture

public struct ConnectionCompleteView: View {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인이요!

Comment on lines 23 to 32
public enum Action: Equatable {
case setNavigation
case view(ViewAction)

public enum ViewAction {
case tappedNextButton
case tappedIssuanceButton
case copyCode
}
}
Copy link
Contributor

@FpRaArNkK FpRaArNkK Jan 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action에 ViewAction 프로토콜 추가해주시고, 프로토콜과 이름이 겹치니
case view(View)로 작성해주세요!
Reducer 작성 컨벤션

Comment on lines 13 to 14

public struct MakeInvitationCodeView: View {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ViewAction 달아주세요!

Copy link
Contributor

@FpRaArNkK FpRaArNkK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳! SNS 로그인 파이팅!

@syss220211 syss220211 merged commit efdbb1c into develop Jan 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨Feat 새로운 기능 구현 (새로운 로직 추가, UI 구현 등)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TNT-158] 트레이너 회원가입 플로우 작성
2 participants