79 lines
2.9 KiB
Swift
79 lines
2.9 KiB
Swift
import SwiftUI
|
|
|
|
struct GiftBoxListView: View {
|
|
@StateObject private var viewModel = GiftBoxListViewModel()
|
|
@State private var hasAppeared = false
|
|
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
DetailNavigationBar(title: "선물함")
|
|
.frame(height: 54)
|
|
BaseView(isLoading: .constant(viewModel.isLoading)) {
|
|
GeometryReader { geometry in
|
|
ScrollView {
|
|
if viewModel.hasLoaded {
|
|
if viewModel.items.isEmpty && isCreator {
|
|
GiftBoxEmptyView {
|
|
AppState.shared.setAppStep(step: GiftConstants.feedbackStep)
|
|
}
|
|
.frame(minHeight: geometry.size.height)
|
|
} else {
|
|
listContent
|
|
}
|
|
}
|
|
}
|
|
.refreshable { await viewModel.refresh() }
|
|
}
|
|
}
|
|
.sodaToast(isPresented: $viewModel.isShowPopup, message: viewModel.errorMessage)
|
|
}
|
|
.background(Color.black.ignoresSafeArea())
|
|
.onAppear {
|
|
guard !hasAppeared else { return }
|
|
hasAppeared = true
|
|
viewModel.fetchInitialPage()
|
|
}
|
|
}
|
|
|
|
private var isCreator: Bool {
|
|
UserDefaults.string(forKey: .role) == MemberRole.CREATOR.rawValue
|
|
}
|
|
|
|
private var listContent: some View {
|
|
VStack(spacing: SodaSpacing.s12) {
|
|
GiftBoxInfoBannerView(direction: viewModel.items.contains {
|
|
GiftDisplayPolicy.listCard(from: $0)?.direction == .received
|
|
} ? .received : .sent)
|
|
|
|
LazyVStack(spacing: 0) {
|
|
LazyVStack(spacing: SodaSpacing.s8) {
|
|
ForEach(viewModel.items, id: \.applicationNo) { item in
|
|
if let model = GiftDisplayPolicy.listCard(from: item) {
|
|
GiftBoxCardView(model: model) {
|
|
AppState.shared.setAppStep(step: .giftDetail(applicationNo: model.applicationNo))
|
|
}
|
|
}
|
|
}
|
|
|
|
if viewModel.isLoadingMore {
|
|
ProgressView()
|
|
.tint(.white)
|
|
.padding(SodaSpacing.s14)
|
|
}
|
|
}
|
|
|
|
if let lastItem = viewModel.items.last {
|
|
Color.clear
|
|
.frame(height: 1)
|
|
.allowsHitTesting(false)
|
|
.accessibilityHidden(true)
|
|
.id(lastItem.applicationNo)
|
|
.onAppear { viewModel.fetchNextPage(currentItem: lastItem) }
|
|
}
|
|
}
|
|
}
|
|
.padding(.top, SodaSpacing.s8)
|
|
.padding(.bottom, SodaSpacing.s14)
|
|
}
|
|
}
|