// // 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) } } } .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() } } } .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) { GeometryReader { geo in HStack { Spacer() Text(viewModel.errorMessage) .padding(.vertical, 13.3) .frame(width: geo.size.width - 66.7, alignment: .center) .font(.custom(Font.medium.rawValue, size: 12)) .background(Color.button) .foregroundColor(Color.white) .multilineTextAlignment(.center) .cornerRadius(20) .padding(.top, 66.7) Spacer() } } } } } #Preview { OriginalTabView() }