Ctrl K
ComunidadGuías…

components/video-result-grid.tsx

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

Archivo original ↗Preguntar a KiBot
'use client'

import Image from 'next/image'

import { IconCirclePlus as PlusCircle } from '@tabler/icons-react'

import { SerperSearchResultItem } from '@/lib/types'
import { faviconUrl } from '@/lib/utils/favicon'

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

import { VideoCarouselDialog } from './video-carousel-dialog'

interface VideoResultGridProps {
  videos: SerperSearchResultItem[]
  query: string
  displayMode: 'chat' | 'artifact'
}

export function VideoResultGrid({
  videos,
  query,
  displayMode
}: VideoResultGridProps) {
  const containerClasses =
    displayMode === 'chat'
      ? 'flex flex-wrap'
      : 'grid grid-cols-1 sm:grid-cols-2 gap-4'

  const itemsToMap = displayMode === 'chat' ? videos.slice(0, 4) : videos

  return (
    <div className={containerClasses}>
      {itemsToMap.map((video, index) => {
        const baseUrl = video.imageUrl ? video.imageUrl.split('?')[0] : ''
        const showOverlay =
          displayMode === 'chat' && index === 3 && videos.length > 4
        const cardClasses = displayMode === 'chat' ? 'w-1/2 md:w-1/4 p-1' : ''

        return (
          <VideoCarouselDialog
            key={video.link || index}
            videos={videos} // Pass all filtered videos for the dialog
            query={query}
            initialIndex={index}
          >
            <div className={`relative cursor-pointer ${cardClasses}`}>
              <Card className="flex-1 min-h-40 overflow-hidden rounded-lg border hover:shadow-xs transition-shadow duration-200">
                <CardContent className="p-0">
                  {' '}
                  {/* Adjusted padding */}
                  {baseUrl && (
                    <div className="relative w-full aspect-video bg-muted">
                      <Image
                        src={baseUrl}
                        alt={`Thumbnail for ${video.title}`}
                        fill
                        sizes={
                          displayMode === 'chat'
                            ? '(max-width: 768px) 50vw, 25vw'
                            : '(max-width: 639px) 300px, 250px'
                        } // Different sizes per mode
                        className="object-cover"
                        priority={index < 4}
                        onError={e => {
                          const target = e.target as HTMLImageElement
                          target.src = '/images/placeholder-image.png'
                        }}
                      />
                    </div>
                  )}
                  <div className="p-2">
                    {' '}
                    {/* Inner padding for text */}
                    <p className="text-xs line-clamp-2 mb-1 font-semibold">
                      {video.title}
                    </p>
                    <div className="flex items-center space-x-2">
                      <Avatar className="h-4 w-4">
                        <AvatarImage
                          src={faviconUrl(video.link)}
                          alt={video.channel || video.source}
                        />
                        <AvatarFallback>
                          {new URL(video.link).hostname[0]}
                        </AvatarFallback>
                      </Avatar>
                      <div className="text-xs text-muted-foreground opacity-60 truncate">
                        {/* Display channel or source if available */}
                        {video.channel ||
                          video.source ||
                          new URL(video.link).hostname}
                      </div>
                    </div>
                  </div>
                </CardContent>
              </Card>
              {showOverlay && (
                <div className="absolute inset-0 bg-black/30 rounded-md flex items-center justify-center text-white/80 text-sm">
                  <PlusCircle size={24} />
                </div>
              )}
            </div>
          </VideoCarouselDialog>
        )
      })}
    </div>
  )
}