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 :: 로그인 Feature #70

Merged
merged 21 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9fcca4c
feat :: SigninFeature 모듈 추가
baekteun Oct 15, 2022
e52e32c
fix :: Common -> Base로 디펜던시 변경
baekteun Oct 16, 2022
18bc054
feat :: SigninComponent
baekteun Oct 16, 2022
8dd7bd5
feat :: signinview, signinviewmodel
baekteun Oct 16, 2022
21e0d90
Merge branch 'develop' of https://github.com/DSM-FLOW/DMS-iOS into 42…
baekteun Oct 16, 2022
2dc8946
Merge branch 'develop' of https://github.com/DSM-FLOW/DMS-iOS into 42…
baekteun Oct 16, 2022
4d421e5
Merge branch 'develop' of https://github.com/DSM-FLOW/DMS-iOS into 42…
baekteun Oct 17, 2022
f0e5135
Merge branch 'develop' of https://github.com/DSM-FLOW/DMS-iOS into 42…
baekteun Oct 17, 2022
c2014b5
feat :: SigninView
baekteun Oct 17, 2022
178c185
Merge branch 'develop' of https://github.com/DSM-FLOW/DMS-iOS into 42…
baekteun Oct 17, 2022
3431caa
Merge branch 'develop' of https://github.com/DSM-FLOW/DMS-iOS into 42…
baekteun Oct 18, 2022
2a69e5c
feat :: SigninView
baekteun Oct 18, 2022
689346b
feat :: view + navigate
baekteun Oct 18, 2022
07573a4
rename :: isNavigation -> isNavigate
baekteun Oct 18, 2022
4937375
feat :: Signin Scene UI
baekteun Oct 19, 2022
870c3f4
Merge branch 'develop' of https://github.com/DSM-FLOW/DMS-iOS into 42…
baekteun Oct 19, 2022
63eee5f
feat :: TextField에 textContetnType 지정
baekteun Oct 19, 2022
638725b
feat :: addCancellable 로그인 execute
baekteun Oct 19, 2022
e619426
feat :: navigateSignup
baekteun Oct 19, 2022
7348c90
feat ::TextField 유효성 검사 조건 변경
baekteun Oct 19, 2022
da7a4c2
test :: SigninViewModelSpec
baekteun Oct 19, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public extension TargetDependency {
}

public extension TargetDependency.Project.Features {
static let SigninFeature = TargetDependency.feature(name: "SigninFeature")
static let BaseFeature = TargetDependency.feature(name: "BaseFeature")
static let RootFeature = TargetDependency.feature(name: "RootFeature")
}
Expand Down
7 changes: 7 additions & 0 deletions Projects/App/Sources/Application/DI/AppComponent.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import NeedleFoundation
import SwiftUI
import KeychainModule
import SigninFeature

