Skip to content

Commit 63e7c59

Browse files
committed
feat: 제보하기 엔티티 구현
1 parent e7740ce commit 63e7c59

18 files changed

Lines changed: 1190 additions & 16 deletions

Projects/DataSource/Sources/Repository/LocationRepository.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ final class LocationRepository: NSObject, LocationRepositoryProtocol {
3737
}
3838

3939
func fetchAddress(coordinate: LocationEntity) async throws -> LocationEntity? {
40-
let endpoint = LocationEndpoint.fetchAddress(longitude: coordinate.longitude, latitude: coordinate.latitude)
40+
guard
41+
let longitude = coordinate.longitude,
42+
let latitude = coordinate.latitude
43+
else { return nil }
44+
45+
let endpoint = LocationEndpoint.fetchAddress(longitude: longitude, latitude: latitude)
4146

4247
guard let response = try await networkService.request(endpoint: endpoint, type: KakaoLocationResponseDTO.self)
4348
else { return nil }
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// ReportProgress.swift
3+
// Domain
4+
//
5+
// Created by 이동현 on 11/15/25.
6+
//
7+
8+
public enum ReportProgress: CaseIterable {
9+
case entire
10+
case received
11+
case inProgress
12+
case completed
13+
14+
public var description: String {
15+
switch self {
16+
case .entire:
17+
"전체"
18+
case .received:
19+
"제보 완료"
20+
case .inProgress:
21+
"처리 중"
22+
case .completed:
23+
"처리완료"
24+
}
25+
}
26+
}

Projects/Domain/Sources/Entity/LocationEntity.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
//
77

88
public struct LocationEntity {
9-
public let longitude: Double
10-
public let latitude: Double
9+
public let longitude: Double?
10+
public let latitude: Double?
1111
public let address: String?
1212

1313
public init(
14-
longitude: Double,
15-
latitude: Double,
14+
longitude: Double?,
15+
latitude: Double?,
1616
address: String?
1717
) {
1818
self.longitude = longitude

Projects/Domain/Sources/Entity/ReportEntity.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,12 @@
66
//
77

88
public struct ReportEntity {
9-
9+
let id: Int
10+
let title: String
11+
let date: String?
12+
let type: ReportType
13+
let progress: ReportProgress
14+
let content: String?
15+
let location: LocationEntity
16+
let photoUrls: [String]
1017
}

Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public struct PresentationDependencyAssembler: DependencyAssemblerProtocol {
128128
return ReportViewModel(reportUseCase: reportUseCase)
129129
}
130130

131+
DIContainer.shared
132+
.register(type: ReportListHistoryViewModel.self) { container in
133+
return ReportListHistoryViewModel()
134+
}
135+
131136
DIContainer.shared.register(type: ReportDetailViewModel.self) { container in
132137
return ReportDetailViewModel()
133138
}

Projects/Presentation/Sources/Report/Model/PhotoItem.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
import Foundation
99

10-
public struct PhotoItem: Hashable {
11-
public let id: UUID
12-
public let data: Data
10+
struct PhotoItem: Hashable {
11+
let id: UUID
12+
let data: Data
1313

14-
public init(id: UUID = .init(), data: Data) {
14+
init(id: UUID = .init(), data: Data) {
1515
self.id = id
1616
self.data = data
1717
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
//
2+
// ReportHistoryItem.swift
3+
// Presentation
4+
//
5+
// Created by 이동현 on 11/19/25.
6+
//
7+
8+
import Domain
9+
10+
struct ReportHistoryItem: Hashable {
11+
let id: Int
12+
let title: String
13+
let thumbnailUrl: String?
14+
let date: String?
15+
let type: ReportType
16+
let progress: ReportProgress
17+
let location: String
18+
}
19+
20+
extension ReportHistoryItem {
21+
static var dummyData: [ReportHistoryItem] {
22+
let types = ReportType.allCases
23+
let progresses = ReportProgress.allCases.filter { $0 != .entire }
24+
25+
func makeItem(
26+
id: Int,
27+
title: String,
28+
date: String,
29+
location: String,
30+
typeIndex: Int,
31+
progressIndex: Int
32+
) -> ReportHistoryItem {
33+
let type = types[typeIndex % types.count]
34+
let progress = progresses[progressIndex % progresses.count]
35+
36+
return ReportHistoryItem(
37+
id: id,
38+
title: title,
39+
thumbnailUrl: "https://picsum.photos/200",
40+
date: date,
41+
type: type,
42+
progress: progress,
43+
location: location
44+
)
45+
}
46+
47+
return [
48+
makeItem(
49+
id: 1,
50+
title: "횡단보도 앞 가로등 불이 꺼져 있어요",
51+
date: "2025-11-19월",
52+
location: "서울시 강남구 삼성동",
53+
typeIndex: 0,
54+
progressIndex: 0
55+
),
56+
makeItem(
57+
id: 2,
58+
title: "지하철 역사 계단 난간이 파손되었어요",
59+
date: "2025-11-19월",
60+
location: "서울시 송파구 잠실동",
61+
typeIndex: 1,
62+
progressIndex: 1
63+
),
64+
65+
// 다른 날짜
66+
makeItem(
67+
id: 3,
68+
title: "공원 놀이터 바닥이 파여 있어 위험해요",
69+
date: "2025-11-18월",
70+
location: "서울시 마포구 상암동",
71+
typeIndex: 2,
72+
progressIndex: 2
73+
),
74+
makeItem(
75+
id: 4,
76+
title: "버스 정류장 안내판 조명이 나갔습니다",
77+
date: "2025-11-18월",
78+
location: "서울시 서초구 서초동",
79+
typeIndex: 3,
80+
progressIndex: 0
81+
),
82+
83+
makeItem(
84+
id: 5,
85+
title: "자전거 도로에 불법 주차된 차량이 있어요",
86+
date: "2025-11-17월",
87+
location: "서울시 노원구 공릉동",
88+
typeIndex: 1,
89+
progressIndex: 1
90+
),
91+
makeItem(
92+
id: 6,
93+
title: "보도블럭이 들떠서 걸려 넘어질 위험이 있어요",
94+
date: "2025-11-16월",
95+
location: "서울시 종로구 종로1가",
96+
typeIndex: 0,
97+
progressIndex: 2
98+
),
99+
100+
makeItem(
101+
id: 7,
102+
title: "교차로 신호등이 고장난 것 같습니다",
103+
date: "2025-11-16월",
104+
location: "서울시 동작구 사당동",
105+
typeIndex: 2,
106+
progressIndex: 0
107+
),
108+
makeItem(
109+
id: 8,
110+
title: "지하차도에 물이 고여 있어요",
111+
date: "2025-11-15월",
112+
location: "서울시 영등포구 영등포동",
113+
typeIndex: 3,
114+
progressIndex: 1
115+
)
116+
]
117+
}
118+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// ReportProgressItem.swift
3+
// Presentation
4+
//
5+
// Created by 이동현 on 11/17/25.
6+
//
7+
8+
import Domain
9+
import Foundation
10+
11+
struct ReportProgressItem: Hashable {
12+
let uuid: UUID
13+
let progress: ReportProgress
14+
let count: Int
15+
var isSelected: Bool
16+
}

Projects/Presentation/Sources/Report/View/Component/ReportCategoryTableViewCell.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ extension ReportType {
106106
var iconImage: UIImage? {
107107
switch self {
108108
case .transportation:
109-
BitnagilIcon.restIcon
109+
BitnagilIcon.carIcon
110110
case .lamp:
111-
BitnagilIcon.outsideIcon
111+
BitnagilIcon.lightIcon
112112
case .water:
113-
BitnagilIcon.wakeupIcon
113+
BitnagilIcon.waterIcon
114114
case .convenience:
115-
BitnagilIcon.growIcon
115+
BitnagilIcon.hammerIcon
116116
}
117117
}
118118
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// ReportHistoryCategoryCollectionViewCell.swift
3+
// Presentation
4+
//
5+
// Created by 이동현 on 11/15/25.
6+
//
7+
8+
import Domain
9+
import SnapKit
10+
import UIKit
11+
12+
final class ReportHistoryCategoryCollectionViewCell: UICollectionViewCell {
13+
private enum Layout {
14+
static let labelHorizontalSpacing: CGFloat = 14
15+
static let labelVerticalSpacing: CGFloat = 9
16+
static let cornerRadius: CGFloat = 18
17+
}
18+
19+
private let titleLabel = UILabel()
20+
21+
override init(frame: CGRect) {
22+
super.init(frame: frame)
23+
24+
configureAttribute()
25+
configureLayout()
26+
}
27+
28+
required init?(coder: NSCoder) {
29+
fatalError("init(coder:) has not been implemented")
30+
}
31+
32+
private func configureAttribute() {
33+
titleLabel.font = BitnagilFont.init(
34+
style: .caption1,
35+
weight: .semiBold
36+
).font
37+
38+
contentView.layer.cornerRadius = Layout.cornerRadius
39+
contentView.layer.masksToBounds = true
40+
}
41+
42+
private func configureLayout() {
43+
contentView.addSubview(titleLabel)
44+
45+
titleLabel.snp.makeConstraints { make in
46+
make.horizontalEdges
47+
.equalToSuperview()
48+
.inset(Layout.labelHorizontalSpacing)
49+
50+
make.verticalEdges
51+
.equalToSuperview()
52+
.inset(Layout.labelVerticalSpacing)
53+
}
54+
}
55+
56+
func configure(
57+
progress: ReportProgress,
58+
count: Int?,
59+
isSelected: Bool
60+
) {
61+
let countText: String
62+
63+
if let count {
64+
countText = " \(count)"
65+
} else {
66+
countText = ""
67+
}
68+
69+
titleLabel.text = "\(progress.description)\(countText)"
70+
71+
contentView.backgroundColor = isSelected ? BitnagilColor.gray10 : .white
72+
titleLabel.textColor = isSelected ? .white : BitnagilColor.gray60
73+
}
74+
}

0 commit comments

Comments
 (0)