import SwiftUI struct SearchScreen: 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: 104), spacing: 12)] var body: some View { VStack(spacing: 0) { HStack(spacing: 10) { Image(systemName: "magnifyingglass") .foregroundStyle(McColors.textDim) TextField("Films, series…", text: $query) .textInputAutocapitalization(.never) .autocorrectionDisabled() .foregroundStyle(McColors.text) .submitLabel(.search) .onSubmit { Task { await runSearch() } } if !query.isEmpty { Button { query = "" results = [] } label: { Image(systemName: "xmark.circle.fill") .foregroundStyle(McColors.textDim) } } } .padding(12) .background(McColors.surface, in: RoundedRectangle(cornerRadius: 14, style: .continuous)) .padding(.horizontal, 16) .padding(.top, 8) .padding(.bottom, 12) if searching { ProgressView().tint(.white).padding(.top, 40) Spacer() } else if let error { Text(error).foregroundStyle(McColors.danger).padding() Spacer() } else if results.isEmpty && query.count >= 2 { ContentUnavailableView("Geen resultaten", systemImage: "magnifyingglass") } else if results.isEmpty { ContentUnavailableView("Zoeken in VMC", systemImage: "sparkle.magnifyingglass", description: Text("Typ minstens 2 tekens.")) } else { ScrollView { LazyVGrid(columns: cols, spacing: 14) { ForEach(results) { item in NavigationLink(value: item) { PosterCard(item: item, width: 104) } .buttonStyle(.plain) } } .padding(.horizontal, 16) .padding(.bottom, 24) } .navigationDestination(for: MediaItem.self) { MediaRouter(item: $0) } } } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(McColors.bg.ignoresSafeArea()) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .principal) { BrandHeader(subtitle: "ZOEKEN") } } .toolbarBackground(McColors.bg, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) .onChange(of: query) { _, newValue in Task { try? await Task.sleep(nanoseconds: 350_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 } } }