trretretret's picture
Fix remaining import paths: Update all components to use @/cn
85a68b2
"use client";
import * as React from "react";
import {
FileText,
Quote,
ExternalLink,
Plus,
Calendar,
User
} from "lucide-react";
import { Button } from "@/components/atoms/Button";
import { Badge } from "@/components/atoms/Badge";
import { Icon } from "@/components/atoms/Icon";
import { cn } from "@/cn";
export interface PaperCardProps {
title: string;
authors: string[];
year: number;
journal?: string;
citationCount?: number;
isOpenAccess?: boolean;
doi?: string;
onAdd?: () => void;
className?: string;
}
/**
* PaperCard Molecule
* Displays core metadata for a research paper.
* Integrated with Badge and Button atoms for status and actions.
*/
export function PaperCard({
title,
authors,
year,
journal,
citationCount,
isOpenAccess,
doi,
onAdd,
className,
}: PaperCardProps) {
// Limit authors display to avoid cluttering the card
const displayAuthors = authors.length > 3
? `${authors.slice(0, 3).join(", ")} et al.`
: authors.join(", ");
return (
<div className={cn(
"group relative flex flex-col gap-3 rounded-lg border bg-card p-5 transition-all hover:shadow-md",
className
)}>
{/* 1. Status Badges */}
<div className="flex items-center justify-between">
<div className="flex gap-2">
{isOpenAccess && (
<Badge variant="success" className="text-[10px] h-5">Open Access</Badge>
)}
{journal && (
<Badge variant="secondary" className="max-w-[150px] truncate text-[10px] h-5">
{journal}
</Badge>
)}
</div>
<div className="flex items-center gap-1 text-xs text-muted-foreground">
<Icon icon={Calendar} size={12} />
{year}
</div>
</div>
{/* 2. Paper Content */}
<div className="space-y-1">
<h3 className="line-clamp-2 text-base font-semibold leading-snug tracking-tight text-foreground group-hover:text-primary transition-colors">
{title}
</h3>
<div className="flex items-center gap-1 text-sm text-muted-foreground">
<Icon icon={User} size={14} className="mt-0.5" />
<span className="line-clamp-1">{displayAuthors}</span>
</div>
</div>
{/* 3. Metrics & Metadata */}
<div className="flex items-center gap-4 text-xs font-medium text-muted-foreground">
<div className="flex items-center gap-1">
<Icon icon={Quote} size={12} />
{citationCount ?? 0} Citations
</div>
{doi && (
<a
href={`https://doi.org/${doi}`}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-1 hover:text-primary transition-colors"
>
<Icon icon={ExternalLink} size={12} />
DOI
</a>
)}
</div>
{/* 4. Action Bar */}
<div className="mt-2 flex items-center gap-2">
<Button variant="default" size="sm" className="h-8 w-full gap-2" onClick={onAdd}>
<Icon icon={Plus} size={14} />
Add to Library
</Button>
<Button variant="outline" size="sm" className="h-8 px-2" asChild title="View Details">
<a href={`/explore/${doi || 'details'}`}>
<Icon icon={FileText} size={14} />
</a>
</Button>
</div>
</div>
);
}