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
9 changes: 6 additions & 3 deletions Projects/App/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import ProjectDescriptionHelpers

let project = Project.dori(
targets: [
DoriAppTarget.make(
.app(
name: "DoriApp",
bundleId: Environment.App.baseBundleId,
resources: [.glob(pattern: "Resources/**", excluding: ["Resources/info.plist"])],
dependencies: [
DoriModules.onboarding.module.projectDependency,
DoriModules.calendar.module.projectDependency,
Expand All @@ -22,8 +25,8 @@ let project = Project.dori(
DoriModules.keychain.module.projectDependency,
DoriModules.designSystem.module.projectDependency,
DoriModules.core.module.projectDependency,
DoriDependency.composableArchitecture,
]
.external(.composableArchitecture)
],
),
]
)
96 changes: 96 additions & 0 deletions Projects/Core/DoriCore/Sources/Extensions/Date+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// Date+Extensions.swift
// Dori-iOS
//
// Created by 강동영 on 2/11/26.
//

import Foundation

public extension Date {
private static let koreanLocale = Locale(identifier: "ko_KR")
private static let koreanCalendar: Calendar = {
var calendar = Calendar(identifier: .gregorian)
calendar.locale = koreanLocale
return calendar
}()

// "12월 12일(금)" 형식
var koreanDateWithWeekday: String {
let formatter = DateFormatter()
formatter.locale = Self.koreanLocale
formatter.dateFormat = "M월 d일(E)"
return formatter.string(from: self)
}

// "2024년 12월" 형식
var koreanYearMonth: String {
let formatter = DateFormatter()
formatter.locale = Self.koreanLocale
formatter.dateFormat = "yyyy년 M월"
return formatter.string(from: self)
}

// "12월" 형식
var koreanMonth: String {
let formatter = DateFormatter()
formatter.locale = Self.koreanLocale
formatter.dateFormat = "M월"
return formatter.string(from: self)
}

// 해당 월의 첫째 날
var startOfMonth: Date {
Self.koreanCalendar.date(from: Self.koreanCalendar.dateComponents([.year, .month], from: self)) ?? self
}

// 해당 월의 마지막 날
var endOfMonth: Date {
Self.koreanCalendar.date(byAdding: DateComponents(month: 1, day: -1), to: startOfMonth) ?? self
}

// 해당 월의 일 수
var daysInMonth: Int {
Self.koreanCalendar.range(of: .day, in: .month, for: self)?.count ?? 30
}

// 해당 월 1일의 요일 (일요일 = 1)
var firstWeekdayOfMonth: Int {
Self.koreanCalendar.component(.weekday, from: startOfMonth)
}

// 해당 날짜의 일(day)
var day: Int {
Self.koreanCalendar.component(.day, from: self)
}

// 해당 날짜의 월(month)
var month: Int {
Self.koreanCalendar.component(.month, from: self)
}

// 해당 날짜의 연(year)
var year: Int {
Self.koreanCalendar.component(.year, from: self)
}

// 이전 달
var previousMonth: Date {
Self.koreanCalendar.date(byAdding: .month, value: -1, to: self) ?? self
}

// 다음 달
var nextMonth: Date {
Self.koreanCalendar.date(byAdding: .month, value: 1, to: self) ?? self
}

// 같은 날인지 확인
func isSameDay(as other: Date) -> Bool {
Self.koreanCalendar.isDate(self, inSameDayAs: other)
}

// 같은 달인지 확인
func isSameMonth(as other: Date) -> Bool {
Self.koreanCalendar.isDate(self, equalTo: other, toGranularity: .month)
}
}
27 changes: 27 additions & 0 deletions Projects/Core/DoriCore/Sources/Extensions/Int+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Int+Extensions.swift
// Dori-iOS
//
// Created by 강동영 on 2/11/26.
//

import Foundation

public extension Int {
// "100,000원" 형식
var wonFormatted: String {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.locale = Locale(identifier: "ko_KR")
let formatted = formatter.string(from: NSNumber(value: self)) ?? "\(self)"
return "\(formatted)원"
}

// "100,000" 형식 (원 없이)
var decimalFormatted: String {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.locale = Locale(identifier: "ko_KR")
return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
}
}
19 changes: 19 additions & 0 deletions Projects/Core/DoriCore/Sources/Models/EventType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// EventType.swift
// Dori-iOS
//
// Created by 강동영 on 2/15/26.
//

import Foundation

public enum EventType: String, CaseIterable, Codable, Equatable, Sendable, Identifiable {
case wedding = "결혼식"
case funeral = "장례식"
case firstBirthday = "돌잔치"
case housewarming = "집들이"
case birthday = "생일"
case other = "기타"

public var id: String { rawValue }
}
17 changes: 17 additions & 0 deletions Projects/Core/DoriCore/Sources/Models/Relationship.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Relationship.swift
// Dori-iOS
//
// Created by 강동영 on 2/15/26.
//

import Foundation

public enum Relationship: String, CaseIterable, Codable, Equatable, Sendable, Hashable, Identifiable {
case friend = "친구"
case family = "가족"
case company = "회사"
case other = "기타"

public var id: String { rawValue }
}
15 changes: 15 additions & 0 deletions Projects/Core/DoriCore/Sources/Models/TransactionType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// TransactionType.swift
// Dori-iOS
//
// Created by 강동영 on 2/15/26.
//

import Foundation

public enum TransactionType: String, CaseIterable, Codable, Equatable, Sendable, Hashable, Identifiable {
case given = "주도리"
case received = "받도리"

public var id: String { rawValue }
}
21 changes: 21 additions & 0 deletions Projects/Core/DoriDesignSystem/Sources/AmountLabel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// AmountLabel.swift
// Dori-iOS
//
// Created by 강동영 on 2/18/26.
//

import SwiftUI
import DoriCore

public struct AmountLabel: View {
let amount: Int

public init(_ amount: Int) {
self.amount = amount
}

public var body: some View {
Text(amount.wonFormatted)
}
}
55 changes: 55 additions & 0 deletions Projects/Core/DoriDesignSystem/Sources/FloatingActionButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// FloatingActionButton.swift
// Dori-iOS
//
// Created by 강동영 on 2/15/26.
//

import SwiftUI

public struct FloatingActionButton: View {
let action: () -> Void

public init(action: @escaping () -> Void) {
self.action = action
}

public var body: some View {
Button(action: action) {
Image(systemName: "plus")
.font(.title2)
.fontWeight(.semibold)
.foregroundColor(.white)
.frame(
width: 56,
height: 56
)
.background(DoriColors.main.color)
.clipShape(Circle())
.shadow(
color: .black.opacity(0.3),
radius: 4,
x: 0,
y: 2
)
}
}
}

#Preview {
ZStack {
Color.gray.opacity(0.2)
.ignoresSafeArea()

VStack {
Spacer()
HStack {
Spacer()
FloatingActionButton {
print("FAB tapped")
}
.padding()
}
}
}
}
42 changes: 42 additions & 0 deletions Projects/Core/DoriDesignSystem/Sources/PageIndicator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// PageIndicator.swift
// Dori-iOS
//
// Created by 강동영 on 2/15/26.
//

