Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Projects/DataSource/Sources/DTO/DeleteRoutineDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// DeleteRoutineDTO.swift
// DataSource
//
// Created by 최정인 on 8/4/25.
//

struct DeleteRoutineDTO: Encodable {
let routineId: String
let routineCompletionId: Int?
let historySeq: Int
let routineType: String
let performedDate: String
let subRoutineInfosForDelete: [DeleteSubRoutineDTO]
}

struct DeleteSubRoutineDTO: Encodable {
let subRoutineId: String
let routineCompletionId: Int?
}
2 changes: 1 addition & 1 deletion Projects/DataSource/Sources/Endpoint/EmotionEndpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extension EmotionEndpoint: Endpoint {
return baseURL
case .fetchEmotion(let date):
return baseURL + "/\(date)"
case .registerEmotion(let emotion):
case .registerEmotion:
return baseURL
}
}
Expand Down
10 changes: 10 additions & 0 deletions Projects/DataSource/Sources/Endpoint/RoutineEndpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ enum RoutineEndpoint {
case fetchRoutine(routineId: String)
case fetchRoutines(startDate: String, endDate: String)
case updateRoutine(routine: RoutineUpdateDTO)
case deleteAllRoutine(routineId: String)
case deleteDailyRoutine(routine: DeleteRoutineDTO)
}

extension RoutineEndpoint: Endpoint {
Expand All @@ -21,6 +23,10 @@ extension RoutineEndpoint: Endpoint {
switch self {
case .fetchRoutine(let routineId):
"\(baseURL)/\(routineId)"
case .deleteAllRoutine(let routineId):
"\(baseURL)/\(routineId)"
case .deleteDailyRoutine:
"\(baseURL)/day"
default:
baseURL
}
Expand All @@ -34,6 +40,8 @@ extension RoutineEndpoint: Endpoint {
.get
case .updateRoutine:
.patch
case .deleteAllRoutine, .deleteDailyRoutine:
.delete
}
}

Expand Down Expand Up @@ -62,6 +70,8 @@ extension RoutineEndpoint: Endpoint {
return routine.dictionary
case .updateRoutine(let routine):
return routine.dictionary
case .deleteDailyRoutine(let routine):
return routine.dictionary
default:
return [:]
}
Expand Down
22 changes: 22 additions & 0 deletions Projects/DataSource/Sources/Repository/RoutineRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,26 @@ final class RoutineRepository: RoutineRepositoryProtocol {

_ = try await networkService.request(endpoint: endpoint, type: EmptyResponseDTO.self)
}

func deleteAllRoutine(routineId: String) async throws {
let endpoint = RoutineEndpoint.deleteAllRoutine(routineId: routineId)
_ = try await networkService.request(endpoint: endpoint, type: EmptyResponseDTO.self)
}

func deleteDailyRoutine(routine: DeleteRoutineEntity) async throws {
let deleteSubRoutineDTO = routine
.subRoutineInfosForDelete
.map({ DeleteSubRoutineDTO(subRoutineId: $0.subRoutineId, routineCompletionId: $0.routineCompletionId) })

let deleteRoutineDTO = DeleteRoutineDTO(
routineId: routine.routineId,
routineCompletionId: routine.routineCompletionId,
historySeq: routine.historySeq,
routineType: routine.routineType,
performedDate: routine.performedDate,
subRoutineInfosForDelete: deleteSubRoutineDTO)

let endpoint = RoutineEndpoint.deleteDailyRoutine(routine: deleteRoutineDTO)
_ = try await networkService.request(endpoint: endpoint, type: EmptyResponseDTO.self)
}
}
41 changes: 41 additions & 0 deletions Projects/Domain/Sources/Entity/DeleteRoutineEntity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// DeleteRoutineEntity.swift
// Domain
//
// Created by 최정인 on 8/4/25.
//

