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

๐Ÿ”€ :: [#315] ์„ ์ƒ๋‹˜ ์ •๋ณด์ž…๋ ฅ ํŽ˜์ด์ง€ UI #316

Merged
merged 14 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
9d86f0b
:sparkles: :: [#315] addInputTeacherInfoFeature
uuuunseo Jan 18, 2024
3e275b6
:sparkles: :: [#315] InputTeacherInfoFeature / DI, Intent, Model, Intโ€ฆ
uuuunseo Jan 18, 2024
b293b03
:sparkles: :: [#315] InputTeacherInfoFeature / ๊ธฐ๋ณธ ์„ธํŒ…
uuuunseo Jan 19, 2024
f747357
:sparkles: :: [#315] InputTeacherInfoFeature / InputTeacherInfoComponent
uuuunseo Jan 19, 2024
51c0e57
:sparkles: :: [#315] InputTeacherInfoFeature / Demo ์ถ”๊ฐ€
uuuunseo Jan 19, 2024
215d84c
:sparkles: :: [#315] InputTeacherInfoFeature / AppDelegate ์ˆ˜์ •
uuuunseo Jan 20, 2024
aa12bad
:lipstick: :: [#315] InputTeacherInfoView / ์„ ์ƒ๋‹˜ ์ •๋ณด์ž…๋ ฅ ํŽ˜์ด์ง€ UI
uuuunseo Jan 20, 2024
cc99328
:sparkles: :: [#315] InputTeacherInfoFeature / InputTeacherDelegate ์ถ”๊ฐ€
uuuunseo Jan 20, 2024
0c5def1
:sparkles: :: [#315] InputTeacherInfoFeature / ์„ ์ƒ๋‹˜ ์งํ•จ ์„ ํƒ BottomSheet
uuuunseo Jan 20, 2024
5f57ea1
:sparkles: :: [#315] InputTeacherInfoFeature / ํ•™๋…„ ์„ ํƒ BottomSheet
uuuunseo Jan 20, 2024
0fc2951
:sparkles: :: [#315] InputTeacherInfoFeature / ๋ฐ˜ ์„ ํƒ BottomSheet
uuuunseo Jan 20, 2024
7719efd
:recycle: :: [#315] InputTeacherInfoView / ํ•™๋…„, ๋ฐ˜ ์„ ํƒ placeholder ๋‹ด๋‹น ํ•™๋…„โ€ฆ
uuuunseo Jan 20, 2024
9ffb688
:green_heart: :: BaseFeature dependency ์ถ”๊ฐ€
uuuunseo Jan 20, 2024
cf890d8
:green_heart: :: [#315] InputInformaionBaseFeature dependency ์ถ”๊ฐ€
uuuunseo Jan 20, 2024
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 @@ -9,6 +9,14 @@ public extension TargetDependency {
}

public extension TargetDependency.Feature {
static let InputTeacherInfoFeatureInterface = TargetDependency.project(
target: ModulePaths.Feature.InputTeacherInfoFeature.targetName(type: .interface),
path: .relativeToFeature(ModulePaths.Feature.InputTeacherInfoFeature.rawValue)
)
static let InputTeacherInfoFeature = TargetDependency.project(
target: ModulePaths.Feature.InputTeacherInfoFeature.targetName(type: .sources),
path: .relativeToFeature(ModulePaths.Feature.InputTeacherInfoFeature.rawValue)
)
static let InputPrizeInfoFeatureInterface = TargetDependency.project(
target: ModulePaths.Feature.InputPrizeInfoFeature.targetName(type: .interface),
path: .relativeToFeature(ModulePaths.Feature.InputPrizeInfoFeature.rawValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public enum ModulePaths {

public extension ModulePaths {
enum Feature: String {
case InputTeacherInfoFeature
case InputPrizeInfoFeature
case MyPageFeature
case InputProjectInfoFeature
Expand Down
1 change: 1 addition & 0 deletions Projects/App/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ let targets: [Target] = [
.Feature.InputCertificateInfoFeature,
.Feature.InputLanguageInfoFeature,
.Feature.InputProjectInfoFeature,
.Feature.InputTeacherInfoFeature,
.Feature.MainFeature,
.Feature.SplashFeature,
.Feature.TechStackAppendFeature,
Expand Down
1 change: 1 addition & 0 deletions Projects/App/Sources/Application/NeedleGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import InputProjectInfoFeature
import InputProjectInfoFeatureInterface
import InputSchoolLifeInfoFeature
import InputSchoolLifeInfoFeatureInterface
import InputTeacherInfoFeatureInterface
import InputWorkInfoFeature
import InputWorkInfoFeatureInterface
import JwtStore
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import BaseFeature
import SwiftUI
import InputTeacherInfoFeatureInterface
@testable import InputTeacherInfoFeature

final class DummyInputTeacherInfoDelegate: InputTeacherDelegate {
func completeToInputTeacherInformation() {}
}

@main
struct InputTeacherInfoApp: App {
var body: some Scene {
WindowGroup {
let model = InputTeacherInfoModel()
let intent = InputTeacherInfoIntent(
model: model,
teacherDelegate: DummyInputTeacherInfoDelegate()
)
let container = MVIContainer(
intent: intent as InputTeacherInfoIntentProtocol,
model: model as InputTeacherInfoStateProtocol,
modelChangePublisher: model.objectWillChange
)
InputTeacherInfoView(container: container)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public protocol InputTeacherDelegate: AnyObject {
func completeToInputTeacherInformation()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import SwiftUI

public protocol InputTeacherInfoBuildable {
associatedtype ViewType: View
func makeView(delegate: InputTeacherDelegate) -> ViewType
}
13 changes: 13 additions & 0 deletions Projects/Feature/InputTeacherInfoFeature/Project.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import ProjectDescription
import ProjectDescriptionHelpers
import DependencyPlugin

let project = Project.makeModule(
name: ModulePaths.Feature.InputTeacherInfoFeature.rawValue,
product: .staticLibrary,
targets: [.interface, .unitTest, .demo],
internalDependencies: [
.Feature.BaseFeature,
.Feature.InputInformationBaseFeature
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import BaseFeature
import InputTeacherInfoFeatureInterface
import NeedleFoundation
import SwiftUI

public protocol InputTeacherInfoDependency: Dependency {}

public final class InputTeacherInfoComponent: Component<InputTeacherInfoDependency>, InputTeacherInfoBuildable {

public func makeView(delegate: InputTeacherDelegate) -> some View {
let model = InputTeacherInfoModel()
let intent = InputTeacherInfoIntent(model: model, teacherDelegate: delegate)
let container = MVIContainer(
intent: intent as InputTeacherInfoIntentProtocol,
model: model as InputTeacherInfoStateProtocol,
modelChangePublisher: model.objectWillChange
)
return InputTeacherInfoView(container: container)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Foundation
import InputTeacherInfoFeatureInterface

final class InputTeacherInfoIntent: InputTeacherInfoIntentProtocol {
private weak var model: (any InputTeacherInfoActionProtocol)?
private weak var teacherDelegate: (any InputTeacherDelegate)?

init(
model: any InputTeacherInfoActionProtocol,
teacherDelegate: any InputTeacherDelegate
) {
self.model = model
self.teacherDelegate = teacherDelegate
}

func completeButtonDidTap() {
teacherDelegate?.completeToInputTeacherInformation()
}

func jobTitleSheetIsRequired() {
model?.updateIsPresentedJobTitleSheet(isPresented: true)
}

func jobTitleSheetDismissed() {
model?.updateIsPresentedJobTitleSheet(isPresented: false)
}

func gradeSheetIsRequired() {
model?.updateIsPresentedGradeSheet(isPresented: true)
}

func gradeSheetDismissed() {
model?.updateIsPresentedGradeSheet(isPresented: false)
}

func classSheetIsRequired() {
model?.updateIsPresentedClassSheet(isPresented: true)
}

func classSheetDismissed() {
model?.updateIsPresentedClassSheet(isPresented: false)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

protocol InputTeacherInfoIntentProtocol {
func completeButtonDidTap()
func jobTitleSheetIsRequired()
func jobTitleSheetDismissed()
func gradeSheetIsRequired()
func gradeSheetDismissed()
func classSheetIsRequired()
func classSheetDismissed()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Foundation

final class InputTeacherInfoModel: ObservableObject, InputTeacherInfoStateProtocol {
@Published var isPresentedJobTitleSheet: Bool = false
@Published var isPresentedGradeSheet: Bool = false
@Published var isPresentedClassSheet: Bool = false
}

extension InputTeacherInfoModel: InputTeacherInfoActionProtocol {
func updateIsPresentedJobTitleSheet(isPresented: Bool) {
self.isPresentedJobTitleSheet = isPresented
}

func updateIsPresentedGradeSheet(isPresented: Bool) {
self.isPresentedGradeSheet = isPresented
}

func updateIsPresentedClassSheet(isPresented: Bool) {
self.isPresentedClassSheet = isPresented
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Foundation

protocol InputTeacherInfoStateProtocol {
var isPresentedJobTitleSheet: Bool { get }
var isPresentedGradeSheet: Bool { get }
var isPresentedClassSheet: Bool { get }
}

protocol InputTeacherInfoActionProtocol: AnyObject {
func updateIsPresentedJobTitleSheet(isPresented: Bool)
func updateIsPresentedGradeSheet(isPresented: Bool)
func updateIsPresentedClassSheet(isPresented: Bool)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import BaseFeature
import DesignSystem
import InputInformationBaseFeature
import SwiftUI

struct InputTeacherInfoView: View {
@StateObject var container: MVIContainer<InputTeacherInfoIntentProtocol, InputTeacherInfoStateProtocol>
var intent: any InputTeacherInfoIntentProtocol { container.intent }
var state: any InputTeacherInfoStateProtocol { container.model }

var body: some View {
SMSNavigationTitleView(title: "์ •๋ณด์ž…๋ ฅ") {
VStack(spacing: 0) {
HStack(spacing: 4) {
Text("ํ”„๋กœํ•„")
.foregroundColor(.sms(.system(.black)))

Text("*")
.foregroundColor(.sms(.sub(.s2)))

Spacer()
}
.smsFont(.title1)
.padding(.top, 36)

VStack(spacing: 24) {
inputTeacherInfoTextField(
title: "์งํ•จ",
placeholder: "์งํ•จ ์„ ํƒ",
text: .constant("")
)
.onTapGesture {
intent.jobTitleSheetIsRequired()
}

inputTeacherInfoTextField(
title: "ํ•™๋…„",
placeholder: "๋‹ด๋‹น ํ•™๋…„ ์„ ํƒ",
text: .constant("")
)
.onTapGesture {
intent.gradeSheetIsRequired()
}

inputTeacherInfoTextField(
title: "๋ฐ˜",
placeholder: "๋‹ด๋‹น ๋ฐ˜ ์„ ํƒ",
text: .constant("")
)
Comment on lines +27 to +49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

placeholder๊ฐ€ ๋””์ž์ธ์ด๋ž‘ ๋‹ค๋ฅธ ๊ฒƒ ๊ฐ™์•„์š”!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

placeholder ๋ถ€๋ถ„ text ๋ง์”€ํ•˜์‹œ๋Š”๊ฑฐ๋ฉด ๋””์ž์ธ์ด๋ž‘ ์ด์•ผ๊ธฐ ํ•ด์„œ

  • ์„ ํƒํ•ด ์ฃผ์„ธ์š”. -> ์„ ํƒ
  • ํ•™๋…„, ๋ฐ˜ -> ๋‹ด๋‹น ํ•™๋…„, ๋‹ด๋‹น ๋ฐ˜
    ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋์–ด์š”!!

.onTapGesture {
intent.classSheetIsRequired()
}
}
.padding(.top, 32)

CTAButton(text: "์™„๋ฃŒ")
.padding(.top, 32)

Spacer()
}
.padding(.horizontal, 20)
}
.smsBottomSheet(
isShowing: Binding(
get: { state.isPresentedJobTitleSheet },
set: { _ in intent.jobTitleSheetDismissed() }
)
) {
jobTitleListView()
}
.smsBottomSheet(
isShowing: Binding(
get: { state.isPresentedGradeSheet },
set: { _ in intent.gradeSheetDismissed() }
)
) {
gradeListView()
}
.smsBottomSheet(
isShowing: Binding(
get: { state.isPresentedClassSheet},
set: { _ in intent.classSheetDismissed() }
)
) {
classListView()
}
}

@ViewBuilder
func inputTeacherInfoTextField(
title: String,
placeholder: String,
text: Binding<String>
) -> some View {
SMSTextField(
placeholder,
text: text
)
.disabled(true)
.overlay(alignment: .trailing) {
SMSIcon(.downChevron)
.padding(.trailing, 12)
}
.titleWrapper(title)
}

@ViewBuilder
func jobTitleListView() -> some View {
VStack(spacing: 16) {
ForEach(0..<5, id: \.self) { index in
HStack {
Text("\(index)")
.smsFont(.body1, color: .neutral(.n50))

Spacer()

Circle()
.fill(Color.sms(.primary(.p2)))
.frame(width: 24, height: 24)
}
.padding(.horizontal, 20)
}
}
}

@ViewBuilder
func gradeListView() -> some View {
VStack(spacing: 16) {
ForEach(1..<4, id: \.self) { index in
HStack {
Text("\(index)ํ•™๋…„")
.smsFont(.body1, color: .neutral(.n50))

Spacer()

Circle()
.fill(Color.sms(.primary(.p2)))
.frame(width: 24, height: 24)
}
.padding(.horizontal, 20)
}
}
}

@ViewBuilder
func classListView() -> some View {
VStack(spacing: 16) {
ForEach(1..<5, id: \.self) { index in
HStack {
Text("\(index)๋ฐ˜")
.smsFont(.body1, color: .neutral(.n50))

Spacer()

Circle()
.fill(Color.sms(.primary(.p2)))
.frame(width: 24, height: 24)
}
.padding(.horizontal, 20)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// This is for Tuist
Loading
Loading