Skip to content

Commit

Permalink
Merge pull request #55 from YAPP-Github/TNT-208-mainTab
Browse files Browse the repository at this point in the history
[TNT-208] νŠΈλ ˆμ΄λ„ˆ/νŠΈλ ˆμ΄λ‹ˆ 메인 νƒ­ μž‘μ„±
  • Loading branch information
FpRaArNkK authored Feb 5, 2025
2 parents 725b3b4 + 6a65372 commit af7ea5e
Show file tree
Hide file tree
Showing 24 changed files with 640 additions and 292 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "icn_feedback.svg",
"filename" : "icn_feedback_empty.svg",
"idiom" : "universal"
}
],
Expand Down

This file was deleted.

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
@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "icn_home.svg",
"filename" : "icn_home_empty.svg",
"idiom" : "universal"
}
],
Expand Down
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
@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "icn_list.svg",
"filename" : "icn_list_empty.svg",
"idiom" : "universal"
}
],
Expand Down

This file was deleted.

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
@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "icn_mypage.svg",
"filename" : "icn_mypage_empty.svg",
"idiom" : "universal"
}
],
Expand Down

This file was deleted.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions TnT/Projects/DesignSystem/Sources/Button/TMainTabButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// TMainTabButton.swift
// DesignSystem
//
// Created by λ°•λ―Όμ„œ on 2/5/25.
// Copyright Β© 2025 yapp25thTeamTnT. All rights reserved.
//

import SwiftUI

