Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/llms-txt-hub / apps/web/components/sections/guide-card.tsx |
| Date | Not specified in source |
| Repository | Janady13/llms-txt-hub |
| Revision | e0f4bf978d4df168369c7601d9c5f5ea89e84377 |
| Branch | main |
| Path or archive member | apps/web/components/sections/guide-card.tsx |
| Original SHA-256 | 4dc6d4de46c6c8eed6bd8b8be4f1872c6f20597d6dd886bbe9d91eca27537a87 |
| Git blob SHA | 9e1184296de0276b19558d24dc4cafd7b2a802a3 |
| Reading-copy SHA-256 | 4dc6d4de46c6c8eed6bd8b8be4f1872c6f20597d6dd886bbe9d91eca27537a87 |
Recovered source transcript
Download complete source text ↓92 lines · 3.1 KB
import { Badge } from '@thedaviddias/design-system/badge'
import { Book, GraduationCap } from 'lucide-react'
import Image from 'next/image'
import Link from 'next/link'
import { Card, CardContent } from '@/components/ui/card'
import { getRoute } from '@/lib/routes'
import type { Guide } from '@/types/types'
interface GuideCardProps {
guide: Guide
index?: number
}
/**
* Returns a CSS class based on the difficulty level
*
* @param difficulty - The difficulty level of the guide
* @returns CSS class string for styling the difficulty badge
*/
function getDifficultyColor(difficulty: Guide['difficulty']) {
switch (difficulty) {
case 'beginner':
return 'bg-green-500/10 text-green-500 dark:bg-green-500/20'
case 'intermediate':
return 'bg-blue-500/10 text-blue-500 dark:bg-blue-500/20'
case 'advanced':
return 'bg-purple-500/10 text-purple-500 dark:bg-purple-500/20'
default:
return 'bg-gray-500/10 text-gray-500 dark:bg-gray-500/20'
}
}
/**
* Card component for displaying a guide
*
* @param props - Component props
* @param props.guide - The guide to display
* @param props.index - Optional index for staggered animations
* @returns React component
*/
export function GuideCard({ guide, index = 0 }: GuideCardProps) {
return (
<Card
className="p-0 gap-0 transition-all hover:border-primary hover:bg-muted/50 relative overflow-hidden animate-fade-in-up group"
style={{ animationDelay: `${(index + 1) * 50}ms` }}
>
{guide.image && (
<div className="relative aspect-video w-full overflow-hidden">
<Image
src={guide.image}
alt={guide.title}
fill
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
className="object-cover transition-transform duration-300 group-hover:scale-105"
/>
</div>
)}
<CardContent className="p-4 space-y-2">
<div className="flex items-center gap-1.5">
<Badge variant="secondary" className={getDifficultyColor(guide.difficulty)}>
{guide.difficulty}
</Badge>
</div>
<div className="space-y-1">
<h3 className="font-semibold text-sm sm:text-base line-clamp-2">
<Link
href={getRoute('guides.guide', { slug: guide.slug })}
className="block after:absolute after:inset-0 after:content-[''] z-10 hover:text-primary transition-colors"
>
{guide.title}
</Link>
</h3>
<p className="text-xs sm:text-sm text-muted-foreground line-clamp-2">
{guide.description}
</p>
</div>
<div className="flex items-center gap-1.5">
{guide.category === 'getting-started' && (
<Book className="size-4 text-muted-foreground" />
)}
{guide.category === 'implementation' && (
<GraduationCap className="size-4 text-muted-foreground" />
)}
<span className="text-xs text-muted-foreground capitalize">
{guide.category.replace('-', ' ')}
</span>
</div>
</CardContent>
</Card>
)
}