forked from AcaMate/AcaMate_iOS
[✨] 학원 선택 페이지 작성 및 기존 코드 로직 분리 작업
This commit is contained in:
parent
ca49db680c
commit
71b2c3389f
Binary file not shown.
|
@ -7,9 +7,12 @@
|
|||
import SwiftUI
|
||||
// MARK: - ACAMATE
|
||||
// APPSTORE_URL : https://apps.apple.com/us/app/%EC%95%84%EC%B9%B4%EB%8D%B0%EB%AF%B8%EB%A9%94%EC%9D%B4%ED%8A%B8/id6739448113
|
||||
/// 주의사항
|
||||
/// plist 에서 http 설정 걸려있는거 지워야 함
|
||||
#if LOCAL
|
||||
//public let API_URL: String = "http://0.0.0.0:5144"
|
||||
public let API_URL: String = "https://localhost:7086"
|
||||
public let API_URL: String = "http://10.149.217.64:5144"
|
||||
//public let API_URL: String = "http://localhost:5144"
|
||||
//public let API_URL: String = "https://localhost:7086"
|
||||
public let WS_URL: String = "ws://localhost:5144"
|
||||
|
||||
/// 회사 맥에서 사용할 경우의 URL
|
||||
|
|
|
@ -1,117 +1,117 @@
|
|||
////
|
||||
//// AccountLoginView.swift
|
||||
//// AcaMate
|
||||
////
|
||||
//// Created by Sean Kim on 12/14/24.
|
||||
////
|
||||
//
|
||||
// AccountLoginView.swift
|
||||
// AcaMate
|
||||
//import SwiftUI
|
||||
//
|
||||
// Created by Sean Kim on 12/14/24.
|
||||
//struct AccountLoginView: View {
|
||||
// @ObservedObject var loginVM.: LoginViewModel
|
||||
// @Binding var userId: String
|
||||
// @Binding var password: String
|
||||
// @Binding var isSecure: Bool
|
||||
// @Binding var isSave: Bool
|
||||
// var body: some View {
|
||||
// VStack(spacing: 0) {
|
||||
// ZStack(alignment: .leading) {
|
||||
// if userId.isEmpty {
|
||||
// Text("아이디를 입력하세요.")
|
||||
// .font(.nps(font: .regular, size: 16))
|
||||
// .foregroundStyle(Color(.Text.border))
|
||||
// .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
// }
|
||||
// CustomTextField(placeholder: "", text: $userId)
|
||||
// .frame(maxWidth: .infinity,maxHeight: 24)
|
||||
// .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
// }
|
||||
// .background {
|
||||
// RoundedRectangle(cornerRadius: 24)
|
||||
// .foregroundStyle(.white)
|
||||
// }
|
||||
// .padding(EdgeInsets(top: 0, leading: 12, bottom: 8, trailing: 12))
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct AccountLoginView: View {
|
||||
@ObservedObject var viewModel: LoginViewModel
|
||||
@Binding var userId: String
|
||||
@Binding var password: String
|
||||
@Binding var isSecure: Bool
|
||||
@Binding var isSave: Bool
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
ZStack(alignment: .leading) {
|
||||
if userId.isEmpty {
|
||||
Text("아이디를 입력하세요.")
|
||||
.font(.nps(font: .regular, size: 16))
|
||||
.foregroundStyle(Color(.Text.border))
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
}
|
||||
CustomTextField(placeholder: "", text: $userId)
|
||||
.frame(maxWidth: .infinity,maxHeight: 24)
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
}
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(.white)
|
||||
}
|
||||
.padding(EdgeInsets(top: 0, leading: 12, bottom: 8, trailing: 12))
|
||||
|
||||
ZStack(alignment: .leading) {
|
||||
if password.isEmpty {
|
||||
Text("비밀번호를 입력하세요.")
|
||||
.font(.nps(font: .regular, size: 16))
|
||||
.foregroundStyle(Color(.Text.border))
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
}
|
||||
CustomTextField(placeholder: "", text: $password, isSecure: $isSecure)
|
||||
.frame(maxWidth: .infinity,maxHeight: 24)
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
Button {
|
||||
isSecure.toggle()
|
||||
} label: {
|
||||
if password.isEmpty {
|
||||
Rectangle()
|
||||
.frame(width: 16, height: 2)
|
||||
.foregroundStyle(Color(.Text.border))
|
||||
.padding(.trailing,24)
|
||||
}
|
||||
else {
|
||||
if isSecure {
|
||||
Image(systemName: "eye")
|
||||
.frame(width: 16, height: 16)
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
.padding(.trailing,24)
|
||||
}
|
||||
else {
|
||||
Image(systemName: "eye.slash")
|
||||
.frame(width: 16, height: 16)
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
.padding(.trailing,24)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(.white)
|
||||
}
|
||||
.padding(EdgeInsets(top: 0, leading: 12, bottom: 8, trailing: 12))
|
||||
|
||||
Button {
|
||||
isSave.toggle()
|
||||
} label: {
|
||||
HStack(alignment: .center, spacing: 4) {
|
||||
Spacer(minLength: 1)
|
||||
if isSave {
|
||||
Image(systemName: "checkmark.square")
|
||||
.foregroundStyle(Color(.Second.normal))
|
||||
.frame(width: 24, height: 24)
|
||||
} else {
|
||||
Image(systemName: "square")
|
||||
.foregroundStyle(Color(.Second.normal))
|
||||
.frame(width: 24, height: 24)
|
||||
}
|
||||
|
||||
Text("로그인 정보 저장")
|
||||
.font(.nps(font: .regular, size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
}
|
||||
}
|
||||
.padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 12))
|
||||
|
||||
Button {
|
||||
viewModel.loginAction.send(true)
|
||||
} label: {
|
||||
Text("로그인")
|
||||
.font(.nps(font: .bold, size: 24))
|
||||
.foregroundStyle(Color(.Text.white))
|
||||
.padding(EdgeInsets(top: 8, leading: 48, bottom: 8, trailing: 48))
|
||||
.background{
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.foregroundStyle(Color(.Second.normal))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ZStack(alignment: .leading) {
|
||||
// if password.isEmpty {
|
||||
// Text("비밀번호를 입력하세요.")
|
||||
// .font(.nps(font: .regular, size: 16))
|
||||
// .foregroundStyle(Color(.Text.border))
|
||||
// .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
// }
|
||||
// CustomTextField(placeholder: "", text: $password, isSecure: $isSecure)
|
||||
// .frame(maxWidth: .infinity,maxHeight: 24)
|
||||
// .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
//
|
||||
// HStack {
|
||||
// Spacer()
|
||||
// Button {
|
||||
// isSecure.toggle()
|
||||
// } label: {
|
||||
// if password.isEmpty {
|
||||
// Rectangle()
|
||||
// .frame(width: 16, height: 2)
|
||||
// .foregroundStyle(Color(.Text.border))
|
||||
// .padding(.trailing,24)
|
||||
// }
|
||||
// else {
|
||||
// if isSecure {
|
||||
// Image(systemName: "eye")
|
||||
// .frame(width: 16, height: 16)
|
||||
// .foregroundStyle(Color(.Text.detail))
|
||||
// .padding(.trailing,24)
|
||||
// }
|
||||
// else {
|
||||
// Image(systemName: "eye.slash")
|
||||
// .frame(width: 16, height: 16)
|
||||
// .foregroundStyle(Color(.Text.detail))
|
||||
// .padding(.trailing,24)
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .background {
|
||||
// RoundedRectangle(cornerRadius: 24)
|
||||
// .foregroundStyle(.white)
|
||||
// }
|
||||
// .padding(EdgeInsets(top: 0, leading: 12, bottom: 8, trailing: 12))
|
||||
//
|
||||
// Button {
|
||||
// isSave.toggle()
|
||||
// } label: {
|
||||
// HStack(alignment: .center, spacing: 4) {
|
||||
// Spacer(minLength: 1)
|
||||
// if isSave {
|
||||
// Image(systemName: "checkmark.square")
|
||||
// .foregroundStyle(Color(.Second.normal))
|
||||
// .frame(width: 24, height: 24)
|
||||
// } else {
|
||||
// Image(systemName: "square")
|
||||
// .foregroundStyle(Color(.Second.normal))
|
||||
// .frame(width: 24, height: 24)
|
||||
// }
|
||||
//
|
||||
// Text("로그인 정보 저장")
|
||||
// .font(.nps(font: .regular, size: 16))
|
||||
// .foregroundStyle(Color(.Text.detail))
|
||||
// }
|
||||
// }
|
||||
// .padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 12))
|
||||
//
|
||||
// Button {
|
||||
// loginVM..loginAction.send(true)
|
||||
// } label: {
|
||||
// Text("로그인")
|
||||
// .font(.nps(font: .bold, size: 24))
|
||||
// .foregroundStyle(Color(.Text.white))
|
||||
// .padding(EdgeInsets(top: 8, leading: 48, bottom: 8, trailing: 48))
|
||||
// .background{
|
||||
// RoundedRectangle(cornerRadius: 12)
|
||||
// .foregroundStyle(Color(.Second.normal))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
|
|
@ -11,16 +11,6 @@ import Combine
|
|||
struct LoginView: View {
|
||||
@EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject private var loginVM = LoginViewModel()
|
||||
@State var cancellables: Set<AnyCancellable> = []
|
||||
// @Binding var naviState : NaviState
|
||||
|
||||
@State var selectIdLogin: Bool = false
|
||||
|
||||
@State var userId: String = ""
|
||||
@State var password: String = ""
|
||||
@State var isSecure: Bool = true
|
||||
@State var isSave: Bool = false
|
||||
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
|
@ -35,15 +25,15 @@ struct LoginView: View {
|
|||
VStack(spacing: 16) {
|
||||
Button {
|
||||
// MARK: - TODO, 카카오 계정 로그인 구현
|
||||
appVM.isLoading.toggle()
|
||||
loginAction(type: .Kakao)
|
||||
loginVM.toggleLoading = true
|
||||
loginVM.loginAction(type: .Kakao)
|
||||
|
||||
} label: {
|
||||
makeButton(image: Image(.Logo.kakaoIcon),color: Color(.Other.yellow), "카카오 계정으로 시작하기")
|
||||
}
|
||||
|
||||
Button {
|
||||
// MARK: - TODO, 애플 계정 로그인 구현
|
||||
// appVM.naviState.set(act: .MOVE, path: .Main)
|
||||
appVM.naviState.set(act: .ADD, path: .SelectAcademy(bids: ["AA0000", "AA0001"]))
|
||||
|
||||
} label: {
|
||||
|
@ -54,65 +44,17 @@ struct LoginView: View {
|
|||
|
||||
Spacer(minLength: 1)
|
||||
|
||||
|
||||
/*
|
||||
VStack(spacing: 16) {
|
||||
|
||||
Button {
|
||||
// MARK: TO-DO
|
||||
// 카카오 로그인 연동
|
||||
naviState.set(act: .MOVE, path: .Main)
|
||||
} label: {
|
||||
HStack(spacing: 24) {
|
||||
Image("Kakao_Icon")
|
||||
.resizable()
|
||||
.frame(width: 32, height: 32)
|
||||
Text("카카오 계정으로 시작하기")
|
||||
.font(.nps(font: .regular, size: 16))
|
||||
.foregroundStyle(Color(.Text.black))
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(12)
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.foregroundStyle(Color(.Other.yellow))
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
/// KAKAO 로그인 버튼
|
||||
|
||||
Button {
|
||||
// MARK: TO-DO
|
||||
// 애플 로그인 연동
|
||||
} label: {
|
||||
HStack(spacing: 24) {
|
||||
Image(systemName: "apple.logo")
|
||||
.resizable()
|
||||
.accentColor(Color(.Text.white))
|
||||
.frame(width: 32, height: 32)
|
||||
|
||||
Text("애플 계정으로 시작하기")
|
||||
.font(.nps(font: .regular, size: 16))
|
||||
.foregroundStyle(Color(.Text.white))
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(12)
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.foregroundStyle(Color(.Text.black))
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
/// APPLE 로그인 버튼
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
.onAppear {
|
||||
subscribeLoginAction()
|
||||
}
|
||||
.frame(maxWidth: .infinity,maxHeight: .infinity)
|
||||
.fullDrawView(.Normal.normal)
|
||||
.onChange(of: loginVM.navigateToAcademy, { _, _ in
|
||||
appVM.naviState.set(act: .ADD, path: .SelectAcademy(bids: loginVM.bidArray))
|
||||
})
|
||||
|
||||
.onChange(of: loginVM.toggleLoading) { _, new in
|
||||
appVM.isLoading = new
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func makeButton(image: Image, color: Color? = nil, _ body: String) -> some View {
|
||||
|
@ -134,58 +76,4 @@ struct LoginView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func subscribeLoginAction() {
|
||||
loginVM.loginAction
|
||||
.sink { isTapped in
|
||||
if isTapped {
|
||||
if userId.isEmpty || password.isEmpty {
|
||||
appVM.alertData = SetAlertData().setErrorLogin()
|
||||
appVM.showAlert.toggle()
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
printLog("로그인")
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
private func loginAction(type: SNSLoginType) {
|
||||
LoginController().login(type)
|
||||
.flatMap{ snsId in
|
||||
loadAPIData(url: "\(API_URL)",
|
||||
path: "/api/v1/in/user/login",
|
||||
parameters: [
|
||||
"sns_id": "\(snsId.snsId)",
|
||||
"acctype": "\(type == .Apple ? "ST00": "ST01")"
|
||||
],
|
||||
decodingType: APIResponse<User_Academy>.self)
|
||||
|
||||
}
|
||||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
printLog("\(error)")
|
||||
appVM.isLoading.toggle()
|
||||
case .finished:
|
||||
appVM.isLoading.toggle()
|
||||
}
|
||||
} receiveValue: { response in
|
||||
guard let ua = response as? APIResponse<User_Academy> else {return}
|
||||
if let bids = ua.data.toStringDict()["bid"] {
|
||||
printLog(bids)
|
||||
if let bidArray: [String] = jsonToSwift(bids) {
|
||||
// 정상 적으로 학원 ID를 불러 온거니까 이제 여기서 할 걸 정해야 함
|
||||
appVM.naviState.set(act: .ADD, path: .SelectAcademy(bids: bidArray))
|
||||
} else {
|
||||
printLog("JSON 변환 실패")
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,56 +6,131 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
|
||||
struct SelectAcademyView: View {
|
||||
@State var cancellables: Set<AnyCancellable> = []
|
||||
@EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject var saVM = SelectAcademyViewModel()
|
||||
|
||||
@State private var scrollOffset: CGPoint = .zero
|
||||
|
||||
var bids: [String]
|
||||
@State private var academyCode: String = ""
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
Spacer()
|
||||
.frame(height: 100)
|
||||
.frame(maxHeight: 100)
|
||||
Image(.Logo.appIcon)
|
||||
.resizable()
|
||||
.frame(width: 200, height: 200)
|
||||
CustomTextField(placeholder: "학원 코드 입력", text: $academyCode)
|
||||
|
||||
VStack(spacing: 4) {
|
||||
HStack(spacing: 0){
|
||||
Text("학원 코드")
|
||||
.font(.nps(font: .bold, size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
//MARK: TO-DO
|
||||
// 문제
|
||||
// 1. txf 클릭시 겉 뷰가 작아지는 현상
|
||||
// 2. 코드 입력시 버튼 나타나게 하기
|
||||
CustomTextField(placeholder: "학원 코드 입력", text: $saVM.academyCode)
|
||||
.frame(maxWidth: .infinity,maxHeight: 48)
|
||||
.padding(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20))
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
// .padding([.leading, .trailing], 24)
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 40, trailing: 24))
|
||||
|
||||
VStack(spacing: 4) {
|
||||
HStack(spacing: 0){
|
||||
Text("학원 목록")
|
||||
.font(.nps(font: .bold, size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
Spacer(minLength: 1)
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 0, trailing: 24))
|
||||
OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in
|
||||
VStack(spacing: 12) {
|
||||
ForEach(Array(saVM.academyList.enumerated()), id: \.offset) { index, academy in
|
||||
AcademyCell(numbering: index, academy: saVM.academyList[index],selectNum: $saVM.selectNum){
|
||||
saVM.toggleSelection(for: index)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(EdgeInsets(top: 0, leading: 24, bottom: 12, trailing: 24))
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
}
|
||||
|
||||
Spacer(minLength: 1)
|
||||
|
||||
Button {
|
||||
appVM.naviState.set(act: .MOVE, path: .Main)
|
||||
} label: {
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(Color(.Second.normal))
|
||||
Text("입장하기")
|
||||
.font(.nps(size: 16))
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
.frame(height: 56)
|
||||
}
|
||||
.opacity(saVM.selectNum >= 0 ? 1 : 0)
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
|
||||
|
||||
}
|
||||
.onAppear {
|
||||
loadAPIData(url: "\(API_URL)",
|
||||
path: "/api/v1/in/member/academy",
|
||||
method: .post,
|
||||
parameters: ["bids": bids],
|
||||
decodingType: APIResponse<[AcademyName]>.self)
|
||||
.sink { completion in
|
||||
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
printLog("\(error)")
|
||||
// appVM.isLoading.toggle()
|
||||
case .finished:
|
||||
break
|
||||
// appVM.isLoading.toggle()
|
||||
}
|
||||
} receiveValue: { response in
|
||||
guard let ua = response as? APIResponse<[AcademyName]> else {return}
|
||||
printLog(ua)
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
|
||||
saVM.loadAcademy(bids: bids)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AcademyCell: View {
|
||||
let numbering: Int
|
||||
let academy: AcademyName
|
||||
@Binding var selectNum: Int
|
||||
let action: VOID_TO_VOID
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
Image(.Logo.pageIcon)
|
||||
.resizable()
|
||||
.frame(width: 32, height: 32, alignment: .center)
|
||||
.padding(12)
|
||||
Spacer(minLength: 1)
|
||||
|
||||
Text("\(academy.name)")
|
||||
.font(.nps(size: 18))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
.multilineStyle(.center)
|
||||
|
||||
Spacer(minLength: 1)
|
||||
|
||||
Button{
|
||||
// saVM.toggleSelection(for: numbering)
|
||||
action()
|
||||
} label: {
|
||||
Circle()
|
||||
.stroke(Color(.Text.detail), lineWidth: 4)
|
||||
.fill (selectNum == numbering ? Color(.Point.normal) : Color(.Normal.normal))
|
||||
.frame(width: 18, height: 18)
|
||||
}
|
||||
.frame(width: 32, height: 32)
|
||||
.padding(12)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.stroke(Color(.Second.normal), lineWidth: 2)
|
||||
}
|
||||
.onTapGesture {
|
||||
action()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,49 @@
|
|||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
|
||||
class LoginViewModel: ObservableObject {
|
||||
let loginAction = CurrentValueSubject<Bool, Never>(false)
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
@Published var toggleLoading: Bool = false
|
||||
|
||||
@Published var navigateToAcademy: Bool = false
|
||||
@Published var bidArray: [String] = []
|
||||
|
||||
func loginAction(type: SNSLoginType) {
|
||||
LoginController().login(type)
|
||||
.flatMap{ snsId in
|
||||
loadAPIData(url: "\(API_URL)",
|
||||
path: "/api/v1/in/user/login",
|
||||
parameters: [
|
||||
"acctype": "\(type == .Apple ? "ST00": "ST01")",
|
||||
"sns_id": "\(snsId.snsId)"
|
||||
],
|
||||
decodingType: APIResponse<User_Academy>.self)
|
||||
|
||||
}
|
||||
.sink { [weak self] completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
printLog("\(error)")
|
||||
self?.toggleLoading = false
|
||||
case .finished:
|
||||
self?.toggleLoading = false
|
||||
}
|
||||
} receiveValue: { [weak self] response in
|
||||
guard let self = self else { return }
|
||||
guard let ua = response as? APIResponse<User_Academy> else {return}
|
||||
if let bids = ua.data.toStringDict()["bid"] {
|
||||
printLog(bids)
|
||||
if let bidArray: [String] = jsonToSwift(bids) {
|
||||
// 정상 적으로 학원 ID를 불러 온거니까 이제 여기서 할 걸 정해야 함
|
||||
printLog("GOOD")
|
||||
self.navigateToAcademy = true
|
||||
self.bidArray = bidArray
|
||||
} else {
|
||||
printLog("JSON 변환 실패")
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
}
|
||||
|
|
45
AcaMate/3. ViewModel/SelectAcademyViewModel.swift
Normal file
45
AcaMate/3. ViewModel/SelectAcademyViewModel.swift
Normal file
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// SelectAcademyViewModel.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 2/19/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
class SelectAcademyViewModel: ObservableObject {
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
@Published var academyCode: String = ""
|
||||
@Published var academyList: [AcademyName] = []
|
||||
@Published var selectNum: Int = -1
|
||||
|
||||
func loadAcademy(bids: [String]) {
|
||||
loadAPIData(url: "\(API_URL)",
|
||||
path: "/api/v1/in/member/academy",
|
||||
method: .post,
|
||||
parameters: ["bids": bids],
|
||||
decodingType: APIResponse<[AcademyName]>.self)
|
||||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
printLog("\(error)")
|
||||
case .finished:
|
||||
break
|
||||
}
|
||||
} receiveValue: { [weak self] response in
|
||||
guard let self = self else {return}
|
||||
guard let academyNames = response as? APIResponse<[AcademyName]> else {return}
|
||||
self.academyList = academyNames.data
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toggleSelection(for index: Int){
|
||||
if selectNum == index {
|
||||
selectNum = -1
|
||||
} else {
|
||||
selectNum = index
|
||||
}}
|
||||
}
|
|
@ -11,7 +11,6 @@ import KakaoSDKCommon
|
|||
import KakaoSDKAuth
|
||||
import KakaoSDKUser
|
||||
|
||||
import Alamofire
|
||||
import Foundation
|
||||
|
||||
class LoginController {
|
||||
|
@ -29,7 +28,6 @@ class LoginController {
|
|||
}
|
||||
})
|
||||
.eraseToAnyPublisher()
|
||||
//
|
||||
|
||||
case .Apple:
|
||||
return Fail(error: NSError(domain: "Apple login not implemented", code: 1, userInfo: nil))
|
||||
|
|
|
@ -16,12 +16,13 @@ public func loadAPIData<T: Decodable>(url: String, path: String,
|
|||
parameters: [String: Any],
|
||||
headers: HTTPHeaders = [:],//["Accept": "application/json"],
|
||||
decodingType: T.Type) -> Future<Any, Error> {
|
||||
let encoding: ParameterEncoding = (method == .get) ? URLEncoding.default : JSONEncoding.default
|
||||
return Future { promise in
|
||||
printLog(parameters)
|
||||
AF.request("\(url)\(path)",
|
||||
method: method,
|
||||
parameters: parameters,
|
||||
encoding: JSONEncoding.default,
|
||||
encoding: encoding,
|
||||
headers: headers
|
||||
)
|
||||
.validate(statusCode: 200 ..< 300)
|
||||
|
@ -38,3 +39,5 @@ public func loadAPIData<T: Decodable>(url: String, path: String,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,10 +8,6 @@
|
|||
import SwiftUI
|
||||
|
||||
protocol MultilineStyle: View {
|
||||
// func lineLimit(_ limit: Int?) -> Self
|
||||
// func minimumScaleFactor(_ scale: CGFloat) -> Self
|
||||
// func multilineTextAlignment(_ alignment: TextAlignment) -> Self
|
||||
// func truncationMode(_ mode: Text.TruncationMode) -> Self
|
||||
}
|
||||
|
||||
extension Text: MultilineStyle {
|
||||
|
|
|
@ -21,6 +21,13 @@
|
|||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>10.149.217.64</key>
|
||||
<dict>
|
||||
<key>NSIncludesSubdomains</key>
|
||||
<true/>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>ipstein.myds.me</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
|
|
Loading…
Reference in New Issue
Block a user