Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge :: 회원가입 - 비밀번호 설정 페이지 #106

Merged
merged 2 commits into from
Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Projects/App/Sources/Application/DI/AppComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public extension AppComponent {
var signupProfileImageComponent: SignupProfileImageComponent {
SignupProfileImageComponent(parent: self)
}
var signupPasswordComponent: SignupPasswordComponent {
SignupPasswordComponent(parent: self)
}
}

// MARK: - Main
Expand Down
2 changes: 1 addition & 1 deletion Projects/App/Sources/Application/DMSApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct DMSApp: App {

var body: some Scene {
WindowGroup {
AppComponent().mainTabComponent.makeView()
AppComponent().signupPasswordComponent.makeView()
}
}
}
18 changes: 18 additions & 0 deletions Projects/App/Sources/Application/NeedleGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ private class SchoolCodeDependencyc0114744c1c8c7843672Provider: SchoolCodeDepend
private func factoryb65c1efbf06b87162473f47b58f8f304c97af4d5(_ component: NeedleFoundation.Scope) -> AnyObject {
return SchoolCodeDependencyc0114744c1c8c7843672Provider(appComponent: parent1(component) as! AppComponent)
}
private class SignupPasswordDependency778bf5389a70d7df6152Provider: SignupPasswordDependency {


init() {

}
}
/// ^->AppComponent->SignupPasswordComponent
private func factorye93d1d56840ff97c674ae3b0c44298fc1c149afb(_ component: NeedleFoundation.Scope) -> AnyObject {
return SignupPasswordDependency778bf5389a70d7df6152Provider()
}
private class SignupEmailAuthCodeVerifyDependencyaf9da1ebf0e9e5f1b708Provider: SignupEmailAuthCodeVerifyDependency {
var sendAuthCodeUseCase: any SendAuthCodeUseCase {
return appComponent.sendAuthCodeUseCase
Expand Down Expand Up @@ -156,6 +167,7 @@ extension AppComponent: Registration {
localTable["signupEmailVerifyComponent-SignupEmailVerifyComponent"] = { self.signupEmailVerifyComponent as Any }
localTable["signupEmailAuthCodeVerifyComponent-SignupEmailAuthCodeVerifyComponent"] = { self.signupEmailAuthCodeVerifyComponent as Any }
localTable["signupProfileImageComponent-SignupProfileImageComponent"] = { self.signupProfileImageComponent as Any }
localTable["signupPasswordComponent-SignupPasswordComponent"] = { self.signupPasswordComponent as Any }
localTable["mainTabComponent-MainTabComponent"] = { self.mainTabComponent as Any }
localTable["homeComponent-HomeComponent"] = { self.homeComponent as Any }
localTable["remoteStudentsDataSource-any RemoteStudentsDataSource"] = { self.remoteStudentsDataSource as Any }
Expand Down Expand Up @@ -185,6 +197,11 @@ extension SchoolCodeComponent: Registration {
keyPathToName[\SchoolCodeDependency.checkSchoolCodeUseCase] = "checkSchoolCodeUseCase-any CheckSchoolCodeUseCase"
}
}
extension SignupPasswordComponent: Registration {
public func registerItems() {

}
}
extension SignupEmailAuthCodeVerifyComponent: Registration {
public func registerItems() {
keyPathToName[\SignupEmailAuthCodeVerifyDependency.sendAuthCodeUseCase] = "sendAuthCodeUseCase-any SendAuthCodeUseCase"
Expand Down Expand Up @@ -241,6 +258,7 @@ private func registerProviderFactory(_ componentPath: String, _ factory: @escapi
private func register1() {
registerProviderFactory("^->AppComponent", factoryEmptyDependencyProvider)
registerProviderFactory("^->AppComponent->SchoolCodeComponent", factoryb65c1efbf06b87162473f47b58f8f304c97af4d5)
registerProviderFactory("^->AppComponent->SignupPasswordComponent", factorye93d1d56840ff97c674ae3b0c44298fc1c149afb)
registerProviderFactory("^->AppComponent->SignupEmailAuthCodeVerifyComponent", factoryb06be35aa893adde971bf47b58f8f304c97af4d5)
registerProviderFactory("^->AppComponent->SignupEmailVerifyComponent", factory3b1904c76335d70151ebf47b58f8f304c97af4d5)
registerProviderFactory("^->AppComponent->SignupProfileImageComponent", factory6792674212c15df7e9cfe3b0c44298fc1c149afb)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import SwiftUI
import NeedleFoundation

public protocol SignupPasswordDependency: Dependency {}

public final class SignupPasswordComponent: Component<SignupPasswordDependency> {
public func makeView() -> some View {
SignupPasswordView(
viewModel: .init()
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import DesignSystem
import SwiftUI

struct SignupPasswordView: View {
private enum FocusField {
case password
case passwordCheck
}
@StateObject var viewModel: SignupPasswordViewModel
@FocusState private var focusField: FocusField?

public init(
viewModel: SignupPasswordViewModel
) {
_viewModel = StateObject(wrappedValue: viewModel)
}

var body: some View {
VStack(spacing: 4) {
HStack {
VStack(alignment: .leading, spacing: 8) {
Text("DMS")
.dmsFont(.title(.extraLarge), color: .PrimaryVariant.primary)

Text("학교 인증코드 입력")
.dmsFont(.text(.medium), color: .GrayScale.gray6)

Text("비밀번호는 영문, 숫자, 기호를 포함한 8~20자이어야 합니다.")
.dmsFont(.text(.extraSmall), color: .GrayScale.gray5)
}

Spacer()
}
.padding(.top, 24)

VStack(spacing: 56) {
SecureDMSFloatingTextField(
"비밀번호",
text: $viewModel.password,
isError: viewModel.isPasswordRegexError,
errorMessage: "비밀번호 형식이 올바르지 않습니다."
) {
focusField = .passwordCheck
}
.padding(.top, 56)
.focused($focusField, equals: .password)

SecureDMSFloatingTextField(
"비밀번호 확인",
text: $viewModel.passwordCheck,
isError: viewModel.isPasswordMismatchedError,
errorMessage: "비밀번호가 일치하지 않습니다."
) {
viewModel.nextButtonDidTap()
}
.focused($focusField, equals: .passwordCheck)
}

Spacer()

DMSWideButton(text: "다음", color: .PrimaryVariant.primary) {
viewModel.nextButtonDidTap()
}
.padding(.bottom, 40)
}
.dmsBackground()
.padding(.horizontal, 24)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import BaseFeature
import Combine
import Utility

final class SignupPasswordViewModel: BaseViewModel {
@Published var password = "" {
didSet { resettingError() }
}
@Published var passwordCheck = "" {
didSet { resettingError() }
}
@Published var isPasswordRegexError = false
@Published var isPasswordMismatchedError = false

var isEnabledNextStep: Bool {
!password.isEmpty && !passwordCheck.isEmpty
}

func nextButtonDidTap() {
guard isEnabledNextStep else {
return
}

let passwordExpression = "^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[!@#$%^&*()_+=-]).{8,20}"
guard password ~= passwordExpression else {
isPasswordRegexError = true
return
}

guard password == passwordCheck else {
isPasswordMismatchedError = true
return
}
}

func resettingError() {
isPasswordRegexError = false
isPasswordMismatchedError = false
}
}