Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/GSM-MSG/SMS-iOS into 334-…
Browse files Browse the repository at this point in the history
…authentication-form-ui-building
  • Loading branch information
baekteun committed Jul 6, 2024
2 parents 79491e2 + 352683f commit 8e987e5
Show file tree
Hide file tree
Showing 23 changed files with 427 additions and 11 deletions.
80 changes: 80 additions & 0 deletions Projects/Core/DesignSystem/Sources/Dialog/SMSDialog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ public extension View {
)
)
}

func smsDialog<DialogView: View>(
title: String,
isShowing: Binding<Bool>,
dialogActions: [SMSAlertButtonType],
@ViewBuilder dialogView: @escaping () -> DialogView = { EmptyView() }
) -> some View {
modifier(
SMSDialogModifier(
title: title,
isShowing: isShowing,
dialogActions: dialogActions,
dialogView: dialogView
)
)
}
}

struct SMSAlertModifier: ViewModifier {
Expand Down Expand Up @@ -82,3 +98,67 @@ struct SMSAlertModifier: ViewModifier {
.cornerRadius(16)
}
}

struct SMSDialogModifier<DialogView: View>: ViewModifier {
var title: String
@Binding var isShowing: Bool
var dialogActions: [SMSAlertButtonType]
var dialogView: () -> DialogView

public init(
title: String,
isShowing: Binding<Bool>,
dialogActions: [SMSAlertButtonType],
@ViewBuilder dialogView: @escaping () -> DialogView = { EmptyView() }
) {
self.title = title
_isShowing = isShowing
self.dialogActions = dialogActions
self.dialogView = dialogView
}

func body(content: Content) -> some View {
ZStack {
content

ConditionView(isShowing) {
Color.sms(.system(.black))
.opacity(0.25)
.ignoresSafeArea()

smsDialog()
.padding(40)
.transition(
.asymmetric(
insertion: AnyTransition.move(edge: .bottom),
removal: .move(edge: .bottom).combined(with: .opacity)
)
)
}
}
}

@ViewBuilder
func smsDialog() -> some View {
VStack(alignment: .leading, spacing: 24) {
Text(title)
.smsFont(.title2, color: .system(.black))

dialogView()
.padding(.bottom, 13)

HStack(spacing: 8) {
ForEach(dialogActions, id: \.id) { button in
CTAButton(
text: button.text,
style: button.style,
action: button.action
)
}
}
}
.padding(24)
.background(Color.sms(.system(.white)))
.cornerRadius(16)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ public protocol StudentDomainBuildable {
var inputInformationUseCase: any InputInformationUseCase { get }
var studentRepository: any StudentRepository { get }
var fetchStudentListUseCase: any FetchStudentListUseCase { get }
var fetchStudentDetailUSeCase: any FetchStudentDetailUseCase { get }
var fetchStudentDetailUseCase: any FetchStudentDetailUseCase { get }
var modifyInformationUseCase: any ModifyInformationUseCase { get }
var createPortfolioLinkUseCase: any CreatePortfolioLinkUseCase { get }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Foundation

public struct CreatePortfolioLinkRequestDTO: Encodable {
public let studentID: String
public let periodDay: Int

public init(
studentID: String,
periodDay: Int
) {
self.studentID = studentID
self.periodDay = periodDay
}

enum CodingKeys: String, CodingKey {
case studentID = "studentId"
case periodDay
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public protocol RemoteStudentDataSource {
func fetchStudentDetailByGuest(userID: String) async throws -> StudentDetailEntity
func fetchStudentDetailByTeacher(userID: String) async throws -> StudentDetailEntity
func modifyInformation(req: ModifyStudentInformationRequestDTO) async throws
func createPortfolioLink(req: CreatePortfolioLinkRequestDTO) async throws -> PortfolioLinkEntity
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

public struct PortfolioLinkEntity: Equatable {
public let token: String

public init(token: String) {
self.token = token
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public protocol StudentRepository {
func fetchStudentDetailByGuest(userID: String) async throws -> StudentDetailEntity
func fetchStudentDetailByTeacher(userID: String) async throws -> StudentDetailEntity
func modifyInformation(req: ModifyStudentInformationRequestDTO) async throws
func createPortfolioLink(req: CreatePortfolioLinkRequestDTO) async throws -> PortfolioLinkEntity
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

public protocol CreatePortfolioLinkUseCase {
func execute(req: CreatePortfolioLinkRequestDTO) async throws -> PortfolioLinkEntity
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ public final class StudentDomainComponent: Component<StudentDomainDependency>, S
public var fetchStudentListUseCase: any FetchStudentListUseCase {
FetchStudentListUseCaseImpl(studentRepository: studentRepository)
}
public var fetchStudentDetailUSeCase: any FetchStudentDetailUseCase {
public var fetchStudentDetailUseCase: any FetchStudentDetailUseCase {
FetchStudentDetailUseCaseImpl(studentRepository: studentRepository)
}
public var modifyInformationUseCase: any ModifyInformationUseCase {
ModifyInformationUseCaseImpl(studentRepository: studentRepository)
}
public var createPortfolioLinkUseCase: any CreatePortfolioLinkUseCase {
CreatePortfolioLinkUseCaseImpl(studentRepository: studentRepository)
}
public var studentRepository: any StudentRepository {
StudentRepositoryImpl(remoteStudentDataSource: remoteStudentDataSource)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import StudentDomainInterface

public struct CreatePortfolioLinkResponseDTO: Decodable {
public let token: String
}

public extension CreatePortfolioLinkResponseDTO {
func toDomain() -> PortfolioLinkEntity {
PortfolioLinkEntity(
token: token
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,12 @@ final class RemoteStudentDataSourceImpl: BaseRemoteDataSource<StudentEndpoint>,
func modifyInformation(req: ModifyStudentInformationRequestDTO) async throws {
try await request(.modifyInformation(req))
}

func createPortfolioLink(req: CreatePortfolioLinkRequestDTO) async throws -> PortfolioLinkEntity {
try await request(
.createPortfolioLink(req),
dto: CreatePortfolioLinkResponseDTO.self
)
.toDomain()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enum StudentEndpoint {
case fetchStudentDetailByGuest(userID: String)
case fetchStudentDetailByTeacher(userID: String)
case modifyInformation(ModifyStudentInformationRequestDTO)
case createPortfolioLink(CreatePortfolioLinkRequestDTO)
}

extension StudentEndpoint: SMSEndpoint {
Expand Down Expand Up @@ -37,6 +38,9 @@ extension StudentEndpoint: SMSEndpoint {

case .modifyInformation:
return .put("")

case .createPortfolioLink:
return .post("/link")
}
}

Expand Down Expand Up @@ -74,6 +78,9 @@ extension StudentEndpoint: SMSEndpoint {

case let .modifyInformation(req):
return .requestJSONEncodable(req)

case let .createPortfolioLink(req):
return .requestJSONEncodable(req)

default:
return .requestPlain
Expand Down Expand Up @@ -117,6 +124,9 @@ extension StudentEndpoint: SMSEndpoint {
return [
400: .invalidRequest
]

case .createPortfolioLink:
return [:]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ struct StudentRepositoryImpl: StudentRepository {
func modifyInformation(req: ModifyStudentInformationRequestDTO) async throws {
try await remoteStudentDataSource.modifyInformation(req: req)
}

func createPortfolioLink(req: CreatePortfolioLinkRequestDTO) async throws -> PortfolioLinkEntity {
try await remoteStudentDataSource.createPortfolioLink(req: req)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import StudentDomainInterface

struct CreatePortfolioLinkUseCaseImpl: CreatePortfolioLinkUseCase {
private let studentRepository: any StudentRepository

init(studentRepository: any StudentRepository) {
self.studentRepository = studentRepository
}

func execute(req: CreatePortfolioLinkRequestDTO) async throws -> PortfolioLinkEntity {
try await studentRepository.createPortfolioLink(req: req)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import StudentDomainInterface

public final class CreatePortfolioLinkUseCaseSpy: CreatePortfolioLinkUseCase {
public init() {}

public func execute(
req: CreatePortfolioLinkRequestDTO
) async throws -> PortfolioLinkEntity {
return .init(token: "")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// This is for Tuist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ struct StudentDetailDemoApp: App {
userID: "2f004cba-a22e-414a-9e52-afd54c762216",
model: model,
loadUserRoleUseCase: LoadUserRoleUseCaseSpy(),
fetchStudentDetailUseCase: fetchStudentDetailUseCase
fetchStudentDetailUseCase: FetchStudentDetailUseCaseSpy(),
createPortfolioLinkUseCase: CreatePortfolioLinkUseCaseSpy()
)
let container = MVIContainer(
intent: intent as StudentDetailIntentProtocol,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public final class StudentDetailComponent: Component<StudentDetailDependency>, S
userID: userID,
model: model,
loadUserRoleUseCase: dependency.userDomainBuildable.loadUserRoleUseCase,
fetchStudentDetailUseCase: dependency.studentDomainBuildable.fetchStudentDetailUSeCase
fetchStudentDetailUseCase: dependency.studentDomainBuildable.fetchStudentDetailUseCase,
createPortfolioLinkUseCase: dependency.studentDomainBuildable.createPortfolioLinkUseCase
)
let container = MVIContainer(
intent: intent as StudentDetailIntentProtocol,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import UIKit
import UserDomainInterface
import StudentDomainInterface
import EventLimiter
Expand All @@ -8,18 +9,21 @@ final class StudentDetailIntent: StudentDetailIntentProtocol {
private weak var model: (any StudentDetailActionProtocol)?
private let loadUserRoleUseCase: any LoadUserRoleUseCase
private let fetchStudentDetailUseCase: any FetchStudentDetailUseCase
private let createPortfolioLinkUseCase: any CreatePortfolioLinkUseCase
private let throttler = Throttler(for: 1)

init(
userID: String,
model: any StudentDetailActionProtocol,
loadUserRoleUseCase: any LoadUserRoleUseCase,
fetchStudentDetailUseCase: any FetchStudentDetailUseCase
fetchStudentDetailUseCase: any FetchStudentDetailUseCase,
createPortfolioLinkUseCase: any CreatePortfolioLinkUseCase
) {
self.userID = userID
self.model = model
self.loadUserRoleUseCase = loadUserRoleUseCase
self.fetchStudentDetailUseCase = fetchStudentDetailUseCase
self.createPortfolioLinkUseCase = createPortfolioLinkUseCase
}

func onAppear() {
Expand All @@ -40,6 +44,47 @@ final class StudentDetailIntent: StudentDetailIntentProtocol {
}
}
}

func effectiveDateDialogIsRequired() {
model?.updateIsPresentedEffectiveDateDialog(isPresented: true)
}

func effectiveDateDialogDismissed() {
model?.updateIsPresentedEffectiveDateDialog(isPresented: false)
}

func effectiveDateSelect(effectiveDate: EffectiveDateType) {
model?.insertEffectiveDateType(effectiveDateType: effectiveDate)
}

func pasteLinkDialogIsRequired() {
model?.updateIsPresentedPasteLinkDialog(isPresented: true)
}

func pasteLinkDialogDismissed() {
model?.updateIsPresentedPasteLinkDialog(isPresented: false)
}

func pastePortfolioLink(portfolioLink: String) {
UIPasteboard.general.string = portfolioLink
}

func createPortfolioLink(state: any StudentDetailStateProtocol, portfolioLink: String) {
Task {
do {
let createPortfolioLinkRequest = CreatePortfolioLinkRequestDTO(
studentID: userID,
periodDay: state.effectiveDateType.rawValue
)

let token = try await createPortfolioLinkUseCase.execute(req: createPortfolioLinkRequest)
model?.updateToken(token: token.token)
model?.updatePortfolioLink(portfolioLink: "https:/$()/sms.msg-team.com/student/link?token=\(token.token)")
} catch {
print(error.localizedDescription)
}
}
}
}

private extension UserRoleType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@ import Foundation

protocol StudentDetailIntentProtocol {
func onAppear()
func effectiveDateDialogIsRequired()
func effectiveDateDialogDismissed()
func effectiveDateSelect(effectiveDate: EffectiveDateType)
func pasteLinkDialogIsRequired()
func pasteLinkDialogDismissed()
func pastePortfolioLink(portfolioLink: String)
func createPortfolioLink(state: any StudentDetailStateProtocol, portfolioLink: String)
}
Loading

0 comments on commit 8e987e5

Please sign in to comment.