import SwiftUI

public struct PageIndicator: View {
let count: Int
@Binding var currentIndex: Int?

public init(
count: Int,
currentIndex: Binding<Int?>
) {
self.count = count
if currentIndex.wrappedValue == nil {
self._currentIndex = .constant(0)
} else {
self._currentIndex = currentIndex
}
}

public var body: some View {
HStack {
ForEach(0..<count, id: \.self) { index in
Circle()
.frame(
width: 10,
height: 10
)
.foregroundStyle(
currentIndex == index
? DoriColors.main.color
: DoriColors.grey200.color
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ fileprivate struct DesignTokenDemoView: View {
.frame(height: 50)
.foregroundStyle(.grey100)
Text("도리 화이팅")
.pretendard(.heading(heading))
.pretendard(.headline(heading))
}
}
} header: {
Text("헤딩")
.padding()
.pretendard(.heading(.h15))
.pretendard(.bold(.b15))
.foregroundStyle(.doriWhite)
.frame(maxWidth: .infinity)
.background(.secondary)
Expand All @@ -73,7 +73,7 @@ fileprivate struct DesignTokenDemoView: View {
} header: {
Text("서브 타이틀")
.padding()
.pretendard(.heading(.h15))
.pretendard(.bold(.b15))
.foregroundStyle(.doriWhite)
.frame(maxWidth: .infinity)
.background(.secondary)
Expand All @@ -93,7 +93,7 @@ fileprivate struct DesignTokenDemoView: View {
} header: {
Text("바디")
.padding()
.pretendard(.heading(.h15))
.pretendard(.bold(.b15))
.foregroundStyle(.doriWhite)
.frame(maxWidth: .infinity)
.background(.main)
Expand All @@ -113,7 +113,7 @@ fileprivate struct DesignTokenDemoView: View {
} header: {
Text("캡션")
.padding()
.pretendard(.heading(.h15))
.pretendard(.bold(.b15))
.foregroundStyle(.doriWhite)
.frame(maxWidth: .infinity)
.background(.main)
Expand Down Expand Up @@ -142,10 +142,10 @@ extension DesignTokenDemoView {
DoriColors.doriBlack.color
]

private static let typoHeadings: [TypoStyle.Heading] = TypoStyle.Heading.allCases
private static let typoSubTitles: [TypoStyle.SubTitle] = TypoStyle.SubTitle.allCases
private static let typoBodys: [TypoStyle.Body] = TypoStyle.Body.allCases
private static let typoCaptions: [TypoStyle.Caption] = TypoStyle.Caption.allCases
private static let typoHeadings: [TypoSemantic.Heading] = TypoSemantic.Heading.allCases
private static let typoSubTitles: [TypoSemantic.SubTitle] = TypoSemantic.SubTitle.allCases
private static let typoBodys: [TypoSemantic.Body] = TypoSemantic.Body.allCases
private static let typoCaptions: [TypoSemantic.Caption] = TypoSemantic.Caption.allCases
}

#Preview {
Expand Down
Loading