Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TNT-214] TrainerAddPTSession 관련 신규 디자인 컴포넌트 추가 #59

Merged
merged 4 commits into from
Feb 7, 2025
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 @@ -26,10 +26,10 @@ struct AutoSizingBottomSheetModifier: ViewModifier {
GeometryReader { proxy in
Color.clear
.onAppear {
contentHeight = proxy.size.height + 50
contentHeight = proxy.size.height + 10
}
.onChange(of: proxy.size.height) { _, newHeight in
contentHeight = newHeight + 50
contentHeight = newHeight + 10
}
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import FSCalendar
final class TCalendarCell: FSCalendarCell {
// MARK: Properties
static let identifier: String = "TCalendarCell"
static let cellSize: CGSize = CGSize(width: 51, height: 54)

/// Cell에 표시되는 날짜
private var customDate: Date?
Expand All @@ -22,8 +21,8 @@ final class TCalendarCell: FSCalendarCell {
private var style: Style = .default
/// Cell에 표시되는 일정 카운트
private var eventCount: Int = 0
/// 주간/월간 모드인지 표시
private var isWeekMode: Bool = false
/// 주간/월간/컴팩트 모드인지 표시
private var mode: TCalendarType = .month

// MARK: UI Elements
private let dayLabel: UILabel = UILabel()
Expand Down Expand Up @@ -100,10 +99,14 @@ final class TCalendarCell: FSCalendarCell {

/// 일정 카운트 표시 업데이트
private func updateEventDisplay() {
guard mode != .compactMonth else {
eventStackView.isHidden = true
return
}
eventCountLabel.text = "\(eventCount)"
let eventExists: Bool = eventCount > 0
eventStackView.isHidden = !eventExists
let presentCount: Bool = !isWeekMode && eventExists
let presentCount: Bool = mode == .month && eventExists
eventCountLabel.isHidden = !presentCount
}

Expand All @@ -112,7 +115,7 @@ final class TCalendarCell: FSCalendarCell {
// 날짜 및 선택 상태 초기화
customDate = nil
isCellSelected = false
isWeekMode = false
mode = .month

// 일정 관련 초기화
eventCount = 0
Expand All @@ -132,12 +135,12 @@ extension TCalendarCell {
with date: Date,
isCellSelected: Bool,
eventCount: Int = 0,
isWeekMode: Bool = false
mode: TCalendarType = .month
) {
self.customDate = date
self.isCellSelected = isCellSelected
self.eventCount = eventCount
self.isWeekMode = isWeekMode
self.mode = mode

// 현재 날짜 및 선택 상태를 반영, Style 설정
if isCellSelected {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ public struct TCalendarRepresentable: UIViewRepresentable {
@Binding private var currentPage: Date
/// 캘린더 높이
@Binding var calendarHeight: CGFloat
/// 주간/월간 표시 여부
private var isWeekMode: Bool
/// 주간/월간/컴팩트 모드인지 표시
private var mode: TCalendarType = .month
/// 캘린더 표시 이벤트 딕셔너리
private var events: [Date: Int]

public init(
selectedDate: Binding<Date>,
currentPage: Binding<Date>,
calendarHeight: Binding<CGFloat>,
isWeekMode: Bool = false,
mode: TCalendarType = .month,
events: [Date: Int] = [:]
) {
self._selectedDate = selectedDate
self._currentPage = currentPage
self._calendarHeight = calendarHeight
self.isWeekMode = isWeekMode
self.mode = mode
self.events = events
}

Expand All @@ -44,7 +44,7 @@ public struct TCalendarRepresentable: UIViewRepresentable {

// Cell 설정
calendar.register(TCalendarCell.self, forCellReuseIdentifier: TCalendarCell.identifier)
calendar.collectionView.contentSize = TCalendarCell.cellSize
calendar.collectionView.contentSize = mode.cellSize

// 기본 설정
calendar.delegate = context.coordinator
Expand All @@ -55,7 +55,7 @@ public struct TCalendarRepresentable: UIViewRepresentable {
calendar.placeholderType = .none
calendar.headerHeight = 0
calendar.weekdayHeight = 18
calendar.rowHeight = TCalendarCell.cellSize.height
calendar.rowHeight = mode.cellSize.height
calendar.appearance.weekdayTextColor = UIColor(.neutral400)
calendar.appearance.weekdayFont = Typography.FontStyle.label2Medium.uiFont
calendar.appearance.selectionColor = .clear
Expand All @@ -77,7 +77,7 @@ public struct TCalendarRepresentable: UIViewRepresentable {
}

// `isWeekMode` 반영
let targetScope: FSCalendarScope = isWeekMode ? .week : .month
let targetScope: FSCalendarScope = mode.scope
if uiView.scope != targetScope {
uiView.scope = targetScope
}
Expand Down Expand Up @@ -137,7 +137,7 @@ public extension TCalendarRepresentable {
with: date,
isCellSelected: isSelected,
eventCount: eventCount,
isWeekMode: parent.isWeekMode
mode: parent.mode
)

return cell
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// TCalendarType.swift
// DesignSystem
//
// Created by 박민서 on 2/6/25.
// Copyright © 2025 yapp25thTeamTnT. All rights reserved.
//

import FSCalendar

/// TCalendar에 사용되는 캘린더 타입입니다
public enum TCalendarType {
/// 주간 캘린더 - 일정 표시
case week
/// 월간 캘린더 - 일정 표시
case month
/// 월간 캘린더 - 날짜와 선택 표시만
case compactMonth

var scope: FSCalendarScope {
switch self {
case .week:
return .week
case .month, .compactMonth:
return .month
}
}

var calendarHeight: CGFloat {
switch self {
case .week:
return 80
case .month:
return 340
case .compactMonth:
return 320
}
}

var cellSize: CGSize {
switch self {
case .week, .month:
return CGSize(width: 51, height: 54)
case .compactMonth:
return CGSize(width: 51, height: 40)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,32 @@ import SwiftUI
/// 앱 전반적으로 사용되는 캘린더입니다.
/// 주간/월간 표시를 포함합니다.
public struct TCalendarView: View {

/// 주간 캘린더 높이
static let weeklyCalendarHeight: CGFloat = 80
/// 월간 캘린더 높이
static let monthlyCalendarHeight: CGFloat = 340

/// 선택한 날짜
@Binding var selectedDate: Date
/// 현재 페이지
@Binding var currentPage: Date
/// 업데이트 플래그
@State private var forceUpdate: UUID = UUID()
/// 캘린더 높이
@State private var calendarHeight: CGFloat = monthlyCalendarHeight
/// 주간/월간 표시 여부
private var isWeekMode: Bool
@State private var calendarHeight: CGFloat = TCalendarType.month.calendarHeight
/// 주간/월간/컴팩트 모드인지 표시
private var mode: TCalendarType = .month
/// 캘린더 표시 이벤트 딕셔너리
private var events: [Date: Int]

public init(
selectedDate: Binding<Date>,
currentPage: Binding<Date>,
forceUpdate: UUID = UUID(),
events: [Date: Int],
isWeekMode: Bool = false
events: [Date: Int] = [:],
mode: TCalendarType = .month
) {
self._selectedDate = selectedDate
self._currentPage = currentPage
self.events = events
self.forceUpdate = forceUpdate
self.isWeekMode = isWeekMode
self.mode = mode
}

public var body: some View {
Expand All @@ -49,23 +45,19 @@ public struct TCalendarView: View {
selectedDate: $selectedDate,
currentPage: $currentPage,
calendarHeight: $calendarHeight,
isWeekMode: isWeekMode,
mode: mode,
events: events
)
.frame(width: proxy.size.width, height: TCalendarView.monthlyCalendarHeight)
.frame(width: proxy.size.width, height: TCalendarType.month.calendarHeight)
.id(forceUpdate)
.onChange(of: events) {
forceUpdate = UUID()
}
.onAppear {
calendarHeight = isWeekMode
? TCalendarView.weeklyCalendarHeight
: TCalendarView.monthlyCalendarHeight
calendarHeight = mode.calendarHeight
}
.onChange(of: isWeekMode) {
calendarHeight = isWeekMode
? TCalendarView.weeklyCalendarHeight
: TCalendarView.monthlyCalendarHeight
.onChange(of: mode) {
calendarHeight = mode.calendarHeight
}
}
.frame(height: calendarHeight)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ public struct TDatePickerView: View {
private let title: String
/// 버튼 실행 action
private let buttonAction: (Date) -> Void
/// 헤더 formatter
private let monthFormatter: (Date) -> String
/// 선택 날짜
@State private var selectedDate: Date = .now
/// 표시 날짜
@State private var currentDate: Date = .now

@Environment(\.dismiss) var dismiss

/// `TDatePickerView` 생성자
/// - Parameters:
Expand All @@ -26,33 +32,55 @@ public struct TDatePickerView: View {
public init(
selectedDate: Date = .now,
title: String,
monthFormatter: @escaping (Date) -> String,
buttonAction: @escaping (Date) -> Void
) {
self.selectedDate = selectedDate
self.title = title
self.monthFormatter = monthFormatter
self.buttonAction = buttonAction
}

public var body: some View {
VStack {
DatePicker(
title,
selection: $selectedDate,
displayedComponents: [.date]
VStack(spacing: 12) {
HStack {
Text(title)
.typographyStyle(.heading3, with: .neutral900)
Spacer()
Button(action: {
dismiss()
}, label: {
Image(.icnDelete)
.renderingMode(.template)
.resizable()
.tint(.neutral400)
.frame(width: 32, height: 32)
})
}
.padding(20)

TCalendarHeader<EmptyView>(
currentPage: $currentDate,
formatter: monthFormatter
)
.padding(.top, 20)

TCalendarView(
selectedDate: $selectedDate,
currentPage: $currentDate,
mode: .compactMonth
)
.tint(Color.red500)
.datePickerStyle(.graphical)
.labelsHidden()
.padding()
.padding(.horizontal, 16)

TBottomButton(
title: "완료",
isEnable: true,
TButton(
title: "확인",
config: .large,
state: .default(.primary(isEnabled: true)),
action: {
buttonAction(selectedDate)
}
)
.ignoresSafeArea(.all, edges: .bottom)
.padding(20)
}
}
}
Loading