diff --git a/Projects/Core/Network/Sources/Services/Article/ArticleAPIClient.swift b/Projects/Core/Network/Sources/Services/Article/ArticleAPIClient.swift index 990322e..5976f68 100644 --- a/Projects/Core/Network/Sources/Services/Article/ArticleAPIClient.swift +++ b/Projects/Core/Network/Sources/Services/Article/ArticleAPIClient.swift @@ -25,7 +25,7 @@ public extension DependencyValues { extension ArticleAPIClient: DependencyKey { public static var liveValue: ArticleAPIClient = .init( - _fetchArticles: { reqeust in + fetchArticles: { reqeust in let api = ArticleAPI.fetchArticles( .init( categoryId: reqeust.category?.id, @@ -40,7 +40,7 @@ extension ArticleAPIClient: DependencyKey { ) public static var testValue: ArticleAPIClient = .init( - _fetchArticles: { _ in + fetchArticles: { _ in return Article.mockArticles } ) diff --git a/Projects/Feature/History/Sources/Component/CheckListBottomSheetView.swift b/Projects/Feature/History/Sources/Component/CheckListBottomSheetView.swift index af7d687..c779583 100644 --- a/Projects/Feature/History/Sources/Component/CheckListBottomSheetView.swift +++ b/Projects/Feature/History/Sources/Component/CheckListBottomSheetView.swift @@ -29,7 +29,7 @@ struct CheckListBottomSheetView: View { ) HStack { - Text("내용 변경") + Text("제목변경") .notoSans(.body_3) .foregroundStyle(Color.greyScale950) Spacer() diff --git a/Projects/Feature/History/Sources/HistoryView.swift b/Projects/Feature/History/Sources/HistoryView.swift index 263df50..9fbea69 100644 --- a/Projects/Feature/History/Sources/HistoryView.swift +++ b/Projects/Feature/History/Sources/HistoryView.swift @@ -26,7 +26,12 @@ public struct HistoryView: View { NavigationStack(path: $store.scope(state: \.path, action: \.path)) { VStack { TopNavigation(centerTitle: "나의 기록") - content + + if store.state.checkList.isEmpty { + emptyView + } else { + content + } } .onAppear { store.send(.onAppear) @@ -89,10 +94,14 @@ public struct HistoryView: View { } private var emptyView: some View { - Image.historyEmptyView - .resizable() - .scaledToFit() - .frame(width: 192, height: 186) + VStack { + Spacer() + Image.historyEmptyView + .resizable() + .scaledToFit() + .frame(width: 192, height: 186) + Spacer() + } } @ViewBuilder diff --git a/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistStore.swift b/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistStore.swift index 543e130..52f88ff 100644 --- a/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistStore.swift +++ b/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistStore.swift @@ -17,6 +17,7 @@ public struct DetailChecklistStore { @ObservableState public struct State { + var index: Int var card: Card var isPresentDeleteCheckBoxAlert: Bool = false var willDeleteCheckBox: CheckBox? diff --git a/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistView.swift b/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistView.swift index e8f27d4..84eb485 100644 --- a/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistView.swift +++ b/Projects/Feature/Home/Sources/DetailChecklist/DetailChecklistView.swift @@ -14,9 +14,11 @@ import ComposableArchitecture struct DetailChecklistView: View { @Bindable private var store: StoreOf + private let colorType: ChecklistColorType init(store: StoreOf) { self.store = store + self.colorType = ChecklistColorType(index: store.index) } var body: some View { @@ -48,6 +50,7 @@ struct DetailChecklistView: View { DetailColorChecklistCellView( title: checkBox.label, isSelected: checkBox.isCompleted, + colorType: colorType, onToggle: { store.send(.didTapChecklistCompleteButton(checkBox: checkBox)) }, diff --git a/Projects/Feature/Home/Sources/Home/HomeStore.swift b/Projects/Feature/Home/Sources/Home/HomeStore.swift index 8220571..9917faa 100644 --- a/Projects/Feature/Home/Sources/Home/HomeStore.swift +++ b/Projects/Feature/Home/Sources/Home/HomeStore.swift @@ -83,7 +83,7 @@ public struct HomeStore { // MARK: - Delegate Actions(parent) - case onNaviagteToDetailChecklist(card: Card) + case onNaviagteToDetailChecklist(card: Card, index: Int) case onRouteToHistoryScreen // MARK: - Scope Actions(child) @@ -141,7 +141,9 @@ public struct HomeStore { return .none case .didTapNavigateToDetailChecklist(let card): - return .send(.onNaviagteToDetailChecklist(card: card)) + guard let index = state.cards.firstIndex(of: card) + else { return .none } + return .send(.onNaviagteToDetailChecklist(card: card, index: index)) case .fetchData: return .run { send in diff --git a/Projects/Feature/Home/Sources/Home/Views/Checklist/CardProgressView.swift b/Projects/Feature/Home/Sources/Home/Views/Checklist/CardProgressView.swift index 82c88c1..112aea5 100644 --- a/Projects/Feature/Home/Sources/Home/Views/Checklist/CardProgressView.swift +++ b/Projects/Feature/Home/Sources/Home/Views/Checklist/CardProgressView.swift @@ -7,14 +7,19 @@ import SwiftUI +import SharedDesignSystem + struct CardProgressView: View { private let progress: CGFloat private let isSelected: Bool + private let colorType: ChecklistColorType init( + colorType: ChecklistColorType, isSelected: Bool, progress: CGFloat ) { + self.colorType = colorType self.isSelected = isSelected self.progress = progress } @@ -29,7 +34,7 @@ struct CardProgressView: View { Circle() .trim(from: 0, to: progress) .stroke( - isSelected ? .primary800 : .greyScale400, + isSelected ? colorType.cardTintColor : .greyScale400, style: StrokeStyle(lineWidth: 8, lineCap: .butt, lineJoin: .bevel) ) .rotationEffect(.degrees(-90)) @@ -42,7 +47,7 @@ struct CardProgressView: View { Text("%") .notoSans(.subhead_2) } - .foregroundStyle(isSelected ? .primary800 : .greyScale400) + .foregroundStyle(isSelected ? colorType.cardTintColor : .greyScale400) } } } diff --git a/Projects/Feature/Home/Sources/Home/Views/Checklist/CardView.swift b/Projects/Feature/Home/Sources/Home/Views/Checklist/CardView.swift index c4abd86..0cf3d3c 100644 --- a/Projects/Feature/Home/Sources/Home/Views/Checklist/CardView.swift +++ b/Projects/Feature/Home/Sources/Home/Views/Checklist/CardView.swift @@ -7,18 +7,23 @@ import SwiftUI +import SharedDesignSystem + struct CardView: View { private let title: String private let isSelected: Bool private let progress: CGFloat private let onTap: () -> Void + private let colorType: ChecklistColorType init( + colorType: ChecklistColorType, title: String, isSelected: Bool, progress: CGFloat, onTap: @escaping () -> Void ) { + self.colorType = colorType self.title = title self.isSelected = isSelected self.progress = progress @@ -31,21 +36,47 @@ struct CardView: View { }) { HStack(spacing: .zero) { VStack(alignment: .leading, spacing: 10) { - CardProgressView(isSelected: isSelected, progress: progress) + CardProgressView(colorType: colorType, isSelected: isSelected, progress: progress) .padding(.top, 14) Text(title) .notoSans(.subhead_3) - .foregroundStyle(isSelected ? .primary800 : .greyScale600) + .foregroundStyle(isSelected ? colorType.cardTintColor : .greyScale600) } Spacer() } } .padding(.horizontal, 12) .frame(width: 162, height: 120) - .background(isSelected ? .primary100 : .greyScale050) + .background(isSelected ? colorType.cardColor : .greyScale050) .clipShape( .rect(cornerRadius: 10) ) } } + +extension ChecklistColorType { + + // MARK: - 카드 색상 + var cardColor: Color { + switch self { + case .blue: + return Color.primary100 + case .green: + return Color(hex: "EFFAF3") + case .orange: + return Color(hex: "FBF1D2") + } + } + + var cardTintColor: Color { + switch self { + case .blue: + return Color.primary800 + case .green: + return Color(hex: "84E1AF") + case .orange: + return Color(hex: "F07603") + } + } +} diff --git a/Projects/Feature/Home/Sources/Home/Views/Checklist/ChecklistList.swift b/Projects/Feature/Home/Sources/Home/Views/Checklist/ChecklistList.swift index f811eca..60c7411 100644 --- a/Projects/Feature/Home/Sources/Home/Views/Checklist/ChecklistList.swift +++ b/Projects/Feature/Home/Sources/Home/Views/Checklist/ChecklistList.swift @@ -14,10 +14,18 @@ import ComposableArchitecture struct ChecklistList: View { @Bindable private var store: StoreOf private let width: CGFloat + private let colorType: ChecklistColorType init(store: StoreOf, width: CGFloat) { self.store = store self.width = width + + if let selected = store.selectedCard, + let index = store.cards.firstIndex(of: selected) { + self.colorType = ChecklistColorType(index: index) + } else { + self.colorType = .blue + } } var body: some View { @@ -43,7 +51,8 @@ struct ChecklistList: View { isSelected: checkBox.isCompleted, onToggle: { store.send(.didTapChecklistCompleteButton(checkBox: checkBox)) - } + }, + colorType: colorType ) } } diff --git a/Projects/Feature/Home/Sources/Home/Views/HeaderView.swift b/Projects/Feature/Home/Sources/Home/Views/HeaderView.swift index 8e87811..c8cd58d 100644 --- a/Projects/Feature/Home/Sources/Home/Views/HeaderView.swift +++ b/Projects/Feature/Home/Sources/Home/Views/HeaderView.swift @@ -7,6 +7,8 @@ import SwiftUI +import SharedDesignSystem + import ComposableArchitecture struct HeaderView: View { @@ -85,8 +87,11 @@ struct HeaderView: View { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 8) { - ForEach(store.cards) { card in + ForEach(0.. () + private let tintColor: Color - init(isSelected: Bool, onToggle: @escaping () -> ()) { + init(isSelected: Bool, onToggle: @escaping () -> (), tintColor: Color) { self.isSelected = isSelected self.onToggle = onToggle + self.tintColor = tintColor } var body: some View { @@ -101,7 +122,7 @@ private struct ColorCheckBoxButton: View { .resizable() .scaledToFit() .frame(width: 20, height: 20) - .foregroundStyle(.primary900) + .foregroundStyle(tintColor) } } .if(!isSelected) { @@ -110,7 +131,7 @@ private struct ColorCheckBoxButton: View { .clipShape(RoundedRectangle(cornerRadius: 2)) .overlay( RoundedRectangle(cornerRadius: 2) - .stroke(.greyScale100, lineWidth: 1) + .stroke(.greyScale300, lineWidth: 1) ) .padding(3) } diff --git a/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DefaultColorChecklistCellView.swift b/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DefaultColorChecklistCellView.swift index 62c8379..b8602d4 100644 --- a/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DefaultColorChecklistCellView.swift +++ b/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DefaultColorChecklistCellView.swift @@ -11,22 +11,25 @@ public struct DefaultColorChecklistCellView: View { private let title: String private let isSelected: Bool private let onToggle: () -> Void + private let colorType: ChecklistColorType public init( title: String, isSelected: Bool, - onToggle: @escaping () -> Void + onToggle: @escaping () -> Void, + colorType: ChecklistColorType ) { self.title = title self.isSelected = isSelected self.onToggle = onToggle + self.colorType = colorType } public var body: some View { BaseColorChecklistCellView( title: title, isSelected: isSelected, - type: .`default`, + type: .`default`(colorType), onToggle: onToggle ) } diff --git a/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DetailColorChecklistCellView.swift b/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DetailColorChecklistCellView.swift index 7621541..eff380d 100644 --- a/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DetailColorChecklistCellView.swift +++ b/Projects/Shared/DesignSystem/Sources/Cells/Checklist/ColorCellView/DetailColorChecklistCellView.swift @@ -13,16 +13,19 @@ public struct DetailColorChecklistCellView: View { private let onToggle: () -> Void private let onEdit: (() -> Void)? private let onDelete: () -> Void + private let colorType: ChecklistColorType public init( title: String, isSelected: Bool, + colorType: ChecklistColorType = .blue, onToggle: @escaping () -> Void, onEdit: (() -> Void)? = nil, onDelete: @escaping () -> Void ) { self.title = title self.isSelected = isSelected + self.colorType = colorType self.onToggle = onToggle self.onEdit = onEdit self.onDelete = onDelete @@ -32,7 +35,7 @@ public struct DetailColorChecklistCellView: View { BaseColorChecklistCellView( title: title, isSelected: isSelected, - type: .detail, + type: .detail(colorType), onToggle: onToggle ) .listRowBackground(Color.clear)