// // RegisterView.swift // AcaMate // // Created by TAnine on 2/20/25. // import SwiftUI struct RegisterView: View { @EnvironmentObject var appVM: AppViewModel @StateObject private var topVM = TopViewModel() @StateObject var btnVM = ButtonViewModel() @StateObject var registerVM: RegisterViewModel // private let responseValue: (SNSLoginType, String) init(_ appVM: AppViewModel, type: SNSLoginType, snsID: String) { _registerVM = StateObject(wrappedValue: RegisterViewModel(appVM, type: type, snsID: snsID)) } @State private var scrollOffset: CGPoint = .zero @State private var showWebView = false @State private var isLoading = false @State private var isSelectAddr: Bool = false @StateObject private var dropdownManager = DropdownManager() @State private var onDomainTxf = false var body: some View { // MARK: TO-DO // 회원가입 뷰 만들기 // 이름, 번호, 이메일, 주소, 생년월일 ZStack { VStack(spacing: 0) { TopView(topVM: topVM) HStack(spacing: 0) { Spacer(minLength: 1) Text("*") .font(.nps(size: 12)) .foregroundStyle(Color(.Other.red)) Text("는 필수 입력 사항입니다.") .font(.nps(size: 12)) } .padding(EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 16)) OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in // 이름 HStack(spacing: 0){ HStack(spacing: 0) { Text("이름") .font(.nps(size: 16)) Text("*") .font(.nps(size: 16)) .foregroundStyle(Color(.Other.red)) } .frame(width: 60, alignment: .center) .padding(.trailing,12) Spacer(minLength: 1) CustomTxfView(placeholder: "이름 입력 (10 글자)", text: $registerVM.nameText, maxLength: 10, alignment: .center) .frame(maxWidth: .infinity,maxHeight: 48) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) }.clipped() } .padding(EdgeInsets(top: 8, leading: 16, bottom: 16, trailing: 16)) // 생년월일 HStack(spacing: 0){ Text("생일") .font(.nps(size: 16)) .frame(width: 60, alignment: .center) .padding(.trailing,12) Spacer(minLength: 1) DatePicker("", selection: $registerVM.selectDate, displayedComponents: [.date]) .datePickerStyle(.compact) .environment(\.locale, Locale(identifier: "ko_KR")) .font(.nps(size: 16)) } .padding() // E-Mail HStack(spacing: 0){ HStack(spacing: 0) { Text("이메일") .font(.nps(size: 16)) Text("*") .font(.nps(size: 16)) .foregroundStyle(Color(.Other.red)) } .frame(width: 60, alignment: .center) .padding(.trailing,12) Spacer(minLength: 1) VStack (spacing: 4) { CustomTxfView(placeholder: "이메일 입력(30 글자)", text: $registerVM.emailFrontText, maxLength: 30, alignment: .center) .frame(maxWidth: .infinity, maxHeight: .infinity) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } HStack(spacing: 0) { Text("@") .font(.nps(size: 16)) .padding([.leading, .trailing], 4) // Spacer(minLength: 1) DropdownButton(manager: dropdownManager, title: "도메인 선택", items: registerVM.emailTailList){ index in if registerVM.emailTailList.count-1 == index { onDomainTxf = true } else { registerVM.emailTailText = registerVM.emailTailList[index] onDomainTxf = false } } .frame(maxWidth: .infinity, maxHeight: .infinity) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } } if onDomainTxf { CustomTxfView(placeholder: "도메인 직접 입력(30 글자)", text: $registerVM.emailTailText, maxLength: 30, alignment: .center) .frame(maxWidth: .infinity, maxHeight: .infinity) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } } } } .padding() // Phone HStack(spacing: 0){ HStack(spacing: 0) { Text("연락처") .font(.nps(size: 16)) Text("*") .font(.nps(size: 16)) .foregroundStyle(Color(.Other.red)) } .frame(width: 60, alignment: .center) .padding(.trailing,12) DropdownButton(manager: dropdownManager, title: "선택", items: registerVM.numberHeadList){ index in registerVM.phoneTextSet.0 = registerVM.numberHeadList[index] } .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } Text("-") .font(.nps(size: 16)) .padding([.leading, .trailing], 4) CustomTxfView(placeholder: "0000", text: $registerVM.phoneTextSet.1, maxLength: 4, alignment: .center) .frame(maxWidth: .infinity,maxHeight: 48) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } Text("-") .font(.nps(size: 16)) .padding([.leading, .trailing], 4) CustomTxfView(placeholder: "0000", text: $registerVM.phoneTextSet.2, maxLength: 4, alignment: .center) .frame(maxWidth: .infinity, maxHeight: 48) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } } .padding() HStack(alignment: .center, spacing: 0){ Text("주소") .font(.nps(size: 16)) .frame(width: 60, alignment: .center) .padding(.trailing,12) VStack(spacing: 0) { SimpleBtnView(vm: btnVM, id: registerVM.addressBtnID) .frame(maxWidth: .infinity, maxHeight: 48) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } .padding(.bottom, isSelectAddr ? 4:0) if isSelectAddr { CustomTxfView(placeholder: "상세 주소 입력 (50 글자)", text: $registerVM.addrDetailText, maxLength: 50, alignment: .center) .frame(maxWidth: .infinity, maxHeight: isSelectAddr ? 48 : 0) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background { RoundedRectangle(cornerRadius: 24) .foregroundStyle(Color(.Normal.light)) } } } } .padding() } .frame(maxWidth: .infinity, maxHeight: .infinity) SimpleBtnView(vm: btnVM, id: registerVM.registerBtnID) .frame(maxWidth: .infinity, maxHeight: 48) .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) // .background { // RoundedRectangle(cornerRadius: 24) // .foregroundStyle(Color(.Normal.light)) // } } GlobalDropdownOverlay(manager: dropdownManager) } .coordinateSpace(name: "dropdownArea") .sheet(isPresented: $showWebView) { WebView(url: URL(string: "https://sean-59.github.io/Kakao-Postcode/")!, showWebView: $showWebView, isLoading: $isLoading) { result in if let result = result as? (String, String) { print(result.0) isSelectAddr = true registerVM.addressText = result.0 btnVM.setSize(for: registerVM.addressBtnID, newWidth: .infinity, newHeight: .infinity) btnVM.setText(for: registerVM.addressBtnID, newText: "\(registerVM.addressText)", newFont: .nps(size: 16)) } } } .onAppear { topVM.titleName = "회원가입" topVM.setLeftBtn(Image(.Icon.left), size: CGPoint(x: 40, y: 40), action: leftAct) topVM.setRightBtn(size: CGPoint(x: 40, y: 40), action: rightAct) btnVM.setSize(for: registerVM.addressBtnID, newWidth: 80, newHeight: 24) btnVM.setText(for: registerVM.addressBtnID, newText: "\(registerVM.addressText)", newFont: .nps(size: 16)) btnVM.setTextColor(for: registerVM.addressBtnID, newColor: Color.Text.black) btnVM.setAction(for: registerVM.addressBtnID) { self.showWebView.toggle() } btnVM.setSize(for: registerVM.registerBtnID, newWidth: .infinity, newHeight: 48) btnVM.setText(for: registerVM.registerBtnID, newText: "회원가입", newFont: .nps(font: .bold, size: 24)) btnVM.setTextColor(for: registerVM.registerBtnID, newColor: Color.Point.dark) btnVM.setAction(for: registerVM.registerBtnID) { registerVM.registerUser() } dropdownManager.font = .nps(size: 16) } // .onChange(of: dropdownManager.onSelect) { _, new in // printLog("CHANGE: \(new)") // // } } func leftAct() { printLog("왼쪽 버튼 클릭") appVM.naviState.set(act: .POP) } func rightAct() { printLog("오른쪽 버튼 클릭") } }