// // OriginalTabView.swift // SodaLive // // Created by klaus on 9/15/25. // import SwiftUI struct OriginalTabView: View { @StateObject var viewModel = OriginalWorkViewModel() private let horizontalPadding: CGFloat = 12 private let gridSpacing: CGFloat = 12 var body: some View { BaseView(isLoading: $viewModel.isLoading) { GeometryReader { geo in let totalSpacing: CGFloat = gridSpacing * 2 let width = (geo.size.width - (horizontalPadding * 2) - totalSpacing) / 3 ScrollView(.vertical, showsIndicators: false) { LazyVGrid( columns: Array( repeating: GridItem( .flexible(), spacing: gridSpacing, alignment: .topLeading ), count: 3 ), alignment: .leading, spacing: gridSpacing ) { ForEach(viewModel.items.indices, id: \.self) { idx in let item = viewModel.items[idx] OriginalTabItemView( item: item, size: width ) .onAppear { viewModel.loadMoreIfNeeded(currentIndex: idx) } .onTapGesture { AppState.shared .setAppStep(step: .originalWorkDetail(originalId: item.id)) } } } .padding(.horizontal, horizontalPadding) if viewModel.isLoadingMore { HStack { Spacer() ProgressView() .progressViewStyle(CircularProgressViewStyle(tint: .white)) .padding(.vertical, 16) Spacer() } } } } .frame(minHeight: 0, maxHeight: .infinity) .padding(.vertical, 12) .onAppear { // 최초 1회만 로드하여 상세 진입 후 복귀 시 스크롤 위치가 유지되도록 함 if viewModel.items.isEmpty { viewModel.fetch() } } } .sodaToast(isPresented: $viewModel.isShowPopup, message: viewModel.errorMessage, autohideIn: 2) } } #Preview { OriginalTabView() }