import SwiftUI struct SearchView: View { @EnvironmentObject private var app: AppModel @State private var query = "" @State private var results: [MediaItem] = [] @State private var error: String? @State private var searching = false private let cols = [ GridItem(.adaptive(minimum: 168, maximum: 200), spacing: 24) ] var body: some View { VStack(alignment: .leading, spacing: 24) { Text("Zoeken") .font(TvFonts.title) .foregroundStyle(TvColors.text) .padding(.horizontal, 48) .padding(.top, 12) TextField("Films, series…", text: $query) .font(TvFonts.headline) .foregroundStyle(TvColors.text) .padding(.horizontal, 28) .padding(.vertical, 20) .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 18, style: .continuous)) .overlay( RoundedRectangle(cornerRadius: 18, style: .continuous) .strokeBorder(Color.white.opacity(0.12), lineWidth: 1) ) .padding(.horizontal, 48) .onSubmit { Task { await runSearch() } } Group { if searching { ProgressView().tint(.white).frame(maxWidth: .infinity, maxHeight: .infinity) } else if let error { Text(error).font(TvFonts.body).foregroundStyle(TvColors.danger).padding(.horizontal, 48) Spacer() } else if results.isEmpty && query.count >= 2 { Text("Geen resultaten") .font(TvFonts.headline) .foregroundStyle(TvColors.textDim) .frame(maxWidth: .infinity, maxHeight: .infinity) } else if results.isEmpty { Text("Typ minstens 2 tekens om te zoeken.") .font(TvFonts.body) .foregroundStyle(TvColors.textDim) .frame(maxWidth: .infinity, maxHeight: .infinity) } else { ScrollView { LazyVGrid(columns: cols, spacing: 28) { ForEach(results) { item in NavigationLink(value: item) { PosterCard(item: item, width: 168) } .buttonStyle(FocusableCardStyle()) } } .padding(.horizontal, 48) .padding(.bottom, 48) } .focusSection() } } } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(TvColors.bg.ignoresSafeArea()) .navigationDestination(for: MediaItem.self) { MediaRouter(item: $0) } .onChange(of: query) { _, newValue in Task { try? await Task.sleep(nanoseconds: 400_000_000) guard newValue == query else { return } await runSearch() } } } private func runSearch() async { let q = query.trimmingCharacters(in: .whitespacesAndNewlines) guard q.count >= 2 else { results = [] error = nil return } searching = true error = nil do { results = try await app.api.search(query: q) searching = false } catch { self.error = error.localizedDescription searching = false } } }