Skip to content

Commit 4db6969

Browse files
authored
Feat: 추천 루틴 화면 서버 v2 연동 (#T3-173)
* Feat: 추천 루틴 서버 v2 적용 및 디자인 연동 (#T3-173) * Chore: 기존 RecommendedRoutineCardView 삭제 (#T3-173) * Feat: RoutineCardView delegate 추가 및 수정 뷰 연결 (#T3-173)
1 parent ffdcac2 commit 4db6969

6 files changed

Lines changed: 52 additions & 126 deletions

File tree

Projects/DataSource/Sources/DTO/RecommendedRoutineDTO.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ struct RecommendedRoutineDTO: Decodable {
1212
let routineName: String
1313
let routineDescription: String
1414
let routineLevel: String?
15+
let routineType: String
1516
let subRoutines: [RecommendedSubRoutineDTO]
1617

1718
enum CodingKeys: String, CodingKey {
1819
case id = "recommendedRoutineId"
1920
case routineName = "recommendedRoutineName"
2021
case routineDescription = "recommendedRoutineDescription"
2122
case routineLevel = "recommendedRoutineLevel"
23+
case routineType = "recommendedRoutineType"
2224
case subRoutines = "recommendedSubRoutineSearchResult"
2325
}
2426
}
@@ -39,6 +41,7 @@ extension RecommendedRoutineDTO {
3941
title: routineName,
4042
description: routineDescription,
4143
category: routineCategory,
44+
type: RoutineCategoryType(rawValue: routineType) ?? .rest,
4245
level: level,
4346
subRoutines: subRoutines.compactMap({ $0.toRecommendedSubRoutineEntity() }))
4447
}

Projects/Domain/Sources/Entity/RecommendedRoutineEntity.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public struct RecommendedRoutineEntity {
1010
public let title: String
1111
public let description: String
1212
public let category: RoutineCategoryType?
13+
public let type: RoutineCategoryType
1314
public let level: RoutineLevelType?
1415
public let subRoutines: [RecommendedSubRoutineEntity]
1516

@@ -18,13 +19,15 @@ public struct RecommendedRoutineEntity {
1819
title: String,
1920
description: String,
2021
category: RoutineCategoryType?,
22+
type: RoutineCategoryType,
2123
level: RoutineLevelType?,
2224
subRoutines: [RecommendedSubRoutineEntity]
2325
) {
2426
self.id = id
2527
self.title = title
2628
self.description = description
2729
self.category = category
30+
self.type = type
2831
self.level = level
2932
self.subRoutines = subRoutines
3033
}

Projects/Presentation/Sources/Common/Component/RoutineCardView.swift

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import Domain
99
import SnapKit
1010
import UIKit
1111

12+
protocol RoutineCardViewDelegate: AnyObject {
13+
func routineCardView(_ sender: RoutineCardView, didTapPlusButton routine: RecommendedRoutine)
14+
}
15+
1216
final class RoutineCardView: UIView {
1317
private enum Layout {
1418
static let horizontalMargin: CGFloat = 16
@@ -29,7 +33,7 @@ final class RoutineCardView: UIView {
2933
}
3034

3135
private let headerInfoStackView = UIStackView()
32-
private let categoryIconView = RoutineCategoryIcon(routineCategory: .connection)
36+
private lazy var categoryIconView = RoutineCategoryIcon(routineCategory: routine.routineType)
3337
private let titleLabel = UILabel()
3438
private let editButton = UIButton()
3539
private let deleteButton = UIButton()
@@ -38,7 +42,10 @@ final class RoutineCardView: UIView {
3842
private let subRoutineLabel = UILabel()
3943
private let subRoutineStackView = UIStackView()
4044

41-
init() {
45+
private let routine: RecommendedRoutine
46+
weak var delegate: RoutineCardViewDelegate?
47+
init(routine: RecommendedRoutine) {
48+
self.routine = routine
4249
super.init(frame: .zero)
4350
configureAttribute()
4451
configureLayout()
@@ -56,14 +63,19 @@ final class RoutineCardView: UIView {
5663
headerInfoStackView.axis = .horizontal
5764
headerInfoStackView.spacing = Layout.headerInfoStackViewSpacing
5865

59-
titleLabel.text = "개운하게 일어나기"
66+
titleLabel.text = routine.mainTitle
6067
titleLabel.font = BitnagilFont(style: .body1, weight: .semiBold).font
6168
titleLabel.textColor = BitnagilColor.gray10
6269

6370
let plusImage = BitnagilIcon.plusIcon?
6471
.resizeAspectFit(to: CGSize(width: Layout.plusImageSize, height: Layout.plusImageSize))
6572
plusButton.setImage(plusImage, for: .normal)
6673
plusButton.tintColor = BitnagilColor.gray10
74+
plusButton.addAction(
75+
UIAction { [weak self] _ in
76+
guard let self else { return }
77+
delegate?.routineCardView(self, didTapPlusButton: routine)
78+
}, for: .touchUpInside)
6779

6880
grayLine.backgroundColor = BitnagilColor.gray97
6981

@@ -78,7 +90,7 @@ final class RoutineCardView: UIView {
7890
}
7991
subRoutineStackView.addArrangedSubview(subRoutineLabel)
8092

81-
["물 마시기", "물 마시기", "물 마시기"].forEach {
93+
routine.subRoutines.forEach {
8294
let subRoutineTitleLabel = UILabel()
8395
subRoutineTitleLabel.text = "\($0)"
8496
subRoutineTitleLabel.font = BitnagilFont(style: .body2, weight: .medium).font

Projects/Presentation/Sources/Onboarding/Model/RecommendedRoutine.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,26 @@ public struct RecommendedRoutine: OnboardingChoiceProtocol, Hashable {
1111
let id: Int
1212
let mainTitle: String
1313
let subTitle: String?
14+
let subRoutines: [String]
1415
let routineCategory: RoutineCategoryType
16+
let routineType: RoutineCategoryType
1517
let routineLevel: RoutineLevelType
1618

1719
init(
1820
id: Int,
1921
mainTitle: String,
2022
subTitle: String?,
23+
subRoutines: [String],
2124
routineCategory: RoutineCategoryType,
25+
routineType: RoutineCategoryType,
2226
routineLevel: RoutineLevelType
2327
) {
2428
self.id = id
2529
self.mainTitle = mainTitle
2630
self.subTitle = subTitle
31+
self.subRoutines = subRoutines
2732
self.routineCategory = routineCategory
33+
self.routineType = routineType
2834
self.routineLevel = routineLevel
2935
}
3036
}
@@ -35,7 +41,9 @@ extension RecommendedRoutineEntity {
3541
id: id,
3642
mainTitle: title,
3743
subTitle: description,
44+
subRoutines: subRoutines.map({ $0.title }),
3845
routineCategory: category ?? .recommendation,
46+
routineType: type,
3947
routineLevel: level ?? .easy
4048
)
4149
}

Projects/Presentation/Sources/RecommendedRoutine/View/Component/RecommendedRoutineCardView.swift

Lines changed: 0 additions & 97 deletions
This file was deleted.

Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineViewController.swift

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ final class RecommendedRoutineViewController: BaseViewController<RecommendedRout
2323
static let headerStackViewHeight: CGFloat = 40
2424
static let recommendedRoutineStackViewSpacing: CGFloat = 12
2525
static let recommendedRoutineScrollViewTopSpacing: CGFloat = 12
26-
static let recommendedRoutineScrollViewBottomSpacing: CGFloat = 10
27-
static let recommendedRoutineStackViewBottomSpacing: CGFloat = 50
26+
static let recommendedRoutineStackViewBottomSpacing: CGFloat = 65
2827
static let routineCardHeight: CGFloat = 80
2928
static let registerEmotionButtonTopSpacing: CGFloat = 20
3029
static let registerEmotionButtonHeight: CGFloat = 66
@@ -44,7 +43,7 @@ final class RecommendedRoutineViewController: BaseViewController<RecommendedRout
4443

4544
private let recommendedRoutineScrollView = UIScrollView()
4645
private let recommendedRoutineStackView = UIStackView()
47-
private var recommendedRoutineCards: [Int: RecommendedRoutineCardView] = [:]
46+
private var recommendedRoutineCards: [Int: RoutineCardView] = [:]
4847
private let registerEmotionButton = RegisterEmotionButtonView()
4948
private let recommendedRoutineEmptyView = RecommendedRoutineEmptyView()
5049

@@ -167,7 +166,7 @@ final class RecommendedRoutineViewController: BaseViewController<RecommendedRout
167166
make.leading.equalTo(safeArea).offset(Layout.horizontalMargin)
168167
make.trailing.equalTo(safeArea).inset(Layout.horizontalMargin)
169168
make.top.equalTo(headerStackView.snp.bottom).offset(Layout.recommendedRoutineScrollViewTopSpacing)
170-
make.bottom.equalTo(safeArea).inset(Layout.recommendedRoutineScrollViewBottomSpacing)
169+
make.bottom.equalTo(safeArea)
171170
}
172171

173172
recommendedRoutineStackView.snp.makeConstraints { make in
@@ -200,6 +199,7 @@ final class RecommendedRoutineViewController: BaseViewController<RecommendedRout
200199
.sink { [weak self] selectedCategory in
201200
self?.categoryView.updateSelectedCategory(selectedCategory: selectedCategory)
202201
self?.showEmotionButton(isShowEmotionButton: selectedCategory == .recommendation)
202+
self?.recommendedRoutineScrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
203203
}
204204
.store(in: &cancellables)
205205

@@ -231,17 +231,12 @@ final class RecommendedRoutineViewController: BaseViewController<RecommendedRout
231231
}
232232
recommendedRoutineCards.removeAll()
233233

234-
// let testView = RoutineCardView()
235-
// recommendedRoutineStackView.addArrangedSubview(testView)
236234
recommendedRoutineEmptyView.isHidden = !recommendedRoutines.isEmpty
237235
for routine in recommendedRoutines {
238-
let routineCard = RecommendedRoutineCardView(recommendedRoutine: routine)
239-
recommendedRoutineCards[routine.id] = routineCard
240-
recommendedRoutineStackView.addArrangedSubview(routineCard)
241-
routineCard.delegate = self
242-
routineCard.snp.makeConstraints { make in
243-
make.height.equalTo(Layout.routineCardHeight)
244-
}
236+
let routineCardView = RoutineCardView(routine: routine)
237+
recommendedRoutineCards[routine.id] = routineCardView
238+
routineCardView.delegate = self
239+
recommendedRoutineStackView.addArrangedSubview(routineCardView)
245240
}
246241
}
247242

@@ -298,25 +293,14 @@ extension RecommendedRoutineViewController: RoutineCategoryViewDelegate {
298293
}
299294
}
300295

301-
// MARK: RecommendedRoutineCardViewDelegate
302-
extension RecommendedRoutineViewController: RecommendedRoutineCardViewDelegate {
303-
func recommendedRoutineCardView(_ sender: RecommendedRoutineCardView, didTapRecommendedRoutine routine: RecommendedRoutine) {
304-
guard let routineCreationViewModel = DIContainer.shared.resolve(type: RoutineCreationViewModel.self)
305-
else { fatalError("routineCreationViewModel 의존성이 등록되지 않았습니다.") }
306-
307-
let routineCreationView = RoutineCreationViewController(viewModel: routineCreationViewModel, recommendRoutineId: routine.id)
308-
routineCreationView.hidesBottomBarWhenPushed = true
309-
self.navigationController?.pushViewController(routineCreationView, animated: true)
310-
}
311-
}
312-
313296
// MARK: SelectableItemTableViewDelegate
314297
extension RecommendedRoutineViewController: SelectableItemTableViewDelegate {
315298
func selectableItemTableView<T: SelectableItem & CaseIterable & Equatable>(_ sender: SelectableItemTableView<T>, didSelectItem: T?) {
316299
guard let didSelectLevel = didSelectItem as? RoutineLevelType?
317300
else { return }
318301
viewModel.action(input: .selectLevel(selectedLevel: didSelectLevel))
319302
levelButton.updateButton(level: didSelectLevel)
303+
recommendedRoutineScrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
320304
}
321305
}
322306

@@ -333,6 +317,7 @@ extension RecommendedRoutineViewController: FloatingMenuViewDelegate {
333317
}
334318
}
335319

320+
// MARK: RegisterEmotionButtonViewDelegate
336321
extension RecommendedRoutineViewController: RegisterEmotionButtonViewDelegate {
337322
func registerEmotionButtonViewDidTapRegisterButton(_ sender: RegisterEmotionButtonView) {
338323
guard let emotionRegisterViewModel = DIContainer.shared.resolve(type: EmotionRegisterViewModel.self)
@@ -343,3 +328,15 @@ extension RecommendedRoutineViewController: RegisterEmotionButtonViewDelegate {
343328
self.navigationController?.pushViewController(emotionRegisterView, animated: true)
344329
}
345330
}
331+
332+
// MARK: RoutineCardViewDelegate
333+
extension RecommendedRoutineViewController: RoutineCardViewDelegate {
334+
func routineCardView(_ sender: RoutineCardView, didTapPlusButton routine: RecommendedRoutine) {
335+
guard let routineCreationViewModel = DIContainer.shared.resolve(type: RoutineCreationViewModel.self)
336+
else { fatalError("routineCreationViewModel 의존성이 등록되지 않았습니다.") }
337+
338+
let routineCreationView = RoutineCreationViewController(viewModel: routineCreationViewModel, recommendRoutineId: routine.id)
339+
routineCreationView.hidesBottomBarWhenPushed = true
340+
self.navigationController?.pushViewController(routineCreationView, animated: true)
341+
}
342+
}

0 commit comments

Comments
 (0)