Skip to content

Commit

Permalink
Merge pull request #100 from TeamHY2/Fix/#99-Signup_TextField
Browse files Browse the repository at this point in the history
  • Loading branch information
Seokki-Kwon authored Nov 15, 2024
2 parents dc0285a + 40237ad commit c5768ed
Show file tree
Hide file tree
Showing 21 changed files with 314 additions and 303 deletions.
66 changes: 38 additions & 28 deletions HongikYeolgong2.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final class AuthRepositoryImpl: AuthRepository {
do {
let response: BaseResponse<LoginResponseDTO> = try await NetworkService.shared.request(endpoint: AuthEndpoint.login(loginReqDto: loginReqDto))
promise(.success(response.data))
} catch let error as NetworkError {
} catch let error as NetworkError {
promise(.failure(error))
}
}
Expand All @@ -33,7 +33,7 @@ final class AuthRepositoryImpl: AuthRepository {
return Future<Bool, NetworkError> { promise in
Task {
do {
let response: BaseResponse<NicknameCheckDTO> = try await NetworkService.shared.request(endpoint: UserEndpoint.checkUserNickname(nickname: nickname))
let response: BaseResponse<NicknameCheckDTO> = try await NetworkService.shared.request(endpoint: UserEndpoint.checkUserNickname(nickname: nickname))
promise(.success(response.data.duplicate))
} catch let error as NetworkError {
promise(.failure(error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ final class StudySessionInteractorImpl: StudySessionInteractor {
}

/// 열람실 이용종료 Notification을 등록합니다.
func registerNotification(for type: StudyNotificationType, endTimeInMinute: TimeInterval) {
func registerNotification(for type: LocalNotification, endTimeInMinute: TimeInterval) {
guard appState.value.userData.isOnAlarm else { return }
let content = configuredNotificationContent(for: type)
let trigger = configuredNotificationTrigger(for: type, endTime: endTimeInMinute)
Expand All @@ -153,15 +153,15 @@ final class StudySessionInteractorImpl: StudySessionInteractor {
}

/// Notification Content 설정
func configuredNotificationContent(for type: StudyNotificationType) -> UNMutableNotificationContent {
func configuredNotificationContent(for type: LocalNotification) -> UNMutableNotificationContent {
let content = UNMutableNotificationContent()
content.body = type.message
content.sound = .default
return content
}

/// Notification Trigger 설정
func configuredNotificationTrigger(for type: StudyNotificationType, endTime: TimeInterval) -> UNTimeIntervalNotificationTrigger? {
func configuredNotificationTrigger(for type: LocalNotification, endTime: TimeInterval) -> UNTimeIntervalNotificationTrigger? {
let triggerTime = endTime - type.timeOffset

assert(endTime - triggerTime == type.timeOffset, "잘못된 시간이 등록되었습니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ final class UserDataMigrationInteractor: UserDataInteractor {
/// - Parameter authorization: ASAuthorization
func requestAppleLogin(_ authorization: ASAuthorization) {
guard let appleIDCredential = appleLoginService.requestAppleLogin(authorization),
let idTokenData = appleIDCredential.identityToken,
let idToken = String(data: idTokenData, encoding: .utf8) else {
let idTokenData = appleIDCredential.identityToken,
let idToken = String(data: idTokenData, encoding: .utf8) else {
return
}

Expand All @@ -89,15 +89,14 @@ final class UserDataMigrationInteractor: UserDataInteractor {
return Fail(error: NetworkError.decodingError("")).eraseToAnyPublisher()
}
let loginReqDto: LoginRequestDTO = .init(email: userID, idToken: idToken)

return authRepository.signIn(loginReqDto: loginReqDto)
}
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { _ in},
receiveValue: { [weak self] loginResDto in

guard let self = self else { return }
guard let self = self else { return }

let isAlreadyExists = loginResDto.alreadyExist

Expand Down Expand Up @@ -127,7 +126,7 @@ final class UserDataMigrationInteractor: UserDataInteractor {
guard let self = self else { return }
appState[\.userSession] = .authenticated
appState[\.routing.onboarding.signUp] = false
KeyChainManager.addItem(key: .accessToken, value: signUpResDto.accessToken)
KeyChainManager.addItem(key: .accessToken, value: signUpResDto.accessToken)
}
)
.store(in: cancleBag)
Expand All @@ -143,12 +142,12 @@ final class UserDataMigrationInteractor: UserDataInteractor {
/// - Parameters:
/// - nickname: 닉네임
/// - isValidate: 중복여부
func checkUserNickname(nickname: String, nicknameCheckSubject: CurrentValueSubject<Bool, Never>) {
func checkUserNickname(inputNickname: String, nickname: Binding<Nickname>) {
authRepository
.checkUserNickname(nickname: nickname)
.checkUserNickname(nickname: inputNickname)
.replaceError(with: true)
.receive(on: DispatchQueue.main)
.sink { nicknameCheckSubject.send($0) }
.sink { $0 ? (nickname.wrappedValue = .alreadyUse) : (nickname.wrappedValue = .available) }
.store(in: cancleBag)
}

Expand Down Expand Up @@ -191,6 +190,40 @@ final class UserDataMigrationInteractor: UserDataInteractor {
.store(in: cancleBag)
}

func validateUserNickname(inputNickname: String, nickname: Binding<Nickname>) {
if inputNickname.isEmpty {
nickname.wrappedValue = .none
} else if inputNickname.count < 2 || inputNickname.count > 8 {
nickname.wrappedValue = .notAllowedLength
} else if inputNickname.contains(" ") || checkSpecialCharacter(inputNickname) {
nickname.wrappedValue = .specialCharactersAndSpaces
} else if checkKoreanLang(inputNickname) {
nickname.wrappedValue = .checkAvailable
} else {
nickname.wrappedValue = .unknown
}
}

func checkSpecialCharacter(_ input: String) -> Bool {
let pattern: String = "[!\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~€£¥₩¢₹©®™§¶°•※≡∞≠≈‽✓✔✕✖←→↑↓↔↕↩↪↖↗↘↙ñ¡¿éèêëçäöüßàìòùåøæ]"

if let _ = input.range(of: pattern, options: .regularExpression) {
return true
} else {
return false
}
}

func checkKoreanLang(_ input: String) -> Bool {
let pattern = "^[가-힣a-zA-Z0-9\\s]*$"

if let _ = input.range(of: pattern, options: .regularExpression) {
return true
} else {
return false
}
}

/// 회원 탈퇴
func withdraw() {
let clientSecret = makeJWT()
Expand Down
15 changes: 11 additions & 4 deletions HongikYeolgong2/Domain/Interactors/UserDataInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ protocol UserDataInteractor: AnyObject {
func signUp(nickname: String, department: Department)
func logout()
func checkAuthentication()
func checkUserNickname(nickname: String, nicknameCheckSubject: CurrentValueSubject<Bool, Never>)
func checkUserNickname(inputNickname: String, nickname: Binding<Nickname>)
func validateUserNickname(inputNickname: String, nickname: Binding<Nickname>)
func getUserProfile()
func withdraw()
}

final class UserDataInteractorImpl: UserDataInteractor {
func validateUserNickname(inputNickname: String, nickname: Binding<Nickname>) {

}


private let cancleBag = CancelBag()
private let appState: Store<AppState>
Expand Down Expand Up @@ -98,12 +103,14 @@ final class UserDataInteractorImpl: UserDataInteractor {
/// - Parameters:
/// - nickname: 닉네임
/// - isValidate: 중복여부
func checkUserNickname(nickname: String, nicknameCheckSubject: CurrentValueSubject<Bool, Never>) {
func checkUserNickname(inputNickname: String, nickname: Binding<Nickname>) {
authRepository
.checkUserNickname(nickname: nickname)
.checkUserNickname(nickname: inputNickname)
.replaceError(with: true)
.receive(on: DispatchQueue.main)
.sink { nicknameCheckSubject.send($0) }
.filter { !$0 }
.map { _ in }
.sink { nickname.wrappedValue = .available}
.store(in: cancleBag)
}

Expand Down
2 changes: 1 addition & 1 deletion HongikYeolgong2/Models/Department.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ enum Department: String, CaseIterable {
case frenchStudies = "프랑스어문학과"
case painting = "회화과"

static func allDepartments() -> [String] {
static var allDepartments: [String] {
Self.allCases.filter { $0 != .none }.map { $0.rawValue }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

enum StudyNotificationType {
enum LocalNotification {
case extensionAvailable
case urgent

Expand Down
45 changes: 2 additions & 43 deletions HongikYeolgong2/Models/Nickname.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,48 +45,7 @@ enum Nickname {
}
}

static func validate(_ nickname: String) -> Nickname {
var status: Nickname = .none
status.validateUserNickname(nickname: nickname)
return status
}

private enum Constant {
static let minLength = 2
static let maxLength = 8
}

mutating func validateUserNickname(nickname: String) {
if nickname.isEmpty {
self = .none
} else if nickname.count < Constant.minLength || nickname.count > Constant.maxLength {
self = .notAllowedLength
} else if nickname.contains(" ") || checkSpecialCharacter(nickname) {
self = .specialCharactersAndSpaces
} else if checkKoreanLang(nickname) {
self = .checkAvailable
} else {
self = .unknown
}
}

func checkSpecialCharacter(_ input: String) -> Bool {
let pattern: String = "[!\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~€£¥₩¢₹©®™§¶°•※≡∞≠≈‽✓✔✕✖←→↑↓↔↕↩↪↖↗↘↙ñ¡¿éèêëçäöüßàìòùåøæ]"

if let _ = input.range(of: pattern, options: .regularExpression) {
return true
} else {
return false
}
}

func checkKoreanLang(_ input: String) -> Bool {
let pattern = "^[가-힣a-zA-Z\\s]*$"

if let _ = input.range(of: pattern, options: .regularExpression) {
return true
} else {
return false
}
var isCheckable: Bool {
self == .checkAvailable
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// DuplicateCheckButton.swift
// HongikYeolgong2
//
// Created by 권석기 on 11/15/24.
//

import SwiftUI

struct DuplicateCheckButton: View {
let action: () -> Void
let disabled: Bool

var body: some View {
Button(action: action, label: {
Text("중복확인")
.foregroundStyle(disabled ? Color.gray200 : Color.white)
.frame(maxWidth: 88.adjustToScreenWidth, maxHeight: 48.adjustToScreenHeight)
})
.background(disabled ? Color.blue400 : Color.blue100)
.disabled(disabled)
.cornerRadius(8)
}
}

#Preview {
DuplicateCheckButton(action: {}, disabled: false)
}
46 changes: 46 additions & 0 deletions HongikYeolgong2/Presentation/Auth/SignUp/Component/Form.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Form.swift
// HongikYeolgong2
//
// Created by 권석기 on 11/15/24.
//

import SwiftUI

struct FormTitle: View {
let title: String

var body: some View {
Text(title)
.font(.suite(size: 18, weight: .bold))
.foregroundStyle(.gray100)
.frame(
maxWidth: .infinity,
maxHeight: 52.adjustToScreenHeight,
alignment: .leading
)
.background(Color.black)
}
}

struct FormLabel: View {
let title: String

var body: some View {
Text(title)
.font(.pretendard(size: 16, weight: .bold), lineHeight: 26)
.foregroundStyle(.gray200)
}
}

struct FormDescription: View {
let message: String
let color: Color

var body: some View {
Text(message)
.font(.pretendard(size: 12, weight: .regular))
.foregroundStyle(color)
.padding(.top, 4.adjustToScreenHeight)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// SubmitButton.swift
// HongikYeolgong2
//
// Created by 권석기 on 11/15/24.
//

import SwiftUI

struct SubmitButton: View {
let action: () -> ()
let disabled: Bool

var body: some View {
Button(action: action) {
Image(.submitButtonEnable)
.resizable()
.frame(height: 50.adjustToScreenHeight)
}
.disabled(disabled)
.overlay(disabled ? Color.dark.opacity(0.5) : nil)
}
}
Loading

0 comments on commit c5768ed

Please sign in to comment.