Skip to content

Commit

Permalink
feat(Announcement): Add create announcement to todo and notification
Browse files Browse the repository at this point in the history
  • Loading branch information
dodo849 committed Aug 25, 2024
1 parent 6b500d8 commit 6719054
Show file tree
Hide file tree
Showing 16 changed files with 181 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
//

import AnnouncementEntity
import OrganizationEntity

/// Define the types of views that can be navigated between using a router
public enum Presentable {
public enum Routable {
case newAnnouncement
case announcementDetail(
announcementSummary: AnnouncementSummaryEntity,
organization: AnnouncementOrganizationEntity
)
case newOrganization
case organizationDetail(OrganizationSummaryEntity)
case mypage
case signup
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UIKit
public extension Router {
/// Pushes a view from right to left
func push(
_ presentable: Presentable,
_ presentable: Routable,
animated: Bool = true
) {
let destination = resolvePresentable(presentable)
Expand All @@ -20,7 +20,7 @@ public extension Router {

/// Presents a view from bottom to top
func present(
_ presentable: Presentable,
_ presentable: Routable,
animated: Bool = true
) {
let destination = resolvePresentable(presentable)
Expand All @@ -30,7 +30,7 @@ public extension Router {

/// Presents a view in full screen mode from bottom to top
func presentFullScreen(
_ presentable: Presentable,
_ presentable: Routable,
animated: Bool = true
) {
let destination = resolvePresentable(presentable)
Expand All @@ -44,7 +44,7 @@ public extension Router {

/// Pushes a view controller on the stack when in a presented state (right to left)
func pushToPresent(
_ presentable: Presentable,
_ presentable: Routable,
animated: Bool = true
) {
let destination = resolvePresentable(presentable)
Expand All @@ -54,7 +54,7 @@ public extension Router {

/// Presents a bottom sheet
func bottomSheet(
_ presentable: Presentable,
_ presentable: Routable,
animated: Bool = true
) {
let destination = resolvePresentable(presentable)
Expand Down
2 changes: 1 addition & 1 deletion Projects/DI/RouterDIModule/Router/Sources/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ final public class Router: UINavigationController {

var presentNavigationController: UINavigationController?

public var resolvePresentable: (Presentable) -> UIViewController = { _ in
public var resolvePresentable: (Routable) -> UIViewController = { _ in
fatalError("""
`resolvePresentable` must be set before using Router.
Check the RouterConfig in main app target.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ public struct AnnouncementRepository: AnnouncementRepositoryInterface {
return Disposables.create()
}
}


public func getTodosByAnnouncement(
_ request: GetTodosByAnnouncementRequest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// NewAnnouncementEntity.swift
// AnnouncementUsecase
//
// Created by DOYEON LEE on 8/25/24.
//

import Foundation

/**
Represents a announcement in group(organization).
*/
public struct NewAnnouncementEntity: Equatable {
/// ID of organization that will generate announcement
public let organizationId: Int64

/// Announcement creation date
public let createdAt: Date?

/// Image URL for the announcement illustration. (optional)
public let imageUrl: String?

/// Title of the announcement
public let title: String

/// Body text of the announcement
public let body: String

/// Event date or deadline (optional)
public let endAt: Date?

/// Place of the announcement (optional)
public let place: AnnouncementPlaceEntity?

/// List of todos associated with the announcement (optional)
public let todos: [String]?

/// Dates for notices before the announcement (optional)
public let notifications: [AnnouncementRemindNotification]?

public init(
organizationId: Int64,
imageURL: String?,
createdAt: Date?,
title: String,
body: String,
endAt: Date?,
place: AnnouncementPlaceEntity?,
todos: [String]?,
notifications: [AnnouncementRemindNotification]?
) {
self.organizationId = organizationId
self.createdAt = createdAt
self.imageUrl = imageURL
self.title = title
self.body = body
self.endAt = endAt
self.place = place
self.todos = todos
self.notifications = notifications
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ public struct CreateAnnouncementUsecase {
// MARK: DTO

public struct Input {
let newAnnouncement: AnnouncementEntity
let newAnnouncement: NewAnnouncementEntity

public init(
newAnnouncement: AnnouncementEntity
newAnnouncement: NewAnnouncementEntity
) {
self.newAnnouncement = newAnnouncement
}
Expand All @@ -38,18 +38,28 @@ public struct CreateAnnouncementUsecase {
let memberUserDefaultsManager = UserDefaultsManager<Member>()

// MARK: Initializer

public init() {}

// MARK: Execute method

public func execute(_ input: Input) -> Observable<Output> {
let newAnnouncement = input.newAnnouncement

// endAt이 nil이면 한 달 뒤의 날짜로 설정
let autoGeneratedEndAt = Calendar.current
.date(byAdding: .month, value: 1, to: Date())!


let (noticeBefore, noticeDate) = (newAnnouncement.notifications ?? [])
.reduce(into: ([Date](), [Date]())) { result, notification in
switch notification {
case let .before(timeInterval):
let date = Date().addingTimeInterval(-timeInterval)
result.0.append(date)

case let .custom(date):
result.1.append(date)
}
}

if let member = memberUserDefaultsManager.get() {
return announcementRepository
.createAnnouncement(
Expand All @@ -58,14 +68,19 @@ public struct CreateAnnouncementUsecase {
memberId: member.id,
title: newAnnouncement.title,
content: newAnnouncement.body,
tasks: (newAnnouncement.todos ?? []).map {
.init(content: $0)
},
endAt: newAnnouncement.endAt ?? autoGeneratedEndAt,
noticeBefore: [],
noticeDate: []
noticeBefore: noticeBefore,
noticeDate: noticeDate
)
)
.map { result in
Output(announcementId: Int(result.announcementId ?? 0)) // TODO: optional 처리
let announcementId = Int(result.announcementId ?? 0)
return Output(announcementId: announcementId)
}

} else {
fatalError("해당 유즈케이스는 로그인 상태에서 실행되어야합니다.")
}
Expand Down
6 changes: 6 additions & 0 deletions Projects/Noffice/Noffice/Sources/Config/RouterConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Router
import AnnouncementPresent
import NewAnnouncementPresent
import NewOrganizationPresent
import OrganizationPresent
import MypagePresent
import SignupPresent

Expand All @@ -27,6 +28,11 @@ struct RouterConfig {
organization: organization
)

case let .organizationDetail(organization):
return OrganizationDetailViewController(
organization: organization
)

// - New organization
case .newOrganization:
return NewOrganizationFunnelViewController()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ import DesignSystem
struct AnnouncementPageConverter {
static func convertToOrganizationSections(
_ entities: [AnnouncementOrganizationEntity],
onTapAnnouncementCard: @escaping (AnnouncementSummaryEntity, AnnouncementOrganizationEntity) -> Void
onTapAnnouncementCard: @escaping (
AnnouncementSummaryEntity,
AnnouncementOrganizationEntity
) -> Void,
onTapOrganizationHeader: @escaping (
AnnouncementOrganizationEntity
) -> Void
) -> [AnnouncementSection] {
// - Convert to join pending card
let convertPendingItems: () -> [any CompositionalItem] = {
Expand Down Expand Up @@ -73,7 +79,10 @@ struct AnnouncementPageConverter {
identifier: "\(organizationEntity.id)",
organizationName: organizationEntity.name,
scrollDisabled: scrollDisabled,
items: convertToItems(organizationEntity)
items: convertToItems(organizationEntity),
onTapHeader: {
onTapOrganizationHeader(organizationEntity)
}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,20 @@ struct AnnouncementSection: CompositionalSection {

let items: [any CompositionalItem]

let onTapHeader: () -> Void

init(
identifier: String,
organizationName: String,
scrollDisabled: Bool = false,
items: [any CompositionalItem]
items: [any CompositionalItem],
onTapHeader: @escaping () -> Void
) {
self.identifier = identifier
self.organizationName = organizationName
self.scrollDisabled = scrollDisabled
self.items = items
self.onTapHeader = onTapHeader
}

func hash(into hasher: inout Hasher) {
Expand All @@ -108,6 +112,9 @@ class AnnouncementSectionHeaderView: UIView, CompositionalReusableView {
$0.contentMode = .scaleAspectFit
}

// MARK: DisposeBag
private let disposeBag = DisposeBag()

required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
Expand Down Expand Up @@ -135,5 +142,12 @@ class AnnouncementSectionHeaderView: UIView, CompositionalReusableView {

func configure(with section: Section) {
label.text = section.organizationName

rx.tapGesture()
.when(.recognized)
.subscribe(onNext: { _ in
section.onTapHeader()
})
.disposed(by: disposeBag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ class AnnouncementPageReactor: Reactor {
enum Mutation {
case setOrganizations([AnnouncementOrganizationEntity])
case setMember(MemberEntity)
case toggleisOpenHasLeaderRoleOrganizationDialog
}

struct State {
// - Data
var organizations: [AnnouncementOrganizationEntity] = []
var member: MemberEntity?

// - View TODO: ㅠㅠ 어떻게하지 변수명 머선일
var isOpenHasLeaderRoleOrganizationDialog: Bool = false
}

// MARK: Dependency
Expand All @@ -33,9 +38,6 @@ class AnnouncementPageReactor: Reactor {
let getMemberUsecase = GetMemberUsecase()

let initialState: State = State()
}

extension AnnouncementPageReactor {

func mutate(action: Action) -> Observable<Mutation> {
switch action {
Expand Down Expand Up @@ -65,8 +67,12 @@ extension AnnouncementPageReactor {
switch mutation {
case let .setOrganizations(organizations):
state.organizations = organizations

case let .setMember(member):
state.member = member

case .toggleisOpenHasLeaderRoleOrganizationDialog:
state.isOpenHasLeaderRoleOrganizationDialog
}
return state
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,23 @@ import SnapKit
import Then

class AnnouncementPageView: BaseView {
// MARK: Data source

// MARK: UI Component
let collectionView = CompositionalCollectionView()
// - Announcement collection view
lazy var collectionView = CompositionalCollectionView()

// - Has leader role organization dialog
lazy var hasLeaderRoleOrganizationDialog = BaseDialog(
contentsBuilder: {
[
UILabel().then {
$0.text = "참여한 그룹이 없어요"
}
]
}
).then {
$0.styled()
}

// MARK: Setup
override func setupHierarchy() {
addSubview(collectionView)
Expand Down
Loading

0 comments on commit 6719054

Please sign in to comment.