A beautiful, animated leaderboard component built with Next.js, Firebase Firestore, and Framer Motion. Perfect for tracking referrals, scores, or any ranking system in your applications.
- Real-time Updates: Powered by Firebase Firestore for instant data synchronization
- Smooth Animations: Beautiful transitions and micro-interactions using Framer Motion
- Responsive Design: Fully responsive with modern glassmorphism UI
- Rank Calculation: Automatic ranking with proper tie handling
- User Management: Add new users and increment referral counts
- Modern UI: Built with shadcn/ui components and Tailwind CSS
- Gradient Background: Eye-catching animated gradient background
- Node.js 18+
- Firebase project with Firestore enabled
- Next.js 13+ (App Router)
- Install dependencies:
npm install firebase framer-motion lucide-react
# or
yarn add firebase framer-motion lucide-react
- Install shadcn/ui components:
npx shadcn-ui@latest add table button input
- Set up Firebase configuration:
Create src/firebaseConfig.js
:
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {
// Your Firebase config
apiKey: "your-api-key",
authDomain: "your-auth-domain",
projectId: "your-project-id",
storageBucket: "your-storage-bucket",
messagingSenderId: "your-messaging-sender-id",
appId: "your-app-id"
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
- Add custom CSS for animations:
Add to your globals.css
:
.animated-gradient {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
}
@keyframes gradient {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.text-shadow-lg {
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
The component expects a leaderboard
collection with documents containing:
{
userId: string, // Unique identifier for the user
referralCount: number // Number of referrals/points
}
import Leaderboard from './path/to/Leaderboard';
export default function App() {
return (
<div>
<Leaderboard />
</div>
);
}
// app/leaderboard/page.tsx
import Leaderboard from '@/components/Leaderboard';
export default function LeaderboardPage() {
return <Leaderboard />;
}
export default function Dashboard() {
return (
<div className="container mx-auto">
<h1>Dashboard</h1>
<div className="mt-8">
<Leaderboard />
</div>
</div>
);
}
The component uses Tailwind CSS classes and can be easily customized:
- Colors: Modify the gradient background in
animated-gradient
class - Animations: Adjust Framer Motion parameters in the component
- Spacing: Update padding and margin classes
- Typography: Change font sizes and weights
You can extend the component with additional props:
interface LeaderboardProps {
title?: string;
maxEntries?: number;
showAddUser?: boolean;
animationDuration?: number;
}
fetchLeaderboardData()
: Retrieves and ranks data from FirestoreincrementReferralCount(id: string)
: Increases a user's referral countaddNewUser(userId: string)
: Adds a new user to the leaderboard
- Read:
getDocs()
withorderBy('referralCount', 'desc')
- Update:
updateDoc()
to increment counts - Create:
addDoc()
to add new users
- Data is fetched on component mount and after mutations
- Animations are optimized with Framer Motion's layout animations
- Firestore queries are ordered server-side for better performance
- Consider implementing pagination for large datasets
- Implement Firestore security rules to protect your data
- Consider authentication before allowing user additions
- Validate input data on both client and server side
Example Firestore rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /leaderboard/{document} {
allow read: if true;
allow write: if request.auth != null;
}
}
}
For real-time functionality, replace getDocs()
with onSnapshot()
:
import { onSnapshot } from 'firebase/firestore';
useEffect(() => {
const unsubscribe = onSnapshot(
query(collection(db, 'leaderboard'), orderBy('referralCount', 'desc')),
(snapshot) => {
// Update leaderboard data
}
);
return () => unsubscribe();
}, []);
Add TypeScript interfaces for better type safety:
interface User {
id: string;
userId: string;
referralCount: number;
createdAt?: Date;
updatedAt?: Date;
}
The component is fully responsive and works on:
- Desktop (1024px+)
- Tablet (768px - 1023px)
- Mobile (320px - 767px)
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
MIT License - feel free to use this component in your projects!
- Next.js 13+ - React framework with App Router
- Firebase Firestore - Real-time database
- Framer Motion - Animation library
- shadcn/ui - UI component library
- Tailwind CSS - Utility-first CSS framework
- Lucide React - Icon library
- TypeScript - Type safety
If you encounter any issues or have questions:
- Check the Firebase console for connectivity issues
- Ensure all dependencies are properly installed
- Verify your Firebase configuration
- Check browser console for error messages
Built with β€οΈ using Next.js and Firebase