diff --git a/Projects/App/Sources/Application/DI/Remains/AppComponent+Remains.swift b/Projects/App/Sources/Application/DI/Remains/AppComponent+Remains.swift index d77b72cf..f7881e34 100644 --- a/Projects/App/Sources/Application/DI/Remains/AppComponent+Remains.swift +++ b/Projects/App/Sources/Application/DI/Remains/AppComponent+Remains.swift @@ -18,25 +18,25 @@ public extension AppComponent { var remainingApplicationsChangesUseCase: any RemainingApplicationsChangesUseCase { shared { - RemainingApplicationsChangesUseCaselmpl(remainsRepository: remainsRepository) + RemainingApplicationsChangesUseCaseImpl(remainsRepository: remainsRepository) } } var fetchMyRemainApplicationItemsUseCase: any FetchMyRemainApplicationItemsUseCase { shared { - FetchMyRemainApplicationItemsUseCaselmpl(remainsRepository: remainsRepository) + FetchMyRemainApplicationItemsUseCaseImpl(remainsRepository: remainsRepository) } } var fetchRemainApplicationListUseCase: any FetchRemainApplicationListUseCase { shared { - FetchRemainAppListUseCaselmpl(remainsRepository: remainsRepository) + FetchRemainAppListUseCaseImpl(remainsRepository: remainsRepository) } } var fetchRemainsAvailableTimeUseCase: any FetchRemainsAvailableTimeUseCase { shared { - FetchRemainsAvailableTimeUseCaselmpl(remainsRepository: remainsRepository) + FetchRemainsAvailableTimeUseCaseImpl(remainsRepository: remainsRepository) } } } diff --git a/Projects/App/Sources/Application/DI/StudyRooms/AppComponent+StudyRooms.swift b/Projects/App/Sources/Application/DI/StudyRooms/AppComponent+StudyRooms.swift index 8799561e..b40487a4 100644 --- a/Projects/App/Sources/Application/DI/StudyRooms/AppComponent+StudyRooms.swift +++ b/Projects/App/Sources/Application/DI/StudyRooms/AppComponent+StudyRooms.swift @@ -35,4 +35,8 @@ public extension AppComponent { var cancelStudyRoomSeatUseCase: any CancelStudyRoomSeatUseCase { CancelStudyRoomSeatUseCaseImpl(studyRoomsRepository: studyRoomsRepository) } + + var fehtchMyStudyRoomAppItemsUseCase: any FetchMyStudyRoomAppItemsUseCase { + FetchMyStudyRoomAppItemsUseCaseImpl(studyRoomsRepository: studyRoomsRepository) + } } diff --git a/Projects/App/Sources/Application/NeedleGenerated.swift b/Projects/App/Sources/Application/NeedleGenerated.swift index b034507e..3c7a4d47 100644 --- a/Projects/App/Sources/Application/NeedleGenerated.swift +++ b/Projects/App/Sources/Application/NeedleGenerated.swift @@ -534,6 +534,7 @@ extension AppComponent: Registration { localTable["fetchDetailStudyRoomUseCase-any FetchDetailStudyRoomUseCase"] = { [unowned self] in self.fetchDetailStudyRoomUseCase as Any } localTable["applyStudyRoomSeatUseCase-any ApplyStudyRoomSeatUseCase"] = { [unowned self] in self.applyStudyRoomSeatUseCase as Any } localTable["cancelStudyRoomSeatUseCase-any CancelStudyRoomSeatUseCase"] = { [unowned self] in self.cancelStudyRoomSeatUseCase as Any } + localTable["fehtchMyStudyRoomAppItemsUseCase-any FetchMyStudyRoomAppItemsUseCase"] = { [unowned self] in self.fehtchMyStudyRoomAppItemsUseCase as Any } localTable["localAuthDataSource-any LocalAuthDataSource"] = { [unowned self] in self.localAuthDataSource as Any } localTable["remoteAuthDataSource-any RemoteAuthDataSource"] = { [unowned self] in self.remoteAuthDataSource as Any } localTable["authRepository-any AuthRepository"] = { [unowned self] in self.authRepository as Any } diff --git a/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageView.swift b/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageView.swift index 81c291ef..193697cc 100644 --- a/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageView.swift +++ b/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageView.swift @@ -3,8 +3,6 @@ import RemainApplyFeature import SwiftUI struct ApplyPageView: View { - @AppStorage("StudyRoomState") var studyRoomState: String? - @AppStorage("RemainState") var remainState: String? @StateObject var viewModel: ApplyPageViewModel @Environment(\.tabbarHidden) var tabbarHidden @@ -32,25 +30,25 @@ struct ApplyPageView: View { Spacer() .frame(height: 5) - applyListCellView( + ApplyListCellView( name: "자습실", content: """ 자습실 사용이 필요한 경우, 자습실 신청을 통해서 원하는 자리를 신청해 보세요. """, buttonTitle: "자습실 신청하기", - applyState: studyRoomState, + applyState: viewModel.studyRoomState, onTapped: { viewModel.isNavigateToStudy.toggle() } ) - applyListCellView( + ApplyListCellView( name: "잔류", content: """ 주말 기숙사 잔류 여부를 확인하고, 잔류 신청을 통해서 잔류 또는 귀가를 신청해 보세요. """, buttonTitle: "잔류 신청하기", - applyState: remainState, + applyState: viewModel.remainState, onTapped: { viewModel.isNavigateToRemain.toggle() } @@ -62,6 +60,10 @@ struct ApplyPageView: View { .navigationTitle("신청") .navigationBarTitleDisplayMode(.inline) .dmsBackground() + .onAppear { +// viewModel.fehtchMyStudyRoomApplicationItems() +// viewModel.fetchMyRemainApplicationItems() + } .onChange(of: viewModel.isNavigateToStudy) { newValue in withAnimation { tabbarHidden.wrappedValue = newValue @@ -83,21 +85,4 @@ struct ApplyPageView: View { .navigationViewStyle(.stack) } } - - @ViewBuilder - func applyListCellView( - name: String, - content: String, - buttonTitle: String, - applyState: String?, - onTapped: @escaping () -> Void - ) -> some View { - ApplyListCellView( - name: name, - content: content, - buttonTitle: buttonTitle, - applyState: applyState, - onTapped: onTapped - ) - } } diff --git a/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageViewModel.swift b/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageViewModel.swift index 5bb8fbb2..4ba224c4 100644 --- a/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageViewModel.swift +++ b/Projects/Features/ApplyFeature/Sources/ApplyPage/ApplyPageViewModel.swift @@ -1,7 +1,56 @@ import BaseFeature +import DomainModule +import DataMappingModule import Combine +import SwiftUI final class ApplyPageViewModel: BaseViewModel { @Published var isNavigateToStudy: Bool = false @Published var isNavigateToRemain: Bool = false + + @Published var myRemainApplicationItem: MyRemainApplicationItemsEntity? + @Published var myStudyRoomApplicationItems: MyStudyRoomAppItemsEntity? + +// private let fetchMyRemainApplicationItemsUseCase: any FetchMyRemainApplicationItemsUseCase +// private let fehtchMyStudyRoomAppItemsUserCase: any FetchMyStudyRoomAppItemsUserCase + + var remainState: String? { + if let item = myRemainApplicationItem { + return item.title + } else { + return nil + } + } + + var studyRoomState: String? { + if let item = myStudyRoomApplicationItems { + return item.floor + "층 " + item.name + } else { + return nil + } + } +// +// public init( +// fetchMyRemainApplicationItemsUseCase: any FetchMyRemainApplicationItemsUseCase, +// fehtchMyStudyRoomAppItemsUserCase: any FetchMyStudyRoomAppItemsUserCase +// ) { +// self.fetchMyRemainApplicationItemsUseCase = fetchMyRemainApplicationItemsUseCase +// self.fehtchMyStudyRoomAppItemsUserCase = fehtchMyStudyRoomAppItemsUserCase +// } + +// func fetchMyRemainApplicationItems() { +// addCancellable( +// fetchMyRemainApplicationItemsUseCase.execute() +// ) { [weak self] myRemainApplicationItem in +// self?.myRemainApplicationItem = myRemainApplicationItem +// } +// } +// +// func fehtchMyStudyRoomApplicationItems() { +// addCancellable( +// fehtchMyStudyRoomAppItemsUserCase.execute() +// ) { [weak self] myStudyRoomApplicationItems in +// self?.myStudyRoomApplicationItems = myStudyRoomApplicationItems +// } +// } } diff --git a/Projects/Features/ApplyFeature/Sources/ApplyPage/Component/ApplyListCellView.swift b/Projects/Features/ApplyFeature/Sources/ApplyPage/Component/ApplyListCellView.swift index 1ddc6420..ded968fd 100644 --- a/Projects/Features/ApplyFeature/Sources/ApplyPage/Component/ApplyListCellView.swift +++ b/Projects/Features/ApplyFeature/Sources/ApplyPage/Component/ApplyListCellView.swift @@ -4,8 +4,6 @@ import RemainApplyFeature import DesignSystem struct ApplyListCellView: View { - @AppStorage("StudyRoomState") var studyRoomState: String? - @AppStorage("RemainState") var remainState: String? var name: String var content: String var buttonTitle: String @@ -37,15 +35,17 @@ struct ApplyListCellView: View { Spacer() - Text(applyState ?? "") - .dmsFont(.etc(.button), color: .PrimaryVariant.primary) - .frame(height: 22) - .padding(.vertical, 6) - .padding(.horizontal, 14) - .background(Color.PrimaryVariant.lighten2) - .cornerRadius(24) - .padding(.trailing, 16) - .padding(.top, -2) + if let applyState { + Text(applyState) + .dmsFont(.etc(.button), color: .PrimaryVariant.primary) + .frame(height: 22) + .padding(.vertical, 6) + .padding(.horizontal, 14) + .background(Color.PrimaryVariant.lighten2) + .cornerRadius(24) + .padding(.trailing, 16) + .padding(.top, -2) + } } Text(content) diff --git a/Projects/Features/RemainApplyFeature/Sources/Component/RemainApplyListCellView.swift b/Projects/Features/RemainApplyFeature/Sources/Component/RemainApplyListCellView.swift index 2f510032..da9775d2 100644 --- a/Projects/Features/RemainApplyFeature/Sources/Component/RemainApplyListCellView.swift +++ b/Projects/Features/RemainApplyFeature/Sources/Component/RemainApplyListCellView.swift @@ -1,78 +1,38 @@ -import DesignSystem -import DomainModule import SwiftUI +import DomainModule +import DesignSystem struct RemainApplyListCellView: View { - @StateObject var viewModel: RemainApplyViewModel - - let dummy1 = RemainOptionEntity( - id: "0", - title: "금요 귀가", - description: """ - 금요일 일과가 모두 끝나고 - 8시 30분 이후부터9시 30분까지 귀가하고 - 일요일 6시 30분 부터 9시 30분까지 귀사해야 합니다. - - 혹시나 개인 일정으로 부득이하기 금요일이 아닌, 토요일 - 또는 일요일에 귀가해야 하는 학생들은 사감 선생님께 - 말씀부탁드립니다. - """ - ) - let dummy2 = RemainOptionEntity( - id: "1", - title: "토요 귀가", - description: """ - 금요일 일과가 모두 끝나고 - 8시 30분 이후부터9시 30분까지 귀가하고 - 일요일 6시 30분 부터 9시 30분까지 귀사해야 합니다. - - 혹시나 개인 일정으로 부득이하기 금요일이 아닌, 토요일 - 또는 일요일에 귀가해야 하는 학생들은 사감 선생님께 - 말씀부탁드립니다. - """ - ) - let dummy3 = RemainOptionEntity( - id: "2", - title: "잔류", - description: """ - 금요일 일과가 모두 끝나고 - 8시 30분 이후부터9시 30분까지 귀가하고 - 일요일 6시 30분 부터 9시 30분까지 귀사해야 합니다. - - 혹시나 개인 일정으로 부득이하기 금요일이 아닌, 토요일 - 또는 일요일에 귀가해야 하는 학생들은 사감 선생님께 - 말씀부탁드립니다. - """ - ) - - var body: some View { - VStack(spacing: 12) { - remainApplyListCellView(list: dummy1, applyType: .friday) - - remainApplyListCellView(list: dummy2, applyType: .saturday) - - remainApplyListCellView(list: dummy3, applyType: .stay) - } + @State private var isShowingDetail = false + var list: RemainOptionEntity + let isSelected: Bool + let action: () -> Void + public init( + list: RemainOptionEntity, + isSelected: Bool, + action: @escaping () -> Void + ) { + self.list = list + self.isSelected = isSelected + self.action = action } - - @ViewBuilder - // swiftlint:disable function_body_length - func remainApplyListCellView(list: RemainOptionEntity, applyType: ApplyType) -> some View { - VStack { + var body: some View { + VStack(alignment: .leading) { HStack(alignment: .center) { Button(action: { - viewModel.selectedType = list.title - viewModel.selectedNum = Int(list.id) ?? 10 + if !isSelected { + action() + } }, label: { HStack { Text(list.title) - .dmsFont(.title(.title2), color: viewModel.selectedNum == applyType.rawValue + .dmsFont(.title(.title2), color: isSelected ? .System.primary : .GrayScale.gray7) .frame(height: 32) .padding(.vertical, 14) .padding(.horizontal, 20) - if viewModel.isAlreadyApplied == true && viewModel.appliedNum == applyType.rawValue { + if list.isApplied { Text("신청 완료") .dmsFont(.etc(.button), color: .PrimaryVariant.primary) .frame(height: 22) @@ -85,19 +45,23 @@ struct RemainApplyListCellView: View { Spacer() - Image(systemName: viewModel.isDetailTapped == true && viewModel.selectedNum == applyType.rawValue - ? "chevron.up" : "chevron.down") - .foregroundColor(viewModel.selectedNum == applyType.rawValue + Image(systemName: "chevron.down") + .foregroundColor(isSelected ? .System.primary : .GrayScale.gray7) - .padding(.trailing, 25) + .rotationEffect( + isShowingDetail + ? Angle.degrees(180) + : .degrees(0) + ) + .padding(25) .onTapGesture { - viewModel.selectedNum = applyType.rawValue - viewModel.selectedType = list.title - viewModel.isDetailTapped.toggle() + withAnimation { + isShowingDetail.toggle() + } } }) } - if viewModel.isDetailTapped == true && viewModel.selectedNum == applyType.rawValue { + if isShowingDetail { Text(list.description) .multilineTextAlignment(.leading) .dmsFont(.body(.body3), color: .GrayScale.gray9) @@ -109,17 +73,11 @@ struct RemainApplyListCellView: View { .overlay( RoundedRectangle(cornerRadius: 10) .inset(by: 1) - .stroke(viewModel.selectedNum == applyType.rawValue ? - Color.System.primary : .clear, lineWidth: 1.5) + .stroke(isSelected ? + Color.System.primary : .clear, + lineWidth: 1.5) ) .padding(.bottom, 12) .dmsShadow(style: .surface) } - // swiftlint:enable function_body_length -} - -enum ApplyType: Int { - case friday = 0 - case saturday - case stay } diff --git a/Projects/Features/RemainApplyFeature/Sources/Component/RemainApplyListView.swift b/Projects/Features/RemainApplyFeature/Sources/Component/RemainApplyListView.swift new file mode 100644 index 00000000..baedb2c6 --- /dev/null +++ b/Projects/Features/RemainApplyFeature/Sources/Component/RemainApplyListView.swift @@ -0,0 +1,24 @@ +import DesignSystem +import DomainModule +import SwiftUI + +struct RemainApplyListView: View { + @StateObject var viewModel: RemainApplyViewModel + + var body: some View { + LazyVStack(spacing: 12) { + ForEach(viewModel.remainApplicationList.remainOptions, id: \.self) { remainApplication in + RemainApplyListCellView( + list: remainApplication, + isSelected: remainApplication.id == viewModel.selectedEntity?.id, + action: { + viewModel.selectedEntity = remainApplication + } + ) + } + } + .onAppear { + viewModel.fetchRemainApplicationList() + } + } +} diff --git a/Projects/Features/RemainApplyFeature/Sources/RemainApplyView.swift b/Projects/Features/RemainApplyFeature/Sources/RemainApplyView.swift index 14c27428..c3d1a636 100644 --- a/Projects/Features/RemainApplyFeature/Sources/RemainApplyView.swift +++ b/Projects/Features/RemainApplyFeature/Sources/RemainApplyView.swift @@ -1,8 +1,8 @@ import DesignSystem +import DomainModule import SwiftUI struct RemainApplyView: View { - @AppStorage("RemainState") var remainState: String? @StateObject var viewModel: RemainApplyViewModel @Environment(\.dismiss) var dismiss @@ -18,50 +18,39 @@ struct RemainApplyView: View { .frame(height: 1) ScrollView(showsIndicators: false) { - if viewModel.isApplicationTime { - RemainApplyNoticeView(notice: viewModel.rangeString) - } - RemainApplyListCellView(viewModel: viewModel) + RemainApplyNoticeView(notice: viewModel.rangeString) + RemainApplyListView(viewModel: viewModel) .padding(.horizontal, 24) } DMSWideButton( - text: { - if viewModel.isAlreadyApplied && (viewModel.selectedType == viewModel.appliedState) { - return "신청 완료" - } else if viewModel.isAlreadyApplied && (viewModel.selectedType != viewModel.appliedState) { - return viewModel.selectedType + "로 변경하기" - } else { - return viewModel.selectedType + " 신청하기" - } - }(), + text: viewModel.buttonTitle, style: .contained, - color: { - if viewModel.isAlreadyApplied && (viewModel.selectedType == viewModel.appliedState) { - return .System.primary.opacity(0.5) - } else if viewModel.selectedType.isEmpty { - return .clear - } else { - return .System.primary - } - }(), + color: .PrimaryVariant.primary, action: { - viewModel.appliedState = viewModel.selectedType - viewModel.isAlreadyApplied = (viewModel.isErrorOcuured ? false : true) - viewModel.appliedNum = viewModel.selectedNum - remainState = viewModel.appliedState + viewModel.changeRemainApply() }) + .disabled(viewModel.selectedEntity?.title == viewModel.myRemainsApplicationItems?.title) .padding(.bottom, 71) .padding(.horizontal, 24) + .opacity(viewModel.selectedEntity == nil ? 0 : 1) } .navigationTitle("잔류 신청") .navigationBarTitleDisplayMode(.inline) .dmsBackground() .dmsBackButton(dismiss: dismiss) .dmsToast( - isShowing: $viewModel.isErrorOcuured, + isShowing: $viewModel.isShowingToast, message: viewModel.toastMessage, style: .error ) + .dmsToast( + isShowing: $viewModel.isShowingToast, + message: viewModel.toastMessage, + style: .success + ) + .onAppear { + viewModel.onAppear() + } } } diff --git a/Projects/Features/RemainApplyFeature/Sources/RemainApplyViewModel.swift b/Projects/Features/RemainApplyFeature/Sources/RemainApplyViewModel.swift index ae6297e8..09a1d812 100644 --- a/Projects/Features/RemainApplyFeature/Sources/RemainApplyViewModel.swift +++ b/Projects/Features/RemainApplyFeature/Sources/RemainApplyViewModel.swift @@ -5,23 +5,38 @@ import Combine import SwiftUI final class RemainApplyViewModel: BaseViewModel { - @Published var selectedNum: Int = 10 - @Published var selectedType: String = "" - @AppStorage("isApplied") var isAlreadyApplied: Bool = false - @Published var appliedState: String = "" - @AppStorage("appliedNum") var appliedNum: Int = 10 - @Published var isDetailTapped: Bool = false - - @Published var isApplicationTime = true + @Published var isShowingToast = false - @Published var toastMessage = "잔류 신청 시간이 아닙니다." + @Published var toastMessage = "" + + @Published var remainsAvailableTime: RemainsAvailableTimeEntity? + @Published var remainApplicationList = RemainApplicationListEntity(remainOptions: []) + @Published var myRemainsApplicationItems: MyRemainApplicationItemsEntity? + @Published var selectedEntity: RemainOptionEntity? - var startTime = "화 18:00" - var endTime = "목 18:00" var rangeString: String { - let text = "잔류 신청 시간은 " + startTime + - " ~ " + endTime + " 까지 입니다." - return text + if let time = remainsAvailableTime { + let startString = "\(time.startDayOfWeek.displayString()) \(time.startTime.toSmallDMSTimeString())" + let endString = "\(time.endDayOfWeek.displayString()) \(time.endTime.toSmallDMSTimeString())" + let text = "잔류 신청 시간은 \(startString) ~ \(endString) 까지 입니다." + return text + } else { + return "" + } + } + + var buttonTitle: String { + if let selectedEntity { + if selectedEntity.title == myRemainsApplicationItems?.title { + return "신청 완료" + } else if myRemainsApplicationItems == nil { + return selectedEntity.title + " 신청하기" + } else { + return selectedEntity.title + "로 변경하기" + } + } else { + return "" + } } private let fetchMyRemainApplicationItemsUseCase: any FetchMyRemainApplicationItemsUseCase @@ -41,6 +56,63 @@ final class RemainApplyViewModel: BaseViewModel { self.remainingApplicationsChangesUseCase = remainingApplicationsChangesUseCase } + private func fetchRemainsAvailableTime() { + addCancellable( + fetchRemainsAvailableTimeUseCase.execute() + ) { [weak self] remainsAvailableTime in + self?.remainsAvailableTime = remainsAvailableTime + } + } + + func fetchRemainApplicationList() { + addCancellable( + fetchRemainApplicationListUseCase.execute() + ) { [weak self] remainApplicationList in + self?.remainApplicationList = remainApplicationList + } + } + + func changeRemainApply() { + if let selectedEntity { + remainingApplicationsChanges( + entity: selectedEntity + ) + } + } + + private func remainingApplicationsChanges(entity: RemainOptionEntity) { + addCancellable( + remainingApplicationsChangesUseCase.execute(id: entity.id) + ) { [weak self] _ in + let remainOptions = self?.remainApplicationList.remainOptions + .map { + return RemainOptionEntity( + id: $0.id, + title: $0.title, + description: $0.description, + isApplied: entity.id == $0.id + ) + } + self?.remainApplicationList = RemainApplicationListEntity(remainOptions: remainOptions ?? []) + self?.myRemainsApplicationItems?.title = entity.title + self?.toastMessage = "잔류 신청이 완료되었습니다." + self?.isShowingToast = true + } onReceiveError: { [weak self] _ in + self?.isShowingToast = true + self?.toastMessage = "잔류 신청 시간이 아닙니다." + } + } + + private func fetchMyRemainApplicationItems() { + addCancellable( + fetchMyRemainApplicationItemsUseCase.execute() + ) { [weak self] myRemainsApplicationItems in + self?.myRemainsApplicationItems = myRemainsApplicationItems + } + } + func onAppear() { + fetchRemainsAvailableTime() + fetchMyRemainApplicationItems() } } diff --git a/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailView.swift b/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailView.swift index 468a1d99..4899764c 100644 --- a/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailView.swift +++ b/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailView.swift @@ -4,7 +4,6 @@ import DomainModule import SwiftUI struct StudyRoomDetailView: View { - @AppStorage("StudyRoomState") var studyRoomState: String? @StateObject var viewModel: StudyRoomDetailViewModel @Environment(\.dismiss) var dismiss @Environment(\.tabbarHidden) var tabbarHidden @@ -43,6 +42,7 @@ struct StudyRoomDetailView: View { .navigationBarTitleDisplayMode(.inline) .dmsBackground() .dmsToast(isShowing: $viewModel.isErrorOcuured, message: viewModel.errorMessage, style: .error) + .dmsToast(isShowing: $viewModel.isShowingToast, message: viewModel.toastMessage, style: .success) .onAppear { viewModel.onAppear() } diff --git a/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailViewModel.swift b/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailViewModel.swift index 73cb9a87..da5af48b 100644 --- a/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailViewModel.swift +++ b/Projects/Features/StudyRoomFeature/Sources/StudyRoomDetail/StudyRoomDetailViewModel.swift @@ -13,7 +13,6 @@ final class StudyRoomDetailViewModel: BaseViewModel { @Published var isShowingToast = false @Published var toastMessage = "" @Published var selectedSeat: SeatEntity? - @AppStorage("StudyRoomState") var studyRoomState: String? let studyRoomEntity: StudyRoomEntity @@ -105,7 +104,6 @@ final class StudyRoomDetailViewModel: BaseViewModel { self?.selectedSeat = nil } onReceiveError: { [weak self] error in self?.toastMessage = error.localizedDescription - self?.studyRoomState = nil } } @@ -116,7 +114,6 @@ final class StudyRoomDetailViewModel: BaseViewModel { self?.fetchDetailStudyRoom() self?.isShowingToast = true self?.toastMessage = "자습실 취소가 완료되었습니다." - self?.studyRoomState = nil } onReceiveError: { [weak self] error in self?.toastMessage = error.localizedDescription } diff --git a/Projects/Modules/ErrorModule/Sources/DmsError.swift b/Projects/Modules/ErrorModule/Sources/DmsError.swift index faf71f41..e1f2a9d2 100644 --- a/Projects/Modules/ErrorModule/Sources/DmsError.swift +++ b/Projects/Modules/ErrorModule/Sources/DmsError.swift @@ -140,7 +140,7 @@ extension DmsError: LocalizedError { return "신청 불가능한 시간대입니다" case .unavailableSex: - return "신청 불가능한 성별입니다" + return "신청할 수 없는 학년 혹은 성별입니다" // MARK: - Remains case .forbiddenRemainPeriod: diff --git a/Projects/Services/APIKit/Sources/StudyRoomsAPI.swift b/Projects/Services/APIKit/Sources/StudyRoomsAPI.swift index 5f297335..5ba53ad5 100644 --- a/Projects/Services/APIKit/Sources/StudyRoomsAPI.swift +++ b/Projects/Services/APIKit/Sources/StudyRoomsAPI.swift @@ -7,6 +7,7 @@ public enum StudyRoomsAPI { case fetchSeatTypes case fetchStudyRoomList case fetchDetailStudyRoom(roomID: String) + case fetchMyStudyRoomApplicationItems case applyStudyRoomSeat(seatID: String) case cancelStudyRoomSeat } @@ -35,12 +36,16 @@ extension StudyRoomsAPI: DmsAPI { case .cancelStudyRoomSeat: return "/seats" + + case .fetchMyStudyRoomApplicationItems: + return "/my" } } public var method: Moya.Method { switch self { - case .fetchStudyAvailableTime, .fetchSeatTypes, .fetchStudyRoomList, .fetchDetailStudyRoom: + case .fetchStudyAvailableTime, .fetchSeatTypes, + .fetchStudyRoomList, .fetchDetailStudyRoom, .fetchMyStudyRoomApplicationItems: return .get case .applyStudyRoomSeat: diff --git a/Projects/Services/DataMappingModule/Sources/Enum/WeekType.swift b/Projects/Services/DataMappingModule/Sources/Enum/WeekType.swift index b28a3bad..47e6355e 100644 --- a/Projects/Services/DataMappingModule/Sources/Enum/WeekType.swift +++ b/Projects/Services/DataMappingModule/Sources/Enum/WeekType.swift @@ -8,4 +8,29 @@ public enum WeekType: String, Decodable { case friday = "FRIDAY" case satuday = "SATURDAY" case sunday = "SUNDAY" + + public func displayString() -> String { + switch self { + case .monday: + return "월" + + case .tuesday: + return "화" + + case .wednesday: + return "수" + + case .thursday: + return "목" + + case .friday: + return "금" + + case .satuday: + return "토" + + case .sunday: + return "일" + } + } } diff --git a/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchListRemainApplicationItemsResponseDTO.swift b/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchListRemainApplicationItemsResponseDTO.swift index 0c5833dd..528c37bd 100644 --- a/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchListRemainApplicationItemsResponseDTO.swift +++ b/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchListRemainApplicationItemsResponseDTO.swift @@ -2,18 +2,14 @@ import Foundation public struct FetchRemainAppListResponseDTO: Decodable { public init( - selectedOption: String, remainOptions: [RemainOptionResponseDTO] ) { - self.selectedOption = selectedOption self.remainOptions = remainOptions } - public let selectedOption: String public let remainOptions: [RemainOptionResponseDTO] enum CodingKeys: String, CodingKey { - case selectedOption = "selected_option" case remainOptions = "remain_options" } } diff --git a/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchRemainsAvailableTimeResponseDTO.swift b/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchRemainsAvailableTimeResponseDTO.swift index aaa91494..0b5e4ae9 100644 --- a/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchRemainsAvailableTimeResponseDTO.swift +++ b/Projects/Services/DataMappingModule/Sources/Remains/Response/FetchRemainsAvailableTimeResponseDTO.swift @@ -3,25 +3,25 @@ import Foundation public struct FetchRemainsAvailableTimeResponseDTO: Decodable { public init( startDayOfWeek: WeekType, - startAt: String, + startTime: String, endDayOfWeek: WeekType, - endAt: String + endTime: String ) { self.startDayOfWeek = startDayOfWeek - self.startAt = startAt + self.startTime = startTime self.endDayOfWeek = endDayOfWeek - self.endAt = endAt + self.endTime = endTime } public let startDayOfWeek: WeekType - public let startAt: String + public let startTime: String public let endDayOfWeek: WeekType - public let endAt: String + public let endTime: String enum CodingKeys: String, CodingKey { case startDayOfWeek = "start_day_of_week" - case startAt = "start_at" + case startTime = "start_time" case endDayOfWeek = "end_day_of_week" - case endAt = "end_at" + case endTime = "end_time" } } diff --git a/Projects/Services/DataMappingModule/Sources/Remains/Response/RemainOptionResponseDTO.swift b/Projects/Services/DataMappingModule/Sources/Remains/Response/RemainOptionResponseDTO.swift index e36f4692..2082ab6a 100644 --- a/Projects/Services/DataMappingModule/Sources/Remains/Response/RemainOptionResponseDTO.swift +++ b/Projects/Services/DataMappingModule/Sources/Remains/Response/RemainOptionResponseDTO.swift @@ -4,14 +4,24 @@ public struct RemainOptionResponseDTO: Decodable { public init( id: String, title: String, - description: String + description: String, + isApplied: Bool ) { self.id = id self.title = title self.description = description + self.isApplied = isApplied } public let id: String public let title: String public let description: String + public let isApplied: Bool + + enum CodingKeys: String, CodingKey { + case id + case title + case description + case isApplied = "is_applied" + } } diff --git a/Projects/Services/DataMappingModule/Sources/StudyRooms/Response/MyStudyRoomApplicationItemsDTO.swift b/Projects/Services/DataMappingModule/Sources/StudyRooms/Response/MyStudyRoomApplicationItemsDTO.swift new file mode 100644 index 00000000..de434a2e --- /dev/null +++ b/Projects/Services/DataMappingModule/Sources/StudyRooms/Response/MyStudyRoomApplicationItemsDTO.swift @@ -0,0 +1,11 @@ +import Foundation + +public struct FehtchMyStudyRoomApplicationItemsDTO: Decodable { + public init(floor: String, name: String) { + self.floor = floor + self.name = name + } + + public let floor: String + public let name: String +} diff --git a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchMyRemainApplicationItemsUseCaselmpl.swift b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchMyRemainApplicationItemsUseCaseImpl.swift similarity index 87% rename from Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchMyRemainApplicationItemsUseCaselmpl.swift rename to Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchMyRemainApplicationItemsUseCaseImpl.swift index cd36364a..05007cd7 100644 --- a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchMyRemainApplicationItemsUseCaselmpl.swift +++ b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchMyRemainApplicationItemsUseCaseImpl.swift @@ -3,7 +3,7 @@ import DataMappingModule import DomainModule import ErrorModule -public struct FetchMyRemainApplicationItemsUseCaselmpl: FetchMyRemainApplicationItemsUseCase { +public struct FetchMyRemainApplicationItemsUseCaseImpl: FetchMyRemainApplicationItemsUseCase { private let remainsRepository: any RemainsRepository public init(remainsRepository: any RemainsRepository) { diff --git a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainAppListUseCaselmpl.swift b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainAppListUseCaseImpl.swift similarity index 86% rename from Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainAppListUseCaselmpl.swift rename to Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainAppListUseCaseImpl.swift index 2e4248f8..b64bb5c6 100644 --- a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainAppListUseCaselmpl.swift +++ b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainAppListUseCaseImpl.swift @@ -3,7 +3,7 @@ import DataMappingModule import DomainModule import ErrorModule -public struct FetchRemainAppListUseCaselmpl: FetchRemainApplicationListUseCase { +public struct FetchRemainAppListUseCaseImpl: FetchRemainApplicationListUseCase { private let remainsRepository: any RemainsRepository public init(remainsRepository: any RemainsRepository) { diff --git a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainsAvailableTimeUseCaselmpl.swift b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainsAvailableTimeUseCaseImpl.swift similarity index 86% rename from Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainsAvailableTimeUseCaselmpl.swift rename to Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainsAvailableTimeUseCaseImpl.swift index 01c5e6cb..5b1ba281 100644 --- a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainsAvailableTimeUseCaselmpl.swift +++ b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/FetchRemainsAvailableTimeUseCaseImpl.swift @@ -3,7 +3,7 @@ import DataMappingModule import DomainModule import ErrorModule -public struct FetchRemainsAvailableTimeUseCaselmpl: FetchRemainsAvailableTimeUseCase { +public struct FetchRemainsAvailableTimeUseCaseImpl: FetchRemainsAvailableTimeUseCase { private let remainsRepository: any RemainsRepository public init(remainsRepository: any RemainsRepository) { diff --git a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/RemainingApplicationsChangesUseCaselmpl.swift b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/RemainingApplicationsChangesUseCaseImpl.swift similarity index 87% rename from Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/RemainingApplicationsChangesUseCaselmpl.swift rename to Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/RemainingApplicationsChangesUseCaseImpl.swift index 5692f444..ffe85fd5 100644 --- a/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/RemainingApplicationsChangesUseCaselmpl.swift +++ b/Projects/Services/DataModule/Sources/Remains/UserCases/lmpl/RemainingApplicationsChangesUseCaseImpl.swift @@ -3,7 +3,7 @@ import DataMappingModule import DomainModule import ErrorModule -public struct RemainingApplicationsChangesUseCaselmpl: RemainingApplicationsChangesUseCase { +public struct RemainingApplicationsChangesUseCaseImpl: RemainingApplicationsChangesUseCase { private let remainsRepository: any RemainsRepository public init(remainsRepository: any RemainsRepository) { diff --git a/Projects/Services/DataModule/Sources/StudyRooms/Repositories/Impl/StudyRoomsRepositoryImpl.swift b/Projects/Services/DataModule/Sources/StudyRooms/Repositories/Impl/StudyRoomsRepositoryImpl.swift index 3d8c08df..304177a7 100644 --- a/Projects/Services/DataModule/Sources/StudyRooms/Repositories/Impl/StudyRoomsRepositoryImpl.swift +++ b/Projects/Services/DataModule/Sources/StudyRooms/Repositories/Impl/StudyRoomsRepositoryImpl.swift @@ -34,4 +34,8 @@ public struct StudyRoomsRepositoryImpl: StudyRoomsRepository { public func cancelStudyRoomSeat() -> AnyPublisher { remoteStudyRoomsDataSource.cancelStudyRoomSeat() } + + public func fehtchMyStudyRoomApplicationItems() -> AnyPublisher { + remoteStudyRoomsDataSource.fetchMyRemainApplicationItems() + } } diff --git a/Projects/Services/DataModule/Sources/StudyRooms/UseCases/Impl/FehtchMyStudyRoomAppItemsUserCaseImpl.swift b/Projects/Services/DataModule/Sources/StudyRooms/UseCases/Impl/FehtchMyStudyRoomAppItemsUserCaseImpl.swift new file mode 100644 index 00000000..231889cf --- /dev/null +++ b/Projects/Services/DataModule/Sources/StudyRooms/UseCases/Impl/FehtchMyStudyRoomAppItemsUserCaseImpl.swift @@ -0,0 +1,16 @@ +import Combine +import DataMappingModule +import DomainModule +import ErrorModule + +public struct FetchMyStudyRoomAppItemsUseCaseImpl: FetchMyStudyRoomAppItemsUseCase { + private let studyRoomsRepository: any StudyRoomsRepository + + public init(studyRoomsRepository: any StudyRoomsRepository) { + self.studyRoomsRepository = studyRoomsRepository + } + + public func execute() -> AnyPublisher { + studyRoomsRepository.fehtchMyStudyRoomApplicationItems() + } +} diff --git a/Projects/Services/DomainModule/Sources/Entities/MyRemainApplicationItemsEntity.swift b/Projects/Services/DomainModule/Sources/Entities/MyRemainApplicationItemsEntity.swift index 779001c2..61fa0146 100644 --- a/Projects/Services/DomainModule/Sources/Entities/MyRemainApplicationItemsEntity.swift +++ b/Projects/Services/DomainModule/Sources/Entities/MyRemainApplicationItemsEntity.swift @@ -4,5 +4,5 @@ public struct MyRemainApplicationItemsEntity: Equatable, Hashable { public init(title: String) { self.title = title } - public let title: String + public var title: String } diff --git a/Projects/Services/DomainModule/Sources/Entities/MyStudyRoomAppItemsEntity.swift b/Projects/Services/DomainModule/Sources/Entities/MyStudyRoomAppItemsEntity.swift new file mode 100644 index 00000000..adefdcc1 --- /dev/null +++ b/Projects/Services/DomainModule/Sources/Entities/MyStudyRoomAppItemsEntity.swift @@ -0,0 +1,11 @@ +import Foundation + +public struct MyStudyRoomAppItemsEntity: Equatable, Hashable { + public init(floor: String, name: String) { + self.floor = floor + self.name = name + } + + public let floor: String + public let name: String +} diff --git a/Projects/Services/DomainModule/Sources/Entities/RemainApplicationListEntity.swift b/Projects/Services/DomainModule/Sources/Entities/RemainApplicationListEntity.swift index 49e9ea89..b32f55bf 100644 --- a/Projects/Services/DomainModule/Sources/Entities/RemainApplicationListEntity.swift +++ b/Projects/Services/DomainModule/Sources/Entities/RemainApplicationListEntity.swift @@ -2,13 +2,10 @@ import Foundation public struct RemainApplicationListEntity: Equatable, Hashable { public init( - selectedOption: String, remainOptions: [RemainOptionEntity] ) { - self.selectedOption = selectedOption self.remainOptions = remainOptions } - public let selectedOption: String public let remainOptions: [RemainOptionEntity] } diff --git a/Projects/Services/DomainModule/Sources/Entities/RemainOptionEntity.swift b/Projects/Services/DomainModule/Sources/Entities/RemainOptionEntity.swift index 0bda16ec..dc38756c 100644 --- a/Projects/Services/DomainModule/Sources/Entities/RemainOptionEntity.swift +++ b/Projects/Services/DomainModule/Sources/Entities/RemainOptionEntity.swift @@ -4,14 +4,17 @@ public struct RemainOptionEntity: Equatable, Hashable { public init( id: String, title: String, - description: String + description: String, + isApplied: Bool ) { self.id = id self.title = title self.description = description + self.isApplied = isApplied } public let id: String public let title: String public let description: String + public let isApplied: Bool } diff --git a/Projects/Services/DomainModule/Sources/Entities/RemainsAvailableTimeEntity.swift b/Projects/Services/DomainModule/Sources/Entities/RemainsAvailableTimeEntity.swift index b7a05197..a6701fa4 100644 --- a/Projects/Services/DomainModule/Sources/Entities/RemainsAvailableTimeEntity.swift +++ b/Projects/Services/DomainModule/Sources/Entities/RemainsAvailableTimeEntity.swift @@ -4,18 +4,18 @@ import DataMappingModule public struct RemainsAvailableTimeEntity: Equatable, Hashable { public init( startDayOfWeek: WeekType, - startAt: String, + startTime: Date, endDayOfWeek: WeekType, - endAt: String + endTime: Date ) { self.startDayOfWeek = startDayOfWeek - self.startAt = startAt + self.startTime = startTime self.endDayOfWeek = endDayOfWeek - self.endAt = endAt + self.endTime = endTime } public let startDayOfWeek: WeekType - public let startAt: String + public let startTime: Date public let endDayOfWeek: WeekType - public let endAt: String + public let endTime: Date } diff --git a/Projects/Services/DomainModule/Sources/StudyRooms/Repository/StudyRoomsRepository.swift b/Projects/Services/DomainModule/Sources/StudyRooms/Repository/StudyRoomsRepository.swift index 923beb0c..4656aa5b 100644 --- a/Projects/Services/DomainModule/Sources/StudyRooms/Repository/StudyRoomsRepository.swift +++ b/Projects/Services/DomainModule/Sources/StudyRooms/Repository/StudyRoomsRepository.swift @@ -9,4 +9,5 @@ public protocol StudyRoomsRepository { func fetchDetailStudyRoom(roomID: String) -> AnyPublisher func applyStudyRoomSeat(seatID: String) -> AnyPublisher func cancelStudyRoomSeat() -> AnyPublisher + func fehtchMyStudyRoomApplicationItems() -> AnyPublisher } diff --git a/Projects/Services/DomainModule/Sources/StudyRooms/UseCases/FetchMyStudyRoomAppItemsUseCase.swift b/Projects/Services/DomainModule/Sources/StudyRooms/UseCases/FetchMyStudyRoomAppItemsUseCase.swift new file mode 100644 index 00000000..dca93fb2 --- /dev/null +++ b/Projects/Services/DomainModule/Sources/StudyRooms/UseCases/FetchMyStudyRoomAppItemsUseCase.swift @@ -0,0 +1,7 @@ +import Combine +import DataMappingModule +import ErrorModule + +public protocol FetchMyStudyRoomAppItemsUseCase { + func execute() -> AnyPublisher +} diff --git a/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchListRemainAppItemsDataTransfer.swift b/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchListRemainAppItemsDataTransfer.swift index 8eb69c30..63b4a1ba 100644 --- a/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchListRemainAppItemsDataTransfer.swift +++ b/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchListRemainAppItemsDataTransfer.swift @@ -4,7 +4,6 @@ import DomainModule public extension FetchRemainAppListResponseDTO { func toDomain() -> RemainApplicationListEntity { RemainApplicationListEntity( - selectedOption: selectedOption, remainOptions: remainOptions.map { $0.toDomain() } ) } @@ -15,7 +14,8 @@ public extension RemainOptionResponseDTO { RemainOptionEntity( id: id, title: title, - description: description + description: description, + isApplied: isApplied ) } } diff --git a/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchRemainsAvailableTimeDataTransfer.swift b/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchRemainsAvailableTimeDataTransfer.swift index 6edfc8c8..3cebec25 100644 --- a/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchRemainsAvailableTimeDataTransfer.swift +++ b/Projects/Services/NetworkModule/Sources/Remains/Remote/Impl/DataTransfer/FetchRemainsAvailableTimeDataTransfer.swift @@ -1,13 +1,14 @@ import DataMappingModule import DomainModule +import Utility public extension FetchRemainsAvailableTimeResponseDTO { func toDomain() -> RemainsAvailableTimeEntity { RemainsAvailableTimeEntity( startDayOfWeek: startDayOfWeek, - startAt: startAt, + startTime: startTime.toDMSTime(), endDayOfWeek: endDayOfWeek, - endAt: endAt + endTime: endTime.toDMSTime() ) } } diff --git a/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/Impl/DataTransfer/FehtchMyStudyRoomApplicationItemsDataTransfer.swift b/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/Impl/DataTransfer/FehtchMyStudyRoomApplicationItemsDataTransfer.swift new file mode 100644 index 00000000..31ef6f28 --- /dev/null +++ b/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/Impl/DataTransfer/FehtchMyStudyRoomApplicationItemsDataTransfer.swift @@ -0,0 +1,11 @@ +import DataMappingModule +import DomainModule + +public extension FehtchMyStudyRoomApplicationItemsDTO { + func toDomain() -> MyStudyRoomAppItemsEntity { + MyStudyRoomAppItemsEntity( + floor: floor, + name: name + ) + } +} diff --git a/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/Impl/RemoteStudyRoomsDataSourceImpl.swift b/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/Impl/RemoteStudyRoomsDataSourceImpl.swift index 404dba43..9fbc654e 100644 --- a/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/Impl/RemoteStudyRoomsDataSourceImpl.swift +++ b/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/Impl/RemoteStudyRoomsDataSourceImpl.swift @@ -5,6 +5,12 @@ import DomainModule import ErrorModule public final class RemoteStudyRoomsDataSourceImpl: BaseRemoteDataSource, RemoteStudyRoomsDataSource { + public func fetchMyRemainApplicationItems() -> AnyPublisher { + request(.fetchMyStudyRoomApplicationItems, dto: FehtchMyStudyRoomApplicationItemsDTO.self) + .map { $0.toDomain() } + .eraseToAnyPublisher() + } + public func fetchStudyAvailableTime() -> AnyPublisher { request(.fetchStudyAvailableTime, dto: FetchStudyAvailableTimeResponseDTO.self) .map { $0.toDomain() } diff --git a/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/RemoteStudyRoomsDataSource.swift b/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/RemoteStudyRoomsDataSource.swift index a82aaf77..464986e9 100644 --- a/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/RemoteStudyRoomsDataSource.swift +++ b/Projects/Services/NetworkModule/Sources/StudyRooms/Remote/RemoteStudyRoomsDataSource.swift @@ -12,4 +12,5 @@ public protocol RemoteStudyRoomsDataSource { func fetchDetailStudyRoom(roomID: String) -> AnyPublisher func applyStudyRoomSeat(seatID: String) -> AnyPublisher func cancelStudyRoomSeat() -> AnyPublisher + func fetchMyRemainApplicationItems() -> AnyPublisher }