From 73e453e72775bb407cf212f71999636bc8db730c Mon Sep 17 00:00:00 2001 From: JaeSunEo Date: Wed, 21 Jan 2026 17:31:57 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat/=20#129=20=EA=B2=BD=EA=B3=A0=EB=AC=B8?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/Network/EndPoint/HomeAPI.swift | 2 +- .../Model/TreatmentInputWarning.swift | 28 ++++++++++++++ .../View/NoTreatment/NoTreatmentView.swift | 3 +- .../View/TargetDdaySettingView.swift | 5 ++- .../View/Treatment/TreatmentView.swift | 3 +- .../View/TreatmentWarningMessgeView.swift | 20 ++++++++++ .../NoTreatment/NoTreatmentViewModel.swift | 18 ++++++--- .../Treatment/TreatmentViewModel.swift | 38 ++++++++++++++++--- 8 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/Model/TreatmentInputWarning.swift create mode 100644 Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TreatmentWarningMessgeView.swift diff --git a/Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/HomeAPI.swift b/Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/HomeAPI.swift index 80ff67d1..3f554c7b 100644 --- a/Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/HomeAPI.swift +++ b/Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/HomeAPI.swift @@ -47,7 +47,7 @@ extension HomeAPI: EndPoint { } } - var queryParameters: [String: String]? { + var queryParameters: [String: Any]? { switch self { case .fetchDashboard: return nil diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/Model/TreatmentInputWarning.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/Model/TreatmentInputWarning.swift new file mode 100644 index 00000000..2d7879a3 --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/Model/TreatmentInputWarning.swift @@ -0,0 +1,28 @@ +// +// TreatmentInputWarning.swift +// Cherrish-iOS +// +// Created by 어재선 on 1/21/26. +// + +import Foundation + +enum TreatmentInputWarning { + case none + case pastDate + case invalidFormat + case beforeProcedureDate + + var message: String { + switch self { + case .none: + return "" + case .pastDate: + return "이미 지난 날짜는 입력할 수 없어요." + case .invalidFormat: + return "올바른 날짜 형식이 아니에요." + case .beforeProcedureDate: + return "목표일은 시술 날짜 이후로만 설정할 수 있어요." + } + } +} diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/NoTreatment/NoTreatmentView.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/NoTreatment/NoTreatmentView.swift index cf35b030..9023c7e0 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/NoTreatment/NoTreatmentView.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/NoTreatment/NoTreatmentView.swift @@ -70,7 +70,8 @@ struct NoTreatmentView: View { dDayState: $viewModel.dDay, year: $viewModel.year, month: $viewModel.month, - day: $viewModel.day + day: $viewModel.day, + warningMessage: .constant(viewModel.warning.message) ) .padding(.horizontal, 34.adjustedW) .id(String(describing: viewModel.state)) diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TargetDdaySettingView.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TargetDdaySettingView.swift index 17af9bc4..1d4f0871 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TargetDdaySettingView.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TargetDdaySettingView.swift @@ -28,7 +28,7 @@ struct TargetDdaySettingView: View { @Binding var year: String @Binding var month: String @Binding var day: String - + @Binding var warningMessage: String var body: some View { ScrollView(.vertical, showsIndicators: false) { VStack { @@ -92,7 +92,8 @@ struct TargetDdaySettingView: View { .frame(height: 24.adjustedH) DateTextBox(year: $year, month: $month, day: $day) - .padding(.bottom, 20.adjustedH) + .padding(.bottom, 12.adjustedH) + TreatmentWarningMessgeView(text: warningMessage) Spacer() } } diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/Treatment/TreatmentView.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/Treatment/TreatmentView.swift index 5781e5c5..7519248c 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/Treatment/TreatmentView.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/Treatment/TreatmentView.swift @@ -65,7 +65,8 @@ struct TreatmentView: View { dDayState: $viewModel.dDay, year: $viewModel.year, month: $viewModel.month, - day: $viewModel.day + day: $viewModel.day, + warningMessage: .constant(viewModel.warning.message) ) diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TreatmentWarningMessgeView.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TreatmentWarningMessgeView.swift new file mode 100644 index 00000000..0e160841 --- /dev/null +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/TreatmentWarningMessgeView.swift @@ -0,0 +1,20 @@ +// +// TreatmentWarningMessgeView.swift +// Cherrish-iOS +// +// Created by 어재선 on 1/21/26. +// + +import SwiftUI + +struct TreatmentWarningMessgeView: View { + let text: String + var body: some View { + HStack(spacing: 0) { + TypographyText(text, style: .body1_r_14, color: .red700) + .frame(height: 20.adjustedH) + Spacer() + } + + } +} diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift index 0413318e..ffb1fbfc 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift @@ -17,6 +17,7 @@ final class NoTreatmentViewModel: ObservableObject{ @Published var year: String = "" @Published var month: String = "" @Published var day: String = "" + @Published private(set) var warning: TreatmentInputWarning = .none private let fetchCategoriesUseCase: FetchTreatmentCategoriesUseCase private let fetchTreatmentsUseCase: FetchTreatmentsUseCase @@ -90,20 +91,27 @@ final class NoTreatmentViewModel: ObservableObject{ return false } - guard let yearInt = Int(year), yearInt >= 2020, - let monthInt = Int(month), (1...12).contains(monthInt), - let dayInt = Int(day), (1...31).contains(dayInt) else { + guard let y = Int(year), let m = Int(month), let d = Int(day) else { + warning = .invalidFormat return false } - - let components = DateComponents(year: yearInt, month: monthInt, day: dayInt) + + let components = DateComponents(year: y, month: m, day: d) guard let date = Calendar.current.date(from: components), Calendar.current.dateComponents([.year, .month, .day], from: date) == components else { + warning = .invalidFormat + return false + } + + let today = Calendar.current.startOfDay(for: Date()) + if date < today { + warning = .pastDate return false } return true + } } diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift index 05288c9f..2bfa1177 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift @@ -17,6 +17,7 @@ final class TreatmentViewModel: ObservableObject{ @Published var month: String = "" @Published var day: String = "" @Published var searchText = "" + @Published private(set) var warning: TreatmentInputWarning = .none private let fetchTreatmentsUseCase: FetchTreatmentsUseCase @@ -48,6 +49,8 @@ final class TreatmentViewModel: ObservableObject{ } } + + @MainActor func fetchTreatments() async throws { do { @@ -71,16 +74,41 @@ final class TreatmentViewModel: ObservableObject{ func isDateTextFieldNotEmpty() -> Bool { guard !year.isEmpty, !month.isEmpty, !day.isEmpty else { + Task { @MainActor in + warning = .none + } return false } - guard let yearInt = Int(year), yearInt >= 2020, - let monthInt = Int(month), monthInt >= 1, monthInt <= 12, - let dayInt = Int(day), dayInt >= 1, dayInt <= 31 else { + + guard let y = Int(year), let m = Int(month), let d = Int(day) else { + Task { @MainActor in + warning = .invalidFormat + } return false } - - return true + + let components = DateComponents(year: y, month: m, day: d) + guard let date = Calendar.current.date(from: components), + Calendar.current.dateComponents([.year, .month, .day], from: date) == components else { + Task { @MainActor in + warning = .invalidFormat + } + return false + } + + let today = Calendar.current.startOfDay(for: Date()) + if date < today { + Task { @MainActor in + warning = .pastDate + } + return false + } + + Task { @MainActor in + warning = .none + } + return true } } From 96a3e74f6f23483b871b21bdc74e6d366b46b50f Mon Sep 17 00:00:00 2001 From: JaeSunEo Date: Wed, 21 Jan 2026 17:37:10 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20#129=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NoTreatment/NoTreatmentViewModel.swift | 18 ++++++++++---- .../Treatment/TreatmentViewModel.swift | 24 +++++++++---------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift index ffb1fbfc..b71608fb 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/NoTreatment/NoTreatmentViewModel.swift @@ -88,11 +88,14 @@ final class NoTreatmentViewModel: ObservableObject{ func isDateTextFieldNotEmpty() -> Bool { guard !year.isEmpty, !month.isEmpty, !day.isEmpty else { + Task { @MainActor in + updateWarning(state: .none) + } return false } guard let y = Int(year), let m = Int(month), let d = Int(day) else { - warning = .invalidFormat + updateWarning(state: .invalidFormat) return false } @@ -100,18 +103,25 @@ final class NoTreatmentViewModel: ObservableObject{ guard let date = Calendar.current.date(from: components), Calendar.current.dateComponents([.year, .month, .day], from: date) == components else { - warning = .invalidFormat + updateWarning(state: .invalidFormat) return false } let today = Calendar.current.startOfDay(for: Date()) if date < today { - warning = .pastDate + updateWarning(state: .pastDate) return false } + updateWarning(state: .none) return true - + } + + + private func updateWarning(state: TreatmentInputWarning) { + Task { @MainActor in + warning = state + } } } diff --git a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift index 2bfa1177..e40d5e93 100644 --- a/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift +++ b/Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/ViewModel/Treatment/TreatmentViewModel.swift @@ -75,15 +75,13 @@ final class TreatmentViewModel: ObservableObject{ func isDateTextFieldNotEmpty() -> Bool { guard !year.isEmpty, !month.isEmpty, !day.isEmpty else { Task { @MainActor in - warning = .none + updateWarning(state: .none) } return false } guard let y = Int(year), let m = Int(month), let d = Int(day) else { - Task { @MainActor in - warning = .invalidFormat - } + updateWarning(state: .invalidFormat) return false } @@ -91,25 +89,27 @@ final class TreatmentViewModel: ObservableObject{ guard let date = Calendar.current.date(from: components), Calendar.current.dateComponents([.year, .month, .day], from: date) == components else { - Task { @MainActor in - warning = .invalidFormat - } + updateWarning(state: .invalidFormat) return false } let today = Calendar.current.startOfDay(for: Date()) if date < today { - Task { @MainActor in - warning = .pastDate - } + updateWarning(state: .pastDate) return false } + updateWarning(state: .none) + return true + } + + + private func updateWarning(state: TreatmentInputWarning) { Task { @MainActor in - warning = .none + warning = state } - return true } + }