// AutoFill/Views/CredentialListView.swift import SwiftUI import KeeVaultCore struct CredentialListView: View { @ObservedObject var vm: ExtensionViewModel @State private var searchQuery: String = "" private var displayedSuggested: [Entry] { searchQuery.isEmpty ? vm.suggestedEntries : [] } private var displayedAll: [Entry] { let entries = searchQuery.isEmpty ? vm.allEntries : vm.session.allEntries() guard !searchQuery.isEmpty else { return entries } let q = searchQuery.lowercased() return entries.filter { $0.title.lowercased().contains(q) || $0.username.lowercased().contains(q) || $0.url.lowercased().contains(q) } } var body: some View { List { if !displayedSuggested.isEmpty { Section("Suggested") { ForEach(displayedSuggested) { entry in CredentialRow(entry: entry) { vm.select(entry) } } } } Section(displayedSuggested.isEmpty ? "" : "All Entries") { if displayedAll.isEmpty { Text("No entries found").foregroundStyle(.secondary) } else { ForEach(displayedAll) { entry in CredentialRow(entry: entry) { vm.select(entry) } } } } } .scrollContentBackground(.hidden) .background(Color("VaultBackground")) .searchable(text: $searchQuery, prompt: "Search…") } } private struct CredentialRow: View { let entry: Entry let onSelect: () -> Void var body: some View { Button(action: onSelect) { VStack(alignment: .leading, spacing: 2) { Text(entry.title).font(.body).foregroundStyle(.primary) Text(entry.username).font(.caption).foregroundStyle(.secondary) if !entry.url.isEmpty { Text(entry.url).font(.caption2).foregroundStyle(.tertiary) } } } } }