Trusted by thousands
Join the companies already growing with our platform
+23%
2.5
M+Active Users
Companies and teams using our platform daily
vs last quarter
+180%
$
1.2
BRevenue Processed
Total transaction volume processed annually
year over year
+45%
340
%Growth Rate
Year-over-year customer growth
from last year
-12%
47
msResponse Time
Average API response time globally
faster than before
Installation
Install dependencies
npm install lucide-reactCopy and paste the following code into your project.
"use client";
import React from "react";
import { TrendingUp, Users, DollarSign, Zap, ArrowUpRight } from "lucide-react";
interface Stat {
id: string;
label: string;
value: string;
description: string;
icon: "growth" | "users" | "revenue" | "speed";
trend?: {
value: string;
label: string;
positive?: boolean;
};
prefix?: string;
suffix?: string;
}
interface AchievementShowcaseProps {
title?: string;
description?: string;
stats: Stat[];
className?: string;
}
export function AchievementShowcase({
title = "Trusted by thousands",
description = "Join the companies already growing with our platform",
stats,
className = "",
}: AchievementShowcaseProps) {
const getIcon = (iconType: Stat["icon"]) => {
switch (iconType) {
case "growth":
return TrendingUp;
case "users":
return Users;
case "revenue":
return DollarSign;
case "speed":
return Zap;
}
};
const getIconGradient = (iconType: Stat["icon"]) => {
switch (iconType) {
case "growth":
return "from-emerald-500 to-teal-500";
case "users":
return "from-blue-500 to-cyan-500";
case "revenue":
return "from-violet-500 to-purple-500";
case "speed":
return "from-orange-500 to-amber-500";
}
};
return (
<section className={`relative w-full overflow-hidden py-24 ${className}`}>
{/* Background Pattern */}
<div className="absolute inset-0 -z-10 bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]" />
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{/* Header */}
<div className="mb-16 text-center">
<h2 className="mb-4 text-4xl font-bold tracking-tight text-zinc-900 dark:text-white sm:text-5xl">
{title}
</h2>
<p className="mx-auto max-w-2xl text-lg text-zinc-600 dark:text-zinc-400">
{description}
</p>
</div>
{/* Stats Grid */}
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
{stats.map((stat, index) => {
const Icon = getIcon(stat.icon);
const gradient = getIconGradient(stat.icon);
return (
<div
key={stat.id}
className="group relative overflow-hidden rounded-2xl border border-zinc-200 bg-white p-6 transition-all hover:border-zinc-300 hover:shadow-xl dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700"
style={{
animationDelay: `${index * 100}ms`,
}}
>
{/* Gradient Orb Background */}
<div
className={`absolute -right-8 -top-8 h-32 w-32 rounded-full bg-gradient-to-br ${gradient} opacity-0 blur-3xl transition-opacity duration-500 group-hover:opacity-20`}
/>
{/* Icon */}
<div className="relative mb-6 flex items-center justify-between">
<div
className={`flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br ${gradient} shadow-lg`}
>
<Icon className="h-6 w-6 text-white" />
</div>
{stat.trend && (
<div
className={`flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-semibold ${
stat.trend.positive !== false
? "bg-emerald-50 text-emerald-700 dark:bg-emerald-950/30 dark:text-emerald-400"
: "bg-red-50 text-red-700 dark:bg-red-950/30 dark:text-red-400"
}`}
>
<ArrowUpRight
className={`h-3 w-3 ${stat.trend.positive === false ? "rotate-90" : ""}`}
/>
{stat.trend.value}
</div>
)}
</div>
{/* Value */}
<div className="mb-2 flex items-baseline gap-1">
{stat.prefix && (
<span className="text-2xl font-bold text-zinc-600 dark:text-zinc-400">
{stat.prefix}
</span>
)}
<div className="text-4xl font-bold tracking-tight text-zinc-900 dark:text-white">
{stat.value}
</div>
{stat.suffix && (
<span className="text-xl font-semibold text-zinc-600 dark:text-zinc-400">
{stat.suffix}
</span>
)}
</div>
{/* Label */}
<div className="mb-2 text-sm font-semibold text-zinc-900 dark:text-white">
{stat.label}
</div>
{/* Description */}
<p className="text-sm leading-relaxed text-zinc-600 dark:text-zinc-400">
{stat.description}
</p>
{/* Trend Label */}
{stat.trend?.label && (
<p className="mt-3 text-xs text-zinc-500 dark:text-zinc-500">
{stat.trend.label}
</p>
)}
{/* Bottom Border Accent */}
<div
className={`absolute bottom-0 left-0 h-1 w-full bg-gradient-to-r ${gradient} opacity-0 transition-opacity duration-300 group-hover:opacity-100`}
/>
</div>
);
})}
</div>
</div>
</section>
);
}Features
- ✅ Gradient icons - Beautiful gradient backgrounds for each icon
- ✅ Trend indicators - Show percentage changes with badges
- ✅ Prefix/Suffix support - Add $, %, ms, etc. to values
- ✅ Hover effects - Subtle gradient orb and border accent
- ✅ Background pattern - Dot grid for depth
- ✅ 4 stat cards - Perfect for key metrics
- ✅ Responsive grid - 1-2-4 column layout
- ✅ Dark mode ready - Beautiful in both themes
- ✅ TypeScript support - Full type safety
Usage
Basic Usage
import AchievementShowcase from "@/components/ui/achievement-showcase";
const stats = [
{
id: "1",
label: "Active Users",
value: "2.5",
suffix: "M+",
description: "Companies using our platform daily",
icon: "users",
},
{
id: "2",
label: "Revenue Processed",
value: "1.2",
prefix: "$",
suffix: "B",
description: "Total transaction volume annually",
icon: "revenue",
},
{
id: "3",
label: "Growth Rate",
value: "340",
suffix: "%",
description: "Year-over-year customer growth",
icon: "growth",
},
{
id: "4",
label: "Response Time",
value: "47",
suffix: "ms",
description: "Average API response time",
icon: "speed",
},
];
export default function Page() {
return <AchievementShowcase stats={stats} />;
}With Trends
const stats = [
{
id: "1",
label: "Active Users",
value: "2.5",
suffix: "M+",
description: "Companies using our platform daily",
icon: "users",
trend: {
value: "+23%",
label: "vs last quarter",
positive: true,
},
},
{
id: "2",
label: "Revenue Processed",
value: "1.2",
prefix: "$",
suffix: "B",
description: "Total transaction volume annually",
icon: "revenue",
trend: {
value: "+180%",
label: "year over year",
positive: true,
},
},
];Props
AchievementShowcaseProps
| Prop | Type | Default | Description |
|---|---|---|---|
stats | Stat[] | Required | Array of stats |
title | string | "Trusted by thousands" | Section title |
description | string | "Join the companies..." | Section description |
className | string | "" | Additional CSS classes |
Stat
| Prop | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
label | string | Yes | Stat label |
value | string | Yes | Stat value (number part) |
description | string | Yes | Stat description |
icon | IconType | Yes | Icon type (see below) |
prefix | string | No | Prefix like "$" |
suffix | string | No | Suffix like "M+", "%", "ms" |
trend | Trend | No | Trend indicator (see below) |
Trend
| Prop | Type | Required | Description |
|---|---|---|---|
value | string | Yes | Trend value like "+23%" |
label | string | Yes | Trend label like "vs last month" |
positive | boolean | No | Whether trend is positive |
Icon Types
Available icon types:
"growth"- TrendingUp icon"users"- Users icon"revenue"- DollarSign icon"speed"- Zap icon
TypeScript Interface
interface Stat {
id: string;
label: string;
value: string;
description: string;
icon: "growth" | "users" | "revenue" | "speed";
trend?: {
value: string;
label: string;
positive?: boolean;
};
prefix?: string;
suffix?: string;
}
interface AchievementShowcaseProps {
title?: string;
description?: string;
stats: Stat[];
className?: string;
}Use Cases
Perfect for:
- Landing pages - Show key metrics above the fold
- About pages - Display company statistics
- Investor pages - Highlight growth metrics
- Product pages - Showcase performance numbers
- Dashboard headers - Summary statistics
- Marketing pages - Build credibility with numbers
- Press pages - Share company milestones
- Pricing pages - Show value with metrics
Common Patterns
SaaS Metrics
const saasMetrics = [
{
id: "users",
label: "Active Users",
value: "50",
suffix: "K+",
description: "Teams using our platform",
icon: "users",
trend: {
value: "+12%",
label: "vs last month",
positive: true,
},
},
{
id: "uptime",
label: "Uptime",
value: "99.99",
suffix: "%",
description: "Service reliability",
icon: "speed",
trend: {
value: "100%",
label: "last 30 days",
positive: true,
},
},
{
id: "growth",
label: "Growth",
value: "250",
suffix: "%",
description: "Year-over-year",
icon: "growth",
trend: {
value: "+45%",
label: "from last year",
positive: true,
},
},
{
id: "revenue",
label: "ARR",
value: "10",
prefix: "$",
suffix: "M",
description: "Annual recurring revenue",
icon: "revenue",
trend: {
value: "+89%",
label: "year over year",
positive: true,
},
},
];Performance Metrics
const performanceMetrics = [
{
id: "speed",
label: "Response Time",
value: "<100ms",
description: "Global average latency",
icon: "speed",
},
{
id: "requests",
label: "API Requests",
value: "1B+",
description: "Requests processed monthly",
icon: "growth",
},
{
id: "uptime",
label: "Uptime",
value: "99.99%",
description: "Last 12 months",
icon: "speed",
},
{
id: "customers",
label: "Customers",
value: "10K+",
description: "Businesses served",
icon: "users",
},
];Growth Metrics
const growthMetrics = [
{
id: "users",
label: "Total Users",
value: "2.5M",
description: "Registered users worldwide",
icon: "users",
},
{
id: "growth",
label: "User Growth",
value: "+180%",
description: "Growth in the last year",
icon: "growth",
},
{
id: "revenue",
label: "Revenue",
value: "$50M",
description: "Annual revenue",
icon: "revenue",
},
{
id: "speed",
label: "Time to Value",
value: "<5min",
description: "Average onboarding time",
icon: "speed",
},
];Customization
Add Custom Icons
import {Shield, Globe, Award, Rocket} from "lucide-react";
const getIcon = (iconType: Stat["icon"]) => {
switch (iconType) {
case "growth":
return TrendingUp;
case "users":
return Users;
case "revenue":
return DollarSign;
case "speed":
return Zap;
case "security":
return Shield;
case "global":
return Globe;
// ... more icons
}
};Change Gradient Colors
const getIconGradient = (iconType: Stat["icon"]) => {
switch (iconType) {
case "growth":
return "from-emerald-500 to-teal-500";
case "users":
return "from-blue-500 to-cyan-500";
case "revenue":
return "from-violet-500 to-purple-500";
case "speed":
return "from-orange-500 to-amber-500";
case "custom":
return "from-pink-500 to-rose-500"; // Your custom gradient
}
};Disable Hover Effects
<div className="relative overflow-hidden rounded-2xl border border-zinc-200 bg-white p-6 dark:border-zinc-800 dark:bg-zinc-900">
{/* Remove group, hover:border-zinc-300, hover:shadow-xl classes */}
</div>Remove Background Pattern
<section className={`relative w-full overflow-hidden py-24 ${className}`}>
{/* Remove the background pattern div */}
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">{/* content */}</div>
</section>Different Grid Layouts
{/* 3 columns */}
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
{/* 2 columns */}
<div className="grid gap-8 sm:grid-cols-2">
{/* 5 columns */}
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-5">Integration
With API
async function getStats() {
const response = await fetch("/api/stats");
const data = await response.json();
return [
{
id: "users",
label: "Active Users",
value: formatNumber(data.activeUsers),
description: "Companies using our platform",
icon: "users",
},
// ... more stats
];
}With Real-Time Data
"use client";
import {useEffect, useState} from "react";
export default function LiveStats() {
const [stats, setStats] = useState(initialStats);
useEffect(() => {
const interval = setInterval(async () => {
const response = await fetch("/api/stats");
const data = await response.json();
setStats(formatStats(data));
}, 60000); // Update every minute
return () => clearInterval(interval);
}, []);
return <AchievementShowcase stats={stats} />;
}Number Formatting
function formatNumber(num: number): string {
if (num >= 1000000000) {
return (num / 1000000000).toFixed(1) + "B";
}
if (num >= 1000000) {
return (num / 1000000).toFixed(1) + "M";
}
if (num >= 1000) {
return (num / 1000).toFixed(1) + "K";
}
return num.toString();
}