All files / components/samples SampleGrid.tsx

100% Statements 56/56
87.5% Branches 7/8
100% Functions 3/3
100% Lines 56/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 801x                       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 35x 4x 4x   35x 35x 35x 76x   76x 76x 76x 76x 76x 76x 76x 76x   76x   76x 50x   50x 50x 50x 50x 50x 50x   26x 26x 26x     76x 76x 76x 76x 76x 58x 58x 58x   76x 76x 76x 76x 76x 76x   35x 35x   35x  
'use client';
 
import { ExternalLink, Github, Dribbble, FileText, Play, Image as ImageIcon } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card';
import { trackEvent } from '@/lib/analytics/track';
import type { Sample } from '@/types/database';
 
interface SampleGridProps {
  samples: Sample[];
  profileId: string;
}
 
const sampleTypeIcons = {
  image: ImageIcon,
  video: Play,
  github: Github,
  dribbble: Dribbble,
  behance: Dribbble, // Using Dribbble as fallback
  url: ExternalLink,
  pdf: FileText,
  other: ExternalLink,
};
 
export function SampleGrid({ samples, profileId }: SampleGridProps) {
  const handleSampleClick = (sampleId: string) => {
    trackEvent(profileId, 'sample_click', { sample_id: sampleId });
  };
 
  return (
    <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
      {samples.map((sample) => {
        const Icon = sampleTypeIcons[sample.type] || ExternalLink;
 
        return (
          <a
            key={sample.id}
            href={sample.url}
            target="_blank"
            rel="noopener noreferrer"
            onClick={() => handleSampleClick(sample.id)}
            className="group"
          >
            <Card className="card-hover h-full overflow-hidden">
              {/* Thumbnail */}
              {sample.thumbnail_url ? (
                <div className="aspect-video overflow-hidden bg-muted">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={sample.thumbnail_url}
                    alt={sample.title}
                    className="h-full w-full object-cover transition-transform group-hover:scale-105"
                  />
                </div>
              ) : (
                <div className="flex aspect-video items-center justify-center bg-muted">
                  <Icon className="h-12 w-12 text-muted-foreground/50" />
                </div>
              )}
 
              <CardContent className="p-4">
                <div className="flex items-start justify-between gap-2">
                  <div>
                    <h3 className="font-medium group-hover:text-primary">{sample.title}</h3>
                    {sample.description && (
                      <p className="mt-1 line-clamp-2 text-sm text-muted-foreground">
                        {sample.description}
                      </p>
                    )}
                  </div>
                  <Icon className="h-4 w-4 shrink-0 text-muted-foreground" />
                </div>
              </CardContent>
            </Card>
          </a>
        );
      })}
    </div>
  );
}