public final class AppComponent: BootstrapComponent {
public func makeRootView() -> some View {
Expand All @@ -11,3 +12,9 @@ public final class AppComponent: BootstrapComponent {
KeychainImpl()
}
}

public extension AppComponent {
var signinComponent: SigninComponent {
SigninComponent(parent: self)
}
}
9 changes: 8 additions & 1 deletion Projects/App/Sources/Application/DMSApp.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import SwiftUI
import DesignSystem
import SigninFeature

@main
struct DMSApp: App {
init() {
registerProviderFactories()
}

var body: some Scene {
WindowGroup {
DesignSystemPlaygroundView()
NavigationView {
AppComponent().signinComponent.makeView()
}
}
}
}
37 changes: 37 additions & 0 deletions Projects/App/Sources/Application/NeedleGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import DomainModule
import KeychainModule
import NeedleFoundation
import NetworkModule
import SigninFeature
import SwiftUI

// swiftlint:disable unused_declaration
Expand All @@ -20,11 +21,46 @@ private func parent1(_ component: NeedleFoundation.Scope) -> NeedleFoundation.Sc

#if !NEEDLE_DYNAMIC

private class SigninDependencyde06a9d0b22764487733Provider: SigninDependency {
var signinUseCase: any SigninUseCase {
return appComponent.signinUseCase
}
private let appComponent: AppComponent
init(appComponent: AppComponent) {
self.appComponent = appComponent
}
}
/// ^->AppComponent->SigninComponent
private func factory2882a056d84a613debccf47b58f8f304c97af4d5(_ component: NeedleFoundation.Scope) -> AnyObject {
return SigninDependencyde06a9d0b22764487733Provider(appComponent: parent1(component) as! AppComponent)
}

#else
extension AppComponent: Registration {
public func registerItems() {

localTable["keychain-any Keychain"] = { self.keychain as Any }
localTable["remoteAuthDataSource-any RemoteAuthDataSource"] = { self.remoteAuthDataSource as Any }
localTable["authRepository-any AuthRepository"] = { self.authRepository as Any }
localTable["signinUseCase-any SigninUseCase"] = { self.signinUseCase as Any }
localTable["verifyAuthCodeUseCase-any VerifyAuthCodeUseCase"] = { self.verifyAuthCodeUseCase as Any }
localTable["sendAuthCodeUseCase-any SendAuthCodeUseCase"] = { self.sendAuthCodeUseCase as Any }
localTable["checkEmailExistByAccountIDUseCase-any CheckEmailExistByAccountIDUseCase"] = { self.checkEmailExistByAccountIDUseCase as Any }
localTable["checkAccountIDIsExistUseCase-any CheckAccountIDIsExistUseCase"] = { self.checkAccountIDIsExistUseCase as Any }
localTable["signinComponent-SigninComponent"] = { self.signinComponent as Any }
localTable["remoteStudentsDataSource-any RemoteStudentsDataSource"] = { self.remoteStudentsDataSource as Any }
localTable["studentsRepository-any StudentsRepository"] = { self.studentsRepository as Any }
localTable["signupUseCase-any SignupUseCase"] = { self.signupUseCase as Any }
localTable["checkDuplicateAccountIDUseCase-any CheckDuplicateAccountIDUseCase"] = { self.checkDuplicateAccountIDUseCase as Any }
localTable["checkDuplicateEmailUseCase-any CheckDuplicateEmailUseCase"] = { self.checkDuplicateEmailUseCase as Any }
localTable["renewalPasswordUseCase-any RenewalPasswordUseCase"] = { self.renewalPasswordUseCase as Any }
localTable["findIDUseCase-any FindIDUseCase"] = { self.findIDUseCase as Any }
localTable["fetchMyProfileUseCase-any FetchMyProfileUseCase"] = { self.fetchMyProfileUseCase as Any }
}
}
extension SigninComponent: Registration {
public func registerItems() {
keyPathToName[\SigninDependency.signinUseCase] = "signinUseCase-any SigninUseCase"
}
}

Expand All @@ -44,6 +80,7 @@ private func registerProviderFactory(_ componentPath: String, _ factory: @escapi

private func register1() {
registerProviderFactory("^->AppComponent", factoryEmptyDependencyProvider)
registerProviderFactory("^->AppComponent->SigninComponent", factory2882a056d84a613debccf47b58f8f304c97af4d5)
}
#endif

Expand Down
3 changes: 2 additions & 1 deletion Projects/Features/RootFeature/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ let project = Project.makeModule(
name: "RootFeature",
product: .staticFramework,
dependencies: [
.Project.Features.BaseFeature
.Project.Features.BaseFeature,
.Project.Features.SigninFeature
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
10 changes: 10 additions & 0 deletions Projects/Features/SigninFeature/Project.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import ProjectDescription
import ProjectDescriptionHelpers

let project = Project.makeModule(
name: "SigninFeature",
product: .staticFramework,
dependencies: [
.Project.Features.BaseFeature
]
)
17 changes: 17 additions & 0 deletions Projects/Features/SigninFeature/Sources/SigninComponent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import DomainModule
import NeedleFoundation
import SwiftUI

public protocol SigninDependency: Dependency {
var signinUseCase: any SigninUseCase { get }
}

public final class SigninComponent: Component<SigninDependency> {
public func makeView() -> some View {
SigninView(
viewModel: .init(
signinUseCase: dependency.signinUseCase
)
)
}
}
117 changes: 117 additions & 0 deletions Projects/Features/SigninFeature/Sources/SigninView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import SwiftUI
import DesignSystem

struct SigninView: View {
private enum FocusField {
case id
case password
}
@StateObject var viewModel: SigninViewModel
@FocusState private var focusField: FocusField?

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

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

Text("더 편한 기숙사 생활을 위해")
.dmsFont(.text(.medium), color: .GrayScale.gray6)
}

Spacer()
}

VStack(spacing: 72) {
DMSFloatingTextField(
"아이디",
text: $viewModel.id,
isError: viewModel.isErrorOcuured
) {
focusField = .password
}
.textContentType(.username)
.focused($focusField, equals: .id)

SecureDMSFloatingTextField("비밀번호", text: $viewModel.password) {
viewModel.signinButtonDidTap()
}
.textContentType(.password)
.focused($focusField, equals: .password)
}
.padding(.top, 68)

HStack(spacing: 16) {
HStack(spacing: 12) {
DMSRadioButton(isOn: $viewModel.isOnAutoSignin)

Text("자동로그인")
.dmsFont(.text(.small), color: .GrayScale.gray6)
}
.onTapGesture {
withAnimation {
viewModel.isOnAutoSignin.toggle()
}
}

Spacer()

NavigationLink {
Text("아이디 찾기")
} label: {
Text("아이디 찾기")
.dmsFont(.text(.extraSmall), color: .GrayScale.gray5)
}

Divider()
.foregroundColor(.GrayScale.gray5)
.frame(height: 13)

NavigationLink {
Text("비밀번호 재설정")
} label: {
Text("비밀번호 재설정")
.dmsFont(.text(.extraSmall), color: .GrayScale.gray5)
}
}
.padding(.top, 16)

Spacer()

HStack(spacing: 16) {
Text("아직 회원이 아니신가요?")
.dmsFont(.text(.extraSmall), color: .GrayScale.gray5)

DMSButton(text: "회원가입", style: .text, color: .GrayScale.gray6) {
viewModel.isNavigateSignup.toggle()
}
}

DMSWideButton(text: "로그인", color: .PrimaryVariant.primary) {
viewModel.signinButtonDidTap()
}
.disabled(!viewModel.isSigninButtonEnabled)
.padding(.top, 24)
.frame(maxWidth: .infinity)
.padding(.bottom, 40)
}
.dmsToast(isShowing: $viewModel.isErrorOcuured, message: viewModel.errorMessage, style: .error)
.frame(maxWidth: .infinity)
.padding(.horizontal, 24)
.dmsBackground()
.navigate(to: Text("회원가입"), when: $viewModel.isNavigateSignup)
.ignoresSafeArea(.keyboard, edges: .bottom)
}
}

struct SigninView_Previews: PreviewProvider {
static var previews: some View {
Text("A")
}
}
27 changes: 27 additions & 0 deletions Projects/Features/SigninFeature/Sources/SigninViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import BaseFeature
import Combine
import DomainModule

final class SigninViewModel: BaseViewModel {
@Published var id = ""
@Published var password = ""
@Published var isOnAutoSignin = true
@Published var isNavigateSignup = false
@Published var isSuccessSignin = false
var isSigninButtonEnabled: Bool {
!id.isEmpty && !password.isEmpty
}

private let signinUseCase: any SigninUseCase

public init(signinUseCase: any SigninUseCase) {
self.signinUseCase = signinUseCase
}

func signinButtonDidTap() {
guard isSigninButtonEnabled else { return }
addCancellable(signinUseCase.execute(req: .init(accountID: id, password: password))) { [weak self] _ in
self?.isSuccessSignin = true
}
}
}
Loading