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
@@ -1,17 +1,17 @@
{
"images" : [
{
"filename" : "expense_emtpy.png",
"filename" : "빈 지갑 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "expense_emtpy@2x.png",
"filename" : "빈 지갑 1@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "expense_emtpy@3x.png",
"filename" : "빈 지갑 1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "지출 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "지출 1@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "지출 1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions DesignSystem/Sources/Image/ImageAsset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ public enum ImageAsset: String {
case profile
case check
case person
case settlementEmpty
}
32 changes: 27 additions & 5 deletions Domain/Sources/Entity/Expense/Expense.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,34 @@ extension Expense {

// MARK: - Helper
extension Expense {
private static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .gregorian)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()

public func formatExpenseDate() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.calendar = Calendar(identifier: .gregorian)
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
return dateFormatter.string(from: expenseDate)
Self.dateFormatter.string(from: expenseDate)
}

public static func formatDate(_ date: Date) -> String {
dateFormatter.string(from: date)
}

public static func parseDate(_ dateString: String) -> Date? {
dateFormatter.date(from: dateString)
}

/// convertedAmount를 포맷팅 (소수점 제거)
public func formattedConvertedAmount() -> String {
convertedAmount.formatted(.number.precision(.fractionLength(0)))
}

/// amount를 포맷팅 (소수점 제거)
public func formattedAmount() -> String {
amount.formatted(.number.precision(.fractionLength(0)))
}
}

Expand Down
42 changes: 42 additions & 0 deletions Domain/Sources/Utility/CurrencyFormatter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// CurrencyFormatter.swift
// Domain
//
// Created by 홍석현 on 12/15/25.
//

import Foundation

public enum CurrencyFormatter {
/// 한국식 통화 포맷 (억/만/원 단위)
public static func formatKoreanCurrency(_ amount: Double) -> String {
let rounded = amount.rounded()

// Double로 계산하고 포맷팅
let eokDouble = (rounded / 100_000_000).rounded(.towardZero) // 억
let remainder1 = rounded.truncatingRemainder(dividingBy: 100_000_000)
let manDouble = (remainder1 / 10_000).rounded(.towardZero) // 만
let wonDouble = remainder1.truncatingRemainder(dividingBy: 10_000) // 원

var result = ""

if eokDouble > 0 {
result += "\(eokDouble.formatted(.number.precision(.fractionLength(0))))억"
if manDouble > 0 {
result += " \(manDouble.formatted(.number.precision(.fractionLength(0))))만"
}
if wonDouble > 0 {
result += " \(wonDouble.formatted(.number.precision(.fractionLength(0))))원"
}
} else if manDouble > 0 {
result += "\(manDouble.formatted(.number.precision(.fractionLength(0))))만"
if wonDouble > 0 {
result += " \(wonDouble.formatted(.number.precision(.fractionLength(0))))원"
}
} else {
result = "\(wonDouble.formatted(.number.precision(.fractionLength(0))))원"
}

return result
}
}
58 changes: 58 additions & 0 deletions Features/ExpenseList/Sources/Components/CategoryFilterView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// CategoryFilterView.swift
// ExpenseListFeature
//
// Created by 홍석현 on 12/15/25.
//

import SwiftUI
import DesignSystem
import Domain

struct CategoryFilterView: View {
@Binding var selectedCategory: ExpenseCategory?

var body: some View {
HStack {
Spacer()
Menu {
Button {
selectedCategory = nil
} label: {
HStack {
Text("전체")
if selectedCategory == nil {
Image(systemName: "checkmark")
}
}
}

ForEach(ExpenseCategory.allCases, id: \.self) { category in
Button {
selectedCategory = category
} label: {
HStack {
Text(category.displayName)
if selectedCategory == category {
Image(systemName: "checkmark")
}
}
}
}
} label: {
HStack(spacing: 4) {
Text(selectedCategory?.displayName ?? "전체")
.font(.app(.caption1, weight: .semibold))
.foregroundStyle(Color.gray7)
Image(systemName: "chevron.down")
.font(.caption)
.foregroundStyle(Color.gray5)
}
}
}
}
}

#Preview {
CategoryFilterView(selectedCategory: .constant(nil))
}
7 changes: 5 additions & 2 deletions Features/ExpenseList/Sources/Components/ExpenseCardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ public struct ExpenseCardView: View {

// 금액 정보
VStack(alignment: .trailing, spacing: 4) {
Text("₩\(Int(expense.convertedAmount).formatted())")
Text("₩\(expense.formattedConvertedAmount())")
.font(.app(.title3, weight: .semibold))
.lineLimit(1)
.foregroundStyle(.black)

Text("\(expense.currency) \(expense.amount.formatted())")
Text("\(expense.currency) \(expense.formattedAmount())")
.font(.app(.caption1, weight: .medium))
.lineLimit(1)
}
}

Expand All @@ -50,6 +52,7 @@ public struct ExpenseCardView: View {
.resizable()
.frame(width: 16, height: 16)
Text(expense.payer.name)
.lineLimit(1)
}

// 구분선 (|)
Expand Down
Loading
Loading