style: more robust ui

This commit is contained in:
eshanized
2025-01-01 11:20:56 +05:30
parent c00685c002
commit 010baf616a

View File

@@ -1,8 +1,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from "react";
import { motion } from 'framer-motion'; import { motion } from "framer-motion";
import { Users, Wrench, Star } from 'lucide-react'; import { Users, Wrench, Star } from "lucide-react";
// Define a new type for the stats
interface Stat { interface Stat {
label: string; label: string;
value: string; value: string;
@@ -10,66 +9,79 @@ interface Stat {
} }
export function StatsSection() { export function StatsSection() {
// Set initial state for the stats
const [stats, setStats] = useState<Stat[]>([ const [stats, setStats] = useState<Stat[]>([
{ label: 'Active Users', value: 'Loading...', icon: Users }, { label: "Active Users", value: "Loading...", icon: Users },
{ label: 'Security Tools', value: 'Loading...', icon: Wrench }, { label: "Security Tools", value: "Loading...", icon: Wrench },
{ label: 'GitHub Stars', value: 'Loading...', icon: Star }, { label: "GitHub Stars", value: "Loading...", icon: Star },
]); ]);
// Function to fetch stats from GitHub API
const fetchGitHubStats = async (username: string) => { const fetchGitHubStats = async (username: string) => {
try { try {
const response = await fetch(`https://api.github.com/users/${username}`); const response = await fetch(`https://api.github.com/users/${username}`);
const userData = await response.json(); const userData = await response.json();
// Fetch repositories to count the stars
const reposResponse = await fetch(userData.repos_url); const reposResponse = await fetch(userData.repos_url);
const reposData = await reposResponse.json(); const reposData = await reposResponse.json();
const starsCount = reposData.reduce((acc: number, repo: any) => acc + repo.stargazers_count, 0); const starsCount = reposData.reduce((acc: number, repo: any) => acc + repo.stargazers_count, 0);
// Set the state with the fetched stats
setStats([ setStats([
{ label: ' ', value: `${userData.followers} Followers`, icon: Users }, { label: "Followers", value: `${userData.followers}`, icon: Users },
{ label: ' ', value: `${reposData.length} Repositories`, icon: Wrench }, { label: "Repositories", value: `${reposData.length}`, icon: Wrench },
{ label: ' ', value: `${starsCount} Stars`, icon: Star }, { label: "Stars", value: `${starsCount}`, icon: Star },
]); ]);
} catch (error) { } catch (error) {
console.error('Error fetching GitHub data:', error); console.error("Error fetching GitHub data:", error);
setStats((prevStats) =>
prevStats.map((stat) => ({
...stat,
value: "N/A",
}))
);
} }
}; };
// Fetch stats when the component is mounted
useEffect(() => { useEffect(() => {
const username = 'Snigdha-OS'; // Replace with the desired GitHub username const username = "Snigdha-OS"; // Replace with the desired GitHub username
fetchGitHubStats(username); fetchGitHubStats(username);
}, []); }, []);
return ( return (
<section className="py-20 bg-gradient-to-b from-white to-gray-50"> <section className="py-20 bg-gradient-to-b from-white to-gray-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-4xl font-bold text-gray-900">Our Impact</h2>
<p className="mt-4 text-lg text-gray-600">
A snapshot of our growing community and contributions.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8"> <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{stats.map((stat, index) => ( {stats.map((stat, index) => (
<motion.div <motion.div
key={stat.label} key={stat.label}
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} whileInView={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.2 }} transition={{ delay: index * 0.2, duration: 0.6 }}
viewport={{ once: true }} viewport={{ once: true }}
className="text-center" className="flex flex-col items-center p-6 bg-white rounded-xl shadow-lg hover:shadow-xl transition-shadow duration-300"
> >
<stat.icon className="h-8 w-8 text-cornflower-blue mx-auto mb-4" /> <motion.div
className="p-4 bg-gradient-to-r from-cornflower-blue/10 to-cornflower-blue/30 rounded-full mb-6"
whileHover={{ scale: 1.1 }}
transition={{ duration: 0.3 }}
>
<stat.icon className="h-10 w-10 text-cornflower-blue" />
</motion.div>
<motion.p <motion.p
initial={{ scale: 0.5 }} initial={{ scale: 0.8 }}
whileInView={{ scale: 1 }} whileInView={{ scale: 1 }}
transition={{ delay: index * 0.2 + 0.2 }} transition={{ delay: index * 0.2 + 0.2 }}
viewport={{ once: true }} viewport={{ once: true }}
className="text-4xl font-bold text-gray-900 mb-2" className="text-4xl font-extrabold text-gray-900"
> >
{stat.value} {stat.value}
</motion.p> </motion.p>
<p className="text-gray-600">{stat.label}</p> <p className="text-lg font-medium text-gray-600">{stat.label}</p>
</motion.div> </motion.div>
))} ))}
</div> </div>