Ctrl K
ComunidadGuías…

components/search-results.tsx

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
'use client'

import { useState } from 'react'
import Link from 'next/link'

import { SearchResultItem } from '@/lib/types'
import { displayUrlName } from '@/lib/utils/domain'
import { faviconUrl } from '@/lib/utils/favicon'

import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'

export interface SearchResultsProps {
  results: SearchResultItem[]
  displayMode?: 'grid' | 'list'
}

export function SearchResults({
  results,
  displayMode = 'grid'
}: SearchResultsProps) {
  // State to manage whether to display the results
  const [showAllResults, setShowAllResults] = useState(false)

  const handleViewMore = () => {
    setShowAllResults(true)
  }

  // Logic for grid mode
  const displayedGridResults = showAllResults ? results : results.slice(0, 3)
  const additionalResultsCount = results.length > 3 ? results.length - 3 : 0

  // --- List Mode Rendering ---
  if (displayMode === 'list') {
    return (
      <div className="flex flex-col gap-2">
        {results.map((result, index) => (
          <Link
            href={result.url}
            key={index}
            passHref
            target="_blank"
            className="block"
          >
            <Card className="w-full hover:bg-muted/50 transition-colors">
              <CardContent className="p-2 flex items-start space-x-2">
                <Avatar className="h-4 w-4 mt-1 shrink-0">
                  <AvatarImage
                    src={faviconUrl(result.url)}
                    alt={new URL(result.url).hostname}
                  />
                  <AvatarFallback className="text-xs">
                    {new URL(result.url).hostname[0]}
                  </AvatarFallback>
                </Avatar>
                <div className="grow overflow-hidden space-y-0.5">
                  <p className="text-sm font-medium line-clamp-1">
                    {result.title || new URL(result.url).pathname}
                  </p>
                  <p className="text-xs text-muted-foreground line-clamp-2">
                    {result.content}
                  </p>
                  <div className="text-xs text-muted-foreground/80 mt-1 truncate">
                    <span className="underline">
                      {new URL(result.url).hostname}
                    </span>
                  </div>
                </div>
              </CardContent>
            </Card>
          </Link>
        ))}
      </div>
    )
  }

  // --- Grid Mode Rendering (Existing Logic) ---
  return (
    <div className="flex flex-col gap-1 md:-m-1 md:flex-row md:flex-wrap md:gap-0">
      {displayedGridResults.map((result, index) => (
        <div className="min-w-0 md:w-1/4 md:p-1" key={index}>
          <Link href={result.url} passHref target="_blank">
            <Card className="h-full flex-1 rounded-md hover:bg-muted/50 transition-colors">
              <CardContent className="flex h-full min-w-0 items-center justify-between gap-2 p-2 md:flex-col md:items-stretch">
                <p className="min-w-0 flex-1 line-clamp-1 text-xs md:min-h-8 md:line-clamp-2">
                  {result.title || result.content}
                </p>
                <div className="flex max-w-[42%] shrink-0 items-center space-x-1 min-w-0 md:mt-2 md:max-w-full md:shrink">
                  <Avatar className="h-4 w-4 shrink-0">
                    <AvatarImage
                      src={faviconUrl(result.url)}
                      alt={new URL(result.url).hostname}
                    />
                    <AvatarFallback>
                      {new URL(result.url).hostname[0]}
                    </AvatarFallback>
                  </Avatar>
                  <div className="text-xs opacity-60 truncate min-w-0">
                    {displayUrlName(result.url)}
                  </div>
                </div>
              </CardContent>
            </Card>
          </Link>
        </div>
      ))}
      {!showAllResults && additionalResultsCount > 0 && (
        <>
          <div className="flex justify-center py-1 md:hidden">
            <Button
              variant="link"
              className="h-auto px-2 py-1 text-muted-foreground"
              onClick={handleViewMore}
            >
              View {additionalResultsCount} more
            </Button>
          </div>
          <div className="hidden md:block md:w-1/4 md:p-1">
            <Card className="flex h-full flex-1 items-center justify-center">
              <CardContent className="p-2">
                <Button
                  variant="link"
                  className="text-muted-foreground"
                  onClick={handleViewMore}
                >
                  View {additionalResultsCount} more
                </Button>
              </CardContent>
            </Card>
          </div>
        </>
      )}
    </div>
  )
}