Component Details
Feature Component 02

FeaturedTemplates.tsx
Next.js•Tailwind CSS
1import Image from "next/image";
2import Link from "next/link";
3import { Badge } from "@/components/ui/badge";
4
5interface Template {
6 id: string;
7 name: string;
8 slug: string;
9 image: string;
10 price: string;
11 category: string;
12}
13
14const featuredTemplates: Template[] = [
15 {
16 id: "1",
17 name: "Modern SaaS Dashboard",
18 slug: "modern-saas-dashboard",
19 image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&auto=format&fit=crop",
20 price: "129",
21 category: "dashboard"
22 },
23 {
24 id: "2",
25 name: "E-commerce Store Template",
26 slug: "ecommerce-store-template",
27 image: "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w-800&auto=format&fit=crop",
28 price: "89",
29 category: "ecommerce"
30 },
31 {
32 id: "3",
33 name: "Portfolio Website",
34 slug: "portfolio-website",
35 image: "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&auto=format&fit=crop",
36 price: "Free",
37 category: "portfolio"
38 },
39 {
40 id: "4",
41 name: "Blog Platform",
42 slug: "blog-platform",
43 image: "https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=800&auto=format&fit=crop",
44 price: "75",
45 category: "blog"
46 },
47 {
48 id: "5",
49 name: "Mobile App Landing Page",
50 slug: "mobile-app-landing-page",
51 image: "https://images.unsplash.com/photo-1551650975-87deedd944c3?w=800&auto=format&fit=crop",
52 price: "99",
53 category: "landing"
54 },
55 {
56 id: "6",
57 name: "Admin Dashboard Pro",
58 slug: "admin-dashboard-pro",
59 image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&auto=format&fit=crop",
60 price: "149",
61 category: "dashboard"
62 }
63];
64
65interface TemplateCardProps {
66 template: Template;
67}
68
69function TemplateCard({ template }: TemplateCardProps) {
70 return (
71 <Link href={`/template/${template.slug}`}>
72 <div className="bg-card rounded-lg shadow-lg hover:shadow-xl transition-all duration-300 group relative border border-gray-700 cursor-pointer">
73 {/* Thumbnail */}
74 <div className="relative aspect-video overflow-hidden rounded-t-2xl border-b border-gray-700 group-hover:border-primary transition-colors">
75 <Image
76 src={template.image}
77 alt={template.name}
78 fill
79 className="object-contain object-center"
80 />
81 </div>
82
83 {/* Title and Price Container */}
84 <div className="p-4">
85 <div className="flex items-center justify-between">
86 {/* Title with character limit */}
87 <h3
88 className="text-base truncate max-w-[70%]"
89 title={template.name}
90 >
91 {template.name.length > 30
92 ? `${template.name.substring(0, 30)}...`
93 : template.name}
94 </h3>
95
96 {/* Price */}
97 <Badge
98 variant="secondary"
99 className="bg-blue-600/20 text-white rounded-sm text-sm font-normal capitalize"
100 >
101 {!isNaN(Number(template.price)) && template.price !== "Free"
102 ? `$${template.price}`
103 : template.price}
104 </Badge>
105 </div>
106 </div>
107 </div>
108 </Link>
109 );
110}
111
112export function FeaturedTemplates() {
113 return (
114 <section className="py-20 md:py-28 bg-secondary/20">
115 <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
116 <div className="text-center mb-16">
117 <h2 className="text-3xl md:text-4xl font-bold mb-4">
118 Featured Templates
119 </h2>
120 <p className="text-lg text-muted-foreground max-w-2xl mx-auto">
121 Our hand-picked selection of premium templates to kickstart your
122 next project with style and functionality.
123 </p>
124 </div>
125
126 {featuredTemplates.length > 0 ? (
127 <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-7xl mx-auto">
128 {featuredTemplates.map((template) => (
129 <TemplateCard key={template.id} template={template} />
130 ))}
131 </div>
132 ) : (
133 <div className="text-center py-12">
134 <p className="text-lg text-muted-foreground">
135 No featured templates available at the moment.
136 </p>
137 </div>
138 )}
139 </div>
140 </section>
141 );
142}