From 129023e70c58cb74a2b820d6ac0dda81ce253e6a Mon Sep 17 00:00:00 2001 From: HyunWoo Jeong Date: Thu, 31 Oct 2024 23:09:27 +0900 Subject: [PATCH 1/3] =?UTF-8?q?Feat:=20=EB=B3=B4=EA=B4=80=ED=95=A8=20flow?= =?UTF-8?q?=20=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProjectDescriptionHelpers/Modules.swift | 2 + .../DomainDiaryInterfaceTemplate.swift | 7 ++ .../Projects/Domain/Diary/Project.swift | 46 ++++++++++++ .../Sources/DomainDiarySourcesTemplate.swift | 7 ++ .../Sources/DomainDiaryTestingTemplate.swift | 7 ++ .../Sources/DomainDiaryTestsTemplate.swift | 7 ++ Namo_SwiftUI/Projects/Domain/Project.swift | 1 + .../Domain/Sources/DomainExport.swift | 1 + .../FeatureArchiveExampleTemplate.swift | 7 ++ .../FeatureArchiveInterfaceTemplate.swift | 7 ++ .../Projects/Feature/Archive/Project.swift | 56 +++++++++++++++ .../ArchiveCalendarStore.swift | 34 +++++++++ .../ArchiveCalendar/ArchiveCalendarView.swift | 46 ++++++++++++ .../ArchiveMain/ArchiveMainStore.swift | 38 ++++++++++ .../Sources/ArchiveMain/ArchiveMainView.swift | 56 +++++++++++++++ .../Coordinator/ArchiveCoordinator.swift | 70 +++++++++++++++++++ .../Coordinator/ArchiveCoordinatorView.swift | 31 ++++++++ .../FeatureArchiveTestingTemplate.swift | 7 ++ .../Sources/FeatureArchiveTestsTemplate.swift | 7 ++ .../Projects/Feature/Home/Project.swift | 3 +- .../Sources/Coordinator/HomeCoordinator.swift | 15 +++- .../Coordinator/HomeCoordinatorView.swift | 3 + Namo_SwiftUI/Projects/Feature/Project.swift | 3 +- .../Feature/Sources/FeatureExport.swift | 2 +- 24 files changed, 458 insertions(+), 5 deletions(-) create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Interface/Sources/DomainDiaryInterfaceTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Project.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Testing/Sources/DomainDiaryTestingTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Tests/Sources/DomainDiaryTestsTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Example/Sources/FeatureArchiveExampleTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Interface/Sources/FeatureArchiveInterfaceTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Project.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainStore.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainView.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinatorView.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Testing/Sources/FeatureArchiveTestingTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Archive/Tests/Sources/FeatureArchiveTestsTemplate.swift diff --git a/Namo_SwiftUI/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Modules.swift b/Namo_SwiftUI/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Modules.swift index 3c642e35..7dd5676f 100644 --- a/Namo_SwiftUI/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Modules.swift +++ b/Namo_SwiftUI/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Modules.swift @@ -34,6 +34,7 @@ public extension ModulePath { case Onboarding case Calendar case PlaceSearch + case Archive public static let name: String = "Feature" } @@ -49,6 +50,7 @@ public extension ModulePath { case Moim case Auth case PlaceSearch + case Diary public static let name: String = "Domain" } diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Interface/Sources/DomainDiaryInterfaceTemplate.swift b/Namo_SwiftUI/Projects/Domain/Diary/Interface/Sources/DomainDiaryInterfaceTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Interface/Sources/DomainDiaryInterfaceTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Project.swift b/Namo_SwiftUI/Projects/Domain/Diary/Project.swift new file mode 100644 index 00000000..3e301fa9 --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Project.swift @@ -0,0 +1,46 @@ +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let targets: [Target] = [ + .domain( + interface: .Diary, + factory: .init( + dependencies: [ + .core + ] + ) + ), + .domain( + implements: .Diary, + factory: .init( + dependencies: [ + .domain(interface: .Diary) + ] + ) + ), + .domain( + testing: .Diary, + factory: .init( + dependencies: [ + .domain(interface: .Diary) + ] + ) + ), + .domain( + tests: .Diary, + factory: .init( + dependencies: [ + .domain(testing: .Diary) + ] + ) + ) +] + +let project: Project = .makeModule( + name: ModulePath.Domain.name+ModulePath.Domain.Diary.rawValue, + targets: targets +) + + + diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Testing/Sources/DomainDiaryTestingTemplate.swift b/Namo_SwiftUI/Projects/Domain/Diary/Testing/Sources/DomainDiaryTestingTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Testing/Sources/DomainDiaryTestingTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Tests/Sources/DomainDiaryTestsTemplate.swift b/Namo_SwiftUI/Projects/Domain/Diary/Tests/Sources/DomainDiaryTestsTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Tests/Sources/DomainDiaryTestsTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Domain/Project.swift b/Namo_SwiftUI/Projects/Domain/Project.swift index b5bd4dbb..9ce9db79 100644 --- a/Namo_SwiftUI/Projects/Domain/Project.swift +++ b/Namo_SwiftUI/Projects/Domain/Project.swift @@ -20,6 +20,7 @@ let targets: [Target] = [ .domain(implements: .Moim), .domain(implements: .Auth), .domain(implements: .PlaceSearch), + .domain(implements: .Diary) ] ) ) diff --git a/Namo_SwiftUI/Projects/Domain/Sources/DomainExport.swift b/Namo_SwiftUI/Projects/Domain/Sources/DomainExport.swift index 8ad7b9cf..5fc26a14 100644 --- a/Namo_SwiftUI/Projects/Domain/Sources/DomainExport.swift +++ b/Namo_SwiftUI/Projects/Domain/Sources/DomainExport.swift @@ -11,3 +11,4 @@ @_exported import DomainMoim @_exported import DomainAuth @_exported import DomainAuthInterface +@_exported import DomainDiary diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Example/Sources/FeatureArchiveExampleTemplate.swift b/Namo_SwiftUI/Projects/Feature/Archive/Example/Sources/FeatureArchiveExampleTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Example/Sources/FeatureArchiveExampleTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Interface/Sources/FeatureArchiveInterfaceTemplate.swift b/Namo_SwiftUI/Projects/Feature/Archive/Interface/Sources/FeatureArchiveInterfaceTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Interface/Sources/FeatureArchiveInterfaceTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Project.swift b/Namo_SwiftUI/Projects/Feature/Archive/Project.swift new file mode 100644 index 00000000..3c2c9a18 --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Project.swift @@ -0,0 +1,56 @@ +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let targets: [Target] = [ + .feature( + interface: .Archive, + factory: .init( + dependencies: [ + .domain + ] + ) + ), + .feature( + implements: .Archive, + factory: .init( + dependencies: [ + .feature(interface: .Archive), + .feature(interface: .Calendar) + ] + ) + ), + .feature( + testing: .Archive, + factory: .init( + dependencies: [ + .feature(interface: .Archive) + ] + ) + ), + .feature( + tests: .Archive, + factory: .init( + dependencies: [ + .feature(testing: .Archive) + ] + ) + ), + .feature( + example: .Archive, + factory: .init( + infoPlist: .exampleAppDefault, + dependencies: [ + .feature(implements: .Archive) + ] + ) + ) +] + +let project: Project = .makeModule( + name: ModulePath.Feature.name+ModulePath.Feature.Archive.rawValue, + targets: targets +) + + + diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift new file mode 100644 index 00000000..c4e8193a --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift @@ -0,0 +1,34 @@ +// +// ArchiveCalendarStore.swift +// FeatureArchive +// +// Created by 정현우 on 10/31/24. +// + +import SwiftUI + +import ComposableArchitecture + +@Reducer +public struct ArchiveCalendarStore { + public init() {} + + @ObservableState + public struct State: Equatable { + } + + public enum Action { + // 뒤로가기 + case backBtnTapped + } + + public var body: some ReducerOf { + Reduce { state, action in + switch action { + case .backBtnTapped: + return .none + } + } + } + +} diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift new file mode 100644 index 00000000..dd66334c --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift @@ -0,0 +1,46 @@ +// +// ArchiveCalendarView.swift +// FeatureArchive +// +// Created by 정현우 on 10/31/24. +// + +import Foundation +import SwiftUI + +import ComposableArchitecture + +import SharedDesignSystem + +public struct ArchiveCalendarView: View { + let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some View { + WithPerceptionTracking { + VStack(spacing: 0) { + + } + .namoNabBar( + center: { + Text("보관함") + .font(.pretendard(.bold, size: 16)) + .foregroundStyle(Color.colorBlack) + }, + left: { + Button( + action: { + store.send(.backBtnTapped) + }, + label: { + Image(asset: SharedDesignSystemAsset.Assets.icArrowLeftThick) + } + ) + } + ) + } + } +} diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainStore.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainStore.swift new file mode 100644 index 00000000..aaabf775 --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainStore.swift @@ -0,0 +1,38 @@ +// +// ArchiveMainStore.swift +// FeatureArchive +// +// Created by 정현우 on 10/31/24. +// + +import SwiftUI + +import ComposableArchitecture + +@Reducer +public struct ArchiveMainStore { + public init() {} + + @ObservableState + public struct State: Equatable { + } + + public enum Action { + // 뒤로가기 + case backBtnTapped + // 캘린더로 + case calendarBtnTapped + } + + public var body: some ReducerOf { + Reduce { state, action in + switch action { + case .backBtnTapped: + return .none + case .calendarBtnTapped: + return .none + } + } + } + +} diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainView.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainView.swift new file mode 100644 index 00000000..6a144498 --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveMain/ArchiveMainView.swift @@ -0,0 +1,56 @@ +// +// ArchiveMainView.swift +// FeatureArchive +// +// Created by 정현우 on 10/31/24. +// + +import Foundation +import SwiftUI + +import ComposableArchitecture + +import SharedDesignSystem + +public struct ArchiveMainView: View { + let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some View { + WithPerceptionTracking { + VStack(spacing: 0) { + + } + .namoNabBar( + center: { + Text("보관함") + .font(.pretendard(.bold, size: 16)) + .foregroundStyle(Color.colorBlack) + }, + left: { + Button( + action: { + store.send(.backBtnTapped) + }, + label: { + Image(asset: SharedDesignSystemAsset.Assets.icArrowLeftThick) + } + ) + }, + right: { + Button( + action: { + store.send(.calendarBtnTapped) + }, + label: { + Image(asset: SharedDesignSystemAsset.Assets.icCalendar) + } + ) + } + ) + } + } +} diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift new file mode 100644 index 00000000..12858fff --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift @@ -0,0 +1,70 @@ +// +// ArchiveCoordinator.swift +// FeatureArchive +// +// Created by 정현우 on 10/31/24. +// + +import Foundation +import ComposableArchitecture +import TCACoordinators + +@Reducer(state: .equatable) +public enum ArchvieScreen { + case archiveMain(ArchiveMainStore) + case archiveCalendar(ArchiveCalendarStore) +} + +@Reducer +public struct ArchiveCoordinator { + public init() {} + + @ObservableState + public struct State: Equatable { + var routes: [Route] = [] + + public static let initialState = State( + routes: [.root(.archiveMain(.init()))] + ) + } + + public enum Action { + case router(IndexedRouterActionOf) + } + + public var body: some ReducerOf { + Reduce { state, action in + switch action { + // 아카이브 메인에서 + case .router(.routeAction(_, action: .archiveMain(let action))): + switch action { + case .calendarBtnTapped: + // 아카이브 캘린더로 + state.routes.push(.archiveCalendar(.init())) + return .none + + default: + return .none + } + + // 아카이브 캘린더에서 + case .router(.routeAction(_, action: .archiveCalendar(let action))): + switch action { + case .backBtnTapped: + // 뒤로가기 + state.routes.pop() + return .none + + default: + return .none + } + + + default: + return .none + } + } + } + + +} diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinatorView.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinatorView.swift new file mode 100644 index 00000000..5f0649b1 --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinatorView.swift @@ -0,0 +1,31 @@ +// +// ArchiveCoordinatorView.swift +// FeatureArchive +// +// Created by 정현우 on 10/31/24. +// + +import SwiftUI + +import ComposableArchitecture +import TCACoordinators + +public struct ArchiveCoordinatorView: View { + let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some View { + TCARouter(store.scope(state: \.routes, action: \.router)) { screen in + switch screen.case { + case let .archiveMain(store): + ArchiveMainView(store: store) + + case let .archiveCalendar(store): + ArchiveCalendarView(store: store) + } + } + } +} diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Testing/Sources/FeatureArchiveTestingTemplate.swift b/Namo_SwiftUI/Projects/Feature/Archive/Testing/Sources/FeatureArchiveTestingTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Testing/Sources/FeatureArchiveTestingTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Tests/Sources/FeatureArchiveTestsTemplate.swift b/Namo_SwiftUI/Projects/Feature/Archive/Tests/Sources/FeatureArchiveTestsTemplate.swift new file mode 100644 index 00000000..caa685bd --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Archive/Tests/Sources/FeatureArchiveTestsTemplate.swift @@ -0,0 +1,7 @@ +// +// emptyfile.swift +// Manifests +// +// Created by 정현우 on 10/1/24. +// + diff --git a/Namo_SwiftUI/Projects/Feature/Home/Project.swift b/Namo_SwiftUI/Projects/Feature/Home/Project.swift index 7a227340..fbbca819 100644 --- a/Namo_SwiftUI/Projects/Feature/Home/Project.swift +++ b/Namo_SwiftUI/Projects/Feature/Home/Project.swift @@ -23,7 +23,8 @@ let targets: [Target] = [ factory: .init( dependencies: [ .feature(interface: .Home), - .feature(implements: .Calendar) + .feature(implements: .Calendar), + .feature(implements: .Archive) ] ) ), diff --git a/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinator.swift b/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinator.swift index 0ab7cd77..d0b3d4a8 100644 --- a/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinator.swift +++ b/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinator.swift @@ -11,10 +11,13 @@ import TCACoordinators import SwiftUICalendar +import FeatureArchive + @Reducer(state: .equatable) public enum HomeScreen { case homeMain(HomeMainStore) case scheduleEditCoordinator(ScheduleEditCoordinator) + case archiveCoordinator(ArchiveCoordinator) } @Reducer @@ -51,8 +54,6 @@ public struct HomeCoordinator { return .none - case .router(.routeAction(_, action: .homeMain(.archiveTapped))): - return .none case let .router(.routeAction(_, action: .homeMain(.editSchedule(isNewSchedule, schedule, selectDate)))): // 홈에서 스케쥴 생성/편집 띄우기 @@ -85,6 +86,16 @@ public struct HomeCoordinator { return .send(.dismiss) + case .router(.routeAction(_, action: .homeMain(.archiveTapped))): + // 홈화면에서 보관함으로 + state.routes.push(.archiveCoordinator(.initialState)) + return .none + + case .router(.routeAction(_, action: .archiveCoordinator(.router(.routeAction(_, action: .archiveMain(.backBtnTapped)))))): + // 보관함 뒤로가기 + state.routes.pop() + return .none + case .dismiss: state.showBackgroundOpacity = false state.routes.dismiss() diff --git a/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinatorView.swift b/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinatorView.swift index 1677504c..3284d070 100644 --- a/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinatorView.swift +++ b/Namo_SwiftUI/Projects/Feature/Home/Sources/Coordinator/HomeCoordinatorView.swift @@ -11,6 +11,7 @@ import ComposableArchitecture import TCACoordinators import SharedDesignSystem +import FeatureArchive public struct HomeCoordinatorView: View { let store: StoreOf @@ -41,6 +42,8 @@ public struct HomeCoordinatorView: View { .onAppear { self.store.send(.toggleBackgroundOpacity) } + case let .archiveCoordinator(store): + ArchiveCoordinatorView(store: store) } } } diff --git a/Namo_SwiftUI/Projects/Feature/Project.swift b/Namo_SwiftUI/Projects/Feature/Project.swift index e823c2f3..ee1ee874 100644 --- a/Namo_SwiftUI/Projects/Feature/Project.swift +++ b/Namo_SwiftUI/Projects/Feature/Project.swift @@ -20,7 +20,8 @@ let targets: [Target] = [ .feature(implements: .Moim), .feature(implements: .Onboarding), .feature(implements: .Calendar), - .feature(implements: .PlaceSearch) + .feature(implements: .PlaceSearch), + .feature(implements: .Archive) ] ) ) diff --git a/Namo_SwiftUI/Projects/Feature/Sources/FeatureExport.swift b/Namo_SwiftUI/Projects/Feature/Sources/FeatureExport.swift index e32dfda2..58f8940f 100644 --- a/Namo_SwiftUI/Projects/Feature/Sources/FeatureExport.swift +++ b/Namo_SwiftUI/Projects/Feature/Sources/FeatureExport.swift @@ -12,4 +12,4 @@ @_exported import FeatureOnboarding @_exported import FeatureCalendar @_exported import FeaturePlaceSearch - +@_exported import FeatureArchive From 27f905ef20b5f019df70bbd338a2ee010eed6c4c Mon Sep 17 00:00:00 2001 From: HyunWoo Jeong Date: Sat, 2 Nov 2024 13:18:49 +0900 Subject: [PATCH 2/3] =?UTF-8?q?Feat:=20=EB=B3=B4=EA=B4=80=ED=95=A8=20?= =?UTF-8?q?=EC=BA=98=EB=A6=B0=EB=8D=94=20=ED=8D=BC=EB=B8=94=EB=A6=AC?= =?UTF-8?q?=EC=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../API/EndPoint/Diary/DiaryEndPoint.swift | 101 +++----- .../EndPoint/Diary/MoimDiaryEndPoint.swift | 103 -------- .../Sources/DTO/Diary/DiaryCalendarDTO.swift | 22 ++ .../Sources/DTO/Diary/DiaryScheduleDTO.swift | 48 ++++ .../Sources/DomainDiarySourcesTemplate.swift | 7 - .../Diary/Sources/Mapper/DiaryMapper.swift | 57 +++++ .../Diary/Sources/Model/DiaryCalendar.swift | 22 ++ .../Diary/Sources/Model/DiarySchedule.swift | 50 ++++ .../Diary/Sources/UseCase/DiaryUseCase.swift | 64 +++++ .../ArchiveCalendarStore.swift | 30 ++- .../ArchiveCalendar/ArchiveCalendarView.swift | 17 +- .../Coordinator/ArchiveCoordinator.swift | 1 + .../ArchiveCalendarDetailScheduleItem.swift | 73 ++++++ .../Sources/Archive/ArchiveCalendarItem.swift | 49 ++++ .../Archive/NamoArchiveCalendarView.swift | 228 ++++++++++++++++++ 15 files changed, 695 insertions(+), 177 deletions(-) delete mode 100644 Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/MoimDiaryEndPoint.swift create mode 100644 Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryCalendarDTO.swift create mode 100644 Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryScheduleDTO.swift delete mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Sources/Mapper/DiaryMapper.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryCalendar.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiarySchedule.swift create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarDetailScheduleItem.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift create mode 100644 Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift diff --git a/Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/DiaryEndPoint.swift b/Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/DiaryEndPoint.swift index bbde894c..3f797556 100644 --- a/Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/DiaryEndPoint.swift +++ b/Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/DiaryEndPoint.swift @@ -1,78 +1,51 @@ // // DiaryEndPoint.swift -// Namo_SwiftUI +// CoreNetwork // -// Created by 서은수 on 3/16/24. +// Created by 정현우 on 11/1/24. // import Alamofire -import Foundation +import SwiftUICalendar import SharedUtil public enum DiaryEndPoint { - case createDiary(scheduleId: Int, content: String, images: [Data?]) - case getMonthDiary(request: GetDiaryRequestDTO) - case getOneDiary(scheduleId: Int) - case changeDiary(scheduleId: Int, content: String, images: [Data?], deleteImageIds: [Int]) - case deleteDiary(diaryId: Int) + case getCalendarByMonth(ym: YearMonth) + case getDiaryByDate(ymd: YearMonthDay) } extension DiaryEndPoint: EndPoint { - public var baseURL: String { - return "\(SecretConstants.baseURL)/diaries" - } - - public var path: String { - switch self { - case .createDiary(_, _, _): - return "" - case .getMonthDiary(let req): - return "/month/\(req.year),\(req.month)" - case .getOneDiary(let scheduleId): - return "/\(scheduleId)" - case .changeDiary: - return "" - case .deleteDiary(let diaryId): - return "/\(diaryId)" - } - } - - public var method: Alamofire.HTTPMethod { - switch self { - case .createDiary: - return .post - case .getMonthDiary, .getOneDiary: - return .get - case .changeDiary: - return .patch - case .deleteDiary: - return .delete - } - } - - public var task: APITask { - switch self { - case .createDiary(let scheduleId, let content, let images): - let body = ["scheduleId": scheduleId, "content": content] as [String : Any] - return .uploadImagesWithBody(imageDatas: images, body: body) - case .changeDiary(let scheduleId, let content, let images, let deleteImageIds): - let params = ["scheduleId": scheduleId, "content": content, "deleteImageIds": deleteImageIds] as [String : Any] - return .uploadImagesWithParameter(imageDatas: images, parameters: params, imageKeyName: "createImages") - case .getMonthDiary(let req): - let params = ["page": req.page, "size": req.size] - return .requestParameters(parameters: params, encoding: URLEncoding.default) - case .deleteDiary, .getOneDiary: - return .requestPlain - } - } - - public var headers: HTTPHeaders? { - switch self { - case .createDiary, .changeDiary: - return ["Content-Type": "multipart/form-data"] - default: - return ["Content-Type": "application/json"] - } - } + public var baseURL: String { + return "\(SecretConstants.baseURL)/diaries" + } + + public var path: String { + switch self { + case .getCalendarByMonth(let ym): + return "/calendar/\(ym.year)-\(String(format: "%02d", ym.month))" + case .getDiaryByDate(let ymd): + return "/date/\(ymd.year)-\(String(format: "%02d", ymd.month))-\(String(format: "%02d", ymd.day))" + } + } + + public var method: Alamofire.HTTPMethod { + switch self { + case .getCalendarByMonth: + return .get + case .getDiaryByDate: + return .get + } + } + + public var task: APITask { + switch self { + case .getCalendarByMonth: + return .requestPlain + case .getDiaryByDate: + return .requestPlain + } + } + + } diff --git a/Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/MoimDiaryEndPoint.swift b/Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/MoimDiaryEndPoint.swift deleted file mode 100644 index ff68f3ae..00000000 --- a/Namo_SwiftUI/Projects/Core/Network/Sources/API/EndPoint/Diary/MoimDiaryEndPoint.swift +++ /dev/null @@ -1,103 +0,0 @@ -// -// MoimDiaryEndPoint.swift -// Namo_SwiftUI -// -// Created by 서은수 on 4/6/24. -// - -import Alamofire -import Foundation - -import SharedUtil - -public enum MoimDiaryEndPoint { - case createMoimDiaryPlace(moimScheduleId: Int, req: EditMoimDiaryPlaceReqDTO) - case changeMoimDiaryPlace(activityId: Int, req: EditMoimDiaryPlaceReqDTO, deleteImageIds: [Int]) - case deleteMoimDiaryPlace(activityId: Int) - case editMoimDiary(scheduleId: Int, req: ChangeMoimDiaryRequestDTO) - case deleteMoimDiary(moimScheduleId: Int) - case getMonthMoimDiary(request: GetMonthMoimDiaryReqDTO) - case getOneMoimDiary(moimScheduleId: Int) - case getOneMoimDiaryDetail(moimScheduleId: Int) - case deleteMoimDiaryOnPersonal(scheduleId: Int) -} - -extension MoimDiaryEndPoint: EndPoint { - public var baseURL: String { - return "\(SecretConstants.baseURL)/group/diaries" - } - - public var path: String { - switch self { - case .createMoimDiaryPlace(let moimScheduleId, _): - return "/\(moimScheduleId)" - case .changeMoimDiaryPlace(let activityId, _, _), - .deleteMoimDiaryPlace(let activityId): - return "/\(activityId)" - case .getMonthMoimDiary(let req): - return "/month/\(req.year),\(req.month)" - case .getOneMoimDiary(let moimScheduleId): - return "/\(moimScheduleId)" - case .editMoimDiary(let scheduleId, _): - return "/text/\(scheduleId)" - case .deleteMoimDiary(let moimScheduleId): - return "/all/\(moimScheduleId)" - case .getOneMoimDiaryDetail(let moimScheduleId): - return "/detail/\(moimScheduleId)" - case .deleteMoimDiaryOnPersonal(scheduleId: let scheduleId): - return "/person/\(scheduleId)" - } - } - - public var method: Alamofire.HTTPMethod { - switch self { - case .getMonthMoimDiary, .getOneMoimDiary, .getOneMoimDiaryDetail: - return .get - case .createMoimDiaryPlace: - return .post - case .changeMoimDiaryPlace, .editMoimDiary: - return .patch - case .deleteMoimDiaryPlace, .deleteMoimDiary, .deleteMoimDiaryOnPersonal: - return .delete - } - } - - public var task: APITask { - switch self { - case .createMoimDiaryPlace(let moimScheduleId, let req): - - let params = [ - "moimScheduleId": moimScheduleId, - "activityName": req.name, - "activityMoney": req.money, - "participantUserIds": req.participants - ] as [String : Any] - return .uploadImagesWithParameter(imageDatas: req.imgs, parameters: params, imageKeyName: "createImages") - case .changeMoimDiaryPlace(let activityId, let req, let deleteImageIds): - let params = [ - "activityId": activityId, - "deleteImageIds": deleteImageIds, - "activityName": req.name, - "activityMoney": req.money, - "participantUserIds": req.participants - ] as [String : Any] - return .uploadImagesWithParameter(imageDatas: req.imgs, parameters: params, imageKeyName: "createImages") - case .editMoimDiary(_, let req): - return .requestJSONEncodable(parameters: req) - case .deleteMoimDiaryPlace, .deleteMoimDiary, .getOneMoimDiary, .getOneMoimDiaryDetail, .deleteMoimDiaryOnPersonal: - return .requestPlain - case .getMonthMoimDiary(let req): - let params = ["page": req.page, "size": req.size] - return .requestParameters(parameters: params, encoding: URLEncoding.default) - } - } - - public var headers: HTTPHeaders? { - switch self { - case .createMoimDiaryPlace, .changeMoimDiaryPlace: - return ["Content-Type": "multipart/form-data"] - default: - return ["Content-Type": "application/json"] - } - } -} diff --git a/Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryCalendarDTO.swift b/Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryCalendarDTO.swift new file mode 100644 index 00000000..ba4e889b --- /dev/null +++ b/Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryCalendarDTO.swift @@ -0,0 +1,22 @@ +// +// DiaryCalendarDTO.swift +// CoreNetwork +// +// Created by 정현우 on 11/1/24. +// + +public struct DiaryCalendarDTO: Decodable { + public let year: Int + public let month: Int + public let diaryDateForPersonal: [Int] + public let diaryDateForMeeting: [Int] + public let diaryDateForBirthday: [Int] + + public init(year: Int, month: Int, diaryDateForPersonal: [Int], diaryDateForMeeting: [Int], diaryDateForBirthday: [Int]) { + self.year = year + self.month = month + self.diaryDateForPersonal = diaryDateForPersonal + self.diaryDateForMeeting = diaryDateForMeeting + self.diaryDateForBirthday = diaryDateForBirthday + } +} diff --git a/Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryScheduleDTO.swift b/Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryScheduleDTO.swift new file mode 100644 index 00000000..f19091f5 --- /dev/null +++ b/Namo_SwiftUI/Projects/Core/Network/Sources/DTO/Diary/DiaryScheduleDTO.swift @@ -0,0 +1,48 @@ +// +// DiaryScheduleDTO.swift +// CoreNetwork +// +// Created by 정현우 on 11/1/24. +// + +public struct DiaryScheduleDTO: Decodable { + public let scheduleId: Int + public let scheduleType: Int + public let categoryInfo: DiaryScheduleCategoryDTO + public let scheduleStartDate: String + public let scheduleEndDate: String + public let scheduleTitle: String + public let diaryId: Int + public let participantInfo: DiaryScheduleParticipantDTO + + public init(scheduleId: Int, scheduleType: Int, categoryInfo: DiaryScheduleCategoryDTO, scheduleStartDate: String, scheduleEndDate: String, scheduleTitle: String, diaryId: Int, participantInfo: DiaryScheduleParticipantDTO) { + self.scheduleId = scheduleId + self.scheduleType = scheduleType + self.categoryInfo = categoryInfo + self.scheduleStartDate = scheduleStartDate + self.scheduleEndDate = scheduleEndDate + self.scheduleTitle = scheduleTitle + self.diaryId = diaryId + self.participantInfo = participantInfo + } +} + +public struct DiaryScheduleCategoryDTO: Decodable { + public let name: String + public let colorId: Int + + public init(name: String, colorId: Int) { + self.name = name + self.colorId = colorId + } +} + +public struct DiaryScheduleParticipantDTO: Decodable { + public let participantsCount: Int + public let participantsNames: String + + public init(participantsCount: Int, participantsNames: String) { + self.participantsCount = participantsCount + self.participantsNames = participantsNames + } +} diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift deleted file mode 100644 index caa685bd..00000000 --- a/Namo_SwiftUI/Projects/Domain/Diary/Sources/DomainDiarySourcesTemplate.swift +++ /dev/null @@ -1,7 +0,0 @@ -// -// emptyfile.swift -// Manifests -// -// Created by 정현우 on 10/1/24. -// - diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/Mapper/DiaryMapper.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Mapper/DiaryMapper.swift new file mode 100644 index 00000000..59f10da8 --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Mapper/DiaryMapper.swift @@ -0,0 +1,57 @@ +// +// DiaryMapper.swift +// DomainDiary +// +// Created by 정현우 on 11/1/24. +// + +import Foundation + +import CoreNetwork +import SharedUtil + +// MARK: - toEntity() +extension DiaryCalendarDTO { + func toEntity() -> DiaryCalendar { + return DiaryCalendar( + year: year, + month: month, + diaryDateForPersonal: diaryDateForPersonal, + diaryDateForMeeting: diaryDateForMeeting, + diaryDateForBirthday: diaryDateForBirthday + ) + } +} + +extension DiaryScheduleDTO { + func toEntity() -> DiarySchedule { + return DiarySchedule( + scheduleId: scheduleId, + scheduleType: scheduleType, + categoryInfo: categoryInfo.toEntity(), + scheduleStartDate: Date.ISO8601toDate(scheduleStartDate), + scheduleEndDate: Date.ISO8601toDate(scheduleEndDate), + scheduleTitle: scheduleTitle, + diaryId: diaryId, + participantInfo: participantInfo.toEntity() + ) + } +} + +extension DiaryScheduleCategoryDTO { + func toEntity() -> DiaryScheduleCategory { + return DiaryScheduleCategory( + name: name, + colorId: colorId + ) + } +} + +extension DiaryScheduleParticipantDTO { + func toEntity() -> DiaryScheduleParticipant { + return DiaryScheduleParticipant( + participantsCount: participantsCount, + participantsNames: participantsNames + ) + } +} diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryCalendar.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryCalendar.swift new file mode 100644 index 00000000..bd5ec044 --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryCalendar.swift @@ -0,0 +1,22 @@ +// +// DiaryCalendar.swift +// DomainDiary +// +// Created by 정현우 on 11/1/24. +// + +public struct DiaryCalendar: Decodable { + public let year: Int + public let month: Int + public let diaryDateForPersonal: [Int] + public let diaryDateForMeeting: [Int] + public let diaryDateForBirthday: [Int] + + public init(year: Int, month: Int, diaryDateForPersonal: [Int], diaryDateForMeeting: [Int], diaryDateForBirthday: [Int]) { + self.year = year + self.month = month + self.diaryDateForPersonal = diaryDateForPersonal + self.diaryDateForMeeting = diaryDateForMeeting + self.diaryDateForBirthday = diaryDateForBirthday + } +} diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiarySchedule.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiarySchedule.swift new file mode 100644 index 00000000..f38bc7b1 --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiarySchedule.swift @@ -0,0 +1,50 @@ +// +// DiarySchedule.swift +// DomainDiary +// +// Created by 정현우 on 11/1/24. +// + +import Foundation + +public struct DiarySchedule: Decodable, Hashable { + public let scheduleId: Int + public let scheduleType: Int + public let categoryInfo: DiaryScheduleCategory + public let scheduleStartDate: Date + public let scheduleEndDate: Date + public let scheduleTitle: String + public let diaryId: Int + public let participantInfo: DiaryScheduleParticipant + + public init(scheduleId: Int, scheduleType: Int, categoryInfo: DiaryScheduleCategory, scheduleStartDate: Date, scheduleEndDate: Date, scheduleTitle: String, diaryId: Int, participantInfo: DiaryScheduleParticipant) { + self.scheduleId = scheduleId + self.scheduleType = scheduleType + self.categoryInfo = categoryInfo + self.scheduleStartDate = scheduleStartDate + self.scheduleEndDate = scheduleEndDate + self.scheduleTitle = scheduleTitle + self.diaryId = diaryId + self.participantInfo = participantInfo + } +} + +public struct DiaryScheduleCategory: Decodable, Hashable { + public let name: String + public let colorId: Int + + public init(name: String, colorId: Int) { + self.name = name + self.colorId = colorId + } +} + +public struct DiaryScheduleParticipant: Decodable, Hashable { + public let participantsCount: Int + public let participantsNames: String + + public init(participantsCount: Int, participantsNames: String) { + self.participantsCount = participantsCount + self.participantsNames = participantsNames + } +} diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift new file mode 100644 index 00000000..44118ecc --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift @@ -0,0 +1,64 @@ +// +// DiaryUseCase.swift +// DomainDiary +// +// Created by 정현우 on 11/1/24. +// + +import SwiftUI + +import ComposableArchitecture +import SwiftUICalendar + +import CoreNetwork + +@DependencyClient +public struct DiaryUseCase { + // 캘린더 일정 월별로 가져오기 + public func getCalendarByMonth(ym: YearMonth) async throws -> DiaryCalendar { + let response: BaseResponse = try await APIManager.shared.performRequest(endPoint: DiaryEndPoint.getCalendarByMonth(ym: ym)) + + return response.result! + } + + // 특정 일 스케쥴 가져오기 + public func getDiaryByDate(ymd: YearMonthDay) async throws -> [DiarySchedule] { + let response: BaseResponse<[DiarySchedule]> = try await APIManager.shared.performRequest(endPoint: DiaryEndPoint.getDiaryByDate(ymd: ymd)) + + return response.result ?? [] + } + + // detailView의 Schedule에 표시할 시간을 리턴하는 함수 + // 하루 일정인지 여러 일 지속 일정인지에 따라 리턴 다르게 + public func getScheduleTimeWithBaseYMD( + schedule: DiarySchedule, + baseYMD: YearMonthDay + ) -> String { + if schedule.scheduleStartDate.toYMD() == schedule.scheduleEndDate.adjustDateIfMidNight().toYMD() { + // 같은 날이라면 그냥 시작시간-종료시간 표시 + return "\(schedule.scheduleStartDate.toHHmm()) - \(schedule.scheduleEndDate.adjustDateIfMidNight().toHHmm())" + } else if baseYMD == schedule.scheduleStartDate.toYMD() { + // 여러 일 지속 스케쥴의 시작일이라면 + return "\(schedule.scheduleStartDate.toHHmm()) - 23:59" + } else if baseYMD == schedule.scheduleEndDate.toYMD() { + // 여러 일 지속 스케쥴의 종료일이라면 + return "00:00 - \(schedule.scheduleEndDate.adjustDateIfMidNight().toHHmm())" + } else { + // 여러 일 지속 스케쥴의 중간이라면 + return "00:00 - 23:59" + } + } +} + +extension DiaryUseCase: DependencyKey { + public static var liveValue: DiaryUseCase { + return DiaryUseCase() + } +} + +extension DependencyValues { + public var diaryUseCase: DiaryUseCase { + get { self[DiaryUseCase.self] } + set { self[DiaryUseCase.self] = newValue } + } +} diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift index c4e8193a..dbfe4d94 100644 --- a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift @@ -8,6 +8,9 @@ import SwiftUI import ComposableArchitecture +import SwiftUICalendar + +import DomainDiary @Reducer public struct ArchiveCalendarStore { @@ -15,17 +18,40 @@ public struct ArchiveCalendarStore { @ObservableState public struct State: Equatable { + // 달력에서 현재 focusing된 날짜 + var focusDate: YearMonthDay? = nil + + // 캘린더에 표시될 일정 + var schedules: [YearMonthDay: [DiarySchedule]] = [:] } - public enum Action { + public enum Action: BindableAction { + case binding(BindingAction) // 뒤로가기 case backBtnTapped + // 특정 날짜 선택 + case selectDate(YearMonthDay) + } public var body: some ReducerOf { + BindingReducer() + Reduce { state, action in switch action { - case .backBtnTapped: + case .binding: + return .none + + case .backBtnTapped: + return .none + + case .selectDate(let date): + if state.focusDate == date { + state.focusDate = nil + } else { + state.focusDate = date + } + return .none } } diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift index dd66334c..c6bf1386 100644 --- a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift @@ -9,11 +9,15 @@ import Foundation import SwiftUI import ComposableArchitecture +import SwiftUICalendar +import SharedUtil import SharedDesignSystem +import FeatureCalendar public struct ArchiveCalendarView: View { - let store: StoreOf + @Perception.Bindable public var store: StoreOf + @StateObject var calendarController = CalendarController(orientation: .vertical) public init(store: StoreOf) { self.store = store @@ -22,8 +26,19 @@ public struct ArchiveCalendarView: View { public var body: some View { WithPerceptionTracking { VStack(spacing: 0) { + NamoArchiveCalendarView( + calendarController: calendarController, + focusDate: $store.focusDate, + schedules: $store.schedules, + dateTapAction: { date in + store.send(.selectDate(date), animation: .default) + } + ) + Spacer() + .frame(height: tabBarHeight) } + .ignoresSafeArea(edges: .bottom) .namoNabBar( center: { Text("보관함") diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift index 12858fff..b8b71f20 100644 --- a/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/Coordinator/ArchiveCoordinator.swift @@ -64,6 +64,7 @@ public struct ArchiveCoordinator { return .none } } + .forEachRoute(\.routes, action: \.router) } diff --git a/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarDetailScheduleItem.swift b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarDetailScheduleItem.swift new file mode 100644 index 00000000..ef3876c7 --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarDetailScheduleItem.swift @@ -0,0 +1,73 @@ +// +// ArchiveCalendarDetailScheduleItem.swift +// FeatureCalendar +// +// Created by 정현우 on 10/31/24. +// + +import SwiftUI + +import SwiftUICalendar + +import SharedDesignSystem +import SharedUtil +import DomainDiary + +public struct ArchiveCalendarDetailScheduleItem: View { + let ymd: YearMonthDay + let schedule: DiarySchedule + + let diaryUseCase = DiaryUseCase.liveValue + + public init( + ymd: YearMonthDay, + schedule: DiarySchedule + ) { + self.ymd = ymd + self.schedule = schedule + } + + public var body: some View { + HStack(spacing: 14) { + Rectangle() + .fill(PalleteColor(rawValue: schedule.categoryInfo.colorId)?.color ?? .clear) + .frame(width: 30, height: schedule.scheduleType == 1 ? 74 : 56) + .clipShape(RoundedCorners(radius: 15, corners: [.topLeft, .bottomLeft])) + + VStack(alignment: .leading, spacing: 4) { + HStack(spacing: 8) { + Text( + diaryUseCase.getScheduleTimeWithBaseYMD( + schedule: schedule, + baseYMD: ymd + ) + ) + .font(.pretendard(.medium, size: 12)) + .foregroundStyle(Color.mainText) + + Rectangle() + .fill(Color.mainText) + .frame(width: 1, height: 10) + + Text(schedule.categoryInfo.name) + .font(.pretendard(.medium, size: 12)) + .foregroundStyle(Color.mainText) + } + + Text(schedule.scheduleTitle) + .font(.pretendard(.bold, size: 15)) + .foregroundStyle(Color.colorBlack) + + } + .padding(.vertical, 10) + + Spacer() + } + .frame(width: screenWidth-50) + .background( + RoundedRectangle(cornerRadius: 15) + .fill(Color.itemBackground) + .shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 0) + ) + } +} diff --git a/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift new file mode 100644 index 00000000..e281c377 --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift @@ -0,0 +1,49 @@ +// +// ArchiveCalendarItem.swift +// FeatureCalendar +// +// Created by 정현우 on 10/31/24. +// + +import SwiftUI +import SwiftUICalendar + +import SharedUtil +import SharedDesignSystem +import DomainDiary + +struct ArchiveCalendarItem: View { + @Binding var focusDate: YearMonthDay? + let date: YearMonthDay + let schedules: [DiarySchedule] + + private let MAX_SCHEDULE = screenHeight < 800 ? 3 : 4 + + var body: some View { + GeometryReader { geometry in + VStack(alignment: .leading, spacing: 4) { + dayView + +// calendarItem(geometry: geometry) + } + .padding(.top, 4) + .padding(.leading, 5) + } + .contentShape(Rectangle()) + } + + private var dayView: some View { + VStack(spacing: 0) { + if date.day == 1 { + Text("\(date.month)/\(date.day)") + .font(.pretendard(.bold, size: 12)) + .foregroundStyle(Color.mainOrange) + } else { + Text("\(date.day)") + .font(.pretendard(.bold, size: 12)) + .foregroundStyle(Color.black) + } + } + } + +} diff --git a/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift new file mode 100644 index 00000000..f77d4e35 --- /dev/null +++ b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift @@ -0,0 +1,228 @@ +// +// NamoArchiveCalendarView.swift +// FeatureCalendar +// +// Created by 정현우 on 10/31/24. +// + +import SwiftUI + +import SwiftUICalendar + +import SharedUtil +import SharedDesignSystem +import DomainDiary + + +public struct NamoArchiveCalendarView: View { + @ObservedObject var calendarController: CalendarController + // 현재 포커싱된(detailView) 날짜 + @Binding var focusDate: YearMonthDay? + // 캘린더에 표시할 스케쥴 + @Binding var schedules: [YearMonthDay: [DiarySchedule]] + // 상단에 요일을 보이게 할지 + let showWeekDay: Bool + // 하단 detail view를 보이게 할지 + let showDetailView: Bool + // 특정 달을 선택했을때 + let dateTapAction: (YearMonthDay) -> Void + + private let weekdays: [String] = ["일", "월", "화", "수", "목", "금", "토"] + + public init( + calendarController: CalendarController, + focusDate: Binding = .constant(nil), + schedules: Binding<[YearMonthDay: [DiarySchedule]]> = .constant([:]), + showWeekDay: Bool = true, + showDetailView: Bool = true, + dateTapAction: @escaping (YearMonthDay) -> Void = { _ in } + ) { + self.calendarController = calendarController + self._focusDate = focusDate + self._schedules = schedules + self.showWeekDay = showWeekDay + self.showDetailView = showDetailView + self.dateTapAction = dateTapAction + } + + public var body: some View { + VStack(spacing: 0) { + if showWeekDay { + weekday + .padding(.bottom, 11) + } + + GeometryReader { reader in + VStack { + CalendarView(calendarController) { date in + GeometryReader { geometry in + VStack(alignment: .leading) { + ArchiveCalendarItem( + focusDate: $focusDate, + date: date, + schedules: schedules[date] ?? [] + ) + .onTapGesture { + dateTapAction(date) + } + } + .frame(width: geometry.size.width, height: geometry.size.height, alignment: .topLeading) + } + } + } + } + .padding(.leading, 14) + .padding(.horizontal, 6) + .padding(.top, 3) + + if showDetailView && focusDate != nil { + detailView + } + } + } + + private var weekday: some View { + VStack(alignment: .leading) { + HStack { + ForEach(weekdays, id: \.self) { weekday in + Text(weekday) + .font(.pretendard(.bold, size: 12)) + .foregroundStyle(Color(asset: SharedDesignSystemAsset.Assets.textUnselected)) + + Spacer() + } + } + .padding(.leading, 14) + .padding(.trailing, 6) + } + .frame(height: 30) + .background( + Rectangle() + .fill(Color.white) + .shadow(color: .black.opacity(0.05), radius: 5, x: 0, y: 8) + ) + } + + private var detailView: some View { + let focusDate = focusDate! + + return VStack(spacing: 0) { + HStack { + Spacer() + + Text(String(format: "%02d.%02d (%@)", focusDate.month, focusDate.day, focusDate.getShortWeekday())) + .font(.pretendard(.bold, size: 22)) + .padding(.vertical, 20) + + Spacer() + } + .contentShape(Rectangle()) + .gesture( + DragGesture() + .onChanged { value in + let dragHeight = value.translation.height + if dragHeight > 0 { + withAnimation { + self.focusDate = nil + } + } + } + ) + + ScrollView(.vertical, showsIndicators: false) { + detailViewPersonalSchedule + .padding(.bottom, 32) + + detailViewMeetingSchedule + + Spacer() + .frame(height: 50) + } + .padding(.leading, 28) + .padding(.trailing, 22) + } + .background(Color.white) + .clipShape(RoundedCorners(radius: 15, corners: [.topLeft, .topRight])) + .shadow(color: .black.opacity(0.15), radius: 12, x: 0, y: -5) + .mask { + // 상단에만 shadow를 주기 위함 + Rectangle().padding(.top, -20) + } + } + + private var detailViewPersonalSchedule: some View { + VStack { + HStack { + Text("개인 일정") + .font(.pretendard(.bold, size: 15)) + .foregroundStyle(Color.mainText) + .padding(.bottom, 11) + .padding(.leading, 3) + + Spacer() + } + + // 개인 일정 + if let schedules = schedules[focusDate!]?.filter({$0.scheduleType == 0 || $0.scheduleType == 2}), + !schedules.isEmpty + { + ForEach(schedules, id: \.self) { schedule in + ArchiveCalendarDetailScheduleItem( + ymd: focusDate!, + schedule: schedule + ) + } + } else { + HStack(spacing: 12) { + Rectangle() + .fill(Color.textPlaceholder) + .frame(width: 3, height: 21) + + Text("등록된 개인 일정이 없습니다.") + .font(.pretendard(.medium, size: 14)) + .foregroundStyle(Color.textDisabled) + + Spacer() + } + } + } + } + + private var detailViewMeetingSchedule: some View { + VStack { + HStack { + Text("모임 일정") + .font(.pretendard(.bold, size: 15)) + .foregroundStyle(Color.mainText) + .padding(.bottom, 11) + .padding(.leading, 3) + + Spacer() + } + + // 개인 일정 + if let schedules = schedules[focusDate!]?.filter({$0.scheduleType == 1}), + !schedules.isEmpty + { + ForEach(schedules, id: \.self) { schedule in + ArchiveCalendarDetailScheduleItem( + ymd: focusDate!, + schedule: schedule + ) + } + } else { + HStack(spacing: 12) { + Rectangle() + .fill(Color(asset: SharedDesignSystemAsset.Assets.textPlaceholder)) + .frame(width: 3, height: 21) + + Text("등록된 모임 일정이 없습니다.") + .font(.pretendard(.medium, size: 14)) + .foregroundStyle(Color.textDisabled) + + Spacer() + } + } + } + } +} From 302547ccaa4498390531aded77e6b7b8dbb74a3e Mon Sep 17 00:00:00 2001 From: HyunWoo Jeong Date: Tue, 5 Nov 2024 20:16:48 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Feat:=20=EB=B3=B4=EA=B4=80=ED=95=A8=20?= =?UTF-8?q?=EC=BA=98=EB=A6=B0=EB=8D=94=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Model/DiaryScheduleType.swift | 12 +++++ .../Diary/Sources/UseCase/DiaryUseCase.swift | 26 +++++++++-- .../ArchiveCalendarStore.swift | 45 +++++++++++++++++++ .../ArchiveCalendar/ArchiveCalendarView.swift | 8 ++++ .../Sources/Archive/ArchiveCalendarItem.swift | 25 ++++++++++- .../Archive/NamoArchiveCalendarView.swift | 7 ++- .../Contents.json | 15 +++++++ .../ic_archive_leaf_gray.svg | 4 ++ .../Contents.json | 15 +++++++ .../ic_archive_leaf_orange.svg | 6 +++ .../Contents.json | 15 +++++++ .../ic_archive_mong_gray.svg | 13 ++++++ .../Contents.json | 15 +++++++ .../ic_archive_mong_orange.svg | 13 ++++++ 14 files changed, 211 insertions(+), 8 deletions(-) create mode 100644 Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryScheduleType.swift create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/Contents.json create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/ic_archive_leaf_gray.svg create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/Contents.json create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/ic_archive_leaf_orange.svg create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/Contents.json create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/ic_archive_mong_gray.svg create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/Contents.json create mode 100644 Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/ic_archive_mong_orange.svg diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryScheduleType.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryScheduleType.swift new file mode 100644 index 00000000..1f2b2a07 --- /dev/null +++ b/Namo_SwiftUI/Projects/Domain/Diary/Sources/Model/DiaryScheduleType.swift @@ -0,0 +1,12 @@ +// +// DiaryScheduleType.swift +// DomainDiary +// +// Created by 정현우 on 11/2/24. +// + +public enum DiaryScheduleType { + case noSchedule + case personalOrBirthdaySchedule + case meetingSchedule +} diff --git a/Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift b/Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift index 44118ecc..12121f3d 100644 --- a/Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift +++ b/Namo_SwiftUI/Projects/Domain/Diary/Sources/UseCase/DiaryUseCase.swift @@ -14,11 +14,29 @@ import CoreNetwork @DependencyClient public struct DiaryUseCase { - // 캘린더 일정 월별로 가져오기 - public func getCalendarByMonth(ym: YearMonth) async throws -> DiaryCalendar { - let response: BaseResponse = try await APIManager.shared.performRequest(endPoint: DiaryEndPoint.getCalendarByMonth(ym: ym)) + // 캘린더 일정 +-1 달씩 월별로 가져오기 + public func getCalendarByMonth(ym: YearMonth) async throws -> [YearMonthDay: DiaryScheduleType] { + var result: [YearMonthDay: DiaryScheduleType] = [:] - return response.result! + for i in -1...1 { + let currentYM = ym.addMonth(i) + let response: BaseResponse = try await APIManager.shared.performRequest(endPoint: DiaryEndPoint.getCalendarByMonth(ym: currentYM)) + + response.result?.diaryDateForPersonal.forEach { day in + result[YearMonthDay(year: currentYM.year, month: currentYM.month, day: day), default: .noSchedule] = .personalOrBirthdaySchedule + } + + response.result?.diaryDateForBirthday.forEach { day in + result[YearMonthDay(year: currentYM.year, month: currentYM.month, day: day), default: .noSchedule] = .personalOrBirthdaySchedule + } + + response.result?.diaryDateForMeeting.forEach { day in + result[YearMonthDay(year: currentYM.year, month: currentYM.month, day: day), default: .noSchedule] = .meetingSchedule + } + + } + + return result } // 특정 일 스케쥴 가져오기 diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift index dbfe4d94..fcf755c0 100644 --- a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarStore.swift @@ -10,6 +10,7 @@ import SwiftUI import ComposableArchitecture import SwiftUICalendar +import CoreLocation import DomainDiary @Reducer @@ -21,6 +22,8 @@ public struct ArchiveCalendarStore { // 달력에서 현재 focusing된 날짜 var focusDate: YearMonthDay? = nil + // 캘린더 타입 + var diaryScheduleTypes: [YearMonthDay: DiaryScheduleType] = [:] // 캘린더에 표시될 일정 var schedules: [YearMonthDay: [DiarySchedule]] = [:] } @@ -32,8 +35,17 @@ public struct ArchiveCalendarStore { // 특정 날짜 선택 case selectDate(YearMonthDay) + // +- 2달 일정 가져오기 + case getSchedules(ym: YearMonth) + case getSchedulesCompleted([YearMonthDay: DiaryScheduleType]) + // 특정 날짜 일정 상세 가져오기 + case getScheduleDetail(ymd: YearMonthDay) + case getScheduleDetailCompleted(ymd: YearMonthDay, schedules: [DiarySchedule]) + } + @Dependency(\.diaryUseCase) var diaryUseCase + public var body: some ReducerOf { BindingReducer() @@ -53,6 +65,39 @@ public struct ArchiveCalendarStore { } return .none + + case .getSchedules(let ym): + return .run { send in + do { + let response = try await diaryUseCase.getCalendarByMonth(ym: ym) + await send(.getSchedulesCompleted(response)) + } catch(let error) { + print(error.localizedDescription) + } + } + + case .getSchedulesCompleted(let response): + state.diaryScheduleTypes = response + return .none + + case .getScheduleDetail(let ymd): + // 이미 받아온 스케쥴들이 있다면 리턴 + if !state.schedules[ymd, default: []].isEmpty { + return .none + } + + return .run { send in + do { + let response = try await diaryUseCase.getDiaryByDate(ymd: ymd) + await send(.getScheduleDetailCompleted(ymd: ymd, schedules: response)) + } catch(let error) { + print(error.localizedDescription) + } + } + + case .getScheduleDetailCompleted(let ymd, let response): + state.schedules[ymd, default: []] = response + return .none } } } diff --git a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift index c6bf1386..4572edab 100644 --- a/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift +++ b/Namo_SwiftUI/Projects/Feature/Archive/Sources/ArchiveCalendar/ArchiveCalendarView.swift @@ -29,8 +29,10 @@ public struct ArchiveCalendarView: View { NamoArchiveCalendarView( calendarController: calendarController, focusDate: $store.focusDate, + diaryScheduleTypes: $store.diaryScheduleTypes, schedules: $store.schedules, dateTapAction: { date in + store.send(.getScheduleDetail(ymd: date)) store.send(.selectDate(date), animation: .default) } ) @@ -39,6 +41,12 @@ public struct ArchiveCalendarView: View { .frame(height: tabBarHeight) } .ignoresSafeArea(edges: .bottom) + .onAppear { + store.send(.getSchedules(ym: calendarController.yearMonth)) + } + .onChange(of: calendarController.yearMonth) { newYM in + store.send(.getSchedules(ym: calendarController.yearMonth)) + } .namoNabBar( center: { Text("보관함") diff --git a/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift index e281c377..935a3354 100644 --- a/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift +++ b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/ArchiveCalendarItem.swift @@ -15,7 +15,7 @@ import DomainDiary struct ArchiveCalendarItem: View { @Binding var focusDate: YearMonthDay? let date: YearMonthDay - let schedules: [DiarySchedule] + let diaryScheduleType: DiaryScheduleType private let MAX_SCHEDULE = screenHeight < 800 ? 3 : 4 @@ -24,7 +24,9 @@ struct ArchiveCalendarItem: View { VStack(alignment: .leading, spacing: 4) { dayView -// calendarItem(geometry: geometry) + if diaryScheduleType != .noSchedule { + calendarItem + } } .padding(.top, 4) .padding(.leading, 5) @@ -46,4 +48,23 @@ struct ArchiveCalendarItem: View { } } + private var calendarItem: some View { + VStack { + if focusDate == nil { + if diaryScheduleType == .meetingSchedule { + Image(asset: SharedDesignSystemAsset.Assets.icArchiveMongOrange) + } else if diaryScheduleType == .personalOrBirthdaySchedule { + Image(asset: SharedDesignSystemAsset.Assets.icArchiveMongGray) + } + } else { + if diaryScheduleType == .meetingSchedule { + Image(asset: SharedDesignSystemAsset.Assets.icArchiveLeafOrange) + } else if diaryScheduleType == .personalOrBirthdaySchedule { + Image(asset: SharedDesignSystemAsset.Assets.icArchiveLeafGray) + } + } + + } + } + } diff --git a/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift index f77d4e35..e7a0ebed 100644 --- a/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift +++ b/Namo_SwiftUI/Projects/Feature/Calendar/Sources/Archive/NamoArchiveCalendarView.swift @@ -13,11 +13,12 @@ import SharedUtil import SharedDesignSystem import DomainDiary - public struct NamoArchiveCalendarView: View { @ObservedObject var calendarController: CalendarController // 현재 포커싱된(detailView) 날짜 @Binding var focusDate: YearMonthDay? + // 스케쥴 타입 + @Binding var diaryScheduleTypes: [YearMonthDay: DiaryScheduleType] // 캘린더에 표시할 스케쥴 @Binding var schedules: [YearMonthDay: [DiarySchedule]] // 상단에 요일을 보이게 할지 @@ -32,6 +33,7 @@ public struct NamoArchiveCalendarView: View { public init( calendarController: CalendarController, focusDate: Binding = .constant(nil), + diaryScheduleTypes: Binding<[YearMonthDay: DiaryScheduleType]> = .constant([:]), schedules: Binding<[YearMonthDay: [DiarySchedule]]> = .constant([:]), showWeekDay: Bool = true, showDetailView: Bool = true, @@ -39,6 +41,7 @@ public struct NamoArchiveCalendarView: View { ) { self.calendarController = calendarController self._focusDate = focusDate + self._diaryScheduleTypes = diaryScheduleTypes self._schedules = schedules self.showWeekDay = showWeekDay self.showDetailView = showDetailView @@ -60,7 +63,7 @@ public struct NamoArchiveCalendarView: View { ArchiveCalendarItem( focusDate: $focusDate, date: date, - schedules: schedules[date] ?? [] + diaryScheduleType: diaryScheduleTypes[date] ?? .noSchedule ) .onTapGesture { dateTapAction(date) diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/Contents.json b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/Contents.json new file mode 100644 index 00000000..43975388 --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "ic_archive_leaf_gray.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/ic_archive_leaf_gray.svg b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/ic_archive_leaf_gray.svg new file mode 100644 index 00000000..08d3436d --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_gray.imageset/ic_archive_leaf_gray.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/Contents.json b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/Contents.json new file mode 100644 index 00000000..93d19c6f --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "ic_archive_leaf_orange.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/ic_archive_leaf_orange.svg b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/ic_archive_leaf_orange.svg new file mode 100644 index 00000000..d6c45c6c --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_leaf_orange.imageset/ic_archive_leaf_orange.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/Contents.json b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/Contents.json new file mode 100644 index 00000000..440da7d5 --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "ic_archive_mong_gray.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/ic_archive_mong_gray.svg b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/ic_archive_mong_gray.svg new file mode 100644 index 00000000..e8dedb73 --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_gray.imageset/ic_archive_mong_gray.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/Contents.json b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/Contents.json new file mode 100644 index 00000000..c0562878 --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "ic_archive_mong_orange.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/ic_archive_mong_orange.svg b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/ic_archive_mong_orange.svg new file mode 100644 index 00000000..31d22d39 --- /dev/null +++ b/Namo_SwiftUI/Projects/Shared/DesignSystem/Resources/Assets.xcassets/NewIcon/ic_archive_mong_orange.imageset/ic_archive_mong_orange.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + +