Skip to content

Commit

Permalink
feat(OrganizationPresent): Add organization detail top section to org…
Browse files Browse the repository at this point in the history
…anization detail view
  • Loading branch information
dodo849 committed Jul 31, 2024
1 parent 9556603 commit 2fc2798
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,193 @@ import Then

class OrganizationDetailView: BaseView {
// MARK: UI Constant
private let organizationProfileCardSize: CGFloat = 86

// MARK: UI Component
// - Navigation bar
lazy var navigationBar = NofficeNavigationBar()

// - Scroll view
lazy var scrollView = UIScrollView().then {
$0.showsVerticalScrollIndicator = true
}

// - Contents view
lazy var contentView = UIView().then {
$0.backgroundColor = .grey50
}

// - Stack view
lazy var stackView = UIStackView().then {
$0.axis = .vertical
$0.spacing = GlobalViewConstant.spacingUnit * 3
}

// - Organization profile
lazy var organizationProfile = BaseHStack(
spacing: GlobalViewConstant.spacingUnit * 3
) {
[
organizationImageView,
BaseVStack(spacing: 0) {
[
organizationNameLabel,
organizationCategoryLabel,
BaseSpacer(
size: GlobalViewConstant.spacingUnit * 2,
fixedSize: true
)
]
}
]
}

lazy var organizationImageView = UIImageView(image: .imgProfileGroup).then {
$0.setSize(
width: organizationProfileCardSize,
height: organizationProfileCardSize
)
$0.layer.cornerRadius = organizationProfileCardSize / 2
$0.layer.masksToBounds = true
}

lazy var organizationNameLabel = UILabel().then {
$0.text = "Skeleton dummy"
$0.setTypo(.heading3)
$0.textColor = .grey800
}

lazy var organizationCategoryLabel = UILabel().then {
$0.text = "Skeleton dummy"
$0.setTypo(.body2)
$0.textColor = .grey700
}

// - Organization participant description
lazy var organizationParticipantDescription = BaseHStack(
alignment: .center,
distribution: .equalSpacing
) {
[
BaseSpacer(),
UILabel().then {
$0.text = "Leader"
$0.setTypo(.body1m)
$0.textColor = .grey400
},
leaderCountLabel,
UILabel().then {
$0.text = "Member"
$0.setTypo(.body1m)
$0.textColor = .grey400
},
memberCountLabel,
BaseSpacer()
]
}

lazy var leaderCountLabel = UILabel().then {
$0.text = "0"
$0.setTypo(.body1m)
$0.textColor = .grey800
}

lazy var memberCountLabel = UILabel().then {
$0.text = "0"
$0.setTypo(.body1m)
$0.textColor = .grey800
}

// - Join waitlist button
lazy var joinWaitlistButton = BaseButton {
[
UIImageView(image: .iconLoading),
UILabel().then {
$0.text = "가입을 대기 중인 멤버가 있어요!"
$0.setTypo(.body1b)
}
]
}.then {
$0.styled(variant: .outline, color: .green, size: .medium)
$0.isHidden = true
}

// - Announcement list collection view
lazy var announcementsCard = BaseCard(
contentsBuilder: {
[
announcementsCollectionView
]
}
).then {
$0.styled(variant: .translucent, color: .background, padding: .medium)
}

lazy var announcementsCollectionView = CompositionalCollectionView().then {
$0.isScrollEnabled = false
}

// MARK: Setup
override func setupHierarchy() { }
public override func setupHierarchy() {
backgroundColor = .grey50

addSubview(navigationBar)

addSubview(scrollView)

scrollView.addSubview(contentView)

scrollView.addSubview(stackView)

stackView.addArrangedSubview(organizationProfile)

stackView.addArrangedSubview(
BaseSpacer(size: GlobalViewConstant.spacingUnit * 3)
)

stackView.addArrangedSubview(BaseDivider(color: .grey200))

stackView.addArrangedSubview(
BaseSpacer(size: GlobalViewConstant.spacingUnit * 3)
)

stackView.addArrangedSubview(organizationParticipantDescription)

stackView.addArrangedSubview(
BaseSpacer(size: GlobalViewConstant.spacingUnit * 2)
)

stackView.addArrangedSubview(joinWaitlistButton)

stackView.addArrangedSubview(
BaseSpacer(size: GlobalViewConstant.spacingUnit * 2)
)

stackView.addArrangedSubview(announcementsCard)
}

override func setupLayout() { }
public override func setupLayout() {
navigationBar.snp.makeConstraints {
$0.top.equalTo(safeAreaLayoutGuide)
$0.left.right.equalToSuperview()
}

scrollView.snp.makeConstraints {
$0.top.equalTo(navigationBar.snp.bottom)
$0.left.right.bottom.equalToSuperview()
}

contentView.snp.makeConstraints {
$0.edges.equalTo(scrollView.contentLayoutGuide)
$0.width.equalTo(scrollView.frameLayoutGuide)
}

stackView.snp.makeConstraints {
$0.top.equalToSuperview()
.offset(GlobalViewConstant.spacingUnit * 2)
$0.left.right.equalToSuperview()
.inset(GlobalViewConstant.pagePaddingLarge)
$0.bottom.equalToSuperview()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import UIKit

import Router
import DesignSystem
import OrganizationEntity

Expand All @@ -33,9 +34,45 @@ class OrganizationDetailViewController: BaseViewController<OrganizationDetailVie
}

// MARK: Setup
override func setupViewBind() { }
override func setupViewBind() {
// - Perform JoinWaitlistButton appearance animation
DispatchQueue.main.async {
self.animateJoinWaitlistButton()
}
}

override func setupStateBind() { }

override func setupActionBind() { }
override func setupActionBind() {
baseView.navigationBar
.onTapBackButton
.subscribe(onNext: { _ in
Router.shared.back()
})
.disposed(by: disposeBag)
}

// MARK: Private
/// Button appearance animation with scaling effect
private func animateJoinWaitlistButton() {
// Initial state
baseView.joinWaitlistButton.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
baseView.joinWaitlistButton.alpha = 0.0

// Animation
UIView.animate(
withDuration: 0.7,
delay: 1,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 0.8,
options: [.curveEaseInOut],
animations: { [weak self] in
guard let self = self else { return }

baseView.joinWaitlistButton.isHidden = false
self.baseView.joinWaitlistButton.transform = CGAffineTransform.identity
self.baseView.joinWaitlistButton.alpha = 1.0
}, completion: nil
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct OrganizationTabConverter {
let sections: [any CompositionalSection] = [
NewOrganizationSection(
items: [
NewOrganizationItem() {
NewOrganizationItem {
onTapNewButton()
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct BasicButtonColorTheme: ButtonColorTheme {
switch variant {
case .fill:
return fillBackgroundColor(color: color, state: state)
case .translucent:
case .translucent, .outline:
return translucentBackgroundColor(color: color, state: state)
case .transparent:
return state == .pressed ? .init(.grey100.opacity(0.5)) : .init(.none)
Expand All @@ -33,7 +33,7 @@ struct BasicButtonColorTheme: ButtonColorTheme {
switch variant {
case .fill:
return fillForegroundColor(color: color, state: state)
case .translucent:
case .translucent, .outline:
return translucentForegroundColor(color: color, state: state)
case .transparent:
return transparentForegroundColor(color: color, state: state)
Expand All @@ -44,6 +44,8 @@ struct BasicButtonColorTheme: ButtonColorTheme {
switch variant {
case .fill, .transparent, .translucent:
return .init(.none)
case .outline:
return outlineborderColor(color: color)
}
}
}
Expand Down Expand Up @@ -93,8 +95,8 @@ private extension BasicButtonColorTheme {
state: ButtonState
) -> UniversalColor {
switch (color, state) {
case (.green, .enabled): return .init(.green700)
case (.green, .pressed): return .init(.green800)
case (.green, .enabled): return .init(.green600)
case (.green, .pressed): return .init(.green700)
case (.ghost, .pressed): return .init(.grey500)
case (.ghost, .enabled): return .init(.grey500)
case (_, .disabled): return .init(.grey500)
Expand All @@ -106,8 +108,8 @@ private extension BasicButtonColorTheme {
state: ButtonState
) -> UniversalColor {
switch (color, state) {
case (.green, .enabled): return .init(.green500)
case (.green, .pressed): return .init(.green600)
case (.green, .enabled): return .init(.green600)
case (.green, .pressed): return .init(.green700)
case (.ghost, .pressed): return .init(.grey500)
case (.ghost, .enabled): return .init(.grey500)
case (_, .disabled): return .init(.grey500)
Expand All @@ -119,11 +121,20 @@ private extension BasicButtonColorTheme {
state: ButtonState
) -> UniversalColor {
switch (color, state) {
case (.green, .enabled): return .init(.green500)
case (.green, .pressed): return .init(.green600)
case (.green, .enabled): return .init(.green600)
case (.green, .pressed): return .init(.green700)
case (.ghost, .pressed): return .init(.grey200)
case (.ghost, .enabled): return .init(.grey200)
case (_, .disabled): return .init(.grey200)
}
}

func outlineborderColor(
color: BasicButtonColor
) -> UniversalColor {
switch color {
case .green: return .init(.green500)
case .ghost: return .init(.grey500)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
import Foundation

public enum BasicButtonVariant: String, CaseIterable {
case fill, translucent, transparent
case fill, outline, translucent, transparent
}

0 comments on commit 2fc2798

Please sign in to comment.