Skip to content

Commit

Permalink
[추가] NoticeList구현
Browse files Browse the repository at this point in the history
  • Loading branch information
lgvv authored and x-0o0 committed Nov 24, 2023
1 parent bf92ab3 commit 9d67d64
Show file tree
Hide file tree
Showing 22 changed files with 918 additions and 133 deletions.
24 changes: 24 additions & 0 deletions KuringApp/KuringApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
A9DAFA562AB1F04B0064F748 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DAFA552AB1F04B0064F748 /* ContentView.swift */; };
A9DAFA582AB1F04C0064F748 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A9DAFA572AB1F04C0064F748 /* Assets.xcassets */; };
A9DAFA5B2AB1F04C0064F748 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A9DAFA5A2AB1F04C0064F748 /* Preview Assets.xcassets */; };
B1CBFA662AC7113C00C1E0ED /* NoticeRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CBFA652AC7113C00C1E0ED /* NoticeRow.swift */; };
CAD5A4272B10723500DED0D5 /* NoticeTypeGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD5A4262B10723500DED0D5 /* NoticeTypeGrid.swift */; };
CAD5A4292B10724100DED0D5 /* NoticeTypeColumn.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD5A4282B10724100DED0D5 /* NoticeTypeColumn.swift */; };
CAD5A42B2B10750800DED0D5 /* DepartmentSelectorLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD5A42A2B10750800DED0D5 /* DepartmentSelectorLink.swift */; };
CAD5A42D2B1077C200DED0D5 /* NoticeList.NoDepartment.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD5A42C2B1077C200DED0D5 /* NoticeList.NoDepartment.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -43,6 +48,12 @@
A9DAFA572AB1F04C0064F748 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A9DAFA5A2AB1F04C0064F748 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
A9DAFA662AB1F09B0064F748 /* KuringModulePackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = KuringModulePackage; path = ../KuringModulePackage; sourceTree = "<group>"; };
B1129A702AF7D11400FB2ED2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
B1CBFA652AC7113C00C1E0ED /* NoticeRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRow.swift; sourceTree = "<group>"; };
CAD5A4262B10723500DED0D5 /* NoticeTypeGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeTypeGrid.swift; sourceTree = "<group>"; };
CAD5A4282B10724100DED0D5 /* NoticeTypeColumn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeTypeColumn.swift; sourceTree = "<group>"; };
CAD5A42A2B10750800DED0D5 /* DepartmentSelectorLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DepartmentSelectorLink.swift; sourceTree = "<group>"; };
CAD5A42C2B1077C200DED0D5 /* NoticeList.NoDepartment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeList.NoDepartment.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -105,6 +116,11 @@
children = (
A9B4F0172ABCA9AF00354C00 /* NoticeDetailView.swift */,
A9B4F0192ABCAF9800354C00 /* NoticeList.swift */,
CAD5A42C2B1077C200DED0D5 /* NoticeList.NoDepartment.swift */,
B1CBFA652AC7113C00C1E0ED /* NoticeRow.swift */,
CAD5A4262B10723500DED0D5 /* NoticeTypeGrid.swift */,
CAD5A4282B10724100DED0D5 /* NoticeTypeColumn.swift */,
CAD5A42A2B10750800DED0D5 /* DepartmentSelectorLink.swift */,
);
path = NoticeList;
sourceTree = "<group>";
Expand All @@ -130,6 +146,7 @@
A9DAFA522AB1F04B0064F748 /* KuringApp */ = {
isa = PBXGroup;
children = (
B1129A702AF7D11400FB2ED2 /* Info.plist */,
A9DAFA532AB1F04B0064F748 /* KuringApp.swift */,
A9B4F0132ABCA86500354C00 /* NoticeApp.swift */,
A9B4F0152ABCA93400354C00 /* NoticeApp.Path.swift */,
Expand Down Expand Up @@ -235,11 +252,16 @@
A9B4F01A2ABCAF9800354C00 /* NoticeList.swift in Sources */,
A9DAFA562AB1F04B0064F748 /* ContentView.swift in Sources */,
A9B4F01D2ABCB4CE00354C00 /* SearchView.swift in Sources */,
CAD5A42D2B1077C200DED0D5 /* NoticeList.NoDepartment.swift in Sources */,
CAD5A4272B10723500DED0D5 /* NoticeTypeGrid.swift in Sources */,
A965B7A32AC013060026ECDC /* DepartmentEditor.swift in Sources */,
A965B7A52AC013BF0026ECDC /* DepartmentSelector.swift in Sources */,
A9B4F0162ABCA93400354C00 /* NoticeApp.Path.swift in Sources */,
A965B7A72AC0696B0026ECDC /* Department.swift in Sources */,
CAD5A42B2B10750800DED0D5 /* DepartmentSelectorLink.swift in Sources */,
A9B4F0182ABCA9AF00354C00 /* NoticeDetailView.swift in Sources */,
CAD5A4292B10724100DED0D5 /* NoticeTypeColumn.swift in Sources */,
B1CBFA662AC7113C00C1E0ED /* NoticeRow.swift in Sources */,
A965B7AF2AC084D20026ECDC /* SubscriptionApp.swift in Sources */,
A9DAFA542AB1F04B0064F748 /* KuringApp.swift in Sources */,
);
Expand Down Expand Up @@ -378,6 +400,7 @@
DEVELOPMENT_TEAM = 77CD4KLN3Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = KuringApp/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
Expand Down Expand Up @@ -407,6 +430,7 @@
DEVELOPMENT_TEAM = 77CD4KLN3Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = KuringApp/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"location" : "https://github.com/pointfreeco/swift-composable-architecture",
"state" : {
"branch" : "main",
"revision" : "667d92fad15e60b32a4c3e1289c9a15814798665"
"revision" : "6226901dec30b679841424d5069c11fdc2e3583a"
}
},
{
Expand All @@ -59,8 +59,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-custom-dump",
"state" : {
"revision" : "edd66cace818e1b1c6f1b3349bb1d8e00d6f8b01",
"version" : "1.0.0"
"revision" : "3efbfba0e4e56c7187cc19137ee16b7c95346b79",
"version" : "1.1.0"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion KuringApp/KuringApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct ContentView: View {
NoticeAppView(
store: Store(
initialState: NoticeAppFeature.State(
noticeList: NoticeListFeature.State(notices: [.random])
noticeList: NoticeListFeature.State()
),
reducer: { NoticeAppFeature() }
)
Expand Down
125 changes: 87 additions & 38 deletions KuringApp/KuringApp/Department/DepartmentEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct DepartmentEditorFeature: Reducer {
@PresentationState var alert: AlertState<Action.Alert>?
}

enum Action: BindableAction {
enum Action: BindableAction, Equatable {
case binding(BindingAction<State>)

/// 학과 추가 버튼 눌렀을 때
Expand All @@ -35,6 +35,8 @@ struct DepartmentEditorFeature: Reducer {
case deleteMyDepartmentButtonTapped(id: Department.ID)
/// 내 학과 전체삭제 버튼 눌렀을 때
case deleteAllMyDepartmentButtonTapped
/// 텍스트 필드의 xmark를 눌렀을 때
case clearTextFieldButtonTapped

/// 알림
enum Alert: Equatable {
Expand Down Expand Up @@ -96,6 +98,9 @@ struct DepartmentEditorFeature: Reducer {
}
}
return .none
case .clearTextFieldButtonTapped:
state.searchText = ""
return .none

// MARK: Alert
case let .alert(.presented(alertAction)):
Expand Down Expand Up @@ -124,90 +129,133 @@ struct DepartmentEditor: View {
var body: some View {
WithViewStore(self.store, observe: { $0 }) { viewStore in
VStack {
List {
Text("학과를 추가하거나 삭제할 수 있어요")

/**
- `viewStore.$searchText`
- `bind(viewStore.$focus, to: $focus)`
*/
Section {
TextField("추가할 학과를 검색해 주세요", text: viewStore.$searchText)
.focused($focus, equals: .search)
.bind(viewStore.$focus, to: self.$focus)
HStack {
Text("학과를 추가하거나 \n삭제할 수 있어요")
.font(.system(size: 24, weight: .bold))
.foregroundColor(Color(red: 0.1, green: 0.12, blue: 0.15))
Spacer()
}
.padding(.top, 28)
.padding(.bottom, 24)

HStack(alignment: .center, spacing: 12) {
if viewStore.searchText.isEmpty {
Image(systemName: "magnifyingglass")
.frame(width: 16, height: 16)
.foregroundStyle(Color(red: 0.21, green: 0.24, blue: 0.29).opacity(0.6))
}

/**
- `viewStore.myDepartments`
- `.deleteMyDepartmentButtonTapped`
*/
Section {
TextField("추가할 학과를 검색해 주세요", text: viewStore.$searchText)
.focused($focus, equals: .search)
.bind(viewStore.$focus, to: self.$focus)

if !viewStore.searchText.isEmpty {
Image(systemName: "xmark")
.frame(width: 16, height: 16)
.foregroundStyle(Color(red: 0.21, green: 0.24, blue: 0.29).opacity(0.6))
.onTapGesture {
viewStore.send(.clearTextFieldButtonTapped)
focus = nil
}
}
}
.padding(.horizontal, 16)
.padding(.vertical, 7)
.background(Color(red: 0.95, green: 0.95, blue: 0.96))
.cornerRadius(20)
.padding(.bottom, 16)

HStack(alignment: .center, spacing: 10) {
Text(viewStore.searchText.isEmpty ? "내 학과" : "검색 결과")
.font(.system(size: 14))
.foregroundStyle(Color(red: 0.21, green: 0.24, blue: 0.29).opacity(0.6))
Spacer()
}
.padding(.horizontal, 4)
.padding(.vertical, 10)

if viewStore.searchText.isEmpty {
// 내학과
ScrollView {
ForEach(viewStore.myDepartments) { myDepartment in
HStack {
HStack(alignment: .center) {
Text(myDepartment.korName)

Spacer()

Button("삭제") {
Button {
viewStore.send(.deleteMyDepartmentButtonTapped(id: myDepartment.id))
} label: {
Text("삭제")
.foregroundStyle(Color(red: 0.21, green: 0.24, blue: 0.29).opacity(0.6))
}
}
.padding(.horizontal, 4)
.padding(.vertical, 10)
}
} header: {
Text("내 학과")
}

/**
- `viewStore.results`
- `addDepartmentButtonTapped`
- `cancelAdditionButtonTapped`
*/
Section {
} else {
// 검색결과
ScrollView {
ForEach(viewStore.results) { result in
HStack {
HStack(alignment: .center) {
Text(result.korName)

Spacer()

Button {
if viewStore.myDepartments.contains(result) {
viewStore.send(.cancelAdditionButtonTapped(id: result.id))
} else {
viewStore.send(.addDepartmentButtonTapped(id: result.id))
}
} label: {
let isSelected = viewStore.myDepartments.contains(result)
Image(
systemName: viewStore.myDepartments.contains(result)
systemName: isSelected
? "checkmark.circle.fill"
: "plus.circle"
)
.foregroundStyle(
isSelected
? Color(red: 0.24, green: 0.74, blue: 0.5)
: Color.black.opacity(0.1)
)
}
}
.padding(.horizontal, 4)
.padding(.vertical, 10)
}
} header: {
Text("검색 결과")
}
}

Spacer()
}
.padding(.horizontal, 20)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("전체 삭제") {
Button {
viewStore.send(.deleteAllMyDepartmentButtonTapped)
focus = .search
} label: {
Text("전체 삭제")
.foregroundStyle(
viewStore.myDepartments.isEmpty
? Color(red: 0.21, green: 0.21, blue: 0.21).opacity(0.5)
: Color(red: 0.24, green: 0.74, blue: 0.5)
)
}
.disabled(viewStore.myDepartments.isEmpty)
}
}
.bind(viewStore.$focus, to: self.$focus)
.alert(
store: self.store.scope(
state: \.$alert,
action: { .alert($0) }
)
)
}

}
}


#Preview {
NavigationStack {
DepartmentEditor(
Expand All @@ -220,5 +268,6 @@ struct DepartmentEditor: View {
)
)
.navigationTitle("Department Editor")
.toolbarTitleDisplayMode(.inline)
}
}
Loading

0 comments on commit 9d67d64

Please sign in to comment.