Skip to content

Commit f1a1fa4

Browse files
authored
Merge pull request #83 from YAPP-Github/TNT-210-TrainerHome
[TNT-210] 트레이너 캘린더 api 연결
2 parents 4958478 + a74ca2d commit f1a1fa4

File tree

6 files changed

+161
-7
lines changed

6 files changed

+161
-7
lines changed

TnT/Projects/DesignSystem/Sources/Components/Calendar/TCalendarRepresentable.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ public struct TCalendarRepresentable: UIViewRepresentable {
6464
calendar.appearance.titleDefaultColor = .clear
6565
calendar.calendarWeekdayView.weekdayLabels[0].textColor = UIColor(.red500)
6666

67+
6768
return calendar
6869
}
69-
70+
7071
public func updateUIView(_ uiView: FSCalendar, context: Context) {
7172
// `selectedDate` 반영
7273
uiView.select(selectedDate)

TnT/Projects/Domain/Sources/DTO/Trainer/TrainerHomeResponseDTO.swift

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,79 @@ public struct SessonEntity: Equatable, Encodable {
9898
self.isCompleted = isCompleted
9999
}
100100
}
101+
102+
// mapper
103+
// MARK: - GetDateSessionListDTO -> GetDateSessionListEntity
104+
public extension GetDateSessionListDTO {
105+
func toEntity() -> GetDateSessionListEntity {
106+
return GetDateSessionListEntity(
107+
count: self.count,
108+
date: self.date,
109+
lessons: self.lessons.map { $0.toEntity() }
110+
)
111+
}
112+
113+
// GetDateSessionListEntity -> GetDateSessionListDTO
114+
func toDTO() -> GetDateSessionListDTO {
115+
return GetDateSessionListDTO(
116+
count: self.count,
117+
date: self.date,
118+
lessons: self.lessons.map { $0.toDTO() }
119+
)
120+
}
121+
}
122+
123+
// MARK: - SessonDTO -> SessonEntity
124+
public extension SessonDTO {
125+
public func toEntity() -> SessonEntity {
126+
return SessonEntity(
127+
ptLessonId: self.ptLessonId,
128+
traineeId: self.traineeId,
129+
traineeName: self.traineeName,
130+
session: self.session,
131+
startTime: self.startTime,
132+
endTime: self.endTime,
133+
isCompleted: self.isCompleted
134+
)
135+
}
136+
137+
// SessonEntity -> SessonDTO
138+
public func toDTO() -> SessonDTO {
139+
return SessonDTO(
140+
ptLessonId: self.ptLessonId,
141+
traineeId: self.traineeId,
142+
traineeName: self.traineeName,
143+
session: self.session,
144+
startTime: self.startTime,
145+
endTime: self.endTime,
146+
isCompleted: self.isCompleted
147+
)
148+
}
149+
}
150+
151+
// MARK: - GetDateSessionListEntity -> GetDateSessionListDTO
152+
public extension GetDateSessionListEntity {
153+
public func toDTO() -> GetDateSessionListDTO {
154+
return GetDateSessionListDTO(
155+
count: self.count,
156+
date: self.date,
157+
lessons: self.lessons.map { $0.toDTO() }
158+
)
159+
}
160+
}
161+
162+
// MARK: - SessonEntity -> SessonDTO
163+
public extension SessonEntity {
164+
public func toDTO() -> SessonDTO {
165+
return SessonDTO(
166+
ptLessonId: self.ptLessonId,
167+
traineeId: self.traineeId,
168+
traineeName: self.traineeName,
169+
session: self.session,
170+
startTime: self.startTime,
171+
endTime: self.endTime,
172+
isCompleted: self.isCompleted
173+
)
174+
}
175+
}
176+

TnT/Projects/Presentation/Sources/Home/Trainer/TrainerHomeFeature.swift

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public struct TrainerHomeFeature {
7878
}
7979

8080
@Dependency(\.traineeUseCase) private var traineeUseCase: TraineeUseCase
81+
@Dependency(\.trainerRepoUseCase) private var trainerRepoUseCase: TrainerRepository
8182

8283
public enum Action: Sendable, ViewAction {
8384
/// 뷰에서 발생한 액션을 처리합니다.
@@ -103,6 +104,14 @@ public struct TrainerHomeFeature {
103104
case tapPopUpConnectButton
104105
/// 화면이 표시될 때
105106
case onAppear
107+
/// events 타입에 맞춰서 달력 스케줄 캐수 표시 데이터 계산
108+
case fetchMonthlyLessons(year: Int, month: Int)
109+
/// 달력 스케줄 캐수 표시 데이터 업데이트
110+
case updateEvents([Date: Int])
111+
/// 특정 날짜 탭
112+
case calendarDateTap
113+
/// 탭한 일자 api 형태에 맞춰 변환하기(yyyy-mm-dd)
114+
case settingSessionList(sessions: GetDateSessionListEntity)
106115
}
107116
}
108117

