[✨] 대시보드 학습관리 & 공지사항 뷰 생성, 메인화면 전환 로직 수정
This commit is contained in:
parent
ad85ccea7a
commit
f6a371923a
Binary file not shown.
|
@ -39,7 +39,9 @@ struct SimpleBtnView: View {
|
|||
if let image = state.image {
|
||||
image
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.frame(width: state.width, height: state.height)
|
||||
.foregroundStyle(state.isUsable ? Color(.Second.normal) : Color(.Normal.normal))
|
||||
}
|
||||
}
|
||||
.disabled(!state.isUsable)
|
|
@ -12,22 +12,23 @@ import Combine
|
|||
/// 이거 위에 다른 뷰들이 위젯 느낌으로 계속 갈아 끼워지는거
|
||||
struct NavigationView: View {
|
||||
@EnvironmentObject var appVM: AppViewModel
|
||||
|
||||
@State private var naviState : NaviState = .init(act: .NONE, path: .Intro)
|
||||
@State private var history: [PathName] = [.Intro]
|
||||
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
switch naviState.path {
|
||||
case .NONE:
|
||||
EmptyView()
|
||||
case .Intro:
|
||||
IntroView(naviState: $naviState)
|
||||
case .Login :
|
||||
LoginView(naviState: $naviState)
|
||||
case .Main:
|
||||
MainView(naviState: $naviState)
|
||||
VStack(spacing: 0) {
|
||||
|
||||
ZStack {
|
||||
switch naviState.path {
|
||||
case .NONE:
|
||||
EmptyView()
|
||||
case .Intro:
|
||||
IntroView(naviState: $naviState)
|
||||
case .Login :
|
||||
LoginView(naviState: $naviState)
|
||||
case .Main:
|
||||
MainView(naviState: $naviState, menuName: .Home)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: naviState) { old, new in
|
||||
|
@ -43,7 +44,6 @@ struct NavigationView: View {
|
|||
case .MOVE:
|
||||
moveHistory(path: new.path)
|
||||
}
|
||||
// LOG
|
||||
printLog("\(old.path) => \(new.path)")
|
||||
showHistory()
|
||||
}
|
||||
|
|
|
@ -37,9 +37,6 @@ struct OffsetObservableScrollView<Content: View>: View {
|
|||
Color.clear
|
||||
.frame(height: 1)
|
||||
.id("TOP")
|
||||
|
||||
// 실제 콘텐츠. content 클로저에서 scrollViewProxy를 전달받으므로,
|
||||
// 버튼 등을 통해 프로그래밍적으로 스크롤할 수 있음.
|
||||
content(scrollViewProxy)
|
||||
.overlay {
|
||||
GeometryReader { geometryProxy in
|
||||
|
@ -58,7 +55,7 @@ struct OffsetObservableScrollView<Content: View>: View {
|
|||
}
|
||||
.coordinateSpace(name: coordinateSpaceName)
|
||||
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
|
||||
printLog("\(scrollOffset) -> \(value)")
|
||||
// printLog("\(scrollOffset) -> \(value)")
|
||||
scrollOffset = value
|
||||
|
||||
}
|
||||
|
|
|
@ -12,10 +12,26 @@ struct CalendarBoxView: View {
|
|||
var body: some View {
|
||||
|
||||
DashBoardView(image: Image(.Icon.calendar), title: "최근 일정") {
|
||||
VStack(spacing: 12) {
|
||||
ForEach(Array(summaryCalDataList.enumerated()), id: \.offset) { index, data in
|
||||
CalCellView(summaryCalData: data)
|
||||
if !summaryCalDataList.isEmpty {
|
||||
VStack(spacing: 12) {
|
||||
ForEach(Array(summaryCalDataList.enumerated()), id: \.offset) { index, data in
|
||||
CalCellView(summaryCalData: data)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Text("최근 일정이 없습니다.")
|
||||
.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))
|
||||
}
|
||||
}
|
||||
|
||||
} moreAction: {
|
72
AcaMate/1. View/12. Main/121. Home/HomeView.swift
Normal file
72
AcaMate/1. View/12. Main/121. Home/HomeView.swift
Normal file
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// HomeView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/11/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct HomeView: View {
|
||||
@State private var scrollOffset: CGPoint = .zero
|
||||
@State private var topViewState: Bool = false
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
ZStack {
|
||||
OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in
|
||||
VStack(spacing: 0) {
|
||||
|
||||
TopProfileView(userType: .Student)
|
||||
// .padding(EdgeInsets(top: 0, leading: 0, bottom: 12, trailing: 0))s
|
||||
.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: [
|
||||
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)
|
||||
])
|
||||
}
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.foregroundStyle(Color(.Other.cell))
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if topViewState {
|
||||
VStack(spacing: 0) {
|
||||
TopView(titleName: "Name")
|
||||
.transition(.move(edge: .top))
|
||||
.animation(.easeInOut, value: scrollOffset)
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.onChange(of: scrollOffset.y) { oldValue, newValue in
|
||||
if newValue > 200 && topViewState == false {
|
||||
topViewState = true
|
||||
} else if newValue < 20 && topViewState == true{
|
||||
topViewState = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
173
AcaMate/1. View/12. Main/121. Home/ManagementBoxView.swift
Normal file
173
AcaMate/1. View/12. Main/121. Home/ManagementBoxView.swift
Normal file
|
@ -0,0 +1,173 @@
|
|||
//
|
||||
// ManagementBoxView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/10/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ManagementBoxView: View {
|
||||
@StateObject var btnVM = ButtonViewModel()
|
||||
@State private var leftBtnID = UUID()
|
||||
@State private var rightBtnID = UUID()
|
||||
@State var managementList: [SummaryManagement]
|
||||
@State private var countNum: Int = 0
|
||||
|
||||
var body: some View {
|
||||
DashBoardView(image: Image(.Icon.edu), title: "학습 관리") {
|
||||
if managementList.count >= 1 {
|
||||
HStack {
|
||||
SimpleBtnView(vm: btnVM, id: leftBtnID)
|
||||
Spacer(minLength: 1)
|
||||
SimpleBtnView(vm: btnVM, id: rightBtnID)
|
||||
}
|
||||
.padding([.bottom],12)
|
||||
|
||||
MangCellView(summaryMang: $managementList[countNum])
|
||||
} else {
|
||||
Text("학습하고 있는 강의가 없습니다.")
|
||||
.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))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} moreAction: {
|
||||
// MARK: TO-DO
|
||||
// 학습관리 전체 페이지 이동 로직 추가
|
||||
printLog("학습 관리의 더보기")
|
||||
}
|
||||
.onAppear {
|
||||
btnVM.setImage(for: leftBtnID, newImage: Image(.Icon.left))
|
||||
btnVM.setSize(for: leftBtnID, newWidth: 24, newHeight: 24)
|
||||
btnVM.setAction(for: leftBtnID) { countNum -= 1 }
|
||||
btnVM.setIsUsable(for: leftBtnID, newValue: false)
|
||||
|
||||
btnVM.setImage(for: rightBtnID, newImage: Image(.Icon.right))
|
||||
btnVM.setSize(for: rightBtnID, newWidth: 24, newHeight: 24)
|
||||
btnVM.setAction(for: rightBtnID) { countNum += 1 }
|
||||
if managementList.count == 0 {
|
||||
btnVM.setIsUsable(for: rightBtnID, newValue: false)
|
||||
}
|
||||
|
||||
}
|
||||
.onChange(of: countNum) { oldValue, newValue in
|
||||
if countNum == 0 {
|
||||
btnVM.setIsUsable(for: leftBtnID, newValue: false)
|
||||
|
||||
} else if 0 < countNum && countNum < managementList.count-1 {
|
||||
btnVM.setIsUsable(for: leftBtnID, newValue: true)
|
||||
btnVM.setIsUsable(for: rightBtnID, newValue: true)
|
||||
}
|
||||
else {
|
||||
btnVM.setIsUsable(for: rightBtnID, newValue: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MangCellView: View {
|
||||
@StateObject var btnVM = ButtonViewModel()
|
||||
@Binding var summaryMang: SummaryManagement
|
||||
@State var ratioBtn = UUID()
|
||||
@State var flagBtn = UUID()
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 8) {
|
||||
HStack(spacing: 12) {
|
||||
Image(.Icon.management)
|
||||
.resizable()
|
||||
.frame(width: 24, height: 24, alignment: .center)
|
||||
Text("\(summaryMang.title)")
|
||||
.font(.nps(size: 20))
|
||||
.foregroundStyle(Color(.Text.title))
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
HStack(spacing: 4) {
|
||||
Spacer(minLength: 1)
|
||||
Text("\(summaryMang.teacher)")
|
||||
.font(.nps(size: 12))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Text("선생님")
|
||||
.font(.nps(size: 12))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// 상단 내용은 여까지
|
||||
HStack(spacing: 6) {
|
||||
HStack(spacing: 10) {
|
||||
CircleBtnView(vm: btnVM, id: ratioBtn)
|
||||
VStack(spacing: 10) {
|
||||
HStack(spacing: 4) {
|
||||
Text("학습")
|
||||
.font(.nps(size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Text("진도")
|
||||
.font(.nps(font: .bold, size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
HStack(spacing: 4) {
|
||||
Spacer(minLength: 1)
|
||||
Text("\(summaryMang.ratio)")
|
||||
.font(.nps(font: .bold, size: 24))
|
||||
.foregroundStyle(summaryMang.ratio > 70 ? Color(.Other.blue):Color(.Other.red))
|
||||
Text("%")
|
||||
.font(.nps(font: .bold, size: 20))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
|
||||
}
|
||||
}
|
||||
VStack(spacing: 10) {
|
||||
HStack(spacing: 4) {
|
||||
Text("숙제")
|
||||
.font(.nps(font: .bold, size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Text("개수")
|
||||
.font(.nps(size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
HStack(spacing: 4) {
|
||||
Spacer(minLength: 1)
|
||||
Text("\(summaryMang.homework)")
|
||||
.font(.nps(font: .bold, size: 24))
|
||||
.foregroundStyle(Color(.Second.normal))
|
||||
Text("개")
|
||||
.font(.nps(font: .bold, size: 20))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
.padding(12)
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 4)
|
||||
.stroke(Color(.Second.normal), lineWidth: 2)
|
||||
.fill(Color(.Second.light))
|
||||
}
|
||||
.onTapGesture {
|
||||
// MARK: TO-DO
|
||||
// 해당 과목의 학습관리 페이지 이동 로직 추가
|
||||
printLog(summaryMang)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
58
AcaMate/1. View/12. Main/121. Home/NoticeBoxView.swift
Normal file
58
AcaMate/1. View/12. Main/121. Home/NoticeBoxView.swift
Normal file
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// NoticeBoxView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/11/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct NoticeBoxView: View {
|
||||
@State var noticeList: [SummaryNotice]
|
||||
|
||||
var body: some View {
|
||||
DashBoardView(image: Image(.Icon.notice), title: "공지사항") {
|
||||
ForEach(Array(noticeList.enumerated()), id: \.offset) { index, notice in
|
||||
|
||||
if index < 3 {
|
||||
NotiCellView(summaryNoti: notice)
|
||||
}
|
||||
}
|
||||
|
||||
// 값없을때도 없다는거 보여주는 창 띄우기
|
||||
|
||||
} moreAction: {
|
||||
// MARK: TO-DO
|
||||
// 공지사항 전체 페이지 이동 로직 추가
|
||||
printLog("공지사항의 더보기")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NotiCellView: View {
|
||||
var summaryNoti: SummaryNotice
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 8) {
|
||||
HStack(spacing: 12) {
|
||||
Image(summaryNoti.new ? .Icon.noticeNew : .Icon.noticeOld)
|
||||
.resizable()
|
||||
.frame(width: 24, height: 24, alignment: .center)
|
||||
Text("\(summaryNoti.title)")
|
||||
.font(.nps(size: 20))
|
||||
.foregroundStyle(Color(.Text.title))
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
HStack(spacing: 4) {
|
||||
Spacer(minLength: 1)
|
||||
Text("날짜 :")
|
||||
.font(.nps(size: 12))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Text("\(summaryNoti.date)")
|
||||
.font(.nps(size: 12))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import SwiftUI
|
|||
struct TopProfileView: View {
|
||||
@StateObject var btnVM = ButtonViewModel()
|
||||
|
||||
var userType: UserType = .Parent
|
||||
var userType: UserType
|
||||
|
||||
// MARK: TO-DO
|
||||
// 여기서 이름 떙겨오는것도 고민을 해야 함
|
||||
|
@ -81,6 +81,8 @@ struct TopProfileView: View {
|
|||
}
|
||||
}
|
||||
.fullDrawView(.Other.cell)
|
||||
|
||||
|
||||
.onAppear {
|
||||
let topBtnIDList = [shopID,notifyID]
|
||||
let iconList = [Image(.Icon.market), Image(.Icon.notificationSET)]
|
||||
|
@ -132,6 +134,3 @@ struct TopProfileView: View {
|
|||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
TopProfileView()
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
//
|
||||
// ManagementBoxView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/10/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ManagementBoxView: View {
|
||||
@StateObject var btnVM = ButtonViewModel()
|
||||
@State private var leftBtnID = UUID()
|
||||
@State private var rightBtnID = UUID()
|
||||
|
||||
var body: some View {
|
||||
DashBoardView(image: Image(.Icon.edu), title: "학습 관리") {
|
||||
|
||||
} moreAction: {
|
||||
printLog("학습 관리의 더보기")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MangCellView: View {
|
||||
@StateObject var btnVM = ButtonViewModel()
|
||||
let summaryMang: SummaryManagement
|
||||
@State var ratioBtn = UUID()
|
||||
@State var flagBtn = UUID()
|
||||
var body: some View {
|
||||
VStack(spacing: 8) {
|
||||
HStack(spacing: 12) {
|
||||
Image(.Icon.management)
|
||||
.resizable()
|
||||
.frame(width: 24, height: 24, alignment: .center)
|
||||
Text("\(summaryMang.title)")
|
||||
.font(.nps(size: 20))
|
||||
.foregroundStyle(Color(.Text.title))
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
HStack(spacing: 4) {
|
||||
Spacer(minLength: 1)
|
||||
Text("\(summaryMang.teacher)")
|
||||
.font(.nps(size: 12))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Text("이름")
|
||||
.font(.nps(size: 12))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// 상단 내용은 여까지
|
||||
HStack(spacing: 6) {
|
||||
HStack(spacing: 10) {
|
||||
CircleBtnView(vm: btnVM, id: ratioBtn)
|
||||
VStack(spacing: 10) {
|
||||
HStack(spacing: 4) {
|
||||
Text("학습")
|
||||
.font(.nps(size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Text("진도")
|
||||
.font(.nps(font: .bold, size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
HStack(spacing: 4) {
|
||||
Spacer(minLength: 1)
|
||||
Text("\(summaryMang.ratio)")
|
||||
.font(.nps(font: .bold, size: 24))
|
||||
.foregroundStyle(summaryMang.ratio > 70 ? Color(.Other.blue):Color(.Other.red))
|
||||
Text("%")
|
||||
.font(.nps(font: .bold, size: 20))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// ManagementView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/11/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ManagementView: View {
|
||||
var body: some View {
|
||||
Text("학습 관리")
|
||||
}
|
||||
}
|
14
AcaMate/1. View/12. Main/123. Chatting/ChattingView.swift
Normal file
14
AcaMate/1. View/12. Main/123. Chatting/ChattingView.swift
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// ChattingView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/11/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ChattingView: View {
|
||||
var body: some View {
|
||||
Text("채팅")
|
||||
}
|
||||
}
|
14
AcaMate/1. View/12. Main/124. Calendar/CalendarView.swift
Normal file
14
AcaMate/1. View/12. Main/124. Calendar/CalendarView.swift
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// CalendarView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/11/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct CalendarView: View {
|
||||
var body: some View {
|
||||
Text("일정")
|
||||
}
|
||||
}
|
15
AcaMate/1. View/12. Main/125. Etc/EtcView.swift
Normal file
15
AcaMate/1. View/12. Main/125. Etc/EtcView.swift
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// EtcView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/11/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct EtcView: View {
|
||||
var body: some View {
|
||||
Text("더보기")
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ struct BottomView: View {
|
|||
@State private var calendarID = UUID()
|
||||
@State private var etcID = UUID()
|
||||
|
||||
@Binding var menuName: MenuName
|
||||
var body: some View {
|
||||
let idList: [UUID] = [homeID,managementID,chattingID,calendarID,etcID]
|
||||
|
||||
|
@ -39,13 +40,14 @@ struct BottomView: View {
|
|||
.frame(maxWidth: .infinity)
|
||||
.onAppear {
|
||||
let idList: [UUID] = [homeID,managementID,chattingID,calendarID,etcID]
|
||||
let btnText: [String] = ["홈", "학습 관리", "채팅", "일정", "더보기"]
|
||||
//["홈", "학습 관리", "채팅", "일정", "더보기"]
|
||||
let btnType: [MenuName] = [.Home, .Management, .Chatting, .Calendar, .Etc]
|
||||
let btnImage: [Image] = [Image(.Icon.home),Image(.Icon.management),Image(.Icon.chatting),Image(.Icon.calendar),Image(.Icon.etc)]
|
||||
|
||||
idList.enumerated().forEach { (index, id) in
|
||||
btnVM.btnStates[id] = ButtonState()
|
||||
btnVM.setSize(for: id, newWidth: 52, newHeight: 52)
|
||||
btnVM.setText(for: id, newText: btnText[index],
|
||||
btnVM.setText(for: id, newText: btnType[index].rawValue,
|
||||
newFont: .nps(font: .bold, size: 6))
|
||||
btnVM.setImage(for: id, newImage: btnImage[index])
|
||||
|
||||
|
@ -56,6 +58,7 @@ struct BottomView: View {
|
|||
btnVM.setIsSelected(for: $0, newValue: false)
|
||||
}
|
||||
}
|
||||
menuName = btnType[index]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,69 +13,44 @@ struct MainView: View {
|
|||
@State var cancellables: Set<AnyCancellable> = []
|
||||
@Binding var naviState : NaviState
|
||||
|
||||
@State private var scrollOffset: CGPoint = .zero
|
||||
@State private var topViewState: Bool = false
|
||||
@State var menuName: MenuName
|
||||
|
||||
// @State private var scrollOffset: CGPoint = .zero
|
||||
// @State private var topViewState: Bool = false
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack(spacing: 0) {
|
||||
ZStack {
|
||||
OffsetObservableScrollView(scrollOffset: $scrollOffset) { proxy in
|
||||
VStack(spacing: 0) {
|
||||
TopProfileView()
|
||||
.padding(EdgeInsets(top: 0, leading: 0, bottom: 12, trailing: 0))
|
||||
AttendanceBoxView()
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.foregroundStyle(Color(.Other.cell))
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
AttendanceBoxView()
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.foregroundStyle(Color(.Other.cell))
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
AttendanceBoxView()
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.foregroundStyle(Color(.Other.cell))
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
CalendarBoxView(summaryCalDataList: [
|
||||
SummaryCalendar(id: "123", date: "2025-02-28", summary: "요약내용입니다."),
|
||||
SummaryCalendar(id: "123", date: "2025-02-28", summary: "요약내용입니다.")])
|
||||
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.foregroundStyle(Color(.Other.cell))
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
}
|
||||
}
|
||||
|
||||
if topViewState {
|
||||
VStack(spacing: 0) {
|
||||
TopView(titleName: "Name")
|
||||
.transition(.move(edge: .top))
|
||||
.animation(.easeInOut, value: scrollOffset)
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
|
||||
|
||||
|
||||
Group {
|
||||
switch menuName {
|
||||
case .Home:
|
||||
HomeView()
|
||||
case .Management:
|
||||
ManagementView()
|
||||
case .Chatting:
|
||||
ChattingView()
|
||||
case .Calendar:
|
||||
CalendarView()
|
||||
case .Etc:
|
||||
EtcView()
|
||||
}
|
||||
}
|
||||
BottomView()
|
||||
Spacer(minLength: 1)
|
||||
|
||||
BottomView(menuName: $menuName)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.onChange(of: scrollOffset.y) { oldValue, newValue in
|
||||
if newValue > 200 && topViewState == false {
|
||||
topViewState = true
|
||||
} else if newValue < 20 && topViewState == true{
|
||||
topViewState = false
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// .onChange(of: scrollOffset.y) { oldValue, newValue in
|
||||
// if newValue > 200 && topViewState == false {
|
||||
// topViewState = true
|
||||
// } else if newValue < 20 && topViewState == true{
|
||||
// topViewState = false
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ struct ButtonState {
|
|||
var textColor: Color = .Text.detail
|
||||
var isUsable: Bool = true
|
||||
|
||||
|
||||
|
||||
// -- CircleBtn 전용 -- //
|
||||
|
||||
var isSelected: Bool = false
|
||||
|
|
|
@ -13,6 +13,8 @@ struct NaviState: Equatable {
|
|||
var act: NaviAction
|
||||
var path: PathName
|
||||
|
||||
|
||||
|
||||
static func == (lhs: NaviState, rhs: NaviState) -> Bool {
|
||||
return lhs.act == rhs.act && lhs.path == rhs.path
|
||||
}
|
||||
|
@ -21,6 +23,7 @@ struct NaviState: Equatable {
|
|||
self.act = act
|
||||
self.path = path
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum NaviAction: Hashable {
|
||||
|
@ -45,3 +48,11 @@ enum PathName: Hashable {
|
|||
|
||||
case NONE
|
||||
}
|
||||
|
||||
enum MenuName: String, Hashable {
|
||||
case Home = "홈"
|
||||
case Management = "학습 관리"
|
||||
case Chatting = "채팅"
|
||||
case Calendar = "일정"
|
||||
case Etc = "더보기"
|
||||
}
|
||||
|
|
15
AcaMate/2. Model/Notice Data.swift
Normal file
15
AcaMate/2. Model/Notice Data.swift
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Notice Data.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/11/25.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SummaryNotice {
|
||||
var id: String
|
||||
var title: String
|
||||
var date: String
|
||||
var new: Bool
|
||||
}
|
|
@ -10,7 +10,6 @@ import Combine
|
|||
|
||||
class AppViewModel: ObservableObject {
|
||||
@Published var isLoading: Bool = false
|
||||
|
||||
@Published var showAlert: Bool = false
|
||||
|
||||
var alertData: AlertData = .init(body: "")
|
||||
|
|
|
@ -60,6 +60,13 @@ class ButtonViewModel: ObservableObject {
|
|||
btnStates[id] = state
|
||||
objectWillChange.send()
|
||||
}
|
||||
//
|
||||
// func setDisable(for id: UUID, _ newValue: Bool) {
|
||||
// var state = btnStates[id] ?? ButtonState()
|
||||
// state.isUsable = newValue
|
||||
// btnStates[id] = state
|
||||
// objectWillChange.send()
|
||||
// }
|
||||
|
||||
// -- CircleBtn 전용 -- //
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user