// // HomeView.swift // AcaMate // // Created by TAnine on 2/11/25. // import SwiftUI struct HomeView: View { @StateObject private var topVM = TopViewModel() @State private var scrollOffset: CGPoint = .zero @State private var topViewState: Bool = false //MARK: - 변경 값 @State private var myType: UserType = .Student var body: some View { VStack(spacing: 0) { ZStack { OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in VStack(spacing: 0) { TopProfileView(userType: .Student) .padding(.bottom,12) Group { AttendanceBoxView() // CalendarBoxView(summaryCalDataList: []) CalendarBoxView(summaryCalDataList: [ SummaryCalendar(id: "123", date: "2025-02-28", summary: "요약내용입니다."), SummaryCalendar(id: "123", date: "2025-02-28", summary: "요약내용입니다.")]) // ManagementBoxView(managementList: []) ManagementBoxView(managementList: [ SummaryManagement(id: "01", title: "과목 명1", teacher: "A", ratio: 27, homework: 3), SummaryManagement(id: "02", title: "과목 명2", teacher: "B", ratio: 80, homework: 10), SummaryManagement(id: "03", title: "과목 명3", teacher: "C", ratio: 13, homework: 2), SummaryManagement(id: "04", title: "과목 명4", teacher: "D", ratio: 72, homework: 0), ]) // NoticeBoxView(noticeList: []) NoticeBoxView(noticeList: [ SummaryNotice(id: "00", title: "공지사항1", date: "2025-02-11", new: true), SummaryNotice(id: "01", title: "공지사항2", date: "2025-01-11", new: false), SummaryNotice(id: "02", title: "공지사항3", date: "2025-01-01", new: false) ]) DriveBoxView(summaryDriveList: [ SummaryDrive(id: "00", title: "강남행", driver: "A", time: "08:00", number: "1", isUsable: true, isAlarm: true, isDrive: false, isIn: true), SummaryDrive(id: "01", title: "강남행", driver: "A", time: "12:00", number: "2", isUsable: true, isAlarm: true, isDrive: true, isIn: true), SummaryDrive(id: "02", title: "강남행", driver: "A", time: "18:00", number: "3", isUsable: false, isAlarm: true, isDrive: false, isIn: true), SummaryDrive(id: "02", title: "강남행", driver: "A", time: "18:00", number: "3", isUsable: true, isAlarm: true, isDrive: false, isIn: false) ]) } .background { RoundedRectangle(cornerRadius: 8) .foregroundStyle(Color(.Other.cell)) } .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24)) } } if topViewState { VStack(spacing: 0) { TopView(topVM: topVM) .transition(.move(edge: .top)) .animation(.easeInOut, value: scrollOffset) Spacer(minLength: 1) } } } } .frame(maxWidth: .infinity, maxHeight: .infinity) .onAppear { topVM.titleName = "Name" if myType == .Student { topVM.setLeftBtn(Image(.Icon.face), size: CGPoint(x: 40, y: 40), action: leftAct) } else { topVM.setLeftBtn(text: "\(myType.rawValue)", font: .nps(font: .bold, size: 24), size: CGPoint(x: 40, y: 40), action: leftAct) } topVM.setRightBtn(Image(.Icon.notificationSET), size: CGPoint(x: 40, y: 40), action: rightAct) topVM.btnVM.setImage(for: topVM.rightBtnID, newImage: Image(.Icon.notificationSET)) } .onChange(of: scrollOffset.y) { oldValue, newValue in if newValue > 200 && topViewState == false { topViewState = true } else if newValue < 20 && topViewState == true{ topViewState = false } } } func leftAct() { printLog("왼쪽 버튼 클릭") } func rightAct() { printLog("오른쪽 버튼 클릭") } } struct EmptyBoxView: View { let title: String var body: some View { Text("\(title)") .font(.nps(size: 20)) .foregroundStyle(Color(.Text.detail)) .lineLimit(1) .minimumScaleFactor(0.5) .truncationMode(.tail) .frame(maxWidth: .infinity) .padding([.top,.bottom],12) .background { RoundedRectangle(cornerRadius: 4) .stroke(Color(.Second.normal), lineWidth: 2) .fill(Color(.Second.light)) } } }