@@ -117,7 +126,7 @@ public struct TrainerHomeFeature {
117126
case .view(let action):
118127
switch action {
119128
case .binding(\.selectedDate):
120-
print(state.events[state.selectedDate])
129+
print("state.events[state.selectedDate] \(state.events[state.selectedDate])")
121130
return .none
122131

123132
case .binding:
@@ -157,11 +166,59 @@ public struct TrainerHomeFeature {
157166
return .send(.setNavigating(.trainerMakeInvitationCodePage))
158167

159168
case .onAppear:
169+
let year: Int = Calendar.current.component(.year, from: state.selectedDate)
170+
let month: Int = Calendar.current.component(.month, from: state.selectedDate)
171+
160172
if let hideUntil = state.hidePopupUntil, hideUntil > Date() {
161173
state.view_isPopUpPresented = false
162174
} else {
163175
state.view_isPopUpPresented = true
164176
}
177+
178+
return .send(.view(.fetchMonthlyLessons(year: year, month: month)))
179+
180+
case .fetchMonthlyLessons(year: let year, month: let month):
181+
return .run { send in
182+
do {
183+
let temp: GetMonthlyLessonListResDTO = try await trainerRepoUseCase.getMonthlyLessonList(
184+
year: year,
185+
month: month
186+
)
187+
188+
let dateFormatter: DateFormatter = DateFormatter()
189+
dateFormatter.dateFormat = "yyyy-MM-dd"
190+
191+
var events: [Date: Int] = [:]
192+
for lesson in temp.calendarPtLessonCounts {
193+
if let date = dateFormatter.date(from: lesson.date) {
194+
events[date] = lesson.count
195+
} else {
196+
print("Invalid date format: \(lesson.date)")
197+
}
198+
}
199+
await send(.view(.updateEvents(events)))
200+
} catch {
201+
print("리스트 Fetching Error: \(error)")
202+
}
203+
}
204+
case .updateEvents(let events):
205+
state.events = events
206+
return .none
207+
208+
case .calendarDateTap:
209+
let formattedDate = TDateFormatUtility.formatter(for: .yyyyMMdd).string(from: state.selectedDate)
210+
211+
return .run { send in
212+
do {
213+
let sessionList: GetDateSessionListEntity = try await trainerRepoUseCase.getDateSessionList(date: formattedDate).toEntity()
214+
await send(.view(.settingSessionList(sessions: sessionList)))
215+
} catch {
216+
print("error \(error.localizedDescription)")
217+
}
218+
}
219+
220+
case .settingSessionList(let list):
221+
state.tappedsessionInfo = list
165222
return .none
166223
}
167224
case .setNavigating:

TnT/Projects/Presentation/Sources/Home/Trainer/TrainerHomeView.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,15 @@ public struct TrainerHomeView: View {
7575
currentPage: $store.view_currentPage,
7676
events: store.events
7777
)
78+
.onChange(of: store.state.selectedDate, { oldValue, newValue in
79+
let startOfDay = Calendar.current.startOfDay(for: newValue)
80+
store.selectedDate = startOfDay
81+
store.send(.view(.calendarDateTap))
82+
})
7883
.padding(.horizontal, 20)
7984
}
8085
}
8186
.padding(.vertical, 12)
82-
8387
}
8488

8589
/// 수업 리스트 상단 타이틀
@@ -110,10 +114,12 @@ public struct TrainerHomeView: View {
110114
@ViewBuilder
111115
private func RecordList() -> some View {
112116
VStack {
113-
if let record = store.tappedsessionInfo {
117+
if let record = store.tappedsessionInfo, !record.lessons.isEmpty {
114118
ForEach(record.lessons, id: \.id) { record in
115119
SessionCellView(session: record) {
116120
send(.tapSessionCompleted(id: record.ptLessonId))
121+
} onTap: {
122+
// TODO: - 트레이너 기록 추가
117123
}
118124
}
119125
} else {
@@ -131,9 +137,10 @@ public struct TrainerHomeView: View {
131137
.frame(width: 126, height: 58)
132138
.overlay {
133139
HStack(spacing: 4) {
134-
Image(.icnPlusEmpty)
140+
Image(.icnPlus)
135141
.resizable()
136142
.frame(width: 24, height: 24)
143+
.tint(Color.common0)
137144
Text("수업추가")
138145
.typographyStyle(.body1Medium, with: .neutral50)
139146
}
@@ -215,6 +222,7 @@ extension TrainerHomeView {
215222
struct SessionCellView: View {
216223
var session: SessonEntity
217224
var onTapComplete: () -> Void
225+
var onTap: (() -> Void)?
218226

219227
var body: some View {
220228
HStack(spacing: 20) {
@@ -237,7 +245,7 @@ extension TrainerHomeView {
237245

238246
if session.isCompleted {
239247
Button {
240-
//
248+
onTap?()
241249
} label: {
242250
HStack(spacing: 4) {
243251
Image(.icnWriteWhite)

TnT/Projects/TnTApp/Sources/ContentView.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,19 @@ import ComposableArchitecture
1212

1313
struct ContentView: View {
1414
var body: some View {
15-
Text("")
15+
TrainerHomeView(store: Store(initialState: TrainerHomeFeature.State(), reducer: {
16+
TrainerHomeFeature()
17+
}))
18+
// TrainerMypageView(store: Store(initialState: TrainerMypageFeature.State(
19+
// userName: "홍길동",
20+
// userImageUrl: nil,
21+
// studentCount: 10,
22+
// oldStudentCount: 5,
23+
// appPushNotificationAllowed: true,
24+
// versionInfo: "1.0.0"
25+
// ), reducer: {
26+
// TrainerMypageFeature()
27+
// }))
1628
}
1729
}
1830

TnT/graph.png

16 KB
Loading

0 commit comments

Comments
 (0)