import SwiftUI struct MainContentRankingView: View { let onTapContent: (Int) -> Void @StateObject private var viewModel = MainContentRankingViewModel() init(onTapContent: @escaping (Int) -> Void = { _ in }) { self.onTapContent = onTapContent } var body: some View { ZStack { Color.black .ignoresSafeArea() if viewModel.isLoading && !viewModel.hasLoaded { ProgressView() .progressViewStyle(CircularProgressViewStyle(tint: .white)) } else if viewModel.shouldShowEmptyState { MainContentAudioRankingEmptyStateView(message: viewModel.emptyStateMessage) } else { rankingContent } } .onAppear { if !viewModel.hasLoaded { viewModel.fetchRankings() } } .sodaToast(isPresented: $viewModel.isShowPopup, message: viewModel.errorMessage, autohideIn: 2) } private var rankingContent: some View { ScrollView(showsIndicators: false) { VStack(alignment: .leading, spacing: SodaSpacing.s8) { if let topItem { MainContentAudioRankingTopCard( item: topItem, showRankChange: viewModel.showRankChange, onTapContent: onTapContent ) } if !secondToSeventhRankItems.isEmpty { LazyVGrid(columns: twoColumns, alignment: .center, spacing: SodaSpacing.s8) { ForEach(secondToSeventhRankItems) { item in MainContentAudioRankingThumbnailCard( item: item, showRankChange: viewModel.showRankChange, columnsPerRow: 2, onTapContent: onTapContent ) } } } if !eighthToTenthRankItems.isEmpty { LazyVGrid(columns: threeColumns, alignment: .center, spacing: SodaSpacing.s8) { ForEach(eighthToTenthRankItems) { item in MainContentAudioRankingThumbnailCard( item: item, showRankChange: viewModel.showRankChange, columnsPerRow: 3, onTapContent: onTapContent ) } } } if !rowRankItems.isEmpty { VStack(spacing: SodaSpacing.s8) { ForEach(rowRankItems) { item in MainContentAudioRankingRow( item: item, showRankChange: viewModel.showRankChange, onTapContent: onTapContent ) } } } } .padding(.horizontal, SodaSpacing.s8) .padding(.vertical, SodaSpacing.s20) } } private var twoColumns: [GridItem] { [GridItem(.flexible()), GridItem(.flexible())] } private var threeColumns: [GridItem] { [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())] } private var topItem: AudioRankingItemResponse? { viewModel.items.first { $0.rank == 1 } } private var secondToSeventhRankItems: [AudioRankingItemResponse] { viewModel.items.filter { 2...7 ~= $0.rank } } private var eighthToTenthRankItems: [AudioRankingItemResponse] { viewModel.items.filter { 8...10 ~= $0.rank } } private var rowRankItems: [AudioRankingItemResponse] { viewModel.items.filter { 11...20 ~= $0.rank } } }