public struct DeleteRoutineEntity: Encodable {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아직 정리도 못했고, 굉장히 막연한 생각이지만, Routine이라는 Entity 하나만으로 굴러가게 하기는 힘들까요?
저도 루틴 추가/수정을 하며 새로운 엔티티를 만들었는데요, 뭔가 루틴에 대한 정책이 바뀌거나 하면 수정할 사항이 굉장히 많아질 것 같다는 생각이 듭니다..!
그리고 '루틴'에 대한 엔티티라 하면, 루틴이 가지고 있는 속성들을 다 가지고 있기 때문에, 추가/수정이든 삭제든 해당 엔티티로 처리할 수 있어야 하지 않을까? 싶기도 하구요!

다만 엔티티 하나로 통일하게 되면, RoutineEntity 내의 프로퍼티들이 옵셔널로 선언되는 경우가 많을것 같아 고민입니다.
오늘 회의에서 가볍게라도 짚고 넘어가면 좋을것 같습니다~!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 서버에서 Routine에 관련된 Response 를 받을 때 DTO에 모든 값들을 저장하고 Entity로 변환할 때에도 모든 값을 다 갖고 있어서 하나의 Entity로만 굴러가게 할 수 있을 것 같아요 !!

하지만 ...... 흠 네네네 !!!! 오늘 회의에서 마저 이야기 해부아요 ㅠㅠ !!!

public let routineId: String
public let routineCompletionId: Int?
public let historySeq: Int
public let performedDate: String
public let routineType: String
public let subRoutineInfosForDelete: [DeleteSubRoutineEntity]

public init(
routineId: String,
routineCompletionId: Int?,
historySeq: Int,
performedDate: String,
routineType: String,
subRoutineInfosForDelete: [DeleteSubRoutineEntity]
) {
self.routineId = routineId
self.routineCompletionId = routineCompletionId
self.historySeq = historySeq
self.performedDate = performedDate
self.routineType = routineType
self.subRoutineInfosForDelete = subRoutineInfosForDelete
}
}

public struct DeleteSubRoutineEntity: Encodable {
public let subRoutineId: String
public let routineCompletionId: Int?

public init(subRoutineId: String, routineCompletionId: Int?) {
self.subRoutineId = subRoutineId
self.routineCompletionId = routineCompletionId
}
}
7 changes: 0 additions & 7 deletions Projects/Domain/Sources/Entity/Untitled.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,17 @@ public protocol RoutineRepositoryProtocol {
/// - endDate: 조회 종료 날짜
func fetchRoutines(from startDate: String, to endDate: String) async throws -> [String: [RoutineEntity]]


/// 루틴을 수정합니다.
/// - Parameters:
/// - routineSummary: 루틴 요약 정보
/// - subRoutineSummaries: 서브 루틴 요약 정보 배열
func updateRoutine(routineSummary: RoutineSummaryEntity, subRoutineSummaries: [SubRoutineSummaryEntity]) async throws

/// 반복되는 루틴을 모두 제거합니다.
/// - Parameter routineId: 삭제할 루틴 id
func deleteAllRoutine(routineId: String) async throws

/// 당일 루틴을 삭제합니다.
/// - Parameter routine: 삭제할 루틴 정보
func deleteDailyRoutine(routine: DeleteRoutineEntity) async throws
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ public protocol RoutineUseCaseProtocol {
subRoutineSummaries: [SubRoutineSummaryEntity],
deletedSubRoutineSummaries: [SubRoutineSummaryEntity]
) async throws

func deleteAllRoutine(routineId: String) async throws

func deleteDailyRoutine(routine: DeleteRoutineEntity) async throws
}
8 changes: 8 additions & 0 deletions Projects/Domain/Sources/UseCase/Routine/RoutineUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,12 @@ public final class RoutineUseCase: RoutineUseCaseProtocol {

try await routineRepository.updateRoutine(routineSummary: routineSummary, subRoutineSummaries: finalSubRoutines)
}

public func deleteAllRoutine(routineId: String) async throws {
try await routineRepository.deleteAllRoutine(routineId: routineId)
}

public func deleteDailyRoutine(routine: DeleteRoutineEntity) async throws {
try await routineRepository.deleteDailyRoutine(routine: routine)
}
}
8 changes: 7 additions & 1 deletion Projects/Presentation/Sources/Home/Model/MainRoutine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ struct MainRoutine {
let startTime: Date
let repeatDay: [Week]
var subRoutines: [SubRoutine]
let historySeq: Int
let completionId: Int?
let routineType: String
}

extension RoutineEntity {
Expand All @@ -31,6 +34,9 @@ extension RoutineEntity {
isDone: completeYn,
startTime: Date.convertToDate(from: executionTime, dateType: .time) ?? Date(),
repeatDay: repeatDay.compactMap({ Week(rawValue: $0.rawValue) }),
subRoutines: subRoutines)
subRoutines: subRoutines,
historySeq: historySeq,
completionId: routineCompletionId,
routineType: routineType)
}
}
4 changes: 3 additions & 1 deletion Projects/Presentation/Sources/Home/Model/SubRoutine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct SubRoutine: Hashable {
let title: String
var isDone: Bool
let sortIndex: Int
let completionId: Int?
}

