| import { Card } from '@/components/ui/card'; | |
| import { ExternalLink, Link2 } from 'lucide-react'; | |
| import { motion } from 'framer-motion'; | |
| import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; | |
| interface Source { | |
| title: string; | |
| url: string; | |
| snippet: string; | |
| } | |
| interface SourceListProps { | |
| sources: Source[]; | |
| } | |
| export function SourceList({ sources }: SourceListProps) { | |
| return ( | |
| <div className="space-y-4 animate-in fade-in-50"> | |
| <div className="flex items-center gap-2 mb-2"> | |
| <Link2 className="h-4 w-4 text-muted-foreground" /> | |
| <h2 className="text-base font-semibold text-foreground/90">Sources</h2> | |
| </div> | |
| <ScrollArea className="w-full whitespace-nowrap rounded-md"> | |
| <motion.div | |
| className="flex space-x-3 pb-4" | |
| initial={{ opacity: 0 }} | |
| animate={{ opacity: 1 }} | |
| transition={{ duration: 0.4, staggerChildren: 0.1 }} | |
| > | |
| {sources.map((source, index) => ( | |
| <motion.div | |
| key={index} | |
| initial={{ opacity: 0, x: 20 }} | |
| animate={{ opacity: 1, x: 0 }} | |
| transition={{ duration: 0.3, delay: index * 0.1 }} | |
| className="shrink-0" | |
| > | |
| <Card | |
| className="w-[280px] group overflow-hidden transition-all hover:shadow-md cursor-pointer bg-card/50 hover:bg-card" | |
| onClick={() => window.open(source.url, '_blank')} | |
| > | |
| <div className="p-4 hover:bg-muted/30"> | |
| <div className="flex items-start justify-between gap-3"> | |
| <div className="flex-1 min-w-0"> | |
| <h3 className="font-medium text-sm text-foreground line-clamp-1 mb-1"> | |
| {source.title.replace(/\*\*/g, '')} | |
| </h3> | |
| {source.snippet && ( | |
| <p className="text-sm text-muted-foreground line-clamp-2 mb-2"> | |
| {source.snippet.replace(/\*\*/g, '')} | |
| </p> | |
| )} | |
| <div className="flex items-center gap-2 text-xs text-muted-foreground/70"> | |
| <span className="truncate max-w-[200px]"> | |
| {new URL(source.url).hostname.replace('www.', '')} | |
| </span> | |
| </div> | |
| </div> | |
| <ExternalLink className="h-4 w-4 flex-shrink-0 text-muted-foreground | |
| opacity-50 group-hover:opacity-100 transition-opacity" /> | |
| </div> | |
| </div> | |
| </Card> | |
| </motion.div> | |
| ))} | |
| </motion.div> | |
| <ScrollBar orientation="horizontal" /> | |
| </ScrollArea> | |
| </div> | |
| ); | |
| } |