"use client"; import type { CSSProperties, ReactNode } from "react"; import type { Entity } from "@/uhm/api/entities"; import type { EntityGeometriesSearchItem, EntityGeometrySearchGeo } from "@/uhm/api/geometries"; import type { Wiki } from "@/uhm/api/wikis"; import UnifiedSearchBar, { type UnifiedSearchKind } from "@/uhm/components/ui/UnifiedSearchBar"; type EditorSearchResultsProps = { searchKind: UnifiedSearchKind; onSearchKindChange: (kind: UnifiedSearchKind) => void; searchQuery: string; onSearchQueryChange: (query: string) => void; onLocalSearchQueryChange: (query: string) => void; searchQueryDraft: string; entitySearchResults: Entity[]; isEntitySearchLoading: boolean; onAddEntityRefToProject: (entity: Entity) => void; wikiSearchResults: Wiki[]; isWikiSearching: boolean; onAddWikiRefToProject: (wiki: Wiki) => void; geoSearchResults: EntityGeometriesSearchItem[]; isGeoSearching: boolean; onImportGeoFromSearch: ( entityItem: EntityGeometriesSearchItem, geo: EntityGeometrySearchGeo ) => void; }; export function EditorSearchResults({ searchKind, onSearchKindChange, searchQuery, onSearchQueryChange, onLocalSearchQueryChange, searchQueryDraft, entitySearchResults, isEntitySearchLoading, onAddEntityRefToProject, wikiSearchResults, isWikiSearching, onAddWikiRefToProject, geoSearchResults, isGeoSearching, onImportGeoFromSearch, }: EditorSearchResultsProps) { // Draft query quyết định có render kết quả hay không; query chính đã debounce ở page. const hasQuery = searchQueryDraft.trim().length > 0; return ( <> {searchKind === "entity" && hasQuery ? ( {entitySearchResults.slice(0, 8).map((entity) => ( onAddEntityRefToProject(entity)} /> ))} {!isEntitySearchLoading && entitySearchResults.length === 0 ? : null} ) : null} {searchKind === "wiki" && hasQuery ? ( {wikiSearchResults.slice(0, 8).map((wiki) => ( onAddWikiRefToProject(wiki)} /> ))} {!isWikiSearching && wikiSearchResults.length === 0 ? : null} ) : null} {searchKind === "geo" && hasQuery ? ( {geoSearchResults.slice(0, 6).map((item) => ( ))} {!isGeoSearching && geoSearchResults.length === 0 ? : null} ) : null} ); } function SearchBox({ title, status, children, }: { title: string; status: string; children: ReactNode; }) { return (
{title}
{status}
{children}
); } function ResultRow({ title, subtitle, actionLabel, actionTitle, onAction, }: { title: string; subtitle: string; actionLabel: string; actionTitle: string; onAction: () => void; }) { return (
{title}
{subtitle}
); } function GeoResultGroup({ item, onImportGeoFromSearch, }: { item: EntityGeometriesSearchItem; onImportGeoFromSearch: ( entityItem: EntityGeometriesSearchItem, geo: EntityGeometrySearchGeo ) => void; }) { const geometries = Array.isArray(item.geometries) ? item.geometries : []; return (
{item.name?.trim() || item.entity_id}
{item.entity_id}
{geometries.length} geos
{item.description?.trim() ? (
{item.description.trim()}
) : null} {geometries.length ? (
{geometries.map((geo) => (
#{geo.id}
type: {geo.type || "unknown"}{" "} {geo.time_start != null || geo.time_end != null ? `| time: ${geo.time_start ?? "?"} -> ${geo.time_end ?? "?"}` : ""}
))}
) : (
No geometry linked.
)}
); } function EmptyResult() { return
No results.
; } const actionButtonStyle: CSSProperties = { border: "none", background: "#111827", color: "#93c5fd", cursor: "pointer", borderRadius: 6, padding: "6px 8px", fontSize: 12, fontWeight: 700, };