diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1518596..92fe6c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,11 +15,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Build & Test + - name: Build run: | xcodebuild \ - -project Moha.xcodeproj \ + -project Moha/Moha.xcodeproj \ -scheme Moha \ -sdk iphonesimulator \ - -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' - clean test \ No newline at end of file + -destination 'generic/platform=iOS Simulator' \ + CODE_SIGNING_ALLOWED=NO \ + clean build diff --git a/Moha/Moha/Assets.xcassets/AccentColor.colorset/Contents.json b/Moha/Moha/Resources/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from Moha/Moha/Assets.xcassets/AccentColor.colorset/Contents.json rename to Moha/Moha/Resources/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/Moha/Moha/Assets.xcassets/AppIcon.appiconset/Contents.json b/Moha/Moha/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Moha/Moha/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Moha/Moha/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Moha/Moha/Assets.xcassets/Contents.json b/Moha/Moha/Resources/Assets.xcassets/Contents.json similarity index 100% rename from Moha/Moha/Assets.xcassets/Contents.json rename to Moha/Moha/Resources/Assets.xcassets/Contents.json diff --git a/Moha/Moha/ContentView.swift b/Moha/Moha/Sources/ContentView.swift similarity index 100% rename from Moha/Moha/ContentView.swift rename to Moha/Moha/Sources/ContentView.swift diff --git a/Moha/Moha/Sources/Features/MohaView.swift b/Moha/Moha/Sources/Features/MohaView.swift new file mode 100644 index 0000000..10f5862 --- /dev/null +++ b/Moha/Moha/Sources/Features/MohaView.swift @@ -0,0 +1,47 @@ +// +// MohaView.swift +// Moha +// +// Created by 변예린 on 8/19/26. +// + +import SwiftUI + +struct MohaView: View { + @State private var router = MainRouter() + + var body: some View { + TabView(selection: $router.selectedTab) { + HomeNavigationStack(router: router.homeRouter) + .tag(TabItem.home) + .tabItem { + Label("Home", systemImage: "house") + } + + ReportNavigationStack(router: router.reportRouter) + .tag(TabItem.report) + .tabItem { + Label("Report", systemImage: "chart.xyaxis.line") + } + + SettingsNavigationStack(router: router.settingsRouter) + .tag(TabItem.settings) + .tabItem { + Label("Settings", systemImage: "person") + } + } + .environment(router) + } +} + +//MARK: Tab Item +enum TabItem { + case home + case report + case settings +} + +//MARK: - MohaView Preview +#Preview { + MohaView() +} diff --git a/Moha/Moha/Item.swift b/Moha/Moha/Sources/Item.swift similarity index 100% rename from Moha/Moha/Item.swift rename to Moha/Moha/Sources/Item.swift diff --git a/Moha/Moha/MohaApp.swift b/Moha/Moha/Sources/MohaApp.swift similarity index 96% rename from Moha/Moha/MohaApp.swift rename to Moha/Moha/Sources/MohaApp.swift index 9a40416..3ee9746 100644 --- a/Moha/Moha/MohaApp.swift +++ b/Moha/Moha/Sources/MohaApp.swift @@ -25,7 +25,7 @@ struct MohaApp: App { var body: some Scene { WindowGroup { - ContentView() + MohaView() } .modelContainer(sharedModelContainer) } diff --git a/Moha/Moha/Sources/Navigation/NavigationStack/HomeNavigationStack.swift b/Moha/Moha/Sources/Navigation/NavigationStack/HomeNavigationStack.swift new file mode 100644 index 0000000..87f7c23 --- /dev/null +++ b/Moha/Moha/Sources/Navigation/NavigationStack/HomeNavigationStack.swift @@ -0,0 +1,29 @@ +// +// HomeNavigationStack.swift +// Moha +// +// Created by 변예린 on 8/21/26. +// + +import SwiftUI + +struct HomeNavigationStack: View { + @Bindable var router: HomeRouter + + var body: some View { + NavigationStack(path: $router.path) { + Text("Home") //TODO: HomeView로 수정 필요 + .navigationDestination(for: HomeRoute.self) { route in + destinationView(for: route) + } + } + } + + @ViewBuilder + private func destinationView(for route: HomeRoute) -> some View { + switch route { + case .createTodo: + Text("Create") + } + } +} diff --git a/Moha/Moha/Sources/Navigation/NavigationStack/ReportNavigationStack.swift b/Moha/Moha/Sources/Navigation/NavigationStack/ReportNavigationStack.swift new file mode 100644 index 0000000..cfcfc0c --- /dev/null +++ b/Moha/Moha/Sources/Navigation/NavigationStack/ReportNavigationStack.swift @@ -0,0 +1,29 @@ +// +// ReportNavigationStack.swift +// Moha +// +// Created by 변예린 on 8/21/26. +// + +import SwiftUI + +struct ReportNavigationStack: View { + @Bindable var router: ReportRouter + + var body: some View { + NavigationStack(path: $router.path) { + Text("Report") //TODO: ReportView로 수정 필요 + .navigationDestination(for: ReportRoute.self) { route in + destinationView(for: route) + } + } + } + + @ViewBuilder + private func destinationView(for route: ReportRoute) -> some View { + switch route { + case .createTodo: + Text("Create") + } + } +} diff --git a/Moha/Moha/Sources/Navigation/NavigationStack/SettingsNavigationStack.swift b/Moha/Moha/Sources/Navigation/NavigationStack/SettingsNavigationStack.swift new file mode 100644 index 0000000..10b05bc --- /dev/null +++ b/Moha/Moha/Sources/Navigation/NavigationStack/SettingsNavigationStack.swift @@ -0,0 +1,29 @@ +// +// SettingsNavigationStack.swift +// Moha +// +// Created by 변예린 on 8/21/26. +// + +import SwiftUI + +struct SettingsNavigationStack: View { + @Bindable var router: SettingsRouter + + var body: some View { + NavigationStack(path: $router.path) { + Text("Settings") //TODO: SettingsView로 수정 필요 + .navigationDestination(for: SettingsRoute.self) { route in + destinationView(for: route) + } + } + } + + @ViewBuilder + private func destinationView(for route: SettingsRoute) -> some View { + switch route { + case .createTodo: + Text("Create") + } + } +} diff --git a/Moha/Moha/Sources/Navigation/Route/HomeRoute.swift b/Moha/Moha/Sources/Navigation/Route/HomeRoute.swift new file mode 100644 index 0000000..9f642bf --- /dev/null +++ b/Moha/Moha/Sources/Navigation/Route/HomeRoute.swift @@ -0,0 +1,10 @@ +// +// HomeRoute.swift +// Moha +// +// Created by 변예린 on 8/20/26. +// + +enum HomeRoute: Route { + case createTodo +} diff --git a/Moha/Moha/Sources/Navigation/Route/ReportRoute.swift b/Moha/Moha/Sources/Navigation/Route/ReportRoute.swift new file mode 100644 index 0000000..2a1bad4 --- /dev/null +++ b/Moha/Moha/Sources/Navigation/Route/ReportRoute.swift @@ -0,0 +1,10 @@ +// +// ReportRoute.swift +// Moha +// +// Created by 변예린 on 8/20/26. +// + +enum ReportRoute: Route { + case createTodo +} diff --git a/Moha/Moha/Sources/Navigation/Route/Route.swift b/Moha/Moha/Sources/Navigation/Route/Route.swift new file mode 100644 index 0000000..16f976d --- /dev/null +++ b/Moha/Moha/Sources/Navigation/Route/Route.swift @@ -0,0 +1,8 @@ +// +// Route.swift +// Moha +// +// Created by 변예린 on 8/20/26. +// + +protocol Route: Hashable { } diff --git a/Moha/Moha/Sources/Navigation/Route/SettingsRoute.swift b/Moha/Moha/Sources/Navigation/Route/SettingsRoute.swift new file mode 100644 index 0000000..50eff2a --- /dev/null +++ b/Moha/Moha/Sources/Navigation/Route/SettingsRoute.swift @@ -0,0 +1,10 @@ +// +// SettingsRoute.swift +// Moha +// +// Created by 변예린 on 8/20/26. +// + +enum SettingsRoute: Route { + case createTodo +} diff --git a/Moha/Moha/Sources/Navigation/Router/MainRouter.swift b/Moha/Moha/Sources/Navigation/Router/MainRouter.swift new file mode 100644 index 0000000..086e799 --- /dev/null +++ b/Moha/Moha/Sources/Navigation/Router/MainRouter.swift @@ -0,0 +1,20 @@ +// +// MainRouter.swift +// Moha +// +// Created by 변예린 on 8/20/26. +// + +import SwiftUI +import Combine + +@Observable +final class MainRouter: ObservableObject { + var selectedTab = TabItem.home + + let homeRouter = HomeRouter() + let reportRouter = ReportRouter() + let settingsRouter = SettingsRouter() + + +} diff --git a/Moha/Moha/Sources/Navigation/Router/NavigationRouter.swift b/Moha/Moha/Sources/Navigation/Router/NavigationRouter.swift new file mode 100644 index 0000000..f015a00 --- /dev/null +++ b/Moha/Moha/Sources/Navigation/Router/NavigationRouter.swift @@ -0,0 +1,60 @@ +// +// Router.swift +// Moha +// +// Created by 변예린 on 8/20/26. +// + +import SwiftUI + +protocol NavigationRouter: AnyObject { + associatedtype Destination: Route + + var path: NavigationPath { get set } +} + +extension NavigationRouter { + func push(to route: Destination) { + path.append(route) + } + + func pop() { + guard !path.isEmpty else { return } + path.removeLast() + } + + func reset() { + path = NavigationPath() + } + + func popTo(count: Int) { + guard count > 0, count <= path.count else { return } + path.removeLast(count) + } + + func replace(with route: Destination) { + path = NavigationPath() + path.append(route) + } +} + +@Observable +final class HomeRouter: NavigationRouter { + typealias Destination = HomeRoute + + var path = NavigationPath() +} + +@Observable +final class ReportRouter: NavigationRouter { + typealias Destination = ReportRoute + + var path = NavigationPath() +} + +@Observable +final class SettingsRouter: NavigationRouter { + typealias Destination = SettingsRoute + + var path = NavigationPath() +} diff --git a/README.md b/README.md index 2e40300..62fdec9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,28 @@ -# Moha -To-do list with daily scrum +# 모하 (Moha) + +> 오늘 뭐 하지? 계획하고, 실행하고, 돌아보는 하루. + +**모하(Moha)** 는 Daily Scrum의 흐름을 개인의 하루에 적용한 iOS 앱입니다. + +단순히 할 일을 기록하는 것에서 끝나지 않고, +**계획 → 실행 → 회고**의 흐름을 통해 하루를 관리하고 돌아볼 수 있도록 만드는 것을 목표로 합니다. + +## 주요 기능 + +* 하루 계획 작성 및 관리 +* 계획별 진행 상태 기록 +* 하루 회고 +* 주간 / 월간 리포트 +* 리마인드 알림 + +## 기술 스택 + +| Category | Technology | +| --- | --- | +| UI | SwiftUI | +| Architecture | MVI + Router Pattern | +| Persistence | SwiftData | + +## Status + +🚧 현재 개발 중입니다.