| 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> |
| ); |
| } |