extension SubRoutineEntity {
Expand All @@ -22,6 +23,7 @@ extension SubRoutineEntity {
id: subRoutineId,
title: subRoutineName,
isDone: completeYn,
sortIndex: sortOrder)
sortIndex: sortOrder,
completionId: routineCompletionId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//
// RoutineDeleteAlertView.swift
// Presentation
//
// Created by 최정인 on 8/4/25.
//

import SnapKit
import UIKit

protocol RoutineDeleteAlertViewDelegate: AnyObject {
func routineDeleteAlertViewDidTapDeleteAllRoutine(_ sender: RoutineDeleteAlertView)
func routineDeleteAlertViewDidTapDeleteDailyRoutine(_ sender: RoutineDeleteAlertView)
}

final class RoutineDeleteAlertView: UIView {

private enum Layout {
static let deleteLabelHeight: CGFloat = 48
static let deleteLabelTopSpacing: CGFloat = 23
static let buttonHorizontalMargin: CGFloat = 23
static let buttonHeight: CGFloat = 44
static let deleteDailyRoutineButtonTopSpacing: CGFloat = 22
static let deleteAllRoutineButtonTopSpacing: CGFloat = 10
}

private let contentView = UIView()
private let deleteLabel = UILabel()
private let deleteDailyRoutineButton = UIButton()
private let deleteAllRoutineButton = UIButton()
weak var delegate: RoutineDeleteAlertViewDelegate?

init() {
super.init(frame: .zero)
configureAttribute()
configureLayout()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func configureAttribute() {
contentView.backgroundColor = .white
contentView.layer.masksToBounds = true
contentView.layer.cornerRadius = 20

deleteLabel.text = "해당 루틴은\n반복 루틴으로 설정되어 있어요"
deleteLabel.numberOfLines = 2
deleteLabel.textAlignment = .center
deleteLabel.font = BitnagilFont(style: .body1, weight: .semiBold).font
deleteLabel.textColor = BitnagilColor.gray10

var deleteDailyRoutineButtonConfiguration = UIButton.Configuration.filled()
deleteDailyRoutineButtonConfiguration.baseBackgroundColor = .white
deleteDailyRoutineButtonConfiguration.background.cornerRadius = 8
deleteDailyRoutineButtonConfiguration.attributedTitle = AttributedString(
"당일만 삭제",
attributes: .init([.font: BitnagilFont(style: .body2, weight: .medium).font]))
deleteDailyRoutineButtonConfiguration.baseForegroundColor = BitnagilColor.navy500
deleteDailyRoutineButtonConfiguration.background.strokeColor = BitnagilColor.navy500
deleteDailyRoutineButtonConfiguration.background.strokeWidth = 1
deleteDailyRoutineButton.configuration = deleteDailyRoutineButtonConfiguration
deleteDailyRoutineButton.addAction(
UIAction { [weak self] _ in
guard let self else { return }
self.delegate?.routineDeleteAlertViewDidTapDeleteDailyRoutine(self)
},
for: .touchUpInside)

var deleteAllRoutineButtonConfiguration = UIButton.Configuration.filled()
deleteAllRoutineButtonConfiguration.baseBackgroundColor = .white
deleteAllRoutineButtonConfiguration.background.cornerRadius = 8
deleteAllRoutineButtonConfiguration.attributedTitle = AttributedString(
"전체 루틴 삭제",
attributes: .init([.font: BitnagilFont(style: .body2, weight: .medium).font]))
deleteAllRoutineButtonConfiguration.baseForegroundColor = BitnagilColor.navy500
deleteAllRoutineButtonConfiguration.background.strokeColor = BitnagilColor.navy500
deleteAllRoutineButtonConfiguration.background.strokeWidth = 1
deleteAllRoutineButton.configuration = deleteAllRoutineButtonConfiguration
deleteAllRoutineButton.addAction(
UIAction { [weak self] _ in
guard let self else { return }
self.delegate?.routineDeleteAlertViewDidTapDeleteAllRoutine(self)
},
for: .touchUpInside)
}

private func configureLayout() {
addSubview(contentView)

contentView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}

[deleteLabel, deleteDailyRoutineButton, deleteAllRoutineButton].forEach {
contentView.addSubview($0)
}

deleteLabel.snp.makeConstraints { make in
make.height.equalTo(Layout.deleteLabelHeight)
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(Layout.deleteLabelTopSpacing)
}

deleteDailyRoutineButton.snp.makeConstraints { make in
make.top.equalTo(deleteLabel.snp.bottom).offset(Layout.deleteDailyRoutineButtonTopSpacing)
make.leading.equalToSuperview().offset(Layout.buttonHorizontalMargin)
make.trailing.equalToSuperview().inset(Layout.buttonHorizontalMargin)
make.height.equalTo(Layout.buttonHeight)
}

deleteAllRoutineButton.snp.makeConstraints { make in
make.top.equalTo(deleteDailyRoutineButton.snp.bottom).offset(Layout.deleteAllRoutineButtonTopSpacing)
make.leading.equalToSuperview().offset(Layout.buttonHorizontalMargin)
make.trailing.equalToSuperview().inset(Layout.buttonHorizontalMargin)
make.height.equalTo(Layout.buttonHeight)
}
}
}
Loading
Loading