Skip to content

Commit

Permalink
Merge pull request #402 from School-of-Company/398-add-fetch-applied-…
Browse files Browse the repository at this point in the history
…lecture-student-detail-feature

🔀 :: [#398] 강의 이수중인 학생 상세조회 기능 추가
  • Loading branch information
uuuunseo authored Aug 8, 2024
2 parents 33b4277 + 6d7551d commit d4968c5
Show file tree
Hide file tree
Showing 39 changed files with 392 additions and 296 deletions.
30 changes: 18 additions & 12 deletions App/Sources/Application/DI/Lecture/AppComponent+Lecture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,33 @@ public extension AppComponent {
}
}

var cancelLectureUseCase: any CancelLectureUseCase {
var cancelLectureApplicationUseCase: any CancelLectureApplicationUseCase {
shared {
CancelLectureUseCaseImpl(lectureRepository: lectureRepository)
CancelLectureApplicationUseCaseImpl(lectureRepository: lectureRepository)
}
}

var fetchInstructorListUseCase: any FetchInstructorListUseCase {
var searchInstructorUseCase: any SearchInstructorUseCase {
shared {
FetchInstructorListUseCaseImpl(lectureRepository: lectureRepository)
SearchInstructorUseCaseImpl(lectureRepository: lectureRepository)
}
}

var fetchLineListUseCase: any FetchLineListUseCase {
var searchLineUseCase: any SearchLineUseCase {
shared {
FetchLineListUseCaseImpl(lectureRepository: lectureRepository)
SearchLineUseCaseImpl(lectureRepository: lectureRepository)
}
}

var fetchDepartmentListUseCase: any FetchDepartmentListUseCase {
var searchDepartmentUseCase: any SearchDepartmentUseCase {
shared {
FetchDepartmentListUseCaseImpl(lectureRepository: lectureRepository)
SearchDepartmentUseCaseImpl(lectureRepository: lectureRepository)
}
}

var fetchDivisionListUseCase: any FetchDivisionListUseCase {
var searchDivisionUseCase: any SearchDivisionUseCase {
shared {
FetchDivisionListUseCaseImpl(lectureRepository: lectureRepository)
SearchDivisionUseCaseImpl(lectureRepository: lectureRepository)
}
}

Expand All @@ -80,9 +80,9 @@ public extension AppComponent {
}
}

var modifyApplicantWhetherUseCase: any ModifyApplicantWhetherUseCase {
var setLectureCompletionUseCase: any SetLectureCompletionUseCase {
shared {
ModifyApplicantWhetherUseCaseImpl(lectureRepository: lectureRepository)
SetLectureCompletionUseCaseImpl(lectureRepository: lectureRepository)
}
}

Expand All @@ -97,4 +97,10 @@ public extension AppComponent {
ModifyLectureUseCaseImpl(lectureRepository: lectureRepository)
}
}

var fetchAppliedLectureStudentDetailUseCase: any FetchAppliedLectureStudentDetailUseCase {
shared {
FetchAppliedLectureStudentDetailUseCaseImpl(lectureRepository: lectureRepository)
}
}
}
49 changes: 25 additions & 24 deletions App/Sources/Application/NeedleGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ private class LectureListDetailDependency2a815f1240973966e6a6Provider: LectureLi
var applyLectureUseCase: any ApplyLectureUseCase {
return appComponent.applyLectureUseCase
}
var cancelLectureUseCase: any CancelLectureUseCase {
return appComponent.cancelLectureUseCase
var cancelLectureApplicationUseCase: any CancelLectureApplicationUseCase {
return appComponent.cancelLectureApplicationUseCase
}
var loadUserAuthorityUseCase: any LoadUserAuthorityUseCase {
return appComponent.loadUserAuthorityUseCase
Expand Down Expand Up @@ -365,17 +365,17 @@ private class LectureDetailSettingDependencyd72c0b79ce6406870a95Provider: Lectur
var inputLectureFactory: any InputLectureFactory {
return appComponent.inputLectureFactory
}
var fetchInstructorListUseCase: any FetchInstructorListUseCase {
return appComponent.fetchInstructorListUseCase
var searchInstructorUseCase: any SearchInstructorUseCase {
return appComponent.searchInstructorUseCase
}
var fetchLineListUseCase: any FetchLineListUseCase {
return appComponent.fetchLineListUseCase
var searchLineUseCase: any SearchLineUseCase {
return appComponent.searchLineUseCase
}
var fetchDepartmentListUseCase: any FetchDepartmentListUseCase {
return appComponent.fetchDepartmentListUseCase
var searchDepartmentUseCase: any SearchDepartmentUseCase {
return appComponent.searchDepartmentUseCase
}
var fetchDivisionListUseCase: any FetchDivisionListUseCase {
return appComponent.fetchDivisionListUseCase
var searchDivisionUseCase: any SearchDivisionUseCase {
return appComponent.searchDivisionUseCase
}
private let appComponent: AppComponent
init(appComponent: AppComponent) {
Expand Down Expand Up @@ -602,8 +602,8 @@ private class LectureApplicantListDependency5bfdb7310dde792c0738Provider: Lectur
var fetchApplicantListUseCase: any FetchApplicantListUseCase {
return appComponent.fetchApplicantListUseCase
}
var modifyApplicantWhetherUseCase: any ModifyApplicantWhetherUseCase {
return appComponent.modifyApplicantWhetherUseCase
var setLectureCompletionUseCase: any SetLectureCompletionUseCase {
return appComponent.setLectureCompletionUseCase
}
private let appComponent: AppComponent
init(appComponent: AppComponent) {
Expand Down Expand Up @@ -1042,7 +1042,7 @@ extension LectureListDetailComponent: Registration {
public func registerItems() {
keyPathToName[\LectureListDetailDependency.fetchLectureDetailUseCase] = "fetchLectureDetailUseCase-any FetchLectureDetailUseCase"
keyPathToName[\LectureListDetailDependency.applyLectureUseCase] = "applyLectureUseCase-any ApplyLectureUseCase"
keyPathToName[\LectureListDetailDependency.cancelLectureUseCase] = "cancelLectureUseCase-any CancelLectureUseCase"
keyPathToName[\LectureListDetailDependency.cancelLectureApplicationUseCase] = "cancelLectureApplicationUseCase-any CancelLectureApplicationUseCase"
keyPathToName[\LectureListDetailDependency.loadUserAuthorityUseCase] = "loadUserAuthorityUseCase-any LoadUserAuthorityUseCase"
keyPathToName[\LectureListDetailDependency.lectureApplicantListFactory] = "lectureApplicantListFactory-any LectureApplicantListFactory"
keyPathToName[\LectureListDetailDependency.deleteLectureUseCase] = "deleteLectureUseCase-any DeleteLectureUseCase"
Expand Down Expand Up @@ -1138,10 +1138,10 @@ extension InputNoticeComponent: Registration {
extension LectureDetailSettingComponent: Registration {
public func registerItems() {
keyPathToName[\LectureDetailSettingDependency.inputLectureFactory] = "inputLectureFactory-any InputLectureFactory"
keyPathToName[\LectureDetailSettingDependency.fetchInstructorListUseCase] = "fetchInstructorListUseCase-any FetchInstructorListUseCase"
keyPathToName[\LectureDetailSettingDependency.fetchLineListUseCase] = "fetchLineListUseCase-any FetchLineListUseCase"
keyPathToName[\LectureDetailSettingDependency.fetchDepartmentListUseCase] = "fetchDepartmentListUseCase-any FetchDepartmentListUseCase"
keyPathToName[\LectureDetailSettingDependency.fetchDivisionListUseCase] = "fetchDivisionListUseCase-any FetchDivisionListUseCase"
keyPathToName[\LectureDetailSettingDependency.searchInstructorUseCase] = "searchInstructorUseCase-any SearchInstructorUseCase"
keyPathToName[\LectureDetailSettingDependency.searchLineUseCase] = "searchLineUseCase-any SearchLineUseCase"
keyPathToName[\LectureDetailSettingDependency.searchDepartmentUseCase] = "searchDepartmentUseCase-any SearchDepartmentUseCase"
keyPathToName[\LectureDetailSettingDependency.searchDivisionUseCase] = "searchDivisionUseCase-any SearchDivisionUseCase"
}
}
extension MainComponent: Registration {
Expand Down Expand Up @@ -1225,7 +1225,7 @@ extension FindPasswordComponent: Registration {
extension LectureApplicantListComponent: Registration {
public func registerItems() {
keyPathToName[\LectureApplicantListDependency.fetchApplicantListUseCase] = "fetchApplicantListUseCase-any FetchApplicantListUseCase"
keyPathToName[\LectureApplicantListDependency.modifyApplicantWhetherUseCase] = "modifyApplicantWhetherUseCase-any ModifyApplicantWhetherUseCase"
keyPathToName[\LectureApplicantListDependency.setLectureCompletionUseCase] = "setLectureCompletionUseCase-any SetLectureCompletionUseCase"
}
}
extension UserListComponent: Registration {
Expand Down Expand Up @@ -1383,16 +1383,17 @@ extension AppComponent: Registration {
localTable["fetchLectureListUseCase-any FetchLectureListUseCase"] = { [unowned self] in self.fetchLectureListUseCase as Any }
localTable["fetchLectureDetailUseCase-any FetchLectureDetailUseCase"] = { [unowned self] in self.fetchLectureDetailUseCase as Any }
localTable["applyLectureUseCase-any ApplyLectureUseCase"] = { [unowned self] in self.applyLectureUseCase as Any }
localTable["cancelLectureUseCase-any CancelLectureUseCase"] = { [unowned self] in self.cancelLectureUseCase as Any }
localTable["fetchInstructorListUseCase-any FetchInstructorListUseCase"] = { [unowned self] in self.fetchInstructorListUseCase as Any }
localTable["fetchLineListUseCase-any FetchLineListUseCase"] = { [unowned self] in self.fetchLineListUseCase as Any }
localTable["fetchDepartmentListUseCase-any FetchDepartmentListUseCase"] = { [unowned self] in self.fetchDepartmentListUseCase as Any }
localTable["fetchDivisionListUseCase-any FetchDivisionListUseCase"] = { [unowned self] in self.fetchDivisionListUseCase as Any }
localTable["cancelLectureApplicationUseCase-any CancelLectureApplicationUseCase"] = { [unowned self] in self.cancelLectureApplicationUseCase as Any }
localTable["searchInstructorUseCase-any SearchInstructorUseCase"] = { [unowned self] in self.searchInstructorUseCase as Any }
localTable["searchLineUseCase-any SearchLineUseCase"] = { [unowned self] in self.searchLineUseCase as Any }
localTable["searchDepartmentUseCase-any SearchDepartmentUseCase"] = { [unowned self] in self.searchDepartmentUseCase as Any }
localTable["searchDivisionUseCase-any SearchDivisionUseCase"] = { [unowned self] in self.searchDivisionUseCase as Any }
localTable["fetchAppliedLectureListUseCase-any FetchAppliedLectureListUseCase"] = { [unowned self] in self.fetchAppliedLectureListUseCase as Any }
localTable["fetchApplicantListUseCase-any FetchApplicantListUseCase"] = { [unowned self] in self.fetchApplicantListUseCase as Any }
localTable["modifyApplicantWhetherUseCase-any ModifyApplicantWhetherUseCase"] = { [unowned self] in self.modifyApplicantWhetherUseCase as Any }
localTable["setLectureCompletionUseCase-any SetLectureCompletionUseCase"] = { [unowned self] in self.setLectureCompletionUseCase as Any }
localTable["deleteLectureUseCase-any DeleteLectureUseCase"] = { [unowned self] in self.deleteLectureUseCase as Any }
localTable["modifyLectureUseCase-any ModifyLectureUseCase"] = { [unowned self] in self.modifyLectureUseCase as Any }
localTable["fetchAppliedLectureStudentDetailUseCase-any FetchAppliedLectureStudentDetailUseCase"] = { [unowned self] in self.fetchAppliedLectureStudentDetailUseCase as Any }
localTable["remoteClubDataSource-any RemoteClubDataSource"] = { [unowned self] in self.remoteClubDataSource as Any }
localTable["clubRepository-any ClubRepository"] = { [unowned self] in self.clubRepository as Any }
localTable["fetchClubListUseCase-any FetchClubListUseCase"] = { [unowned self] in self.fetchClubListUseCase as Any }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,60 @@
import SwiftUI
import Service

struct LectureApplicantListRow: View {
let studentID: String
@State var isComplete: Bool
let email: String
let name: String
let grade: Int
let classNumber: Int
let number: Int
let cohort: Int
let phoneNumber: String
let schoolName: String
let clubName: String
let onSelectedStudent: (Bool, String) -> Void
let studentInfo: ApplicantInfoEntity
@Binding var state: LectureApplicantListPageState
@Binding var isSelected: Bool

var body: some View {
HStack(alignment: .top, spacing: 24) {
CheckButton(
isSelected: Binding(
get: { isComplete },
set: { isSelected in
if isSelected {
isComplete = isSelected
onSelectedStudent(isSelected, studentID)
} else {
isComplete = isSelected
onSelectedStudent(isSelected, studentID)
}
}
)
)

VStack(alignment: .leading, spacing: 8) {
BitgouelText(
text: "\(grade)학년 \(classNumber)\(number)\(cohort)\(name)",
font: .text1
)

Group {
Text("\(phoneNumber.withHypen) | \(email)")

Text(schoolName)

Text(clubName)
HStack(alignment: .center, spacing: 16) {
completionStatusCheckButton()

VStack(alignment: .leading, spacing: 4) {
HStack(spacing: 4) {
BitgouelText(
text: studentInfo.name,
font: .text1
)

completionStatusText()
}

HStack(spacing: 4) {
Text(studentInfo.school)

Text("\(studentInfo.grade)학년 \(studentInfo.classNumber)\(studentInfo.number)")
}
.bitgouelFont(.caption, color: .greyscale(.g7))
.bitgouelFont(.caption, color: .greyscale(.g4))

Text(studentInfo.clubName)
.bitgouelFont(.caption, color: .greyscale(.g7))
}
}
}

@ViewBuilder
func completionStatusCheckButton() -> some View {
switch state {
case .general:
EmptyView()

case .check:
CheckButton(isSelected: $isSelected)
}
}

@ViewBuilder
func completionStatusText() -> some View {
switch state {
case .general:
if studentInfo.isComplete {
Text("이수완료")
.bitgouelFont(.caption, color: .primary(.p5))
}

case .check:
EmptyView()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SwiftUI

public protocol LectureApplicantListDependency: Dependency {
var fetchApplicantListUseCase: any FetchApplicantListUseCase { get }
var modifyApplicantWhetherUseCase: any ModifyApplicantWhetherUseCase { get }
var setLectureCompletionUseCase: any SetLectureCompletionUseCase { get }
}

public final class LectureApplicantListComponent: Component<LectureApplicantListDependency>,
Expand All @@ -14,7 +14,7 @@ public final class LectureApplicantListComponent: Component<LectureApplicantList
viewModel: LectureApplicantListViewModel(
lectureID: lectureID,
fetchApplicantListUseCase: dependency.fetchApplicantListUseCase,
modifyApplicantWhetherUseCase: dependency.modifyApplicantWhetherUseCase
setLectureCompletionUseCase: dependency.setLectureCompletionUseCase
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,17 @@ struct LectureApplicantListView: View {

var body: some View {
VStack(alignment: .leading, spacing: 0) {
Text("강의 이수 여부")
.bitgouelFont(.text3, color: .greyscale(.g4))
.padding(.top, 8)

ScrollView {
LazyVStack(alignment: .leading, spacing: 12) {
ForEach(viewModel.applicantList, id: \.studentID) { student in
LectureApplicantListRow(
studentID: student.studentID,
isComplete: student.isComplete,
email: student.email,
name: student.name,
grade: student.grade,
classNumber: student.classNumber,
number: student.number,
cohort: student.cohort,
phoneNumber: student.phoneNumber,
schoolName: student.school.display(),
clubName: student.clubName
) { isSelected, studentID in
viewModel.updateApplicantInfo(isSelected: isSelected, studentID: studentID)
viewModel.modifyApplicantWhether()
}
studentInfo: student,
state: $viewModel.state,
isSelected: Binding(
get: { student.isComplete },
set: { isComplete in }
)
)

Divider()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
import Foundation
import Service

enum LectureApplicantListPageState {
case general
case check
}

final class LectureApplicantListViewModel: BaseViewModel {
@Published var applicantList: [ApplicantInfoEntity] = []
@Published var selectedStudentID: String = ""
@Published var isComplete: Bool = false
@Published var state: LectureApplicantListPageState = .general
var lectureID: String = ""
var students: [String] = []

private let fetchApplicantListUseCase: any FetchApplicantListUseCase
private let modifyApplicantWhetherUseCase: any ModifyApplicantWhetherUseCase
private let setLectureCompletionUseCase: any SetLectureCompletionUseCase

init(
lectureID: String,
fetchApplicantListUseCase: any FetchApplicantListUseCase,
modifyApplicantWhetherUseCase: any ModifyApplicantWhetherUseCase
setLectureCompletionUseCase: any SetLectureCompletionUseCase
) {
self.lectureID = lectureID
self.fetchApplicantListUseCase = fetchApplicantListUseCase
self.modifyApplicantWhetherUseCase = modifyApplicantWhetherUseCase
self.setLectureCompletionUseCase = setLectureCompletionUseCase
}

func updateApplicantInfo(isSelected: Bool, studentID: String) {
isComplete = isSelected
selectedStudentID = studentID
}

func updateState(state: LectureApplicantListPageState) {
self.state = state
}

@MainActor
func onAppear() {
Task {
Expand All @@ -40,10 +51,9 @@ final class LectureApplicantListViewModel: BaseViewModel {
func modifyApplicantWhether() {
Task {
do {
try await modifyApplicantWhetherUseCase(
try await setLectureCompletionUseCase(
lectureID: lectureID,
studentID: selectedStudentID,
isComplete: isComplete
students: students
)
} catch {
errorMessage = error.lectureDomainErrorMessage()
Expand Down
Loading

0 comments on commit d4968c5

Please sign in to comment.