Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 12 additions & 0 deletions Projects/CommonUI/CommonUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
950A0D562E5C29D000C07CF2 /* LMTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950A0D552E5C29CC00C07CF2 /* LMTextField.swift */; };
950A0D602E5C3C7000C07CF2 /* LMButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950A0D5F2E5C3C6D00C07CF2 /* LMButton.swift */; };
950A0D622E5C562700C07CF2 /* LMInputField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950A0D612E5C561400C07CF2 /* LMInputField.swift */; };
950A0D962E605CEA00C07CF2 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950A0D952E605CE300C07CF2 /* UIStackView+Extension.swift */; };
BAD8B768F782046D4AA1C073 /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3DE048BEDCB92B48F401061 /* RxCocoa.framework */; };
BE81B1F3E60D37D75A058D2B /* SnapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CCDC15081A22BAED6318E3E /* SnapKit.framework */; };
C2B0F8237715D14D8797DBC9 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012F45F908769FA7C3C0792F /* LoginView.swift */; };
Expand Down Expand Up @@ -74,6 +75,7 @@
950A0D552E5C29CC00C07CF2 /* LMTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMTextField.swift; sourceTree = "<group>"; };
950A0D5F2E5C3C6D00C07CF2 /* LMButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMButton.swift; sourceTree = "<group>"; };
950A0D612E5C561400C07CF2 /* LMInputField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMInputField.swift; sourceTree = "<group>"; };
950A0D952E605CE300C07CF2 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.swift"; sourceTree = "<group>"; };
9CCDC15081A22BAED6318E3E /* SnapKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BACC7259FC0C14CB352A4E6B /* OptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionView.swift; sourceTree = "<group>"; };
C28FE6392E1612667826E5C5 /* DiaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -184,6 +186,14 @@
path = Component;
sourceTree = "<group>";
};
950A0D942E605CE100C07CF2 /* Extension */ = {
isa = PBXGroup;
children = (
950A0D952E605CE300C07CF2 /* UIStackView+Extension.swift */,
);
path = Extension;
sourceTree = "<group>";
};
9786E1056828B1E6D5EDAB7C /* View */ = {
isa = PBXGroup;
children = (
Expand All @@ -208,6 +218,7 @@
BADD047B94176A526A5B7FB2 /* Sources */ = {
isa = PBXGroup;
children = (
950A0D942E605CE100C07CF2 /* Extension */,
950A0D522E5C296400C07CF2 /* Component */,
15CD642D82E9115C7976C408 /* Assets */,
88FA467F361B11350139B775 /* Base */,
Expand Down Expand Up @@ -336,6 +347,7 @@
7DC59B80630854028C7C80F4 /* TuistBundle+CommonUI.swift in Sources */,
F3DA12FF4D18AE405F2F6B08 /* BaseViewController.swift in Sources */,
E0865F2849CCB89CC83D3B77 /* Coordinator.swift in Sources */,
950A0D962E605CEA00C07CF2 /* UIStackView+Extension.swift in Sources */,
E055AA66777B1D4CC8C884E4 /* CommonUIAssets.swift in Sources */,
950A0D4F2E5AADB500C07CF2 /* SignUpView.swift in Sources */,
F7673E4248628D67F3542848 /* ChatView.swift in Sources */,
Expand Down
40 changes: 39 additions & 1 deletion Projects/CommonUI/Sources/Component/LMInputField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import UIKit

public class LMInputField: UIStackView {

public var onEmailButtonTapped: ((String) -> Void)?

public enum InputType {
case email
case password
Expand Down Expand Up @@ -62,7 +64,7 @@ public class LMInputField: UIStackView {

warningLabel = warningLabel.then {
$0.text = waringText
$0.textColor = CommonUIAssets.LMRed2
$0.textColor = .clear
$0.font = UIFont.systemFont(ofSize: 13, weight: .light)
}
}
Expand All @@ -88,6 +90,7 @@ public class LMInputField: UIStackView {
let emailButton = LMButton(textColor: CommonUIAssets.LMBlack,
bgColor: CommonUIAssets.LMOrange1).then {
$0.setTitle(buttonTitle, for: .normal)
$0.addTarget(self, action: #selector(emailButtonTapped), for: .touchUpInside)
}

[inputTextField, emailButton]
Expand Down Expand Up @@ -143,4 +146,39 @@ public class LMInputField: UIStackView {
$0.width.equalToSuperview()
}
}

@objc private func emailButtonTapped() {
onEmailButtonTapped?(inputTextField.text ?? "")
}

public func showWarning() {
warningLabel.textColor = CommonUIAssets.LMRed2
}

public func hideWarning() {
warningLabel.textColor = .clear
}

public func currentText() -> String {
return inputTextField.text ?? ""
}

public func disableButton(buttonTitle: String) {
for subview in self.arrangedSubviews {
if let stackView = subview as? UIStackView {
for stackSubview in stackView.arrangedSubviews {
if let textField = stackSubview as? LMTextField {
textField.isEnabled = false
}

if let button = stackSubview as? LMButton {
button.setTitle(buttonTitle, for: .normal)
button.isEnabled = false
button.backgroundColor = CommonUIAssets.LMGray5
button.setTitleColor(CommonUIAssets.LMWhite, for: .normal)
}
}
}
}
}
}
2 changes: 2 additions & 0 deletions Projects/CommonUI/Sources/Coordinator/Coordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public enum CoordinatorType {
case diary
case stats
case myPage
case signIn
case signUp
}

public protocol Coordinator: AnyObject {
Expand Down
17 changes: 17 additions & 0 deletions Projects/CommonUI/Sources/Extension/UIStackView+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// UIStackView+Extension.swift
// CommonUI
//
// Created by 박지윤 on 8/28/25.
//

import UIKit

extension UIStackView {
public func getText() -> String {
return arrangedSubviews
.compactMap { $0 as? LMTextField }
.map { $0.text ?? "" }
.joined(separator: " ")
}
}
12 changes: 6 additions & 6 deletions Projects/CommonUI/Sources/View/Login/SignUpView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ import Then
open class SignUpView: UIView {
var inputFieldStackView = UIStackView()

let nameInputField = LMInputField(inputText: "이름",
public let nameInputField = LMInputField(inputText: "이름",
inputPlaceholder: "이름을 입력하세요",
warningText: " 이름은 필수입니다")
let emailInputField = LMInputField(inputType: .email,
public let emailInputField = LMInputField(inputType: .email,
inputText: "이메일",
inputPlaceholder: " 이메일을 입력하세요",
warningText: " 이메일 형식이 올바르지 않습니다",
buttonTitle: "인증 요청")
let authenticationInputField = LMInputField(inputType: .email,
public let confirmInputField = LMInputField(inputType: .email,
inputText: "인증번호",
inputPlaceholder: " 인증번호를 입력하세요",
warningText: " 인증번호가 일치하지 않습니다",
buttonTitle: "확인")
let passwordInputField = LMInputField(inputType: .password,
public let passwordInputField = LMInputField(inputType: .password,
inputText: "비밀번호",
inputPlaceholder: "비밀번호를 입력하세요",
warningText: " 비밀번호 형식이 올바르지 않습니다")
let passwordCheckInputField = LMInputField(inputText: "비밀번호 확인",
public let passwordCheckInputField = LMInputField(inputText: "비밀번호 확인",
inputPlaceholder: "비밀번호를 한번 더 입력하세요",
warningText: " 비밀번호가 일치하지 않습니다")

Expand Down Expand Up @@ -61,7 +61,7 @@ open class SignUpView: UIView {
func initUI() {
self.addSubview(inputFieldStackView)

[nameInputField, emailInputField, authenticationInputField, passwordInputField, passwordCheckInputField]
[nameInputField, emailInputField, confirmInputField, passwordInputField, passwordCheckInputField]
.forEach { inputFieldStackView.addArrangedSubview($0) }

inputFieldStackView.snp.makeConstraints {
Expand Down
17 changes: 10 additions & 7 deletions Projects/Data/Data.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
archiveVersion = 1;
classes = {
};
objectVersion = 55;
objectVersion = 56;
objects = {

/* Begin PBXBuildFile section */
34FD760EB97BB96E9D770BF0 /* LoginRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D7624DE90CFBBEF778E120E /* LoginRepository.swift */; };
43E9C2380F425520C1FA1AD2 /* CourseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAAC2885ACFE998578DC25E8 /* CourseDTO.swift */; };
684AAEA9796EED3F9FC592FC /* NetworkConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D46FD93B80D052843AD5063 /* NetworkConfiguration.swift */; };
901ACA7B98089AB702ADA830 /* Domain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06FAA1459D11CCE724C34195 /* Domain.framework */; };
950A0D702E5CCF0200C07CF2 /* SignRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950A0D6F2E5CCEFD00C07CF2 /* SignRepository.swift */; };
950A0D902E6039D600C07CF2 /* DefaultDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950A0D8F2E6039D300C07CF2 /* DefaultDTO.swift */; };
A334985695DC9388841BBC43 /* QuizRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCA951B89F2C3D20AA31F7F /* QuizRepository.swift */; };
B2F8FBFA915F696CCCA4152A /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A3B0D3D8C7049B6856791C1D /* Alamofire.framework */; };
E1BFC73FB539432F6E12CD94 /* CourseRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0730BC3657E24BCEA511A3C /* CourseRepository.swift */; };
Expand Down Expand Up @@ -41,6 +43,8 @@
4E75197C294DE74F5162FAA7 /* Data.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Data.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5D46FD93B80D052843AD5063 /* NetworkConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConfiguration.swift; sourceTree = "<group>"; };
77810122262C6CB16D4D47DA /* QuizDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuizDTO.swift; sourceTree = "<group>"; };
950A0D6F2E5CCEFD00C07CF2 /* SignRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignRepository.swift; sourceTree = "<group>"; };
950A0D8F2E6039D300C07CF2 /* DefaultDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultDTO.swift; sourceTree = "<group>"; };
A3B0D3D8C7049B6856791C1D /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A44BC1E2E75FC256F832CA38 /* LoginDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginDTO.swift; sourceTree = "<group>"; };
AAAC2885ACFE998578DC25E8 /* CourseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDTO.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -73,6 +77,7 @@
647255CD65221C9CD4A43DED /* DTO */ = {
isa = PBXGroup;
children = (
950A0D8F2E6039D300C07CF2 /* DefaultDTO.swift */,
AAAC2885ACFE998578DC25E8 /* CourseDTO.swift */,
A44BC1E2E75FC256F832CA38 /* LoginDTO.swift */,
77810122262C6CB16D4D47DA /* QuizDTO.swift */,
Expand All @@ -83,6 +88,7 @@
73F3ED55BFDC2EF15878F5B6 /* Repository */ = {
isa = PBXGroup;
children = (
950A0D6F2E5CCEFD00C07CF2 /* SignRepository.swift */,
B0730BC3657E24BCEA511A3C /* CourseRepository.swift */,
3D7624DE90CFBBEF778E120E /* LoginRepository.swift */,
3CCA951B89F2C3D20AA31F7F /* QuizRepository.swift */,
Expand Down Expand Up @@ -172,8 +178,6 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
TargetAttributes = {
};
};
buildConfigurationList = BDB112DA78B2B42275EC3A62 /* Build configuration list for PBXProject "Data" */;
compatibilityVersion = "Xcode 14.0";
Expand Down Expand Up @@ -212,8 +216,10 @@
FF43B3A4D0DC88307E918DB0 /* LoginDTO.swift in Sources */,
E9463A3FF42D5F0960245F80 /* QuizDTO.swift in Sources */,
684AAEA9796EED3F9FC592FC /* NetworkConfiguration.swift in Sources */,
950A0D702E5CCF0200C07CF2 /* SignRepository.swift in Sources */,
E1BFC73FB539432F6E12CD94 /* CourseRepository.swift in Sources */,
34FD760EB97BB96E9D770BF0 /* LoginRepository.swift in Sources */,
950A0D902E6039D600C07CF2 /* DefaultDTO.swift in Sources */,
A334985695DC9388841BBC43 /* QuizRepository.swift in Sources */,
E6785667C8E247C344474CBB /* TokenRepository.swift in Sources */,
);
Expand Down Expand Up @@ -245,10 +251,7 @@
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = (
"$(inherited)",
DEBUG,
);
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
Expand Down
21 changes: 21 additions & 0 deletions Projects/Data/Sources/DTO/DefaultDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// DefaultDTO.swift
// Data
//
// Created by 박지윤 on 8/28/25.
//

import Foundation
import Domain

public struct DefaultDTO: Decodable {
public let is_success: Bool
public let code: String
public let message: String
}

extension DefaultDTO {
func getMessage() -> DefaultVO {
return .init(message: message)
}
}
75 changes: 75 additions & 0 deletions Projects/Data/Sources/Repository/SignRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// SignRepository.swift
// Data
//
// Created by 박지윤 on 8/26/25.
//

import Domain
import RxSwift
import Alamofire

public class DefaultSignRepository: SignRepository {

public init() { }

public func postEmail(email: String) -> Single<DefaultVO> {
let params = ["email": email]
return request(endpoint: "/api/auth/email",
parameters: params,
responseType: DefaultDTO.self)
.map { dto in
return dto.getMessage()
}
}

public func postConfirm(email: String, code: String) -> Single<DefaultVO> {
let params = ["email": email, "code": code]
return request(endpoint: "/api/auth/email/confirm",
parameters: params,
responseType: DefaultDTO.self)
.map { dto in
return dto.getMessage()
}
}

public func postSignUp(username: String, email: String, password: String) -> Single<DefaultVO> {
let params = ["username": username, "email": email, "password": password]
return request(endpoint: "/api/auth/sign-up",
parameters: params,
responseType: DefaultDTO.self)
.map { dto in
return dto.getMessage()
}
}

private func request<T: Decodable>(
endpoint: String,
parameters: [String: Any]? = nil,
responseType: T.Type
) -> Single<T> {
return Single.create { single in
let url = "\(NetworkConfiguration.baseUrl)\(endpoint)"
let headers: HTTPHeaders = [:]
let request = AF.request(
url,
method: .post,
parameters: parameters,
encoding: JSONEncoding.default,
headers: headers
)
.validate()
.responseDecodable(of: responseType) { response in
switch response.result {
case .success(let value):
print("✅ API 응답 성공: \(value)")
single(.success(value))
case .failure(let error):
print("❌ API 응답 실패: \(error)")
single(.failure(error))
}
}
return Disposables.create { request.cancel() }
}
}
}
Loading
Loading