/// TnT μ•± λ‚΄μ—μ„œ λ°”ν…€ 탭에 μ‚¬μš©λ˜λŠ” λ²„νŠΌ μ»΄ν¬λ„ŒνŠΈ μž…λ‹ˆλ‹€
public struct TMainTabButton: View {
let unselectedIcon: ImageResource
let selectedIcon: ImageResource
let text: String
let isSelected: Bool
let action: () -> Void

public init(
unselectedIcon: ImageResource,
selectedIcon: ImageResource,
text: String,
isSelected: Bool,
action: @escaping () -> Void
) {
self.unselectedIcon = unselectedIcon
self.selectedIcon = selectedIcon
self.text = text
self.isSelected = isSelected
self.action = action
}

public var body: some View {
Button(action: action) {
VStack(spacing: 4) {
Image(isSelected ? selectedIcon : unselectedIcon)
.resizable()
.frame(width: 24, height: 24)
Text(text)
.typographyStyle(
isSelected ? .label2Bold : .label1Medium,
with: isSelected ? .neutral900 : .neutral400
)
}
}
.padding(.vertical, 8)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ public struct TraineeHomeFeature {

@Dependency(\.traineeUseCase) private var traineeUseCase: TraineeUseCase

public enum Action: Sendable, ViewAction {
public enum Action: Equatable, Sendable, ViewAction {
/// λ·°μ—μ„œ λ°œμƒν•œ μ•‘μ…˜μ„ μ²˜λ¦¬ν•©λ‹ˆλ‹€.
case view(View)
/// λ„€λΉ„κ²Œμ΄μ…˜ μ—¬λΆ€ μ„€μ •
case setNavigating
case setNavigating(RoutingScreen)

@CasePathable
public enum View: Sendable, BindableAction {
public enum View: Equatable, Sendable, BindableAction {
/// 바인딩할 μ•‘μ…˜μ„ 처리
case binding(BindingAction<State>)
/// 우츑 상단 μ•Œλ¦Ό νŽ˜μ΄μ§€ 보기 λ²„νŠΌ νƒ­
Expand Down Expand Up @@ -96,14 +96,11 @@ public struct TraineeHomeFeature {
case .view(let action):
switch action {
case .binding(\.selectedDate):
print(state.events[state.selectedDate])
return .none
case .binding:
return .none
case .tapAlarmPageButton:
// TODO: λ„€λΉ„κ²Œμ΄μ…˜ μ—°κ²° μ‹œ μΆ”κ°€
print("tapAlarmPageButton")
return .none
return .send(.setNavigating(.alarmPage))
case .tapShowSessionRecordButton(let id):
// TODO: λ„€λΉ„κ²Œμ΄μ…˜ μ—°κ²° μ‹œ μΆ”κ°€
print("tapShowSessionRecordButton \(id)")
Expand All @@ -130,3 +127,18 @@ public struct TraineeHomeFeature {
}
}
}

extension TraineeHomeFeature {
public enum RoutingScreen: Sendable {
/// μ•Œλ¦Ό νŽ˜μ΄μ§€
case alarmPage
/// μˆ˜μ—… 기둝 상세 νŽ˜μ΄μ§€
case sessionRecordPage
/// 기둝 ν”Όλ“œλ°± νŽ˜μ΄μ§€
case recordFeedbackPage
/// μš΄λ™ 기둝 μΆ”κ°€ νŽ˜μ΄μ§€
case addWorkoutRecordPage
/// 식단 기둝 μΆ”κ°€ νŽ˜μ΄μ§€
case addMealRecordPage
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
import SwiftUI
import DesignSystem

public enum TrainerTabInfo: String, CaseIterable {
public enum TrainerTabInfo: String, CaseIterable, Equatable, Sendable {
case home = "ν™ˆ"
case feedback = "ν”Όλ“œλ°±"
case traineeList = "νšŒμ›λͺ©λ‘"
case mypage = "λ§ˆμ΄νŽ˜μ΄μ§€"
case mypage = "λ‚΄ 정보"

var filledIcn: ImageResource {
public var filledIcn: ImageResource {
switch self {
case .home:
return .icnHomeFilled
Expand All @@ -28,7 +28,7 @@ public enum TrainerTabInfo: String, CaseIterable {
}
}

var emptyIcn: ImageResource {
public var emptyIcn: ImageResource {
switch self {
case .home:
return .icnHomeEmpty
Expand All @@ -42,9 +42,9 @@ public enum TrainerTabInfo: String, CaseIterable {
}
}

public enum TraineeTabInfo: String, CaseIterable {
public enum TraineeTabInfo: String, CaseIterable, Equatable, Sendable {
case home = "ν™ˆ"
case mypage = "λ§ˆμ΄νŽ˜μ΄μ§€"
case mypage = "λ‚΄ 정보"

var filledIcn: ImageResource {
switch self {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//
// TraineeMainTabNavigationFeature.swift
// Presentation
//
// Created by λ°•λ―Όμ„œ on 2/4/25.
// Copyright Β© 2025 yapp25thTeamTnT. All rights reserved.
//

import SwiftUI
import ComposableArchitecture

@Reducer
public struct TraineeMainTabFeature {
@ObservableState
public enum State: Equatable {
case home(TraineeHomeFeature.State)
case myPage(TraineeMyPageFeature.State)

/// state case와 tabinfo μ—°κ²°
var tabInfo: TraineeTabInfo {
switch self {
case .home:
return .home
case .myPage:
return .mypage
}
}

public init() {
self = .home(TraineeHomeFeature.State())
}
}

public enum Action: Sendable, ViewAction {
/// λ·°μ—μ„œ μΌμ–΄λ‚˜λŠ” μ•‘μ…˜μ„ μ²˜λ¦¬ν•©λ‹ˆλ‹€.
case view(View)
/// ν•˜μœ„ ν™”λ©΄μ—μ„œ μΌμ–΄λ‚˜λŠ” μ•‘μ…˜μ„ μ²˜λ¦¬ν•©λ‹ˆλ‹€
case subFeature(SubFeatureAction)
/// ν™”λ©΄ λ„€λΉ„κ²Œμ΄μ…˜ μ„€μ •
case setNavigating(RoutingScreen)

@CasePathable
public enum View: Sendable {
/// νƒ­λ°” 선택
case selectTab(TraineeTabInfo)
}

@CasePathable
public enum SubFeatureAction: Sendable {
/// ν™ˆ ν™”λ©΄μ—μ„œ λ°œμƒν•˜λŠ” μ•‘μ…˜ 처리
case homeAction(TraineeHomeFeature.Action)
/// λ§ˆμ΄νŽ˜μ΄μ§€ ν™”λ©΄μ—μ„œ λ°œμƒν•˜λŠ” μ•‘μ…˜ 처리
case myPageAction(TraineeMyPageFeature.Action)
}
}

public init() {}

public var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case let .view(view):
switch view {
case .selectTab(let tab):
switch tab {
case .home:
state = .home(.init())
return .none
case .mypage:
state = .myPage(.init())
return .none
}
}

case .subFeature(let internalAction):
switch internalAction {
case .homeAction(.setNavigating(let screen)):
return .send(.setNavigating(.traineeHome(screen)))
case .myPageAction(.setNavigating(let screen)):
return .send(.setNavigating(.traineeMyPage(screen)))
default:
return .none
}

case .setNavigating:
return .none
}
}
.ifCaseLet(\.home, action: \.subFeature.homeAction) {
TraineeHomeFeature()
}
.ifCaseLet(\.myPage, action: \.subFeature.myPageAction) {
TraineeMyPageFeature()
}
}
}

extension TraineeMainTabFeature {
/// ν•˜μœ„ ν™”λ©΄μ—μ„œ νŒŒμƒλ˜λŠ” λΌμš°νŒ…μ„ μ „λ‹¬ν•©λ‹ˆλ‹€
public enum RoutingScreen: Sendable {
/// νŠΈλ ˆμ΄λ‹ˆ ν™ˆ
case traineeHome(TraineeHomeFeature.RoutingScreen)
/// νŠΈλ ˆμ΄λ‹ˆ λ§ˆμ΄νŽ˜μ΄μ§€
case traineeMyPage(TraineeMyPageFeature.RoutingScreen)
}
}
Loading

0 comments on commit af7ea5e

Please sign in to comment.