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

Feature/#26 feat TermsOfService View #32

Merged
merged 4 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct WithSuhyeonSmallChip: View {
}
}

struct ChipTestView: View {
struct ChipTestView2: View {
@State private var firstChipState: WithSuhyeonChipState = .unselected
@State private var secondChipState: WithSuhyeonChipState = .selected

Expand Down Expand Up @@ -78,5 +78,5 @@ struct ChipTestView: View {
}

#Preview {
ChipTestView()
ChipTestView2()
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// SignUpContent.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import SwiftUI

struct SignUpContent: View {
@Binding var selectedTab: SignUpContentCase
init(selectedTab: Binding<SignUpContentCase>) {
self._selectedTab = selectedTab
UITabBar.appearance().isHidden = true
}

var body: some View {
TabView(selection: $selectedTab) {
TermsOfServiceView()
.tag(SignUpContentCase.termsOfServiceView)
PhoneAuthenticationView()
.tag(SignUpContentCase.authenticationView)
WriteNickNameView()
.tag(SignUpContentCase.nickNameView)
SelectBirthYearView()
.tag(SignUpContentCase.birthYearView)
SelectGenderView()
.tag(SignUpContentCase.genderView)
ProfileImageView()
.tag(SignUpContentCase.profileImageView)
ActiveAreaView()
.tag(SignUpContentCase.activeAreaView)
}
.tabViewStyle(PageTabViewStyle())
.onAppear {
UIScrollView.appearance().isScrollEnabled = false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// SignUpContentCase.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import Foundation

public enum SignUpContentCase: CaseIterable {
case termsOfServiceView
case authenticationView
case nickNameView
case birthYearView
case genderView
case profileImageView
case activeAreaView

var title: String {
switch self {
case .termsOfServiceView:
return "์ˆ˜ํ˜„์ด๋ž‘\n์„œ๋น„์Šค ์ด์šฉ์•ฝ๊ด€"
case .authenticationView:
return "๋ณธ์ธ์ธ์ฆ์„ ์œ„ํ•œ\nํœด๋Œ€ํฐ ๋ฒˆํ˜ธ ์ธ์ฆ์ด ํ•„์š”ํ•ด์š”"
case .nickNameView:
return "์ˆ˜ํ˜„์ด๋ž‘์—์„œ ์‚ฌ์šฉํ• \n๋‹‰๋„ค์ž„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"
case .birthYearView:
return "ํƒœ์–ด๋‚œ ๋…„๋„๋ฅผ\n์„ ํƒํ•ด์ฃผ์„ธ์š”"
case .genderView:
return "์„ฑ๋ณ„์„\n์„ ํƒํ•ด์ฃผ์„ธ์š”"
case .profileImageView:
return "ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๋ฅผ\n๋“ฑ๋กํ•ด์ฃผ์„ธ์š”"
case .activeAreaView:
return "์ž์ฃผ ํ™œ๋™ํ•˜๋Š”\n์ง€์—ญ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//
// SignUpFeature.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import Foundation
import Combine

class SignUpFeature: Feature {
struct State {
var progress: Double = 0.0
var isAgree: Bool = false
var buttonState: WithSuhyeonButtonState = .disabled
}

enum Intent {
case tapButton
case tapBackButton
}

enum SideEffect {

}

@Published private(set) var state = State()
@Published var currentContent: SignUpContentCase = .termsOfServiceView
private var cancellables = Set<AnyCancellable>()
private let intentSubject = PassthroughSubject<Intent, Never>()
let sideEffectSubject = PassthroughSubject<SideEffect, Never>()

init() {
bindIntents()
updateProgress()
receiveState()
}

private func bindIntents() {
intentSubject.sink { [weak self] intent in
self?.handleIntent(intent)
}.store(in: &cancellables)
}

private func receiveState() {
$state.sink { [weak self] _ in
DispatchQueue.main.async {
self?.updateButtonState()
}
}.store(in: &cancellables)

$currentContent.sink { [weak self] _ in
DispatchQueue.main.async {
self?.updateButtonState()
}
}.store(in: &cancellables)
}

func send(_ intent: Intent) {
intentSubject.send(intent)
}

func handleIntent(_ intent: Intent) {
switch intent {
case .tapButton:
moveToNextStep()
case .tapBackButton:
moveToPreviousStep()
}
}

private func moveToNextStep() {
if let currentIndex = SignUpContentCase.allCases.firstIndex(of: currentContent),
currentIndex < SignUpContentCase.allCases.count - 1 {
currentContent = SignUpContentCase.allCases[currentIndex + 1]
updateProgress()
}
}

private func moveToPreviousStep() {
if let currentIndex = SignUpContentCase.allCases.firstIndex(of: currentContent),
currentIndex > 0 {
currentContent = SignUpContentCase.allCases[currentIndex - 1]
updateProgress()
}
}

private func updateProgress() {
if let currentIndex = SignUpContentCase.allCases.firstIndex(of: currentContent) {
state.progress = Double(currentIndex + 1) / Double(SignUpContentCase.allCases.count) * 100
}
}

private func updateButtonState() {
let newButtonState: WithSuhyeonButtonState

switch currentContent {
case .termsOfServiceView:
newButtonState = state.isAgree ? .enabled : .disabled
default:
newButtonState = .enabled
}

guard state.buttonState != newButtonState else {
return
}

state.buttonState = newButtonState
}

func changeSelectedContent(signUpContentCase: SignUpContentCase) {
currentContent = signUpContentCase
}

func updateIsAgree(_ newValue: Bool) {
state.isAgree = newValue
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// SignUpView.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import SwiftUI

struct SignUpView: View {
@EnvironmentObject private var router: RouterRegistry
@StateObject private var signUpFeature = SignUpFeature()

var body: some View {
VStack(alignment: .leading, spacing: 0) {
WithSuhyeonTopNavigationBar(
title: "",
onTapLeft: {
signUpFeature.send(
.tapBackButton
)
})

WithSuhyeonProgressBar(progress: signUpFeature.state.progress)

Text(signUpFeature.currentContent.title)
.font(.title02B)
.padding(.leading, 16)
.padding(.vertical, 20)

SignUpContent(selectedTab: $signUpFeature.currentContent)

WithSuhyeonButton(
title: "๋‹ค์Œ",
buttonState: signUpFeature.state.buttonState,
clickable: signUpFeature.state.buttonState == .enabled,
onTapButton: {
signUpFeature.send(.tapButton)
}
)
.padding(.horizontal, 16)
}.environmentObject(signUpFeature)
}
}

#Preview {
SignUpView()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// ActiveAreaView.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import SwiftUI

struct ActiveAreaView: View {
var body: some View {
Text("ํ™œ๋™ ์ง€์—ญ ์„ ํƒ")
}
}

#Preview {
ActiveAreaView()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// PhoneAuthenticationView.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import SwiftUI

struct PhoneAuthenticationView: View {
var body: some View {
Text("ํ•ธ๋“œํฐ ์ธ์ฆ")
}
}

#Preview {
PhoneAuthenticationView()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// ProfileImageView.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import SwiftUI

struct ProfileImageView: View {
var body: some View {
Text("ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ ์„ ํƒ")
}
}

#Preview {
ProfileImageView()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// SelectBirthYearView.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import SwiftUI

struct SelectBirthYearView: View {
var body: some View {
Text("ํƒœ์–ด๋‚œ ๋…„๋„ ์„ ํƒ")
}
}

#Preview {
SelectBirthYearView()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// SelectGenderView.swift
// WithSuhyeon-iOS
//
// Created by ๊น€์˜ˆ์ง€ on 1/15/25.
//

import SwiftUI

struct SelectGenderView: View {
var body: some View {
Text("์„ฑ๋ณ„ ์„ ํƒ ๋ทฐ")
.navigationBarBackButtonHidden(true)
}
}

#Preview {
SelectGenderView()
}
Loading