diff --git a/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate b/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate index a7df021..3954990 100644 Binary files a/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate and b/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AcaMate/1. View/10. Common/101. Button/BoxBtnView.swift b/AcaMate/1. View/10. Common/101. Button/BoxBtnView.swift index 10747fb..0b3d917 100644 --- a/AcaMate/1. View/10. Common/101. Button/BoxBtnView.swift +++ b/AcaMate/1. View/10. Common/101. Button/BoxBtnView.swift @@ -20,11 +20,6 @@ struct BoxBtnView: View { action() } label: { content -// if let image = image { -// image -// .resizable() -// .frame(width: width, height: height) -// } } } } diff --git a/AcaMate/1. View/10. Common/101. Button/CircleBtnView.swift b/AcaMate/1. View/10. Common/101. Button/CircleBtnView.swift index 820ada9..a679888 100644 --- a/AcaMate/1. View/10. Common/101. Button/CircleBtnView.swift +++ b/AcaMate/1. View/10. Common/101. Button/CircleBtnView.swift @@ -38,10 +38,8 @@ struct CircleBtnView: View { if let title = state.text, let font = state.font { Text("\(title)") .font(font) - .lineLimit(1) - .minimumScaleFactor(0.5) - .truncationMode(.tail) .foregroundStyle(state.foreColor) + .multilineStyle() } } } diff --git a/AcaMate/1. View/10. Common/101. Button/SimpleBtnView.swift b/AcaMate/1. View/10. Common/101. Button/SimpleBtnView.swift index 97aa65b..4a155e3 100644 --- a/AcaMate/1. View/10. Common/101. Button/SimpleBtnView.swift +++ b/AcaMate/1. View/10. Common/101. Button/SimpleBtnView.swift @@ -18,10 +18,7 @@ struct SimpleBtnView: View { if let title = state.text, let font = state.font { Text("\(title)") .font(font) - .lineLimit(1) - .minimumScaleFactor(0.5) - .multilineTextAlignment(.center) - .truncationMode(.tail) + .multilineStyle(.center) .foregroundStyle(state.textColor) .frame(width: state.width, height: state.height) .onTapGesture { diff --git a/AcaMate/1. View/12. Main/121. Home/AttendanceBoxView.swift b/AcaMate/1. View/12. Main/121. Home/AttendanceBoxView.swift index 12590be..058f01f 100644 --- a/AcaMate/1. View/12. Main/121. Home/AttendanceBoxView.swift +++ b/AcaMate/1. View/12. Main/121. Home/AttendanceBoxView.swift @@ -50,20 +50,21 @@ struct AttCellView: View { .padding(.top,4) HStack(alignment: .center, spacing: 2) { Spacer() - Text("\(valueGroup.0)").font(.nps(font: .bold, size: 20)) + Text("\(valueGroup.0)") + .font(.nps(font: .bold, size: 20)) .foregroundStyle(((Double(valueGroup.0)/Double(valueGroup.1)) < 0.7) ? Color(.Other.red) : Color(.Other.blue)) .frame(width: 28,alignment: .center) - Text("/").font(.nps(size: 12)) + Text("/") + .font(.nps(size: 12)) .foregroundStyle(Color(.Text.detail)) - Text("\(valueGroup.1)").font(.nps(font: .bold, size: 20)) + Text("\(valueGroup.1)") + .font(.nps(font: .bold, size: 20)) .foregroundStyle(Color(.Text.detail)) .frame(width: 28,alignment: .center) Text("\(cellText.group)") .font(.nps(size: 16)) .foregroundStyle(Color(.Text.detail)) - .lineLimit(1) - .minimumScaleFactor(0.5) - .truncationMode(.tail) + .multilineStyle() } .frame(maxWidth: .infinity) } diff --git a/AcaMate/1. View/12. Main/121. Home/CalendarBoxView.swift b/AcaMate/1. View/12. Main/121. Home/CalendarBoxView.swift index dd7fd00..8d4f5b9 100644 --- a/AcaMate/1. View/12. Main/121. Home/CalendarBoxView.swift +++ b/AcaMate/1. View/12. Main/121. Home/CalendarBoxView.swift @@ -48,9 +48,7 @@ struct CalCellView: View { Text("\(summaryCalData.summary)") .font(.nps(size: 20)) .foregroundStyle(Color(.Text.black)) - .lineLimit(1) - .minimumScaleFactor(0.5) - .truncationMode(.tail) + .multilineStyle() } } diff --git a/AcaMate/1. View/12. Main/121. Home/HomeView.swift b/AcaMate/1. View/12. Main/121. Home/HomeView.swift index 4ec26e1..2c86da5 100644 --- a/AcaMate/1. View/12. Main/121. Home/HomeView.swift +++ b/AcaMate/1. View/12. Main/121. Home/HomeView.swift @@ -14,7 +14,6 @@ struct HomeView: View { @State private var topViewState: Bool = false //MARK: - 변경 값 -// @State private var myType: UserType = .Student @Binding var myType: UserType var body: some View { @@ -116,21 +115,3 @@ struct HomeView: View { } -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)) - } - } -} diff --git a/AcaMate/1. View/12. Main/121. Home/TopProfileView.swift b/AcaMate/1. View/12. Main/121. Home/TopProfileView.swift index 3f72a0c..26b1e25 100644 --- a/AcaMate/1. View/12. Main/121. Home/TopProfileView.swift +++ b/AcaMate/1. View/12. Main/121. Home/TopProfileView.swift @@ -48,20 +48,17 @@ struct TopProfileView: View { .padding([.top, .bottom], 40) VStack(alignment: .center, spacing: 8) { Text("\(self.academyName)") - .frame(alignment: .center) .font(.nps(font: .bold, size: 36)) .foregroundStyle(Color(.Text.title)) - .lineLimit(1) - .minimumScaleFactor(0.5) - .truncationMode(.tail) - Text("\(self.myName)") - .multilineTextAlignment(.center) + .multilineStyle() .frame(alignment: .center) + + Text("\(self.myName)") .font(.nps(size: 18)) .foregroundStyle(Color(.Text.detail)) - .lineLimit(1) - .minimumScaleFactor(0.5) - .truncationMode(.tail) + .multilineStyle() + .frame(alignment: .center) + } } /// 위쪽 VStack .padding(EdgeInsets(top: 24, leading: 24, bottom: 12, trailing: 24)) diff --git a/AcaMate/1. View/12. Main/123. Chatting/ChatListView.swift b/AcaMate/1. View/12. Main/123. Chatting/ChatListView.swift new file mode 100644 index 0000000..400017b --- /dev/null +++ b/AcaMate/1. View/12. Main/123. Chatting/ChatListView.swift @@ -0,0 +1,89 @@ +// +// ChatListView.swift +// AcaMate +// +// Created by TAnine on 2/14/25. +// + +import SwiftUI + +struct ChatListView: View { + var chatList: [SummaryChat] + var body: some View { + VStack(spacing: 10) { + ForEach(Array(chatList.enumerated()), id:\.offset) { index, chat in + ChatCellView(summaryChat: chat) + } + } + + } +} + +struct ChatCellView: View { + var summaryChat: SummaryChat + + var body: some View { + VStack(spacing: 8) { + HStack(alignment: .bottom, spacing: 4) { + Image(.Icon.chatting).resizable() + .frame(width: 24, height: 24, alignment: .center) + + Text("\(summaryChat.chatName)") + .font(.nps(size: 20)) + .foregroundStyle(Color(.Text.detail)) + .multilineStyle() + + if summaryChat.groupNum > 0 { + HStack(alignment: .center, spacing: 0) { + Image(.Icon.person).resizable() + .frame(width: 12, height: 12, alignment: .center) + Text("\(summaryChat.groupNum)") + .font(.nps(size: 8)) + .foregroundStyle(Color(.Text.detail)) + } +// .frame(height: 24) + } + Spacer(minLength: 1) + + HStack(alignment: .bottom, spacing: 4) { + Image(summaryChat.notiState ? .Icon.notificationON : .Icon.notificationOFF).resizable() + .frame(width: 12, height: 12, alignment: .center) + Text("\(summaryChat.teacherName)") + .font(.nps(font: .bold, size: 12)) + .foregroundStyle(Color(.Text.detail)) + Text("선생님") + .font(.nps(size: 8)) + .foregroundStyle(Color(.Text.detail)) + } + + } + Text("\(summaryChat.lastMessage)") + .font(.nps(size: 10)) + .foregroundStyle(Color(.Text.detail)) + .multilineStyle(limit: 2, scale: 1) + .padding(.trailing, 8) + + HStack(alignment: .bottom, spacing: 4) { + Spacer(minLength: 1) + Group { + Text("\(summaryChat.dayDate)") + .font(.nps(size: 8)) + Text("\(summaryChat.timeDate)") + .font(.nps(font: .bold, size: 12)) + } + .foregroundStyle(Color(.Text.detail)) + } + } + + .padding(EdgeInsets(top: 8, leading: 12, bottom: 8, trailing: 12)) + .background { + RoundedRectangle(cornerRadius: 4) + .stroke(Color(.Second.normal), lineWidth: 2) + .fill(Color(.Second.light)) + } + .onTapGesture { + printLog("채팅 내부 셀 클릭") + // MARK: TO-DO + } + } +} diff --git a/AcaMate/1. View/12. Main/123. Chatting/ChattingView.swift b/AcaMate/1. View/12. Main/123. Chatting/ChattingView.swift index 11e4f0a..e692339 100644 --- a/AcaMate/1. View/12. Main/123. Chatting/ChattingView.swift +++ b/AcaMate/1. View/12. Main/123. Chatting/ChattingView.swift @@ -9,38 +9,111 @@ import SwiftUI struct ChattingView: View { @StateObject private var topVM = TopViewModel() + @StateObject private var btnVM = ButtonViewModel() @State private var scrollOffset: CGPoint = .zero + + @State private var leftBtnID = UUID() + @State private var rightBtnID = UUID() + + let classList = [ + SummaryChat(id: "00", chatName: "Class 101", teacherName: "홍길동", + lastMessage: "여기에는 채팅이 나올 예정입니다. 2줄 정도로 나올 예정이며 끝자리는 잘려서 나올 것 입니다. 이정도의 채팅으로는 택도 없어서 조금 더 길게 길게 작성을 해봅니다.", + dayDate: "2025. 02. 14", timeDate: "PM 11:00", notiState: true, groupNum: 12), + SummaryChat(id: "01", chatName: "Class 101", teacherName: "홍길동", + lastMessage: "여기에는 채팅이 나올 예정입니다. 2줄 정도로 나올 예정이며 끝자리는 잘려서 나올 것 입니다. 이정도의 채팅으로는 택도 없어서 조금 더 길게 길게 작성을 해봅니다.", + dayDate: "2025. 02. 14", timeDate: "PM 11:00", notiState: false, groupNum: 12), + SummaryChat(id: "02", chatName: "Class 101", teacherName: "홍길동", + lastMessage: "여기에는 채팅이 나올 예정입니다. 2줄 정도로 나올 예정이며 끝자리는 잘려서 나올 것 입니다. 이정도의 채팅으로는 택도 없어서 조금 더 길게 길게 작성을 해봅니다.", + dayDate: "2025. 02. 14", timeDate: "PM 11:00", notiState: true, groupNum: 12) + ] + + //MARK: - 변경 값 + @Binding var myType: UserType + + @State var chatMenu: chatType = .Class + var body: some View { VStack(spacing: 0) { TopView(topVM: topVM) - - OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in - VStack(spacing: 24) { - Group { - DashBoardView(image: Image(.Icon.group), title: "클래스") { - - } - DashBoardView(image: Image(.Icon.talk), title: "선생님과 1:1") { - + if myType == .ETC || myType == .Employee { + EmptyBoxView(title: "이용하실 수 없는 기능입니다.") + .padding(24) + Spacer(minLength: 1) + } else { + if myType == .Teacher || myType == .Admin { + if myType == .Admin { + HStack { + SimpleBtnView(vm: btnVM, id: leftBtnID) + Spacer(minLength: 1) + Text("선생님 이름") + .font(.nps(font: .bold, size: 24)) + .foregroundStyle(Color(.Text.detail)) + Spacer(minLength: 1) + SimpleBtnView(vm: btnVM, id: rightBtnID) } + .padding(EdgeInsets(top: 12, leading: 24, bottom: 0, trailing: 24)) } - .background { - RoundedRectangle(cornerRadius: 8) - .foregroundStyle(Color(.Other.cell)) + + HStack { + SelectChatMenu(chatMenu: $chatMenu, tag: .Class, image: Image(.Icon.group), title: "클래스") + Spacer(minLength: 1) + SelectChatMenu(chatMenu: $chatMenu, tag: .Student, image: Image(.Icon.talk), title: "학생") + Spacer(minLength: 1) + SelectChatMenu(chatMenu: $chatMenu, tag: .Parent, image: Image(.Icon.talk), title: "학부모") } + + .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24)) } - .padding(24) + OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in + VStack(spacing: 24) { + Group { + if myType != .Parent { + DashBoardView(image: Image(.Icon.group), title: "클래스") { + ChatListView(chatList: classList) + } + } + if myType != .Teacher || myType != .Admin { + DashBoardView(image: Image(.Icon.talk), title: "선생님과 1:1") { + + } + } + if myType == .Teacher { + DashBoardView(image: Image(.Icon.talk), title: "부모님과 1:1") { + + } + } + } + .background { + RoundedRectangle(cornerRadius: 8) + .foregroundStyle(Color(.Other.cell)) + } + } + .padding(EdgeInsets( + top: (myType == .Student || myType == .Parent) ? 24 : 12, leading: 24, bottom: 24, trailing: 24)) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) } - - .frame(maxWidth: .infinity, maxHeight: .infinity) } .onAppear { - topVM.titleName = "" - topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct) + // MARK: TO-DO + // 여기도 수정봐야 함 + 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(size: CGPoint(x: 40, y: 40), action: rightAct) + + btnVM.setImage(for: leftBtnID, newImage: Image(.Icon.left)) + btnVM.setImage(for: rightBtnID, newImage: Image(.Icon.right)) + btnVM.setSize(for: leftBtnID, newWidth: 24, newHeight: 24) + btnVM.setSize(for: rightBtnID, newWidth: 24, newHeight: 24) } } @@ -52,3 +125,41 @@ struct ChattingView: View { } } +struct SelectChatMenu: View { + @Binding var chatMenu: chatType + let tag: chatType + let image: Image + let title: String + + var body: some View { + HStack(alignment: .center, spacing: 4) { + if chatMenu == tag { + image.resizable() + .frame(width: 24, height: 24, alignment: .center) + Text("\(title)") + .font(.nps(font: .bold, size: 24)) + .foregroundStyle(Color(.Text.detail)) + } else { + image.resizable() + .renderingMode(.template) + .frame(width: 24, height: 24, alignment: .center) + .foregroundStyle(Color(.Disable.normal)) + Text("\(title)") + .font(.nps(size: 20)) + .foregroundStyle(Color(.Disable.normal)) + } + } + .padding(2) + .background { + if chatMenu == tag { + RoundedRectangle(cornerRadius: 4) + .foregroundStyle(Color.Other.cell) + } + } + .onTapGesture { + chatMenu = tag + } + + } +} + diff --git a/AcaMate/1. View/12. Main/125. Etc/DevInfoView.swift b/AcaMate/1. View/12. Main/125. Etc/DevInfoView.swift index f946037..f71ed18 100644 --- a/AcaMate/1. View/12. Main/125. Etc/DevInfoView.swift +++ b/AcaMate/1. View/12. Main/125. Etc/DevInfoView.swift @@ -27,8 +27,7 @@ struct DevInfoView: View { Text(attributeText) .foregroundStyle(Color(.Text.detail)) - .lineLimit(2) - .multilineTextAlignment(.center) + .multilineStyle(.center, limit: 2) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) VStack(alignment: .leading, spacing: 12){ diff --git a/AcaMate/1. View/12. Main/125. Etc/EtcView.swift b/AcaMate/1. View/12. Main/125. Etc/EtcView.swift index efef015..524c5df 100644 --- a/AcaMate/1. View/12. Main/125. Etc/EtcView.swift +++ b/AcaMate/1. View/12. Main/125. Etc/EtcView.swift @@ -16,7 +16,7 @@ struct EtcView: View { var body: some View { VStack(spacing: 0) { TopView(topVM: topVM) - + OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in VStack(spacing: 24) { UserInfoView(userData: SummaryUser(profile: Image(.Icon.face), name: "이름", userID: "abcdefg", email: "abcdefg@gmail.com")) @@ -25,14 +25,16 @@ struct EtcView: View { TsCsView() AppInfoView() } -// .frame(maxWidth: .infinity, alignment: .leading) .padding(24) DevInfoView() +// Rectangle() +// .foregroundStyle(Color(.Disable.normal)) +// .frame(height: 500) +// .frame(maxWidth: .infinity) } + .frame(maxWidth: .infinity, maxHeight: .infinity) } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .onAppear { topVM.titleName = "" topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct) diff --git a/AcaMate/1. View/12. Main/125. Etc/UserInfoView.swift b/AcaMate/1. View/12. Main/125. Etc/UserInfoView.swift index 1f56990..4b13435 100644 --- a/AcaMate/1. View/12. Main/125. Etc/UserInfoView.swift +++ b/AcaMate/1. View/12. Main/125. Etc/UserInfoView.swift @@ -46,10 +46,8 @@ struct UserInfoView: View { Spacer(minLength: 1) Text("\(userData.email)") .font(.nps(size: 16)) - .lineLimit(1) - .minimumScaleFactor(0.5) - .truncationMode(.tail) .foregroundStyle(Color(.Text.detail)) + .multilineStyle() } } .padding(10) diff --git a/AcaMate/1. View/12. Main/121. Home/DashBoardView.swift b/AcaMate/1. View/12. Main/DashBoardView.swift similarity index 100% rename from AcaMate/1. View/12. Main/121. Home/DashBoardView.swift rename to AcaMate/1. View/12. Main/DashBoardView.swift diff --git a/AcaMate/1. View/12. Main/EmptyBoxView.swift b/AcaMate/1. View/12. Main/EmptyBoxView.swift new file mode 100644 index 0000000..b268320 --- /dev/null +++ b/AcaMate/1. View/12. Main/EmptyBoxView.swift @@ -0,0 +1,25 @@ +// +// EmptyBoxView.swift +// AcaMate +// +// Created by TAnine on 2/14/25. +// + +import SwiftUI + +struct EmptyBoxView: View { + let title: String + var body: some View { + Text("\(title)") + .font(.nps(size: 20)) + .foregroundStyle(Color(.Text.detail)) + .multilineStyle() + .frame(maxWidth: .infinity) + .padding([.top,.bottom],12) + .background { + RoundedRectangle(cornerRadius: 4) + .stroke(Color(.Second.normal), lineWidth: 2) + .fill(Color(.Second.light)) + } + } +} diff --git a/AcaMate/1. View/12. Main/MainView.swift b/AcaMate/1. View/12. Main/MainView.swift index 412b870..312339c 100644 --- a/AcaMate/1. View/12. Main/MainView.swift +++ b/AcaMate/1. View/12. Main/MainView.swift @@ -14,7 +14,7 @@ struct MainView: View { @State var cancellables: Set = [] @Binding var naviState : NaviState - @State private var myType: UserType = .Student + @State private var myType: UserType = .Admin var body: some View { @@ -26,7 +26,7 @@ struct MainView: View { case .Management: ManagementView() case .Chatting: - ChattingView() + ChattingView(myType: $myType) case .Calendar: CalendarView() case .Etc: diff --git a/AcaMate/2. Model/Chat Data.swift b/AcaMate/2. Model/Chat Data.swift new file mode 100644 index 0000000..a17aaae --- /dev/null +++ b/AcaMate/2. Model/Chat Data.swift @@ -0,0 +1,29 @@ +// +// Chat Data.swift +// AcaMate +// +// Created by TAnine on 2/14/25. +// + +import Foundation + +struct SummaryChat { + var id: String + + var chatName: String + var teacherName: String + var lastMessage: String + var dayDate: String + var timeDate: String + + var notiState: Bool + + var groupNum: Int + +} + +enum chatType { + case Class + case Student + case Parent +} diff --git a/AcaMate/5. Modifier/Text.swift b/AcaMate/5. Modifier/Text.swift index 9062425..90271b3 100644 --- a/AcaMate/5. Modifier/Text.swift +++ b/AcaMate/5. Modifier/Text.swift @@ -9,5 +9,11 @@ import SwiftUI extension Text { - + func multilineStyle(_ alignment: TextAlignment = .leading, limit: Int = 1, scale: CGFloat = 0.5) -> some View { + return self + .lineLimit(limit) + .minimumScaleFactor(scale) + .multilineTextAlignment(alignment) + .truncationMode(.tail) + } }