Skip to content

Commit d64f873

Browse files
authored
Merge pull request #90 from YAPP-Github/TNT-254-commonQA
[TNT-254] commonQA μ™„λ£Œ
2 parents 6dd9995 + 4766ef8 commit d64f873

File tree

37 files changed

+414
-199
lines changed

37 files changed

+414
-199
lines changed

β€ŽTnT/Projects/DesignSystem/Sources/Button/TBottomButton.swiftβ€Ž

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ public struct TBottomButton: View {
3333
}
3434

3535
public var body: some View {
36-
Button(title) {
37-
action()
36+
Button(action: { action() }) {
37+
Text(title)
38+
.typographyStyle(.heading4, with: isEnable ? ButtonState.true.textColor : ButtonState.false.textColor)
39+
.padding(.vertical, 20)
40+
.frame(maxWidth: .infinity)
41+
.background(isEnable ? ButtonState.true.background : ButtonState.false.background)
3842
}
39-
.typographyStyle(.heading4, with: isEnable ? ButtonState.true.textColor : ButtonState.false.textColor)
40-
.padding(.vertical, 20)
41-
.frame(maxWidth: .infinity)
42-
.background(isEnable ? ButtonState.true.background : ButtonState.false.background)
4343
}
4444
}
4545

β€ŽTnT/Projects/DesignSystem/Sources/Components/DatePickerView/TDatePickerView.swiftβ€Ž

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import SwiftUI
1111
/// - λ‚ μ§œ 선택할 수 μžˆλŠ” DatePicker View
1212
public struct TDatePickerView: View {
1313

14+
/// μ»€μŠ€ν…€/μ‹œμŠ€ν…œ μΊ˜λ¦°λ” 선택
15+
private let calendarType: CalendarType
1416
/// picker 제λͺ©
1517
private let title: String
1618
/// λ²„νŠΌ μ‹€ν–‰ action
@@ -20,25 +22,29 @@ public struct TDatePickerView: View {
2022
/// 선택 λ‚ μ§œ
2123
@State private var selectedDate: Date = .now
2224
/// ν‘œμ‹œ λ‚ μ§œ
23-
@State private var currentDate: Date = .now
25+
@State private var currentPageDate: Date = .now
2426

2527
@Environment(\.dismiss) var dismiss
2628

2729
/// `TDatePickerView` μƒμ„±μž
2830
/// - Parameters:
31+
/// - calendarType: μ‹œμŠ€ν…œ μΊ˜λ¦°λ” / μ»€μŠ€ν…€ μΊ˜λ¦°λ” 선택 (κΈ°λ³Έκ°’: μ»€μŠ€ν…€)
2932
/// - selectedDate: 초기 선택 λ‚ μ§œ (κΈ°λ³Έκ°’: ν˜„μž¬ λ‚ μ§œ)
3033
/// - title: DatePicker의 제λͺ©
3134
/// - buttonAction: λ‚ μ§œ 선택 ν›„ μ‹€ν–‰ν•  μ•‘μ…˜
3235
public init(
36+
calendarType: CalendarType = .custom,
3337
selectedDate: Date = .now,
3438
title: String,
3539
monthFormatter: @escaping (Date) -> String,
3640
buttonAction: @escaping (Date) -> Void
3741
) {
42+
self.calendarType = calendarType
3843
self.selectedDate = selectedDate
3944
self.title = title
4045
self.monthFormatter = monthFormatter
4146
self.buttonAction = buttonAction
47+
currentPageDate = selectedDate
4248
}
4349

4450
public var body: some View {
@@ -59,28 +65,59 @@ public struct TDatePickerView: View {
5965
}
6066
.padding(20)
6167

68+
Calendar(calendarType)
69+
70+
TButton(
71+
title: "확인",
72+
config: .large,
73+
state: .default(.primary(isEnabled: true)),
74+
action: {
75+
buttonAction(selectedDate)
76+
}
77+
)
78+
.padding(20)
79+
}
80+
}
81+
82+
@ViewBuilder
83+
private func Calendar(_ calendarType: CalendarType) -> some View {
84+
switch calendarType {
85+
case .custom:
6286
TCalendarHeader<EmptyView>(
63-
currentPage: $currentDate,
87+
currentPage: $currentPageDate,
6488
formatter: monthFormatter
6589
)
6690
.padding(.top, 20)
6791

6892
TCalendarView(
6993
selectedDate: $selectedDate,
70-
currentPage: $currentDate,
94+
currentPage: $currentPageDate,
7195
mode: .compactMonth
7296
)
7397
.padding(.horizontal, 16)
74-
75-
TButton(
76-
title: "확인",
77-
config: .large,
78-
state: .default(.primary(isEnabled: true)),
79-
action: {
80-
buttonAction(selectedDate)
98+
case let .system(range):
99+
Group {
100+
if let range {
101+
DatePicker(title, selection: $selectedDate, in: range, displayedComponents: .date)
102+
.datePickerStyle(GraphicalDatePickerStyle())
103+
.environment(\.locale, Locale(identifier: "ko_KR"))
104+
105+
} else {
106+
DatePicker(title, selection: $selectedDate, displayedComponents: .date)
107+
.datePickerStyle(GraphicalDatePickerStyle())
108+
.environment(\.locale, Locale(identifier: "ko_KR"))
81109
}
82-
)
83-
.padding(20)
110+
}
111+
.tint(.red400)
112+
.padding(.top, 20)
113+
.padding(.horizontal, 16)
84114
}
85115
}
86116
}
117+
118+
public extension TDatePickerView {
119+
enum CalendarType {
120+
case system(in: PartialRangeThrough<Date>? = nil)
121+
case custom
122+
}
123+
}

β€ŽTnT/Projects/Domain/Sources/Entity/ConnectedTraineeProfileEntity.swiftβ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public struct ConnectedTraineeProfileEntity: Equatable, Sendable {
1717
/// λ‚˜μ΄
1818
public let age: Int?
1919
/// ν‚€
20-
public let height: Double
20+
public let height: Double?
2121
/// λͺΈλ¬΄κ²Œ
22-
public let weight: Double
22+
public let weight: Double?
2323
/// PT λͺ©ν‘œ
2424
public let ptGoal: String
2525
/// 주의 사항
@@ -29,8 +29,8 @@ public struct ConnectedTraineeProfileEntity: Equatable, Sendable {
2929
traineeName: String,
3030
imageUrl: String,
3131
age: Int?,
32-
height: Double,
33-
weight: Double,
32+
height: Double?,
33+
weight: Double?,
3434
ptGoal: String,
3535
cautionNote: String?
3636
) {

β€ŽTnT/Projects/Domain/Sources/Mapper/TrainerMapper.swiftβ€Ž

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ import Foundation
1010

1111
public extension ConnectTraineeInfoDTO {
1212
func toEntity() -> ConnectedTraineeProfileEntity {
13+
let height = self.height == 0 ? nil : self.height
14+
let weight = self.weight == 0 ? nil : self.weight
1315
return .init(
1416
traineeName: self.traineeName,
1517
imageUrl: self.traineeProfileImageUrl,
1618
age: self.age,
17-
height: self.height,
18-
weight: self.weight,
19+
height: height,
20+
weight: weight,
1921
ptGoal: self.ptGoal,
2022
cautionNote: self.cautionNote
2123
)

β€ŽTnT/Projects/Domain/Sources/Policy/AppLinks.swiftβ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010

1111
public enum AppLinks {
12-
public static let termsOfService: String = "https://yapp25thteam.com/terms"
13-
public static let privacyPolicy: String = "https://yapp25thteam.com/privacy"
14-
public static let openSourceLicense: String = "https://yapp25thteam.com/license"
12+
public static let termsOfService: String = "https://www.notion.so/f1ee7a43b6d941068723163fda127699?pvs=4"
13+
public static let privacyPolicy: String = "https://www.notion.so/775bc037dd1b4e8ba56679e51a7321e5?pvs=4"
14+
public static let openSourceLicense: String = "https://www.notion.so/197cabde9e4b800d8e8ec6c22d343b32?pvs=4"
1515
}

β€ŽTnT/Projects/Domain/Sources/Policy/UserPolicy.swiftβ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ struct UserPolicy {
2222
isRequired: false
2323
)
2424

25-
/// ν‚€ μž…λ ₯ 검증 (μ •μˆ˜ 3자리, ν•„μˆ˜)
25+
/// ν‚€ μž…λ ₯ 검증 (μ •μˆ˜ 3자리)
2626
static let heightInput: PolicyInputInfo = .init(
2727
textValidation: { TextValidator.isValidInput($0, maxLength: 3, regexPattern: #"^\d{3}$"#) },
28-
isRequired: true
28+
isRequired: false
2929
)
3030

31-
/// λͺΈλ¬΄κ²Œ μž…λ ₯ 검증 (μ •μˆ˜ 3자리 + μ†Œμˆ˜μ  1자리, ν•„μˆ˜)
31+
/// λͺΈλ¬΄κ²Œ μž…λ ₯ 검증 (μ •μˆ˜ 3자리 + μ†Œμˆ˜μ  1자리)
3232
/// μ •μˆ˜ μ΅œμ†Œ 2자리 이상, μ†Œμˆ˜μ  1μžλ¦¬κΉŒμ§€λ§Œ
3333
static let weightInput: PolicyInputInfo = .init(
3434
textValidation: { TextValidator.isValidInput($0, maxLength: 5, regexPattern: #"^\d{2,3}(\.\d{1})?$"#) },
35-
isRequired: true
35+
isRequired: false
3636
)
3737

3838
/// μ£Όμ˜μ‚¬ν•­ μ΅œλŒ€ 길이 μ œν•œ (곡백 포함)

β€ŽTnT/Projects/Presentation/Sources/AddDietRecord/TraineeAddDietRecordView.swiftβ€Ž

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public struct TraineeAddDietRecordView: View {
3636
),
3737
leftAction: { send(.tapNavBackButton) }
3838
)
39+
TDivider(color: .neutral200)
40+
3941
ScrollView {
4042
VStack(alignment: .leading, spacing: 8) {
4143
DietPhotoSection()
@@ -57,22 +59,24 @@ public struct TraineeAddDietRecordView: View {
5759
.onTapGesture { focusedField = nil }
5860
.navigationBarBackButtonHidden()
5961
.keyboardDismissOnTap()
60-
.safeAreaInset(edge: .bottom) {
61-
if store.view_focusField == nil {
62-
TButton(
63-
title: "μ €μž₯",
64-
config: .xLarge,
65-
state: .default(.primary(isEnabled: store.view_isSubmitButtonEnabled))
66-
) {
67-
send(.tapSubmitButton)
68-
}
69-
.padding(.horizontal, 16)
62+
.bottomFixWith {
63+
TButton(
64+
title: "μ €μž₯",
65+
config: .xLarge,
66+
state: .default(.primary(isEnabled: store.view_isSubmitButtonEnabled))
67+
) {
68+
send(.tapSubmitButton)
7069
}
70+
.padding(.bottom, .safeAreaBottom)
71+
.disabled(!store.view_isSubmitButtonEnabled)
72+
.debounce()
73+
.padding(.horizontal, 16)
7174
}
7275
.sheet(item: $store.view_bottomSheetItem) { item in
7376
switch item {
7477
case .datePicker(let field):
7578
TDatePickerView(
79+
selectedDate: store.dietDate ?? .now,
7680
title: field.title,
7781
monthFormatter: { TDateFormatUtility.formatter(for: .yyyyλ…„_MMμ›”).string(from: $0) },
7882
buttonAction: {
@@ -82,9 +86,9 @@ public struct TraineeAddDietRecordView: View {
8286
.autoSizingBottomSheet(presentationDragIndicator: .hidden)
8387
case .timePicker(let field):
8488
TTimePickerView(
85-
selectedTime: store.dietDate ?? .now,
89+
selectedTime: store.dietTime ?? .now,
8690
title: field.title,
87-
minuteStep: 10,
91+
minuteStep: 1,
8892
buttonAction: {
8993
send(.tapBottomSheetSubmitButton(field, $0))
9094
}
@@ -163,7 +167,7 @@ public struct TraineeAddDietRecordView: View {
163167
@ViewBuilder
164168
private func DietDateSection() -> some View {
165169
TTextField(
166-
placeholder: "2025/11/19",
170+
placeholder: Date().toString(format: .yyyyMMddSlash),
167171
text: Binding(get: {
168172
store.dietDate?.toString(format: .yyyyMMddSlash) ?? ""
169173
}, set: { _ in }),
@@ -185,7 +189,7 @@ public struct TraineeAddDietRecordView: View {
185189
@ViewBuilder
186190
private func DietTimeSection() -> some View {
187191
TTextField(
188-
placeholder: "09:00",
192+
placeholder: Date().toString(format: .HHmm),
189193
text: Binding(get: {
190194
store.dietTime?.toString(format: .HHmm) ?? ""
191195
}, set: { _ in }),

β€ŽTnT/Projects/Presentation/Sources/AddPTSession/TrainerAddPTSessionView.swiftβ€Ž

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public struct TrainerAddPTSessionView: View {
3636
leftAction: { send(.tapNavBackButton) }
3737
)
3838
TDivider(height: 1, color: .neutral200)
39+
3940
ScrollView {
4041
VStack(alignment: .leading, spacing: 0) {
4142
Header()
@@ -62,19 +63,20 @@ public struct TrainerAddPTSessionView: View {
6263
.padding(.bottom, .safeAreaBottom + 20)
6364
}
6465
}
66+
.bottomFixWith {
67+
TBottomButton(
68+
title: "μ™„λ£Œ",
69+
isEnable: store.view_isSubmitButtonEnabled
70+
) {
71+
send(.tapSubmitButton)
72+
}
73+
.padding(.bottom, .safeAreaBottom)
74+
.disabled(!store.view_isSubmitButtonEnabled)
75+
.debounce()
76+
}
6577
.onTapGesture { focusedField = nil }
6678
.navigationBarBackButtonHidden()
6779
.keyboardDismissOnTap()
68-
.safeAreaInset(edge: .bottom) {
69-
if store.view_focusField == nil {
70-
TBottomButton(
71-
title: "μ™„λ£Œ",
72-
isEnable: store.view_isSubmitButtonEnabled
73-
) {
74-
send(.tapSubmitButton)
75-
}
76-
}
77-
}
7880
.sheet(item: $store.view_bottomSheetItem) { item in
7981
switch item {
8082
case .traineeList:
@@ -86,6 +88,7 @@ public struct TrainerAddPTSessionView: View {
8688
)
8789
case .datePicker(let field):
8890
TDatePickerView(
91+
selectedDate: store.ptDate ?? .now,
8992
title: field.title,
9093
monthFormatter: { TDateFormatUtility.formatter(for: .yyyyλ…„_MMμ›”).string(from: $0) },
9194
buttonAction: {
@@ -196,7 +199,7 @@ public struct TrainerAddPTSessionView: View {
196199
HStack(alignment: .bottom, spacing: 12) {
197200
// StartTime
198201
TTextField(
199-
placeholder: "09:00",
202+
placeholder: Date().toString(format: .HHmm),
200203
text: Binding(get: {
201204
store.startTime?.toString(format: .HHmm) ?? ""
202205
}, set: { _ in }),
@@ -227,7 +230,7 @@ public struct TrainerAddPTSessionView: View {
227230

228231
// EndTime
229232
TTextField(
230-
placeholder: "10:00",
233+
placeholder: Date().addingTimeInterval(3600).toString(format: .HHmm),
231234
text: Binding(get: {
232235
store.endTime?.toString(format: .HHmm) ?? ""
233236
}, set: { _ in }),

β€ŽTnT/Projects/Presentation/Sources/Alarm/AlarmCheckView.swiftβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import ComposableArchitecture
1212
import Domain
1313
import DesignSystem
1414

15-
/// μ•ŒλžŒ λͺ©λ‘μ„ μž…λ ₯ν•˜λŠ” ν™”λ©΄
15+
/// μ•ŒλžŒ λͺ©λ‘μ„ ν™•μΈν•˜λŠ” ν™”λ©΄
1616
/// μœ μ €μ—κ²Œ λ„μ°©ν•œ μ•ŒλžŒμ„ ν‘œμ‹œ - μœ μ € νƒ€μž…μ— 따라 λΆ„λ₯˜
1717
@ViewAction(for: AlarmCheckFeature.self)
1818
public struct AlarmCheckView: View {
@@ -30,6 +30,7 @@ public struct AlarmCheckView: View {
3030
type: .LButtonWithTitle(leftImage: .icnArrowLeft, centerTitle: "μ•Œλ¦Ό"),
3131
leftAction: { send(.tapNavBackButton) }
3232
)
33+
TDivider(color: .neutral200)
3334

3435
ScrollView(showsIndicators: false) {
3536
AlarmList()

β€ŽTnT/Projects/Presentation/Sources/Coordinator/OnboardingFlow/OnboardingFlowFeature.swiftβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public struct OnboardingFlowFeature {
103103

104104
/// νŠΈλ ˆμ΄λ‹ˆ νšŒμ›κ°€μž… μ™„λ£Œ ν™”λ©΄ -> νŠΈλ ˆμ΄λ„ˆ μ΄ˆλŒ€μ½”λ“œ μž…λ ₯ ν™”λ©΄ 이동
105105
case .element(id: _, action: .traineeProfileCompletion(.setNavigating)):
106-
state.path.append(.traineeInvitationCodeInput(.init(view_popUp: .invitePopUp, view_isPopupPresented: true)))
106+
state.path.append(.traineeInvitationCodeInput(.init()))
107107
return .none
108108

109109
/// νŠΈλ ˆμ΄λ‹ˆ μ΄ˆλŒ€μ½”λ“œ μž…λ ₯ ν™”λ©΄ -> νŠΈλ ˆμ΄λ‹ˆ ν™ˆν™”λ©΄/PT 정보 μž…λ ₯ ν™”λ©΄

0 commit comments

Comments
Β (0)