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
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ final class LocationRepository: NSObject, LocationRepositoryProtocol {
}

func fetchAddress(coordinate: LocationEntity) async throws -> LocationEntity? {
let endpoint = LocationEndpoint.fetchAddress(longitude: coordinate.longitude, latitude: coordinate.latitude)
guard
let longitude = coordinate.longitude,
let latitude = coordinate.latitude
else { return nil }

let endpoint = LocationEndpoint.fetchAddress(longitude: longitude, latitude: latitude)

guard let response = try await networkService.request(endpoint: endpoint, type: KakaoLocationResponseDTO.self)
else { return nil }
Expand Down
26 changes: 26 additions & 0 deletions Projects/Domain/Sources/Entity/Enum/ReportProgress.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// ReportProgress.swift
// Domain
//
// Created by 이동현 on 11/15/25.
//

public enum ReportProgress: CaseIterable {
case entire
case received
case inProgress
case completed

public var description: String {
switch self {
case .entire:
"전체"
case .received:
"제보 완료"
case .inProgress:
"처리 중"
case .completed:
"처리 완료"
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
8 changes: 4 additions & 4 deletions Projects/Domain/Sources/Entity/LocationEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
//

public struct LocationEntity {
public let longitude: Double
public let latitude: Double
public let longitude: Double?
public let latitude: Double?
public let address: String?

public init(
longitude: Double,
latitude: Double,
longitude: Double?,
latitude: Double?,
address: String?
) {
self.longitude = longitude
Expand Down
28 changes: 28 additions & 0 deletions Projects/Domain/Sources/Entity/ReportEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,33 @@
//

public struct ReportEntity {
public let id: Int
public let title: String
public let date: String?
public let type: ReportType
public let progress: ReportProgress
public let content: String?
public let location: LocationEntity
public let photoUrls: [String]

public init(
id: Int,
title: String,
date: String?,
type: ReportType,
progress: ReportProgress,
content: String?,
location: LocationEntity,
photoUrls: [String]
) {
self.id = id
self.title = title
self.date = date
self.type = type
self.progress = progress
self.content = content
self.location = location
self.photoUrls = photoUrls
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public struct PresentationDependencyAssembler: DependencyAssemblerProtocol {
return ReportViewModel(reportUseCase: reportUseCase)
}

DIContainer.shared
.register(type: ReportListHistoryViewModel.self) { container in
return ReportListHistoryViewModel()
}

DIContainer.shared.register(type: ReportDetailViewModel.self) { container in
return ReportDetailViewModel()
}
Expand Down
8 changes: 4 additions & 4 deletions Projects/Presentation/Sources/Report/Model/PhotoItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

import Foundation

public struct PhotoItem: Hashable {
public let id: UUID
public let data: Data
struct PhotoItem: Hashable {
let id: UUID
let data: Data

public init(id: UUID = .init(), data: Data) {
init(id: UUID = .init(), data: Data) {
self.id = id
self.data = data
}
Expand Down
118 changes: 118 additions & 0 deletions Projects/Presentation/Sources/Report/Model/ReportHistoryItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//
// ReportHistoryItem.swift
// Presentation
//
// Created by 이동현 on 11/19/25.
//

import Domain

struct ReportHistoryItem: Hashable {
let id: Int
let title: String
let thumbnailUrl: String
let date: String
let type: ReportType
let progress: ReportProgress
let location: String
}

extension ReportHistoryItem {
static var dummyData: [ReportHistoryItem] {
let types = ReportType.allCases
let progresses = ReportProgress.allCases.filter { $0 != .entire }

func makeItem(
id: Int,
title: String,
date: String,
location: String,
typeIndex: Int,
progressIndex: Int
) -> ReportHistoryItem {
let type = types[typeIndex % types.count]
let progress = progresses[progressIndex % progresses.count]

return ReportHistoryItem(
id: id,
title: title,
thumbnailUrl: "https://picsum.photos/200",
date: date,
type: type,
progress: progress,
location: location
)
}

return [
makeItem(
id: 1,
title: "횡단보도 앞 가로등 불이 꺼져 있어요",
date: "2025-11-19월",
location: "서울시 강남구 삼성동",
typeIndex: 0,
progressIndex: 0
),
makeItem(
id: 2,
title: "지하철 역사 계단 난간이 파손되었어요",
date: "2025-11-19월",
location: "서울시 송파구 잠실동",
typeIndex: 1,
progressIndex: 1
),

// 다른 날짜
makeItem(
id: 3,
title: "공원 놀이터 바닥이 파여 있어 위험해요",
date: "2025-11-18월",
location: "서울시 마포구 상암동",
typeIndex: 2,
progressIndex: 2
),
makeItem(
id: 4,
title: "버스 정류장 안내판 조명이 나갔습니다",
date: "2025-11-18월",
location: "서울시 서초구 서초동",
typeIndex: 3,
progressIndex: 0
),

makeItem(
id: 5,
title: "자전거 도로에 불법 주차된 차량이 있어요",
date: "2025-11-17월",
location: "서울시 노원구 공릉동",
typeIndex: 1,
progressIndex: 1
),
makeItem(
id: 6,
title: "보도블럭이 들떠서 걸려 넘어질 위험이 있어요",
date: "2025-11-16월",
location: "서울시 종로구 종로1가",
typeIndex: 0,
progressIndex: 2
),

makeItem(
id: 7,
title: "교차로 신호등이 고장난 것 같습니다",
date: "2025-11-16월",
location: "서울시 동작구 사당동",
typeIndex: 2,
progressIndex: 0
),
makeItem(
id: 8,
title: "지하차도에 물이 고여 있어요",
date: "2025-11-15월",
location: "서울시 영등포구 영등포동",
typeIndex: 3,
progressIndex: 1
)
]
}
Comment on lines +21 to +117

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

더미 데이터의 날짜 형식을 확인해주세요.

더미 데이터의 모든 날짜가 "월"(월요일) 요일 접미사를 가지고 있습니다. 예를 들어 2025-11-19, 2025-11-18, 2025-11-17 등 서로 다른 날짜임에도 모두 "월"로 표시되어 있어 실제 요일과 일치하지 않을 수 있습니다. UI 검증을 위해 다양한 요일 표현(월, 화, 수 등)을 사용하는 것이 좋겠습니다.

참고: PR 설명에 언급된 대로, UI 완성 시 이 더미 데이터는 제거 예정입니다.

날짜별로 올바른 요일을 계산하는 헬퍼 함수를 생성하는 것이 도움이 될까요?

🤖 Prompt for AI Agents
In Projects/Presentation/Sources/Report/Model/ReportHistoryItem.swift around
lines 21 to 117, the dummy items use hard-coded weekday suffixes ("월") that may
not match the actual weekday for each date; replace these hard-coded weekday
strings by computing the correct weekday from the date value: add a small helper
that parses the date string (use the same format used elsewhere, e.g.
"yyyy-MM-dd"), computes the calendar weekday, maps it to the Korean weekday
symbols ("일","월","화","수","목","금","토"), and returns a formatted date string like
"2025-11-19월"; update the dummyData builder to call this helper for each item
(or store correctly formatted date strings) and make the helper resilient to
parse failures by falling back to the original string or a safe default.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// ReportProgressItem.swift
// Presentation
//
// Created by 이동현 on 11/17/25.
//

import Domain
import Foundation

struct ReportProgressItem: Hashable {
let uuid: UUID
let progress: ReportProgress
let count: Int
var isSelected: Bool
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ extension ReportType {
var iconImage: UIImage? {
switch self {
case .transportation:
BitnagilIcon.restIcon
BitnagilIcon.carIcon
case .lamp:
BitnagilIcon.outsideIcon
BitnagilIcon.lightIcon
case .water:
BitnagilIcon.wakeupIcon
BitnagilIcon.waterIcon
case .convenience:
BitnagilIcon.growIcon
BitnagilIcon.hammerIcon
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// ReportHistoryTableHeaderView.swift
// Presentation
//
// Created by 이동현 on 11/15/25.
//

import SnapKit
import UIKit

final class ReportHistoryTableHeaderView: UITableViewHeaderFooterView {
private enum Layout {
static let labelHeight: CGFloat = 20
static let weekLabelLeadingSpacing: CGFloat = 2
}

private let dateLabel = UILabel()
private let weekLabel = UILabel()

override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)

configureAttribute()
configureLayout()
}

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

private func configureAttribute() {
backgroundColor = .clear

dateLabel.textColor = BitnagilColor.gray10
dateLabel.font = BitnagilFont.init(style: .body2, weight: .semiBold).font

weekLabel.textColor = BitnagilColor.gray40
weekLabel.font = BitnagilFont.init(style: .body2, weight: .medium).font
}

private func configureLayout() {
contentView.addSubview(dateLabel)
contentView.addSubview(weekLabel)

dateLabel.snp.makeConstraints { make in
make.leading.equalToSuperview()
make.top.equalToSuperview()
make.height.equalTo(Layout.labelHeight)
}

weekLabel.snp.makeConstraints { make in
make.top.equalToSuperview()

make.leading
.equalTo(dateLabel.snp.trailing)
.offset(Layout.weekLabelLeadingSpacing)

make.height.equalTo(Layout.labelHeight)
}
}

func configure(with dateString: String) {
guard let weekCharacter = dateString.last else {
dateLabel.text = dateString
weekLabel.text = nil
return
}

let datePart = String(dateString.dropLast())
dateLabel.text = datePart
weekLabel.text = String(weekCharacter)
}
}
Loading