diff --git a/src/pages/dashboard/giveaway/index.tsx b/src/pages/dashboard/giveaway/index.tsx index be38eb3d..32252f7e 100644 --- a/src/pages/dashboard/giveaway/index.tsx +++ b/src/pages/dashboard/giveaway/index.tsx @@ -1,26 +1,472 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import Layout from "@theme/Layout"; import Head from "@docusaurus/Head"; import { motion } from "framer-motion"; import SlotCounter from "react-slot-counter"; import NavbarIcon from "../../../components/navbar/NavbarIcon"; import { useHistory } from "@docusaurus/router"; +import { Home, MessageCircle, Gift, Trophy, Crown, Star, Award, Clock, Users, TrendingUp, Medal } from "lucide-react"; import "../dashboard.css"; +// Giveaway-specific styles +const giveawayStyles = ` +.giveaway-stats-banner { + display: flex; + justify-content: space-between; + gap: 0.75rem; + margin-bottom: 2rem; + padding: 0 1rem; +} + +.stat-item { + flex: 1; + display: flex; + align-items: center; + gap: 0.5rem; + background: var(--ifm-background-color); + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 8px; + padding: 0.5rem; + transition: all 0.3s ease; + box-shadow: 0 2px 8px var(--ifm-color-emphasis-200); +} + +.stat-item:hover { + transform: translateY(-2px); + box-shadow: 0 4px 16px var(--ifm-color-emphasis-300); +} + +.timer-icon { + background: linear-gradient(135deg, #ff6b6b, #ffa726) !important; +} + +.entries-icon { + background: linear-gradient(135deg, #4ecdc4, #44a08d) !important; +} + +.score-icon { + background: linear-gradient(135deg, #667eea, #764ba2) !important; +} + +.winners-icon { + background: linear-gradient(135deg, #f093fb, #f5576c) !important; +} + +.stat-icon { + width: 28px; + height: 28px; + border-radius: 6px; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.9rem; + flex-shrink: 0; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.stat-content { + min-width: 0; +} + +.stat-content h3 { + font-size: 0.65rem; + font-weight: 600; + color: var(--ifm-color-emphasis-700); + margin: 0 0 0.15rem 0; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.stat-value { + font-size: 1.1rem; + font-weight: 800; + color: var(--ifm-color-emphasis-900); + display: flex; + align-items: baseline; + gap: 0.15rem; + margin-bottom: 0.15rem; +} + +.stat-value span { + font-size: 0.6rem; + font-weight: 600; + color: var(--ifm-color-emphasis-600); +} + +.stat-content p { + font-size: 0.55rem; + color: var(--ifm-color-emphasis-500); + margin: 0; +} + +[data-theme='dark'] .stat-item { + background: var(--ifm-color-emphasis-100); + border-color: var(--ifm-color-emphasis-300); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); +} + +[data-theme='dark'] .stat-item:hover { + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); +} + +.giveaway-leaderboard-section { + margin: 3rem 0; + padding: 0 1rem; +} + +.giveaway-leaderboard-header { + text-align: center; + margin-bottom: 2rem; +} + +.giveaway-leaderboard-title { + font-size: 2.5rem; + font-weight: 800; + margin-bottom: 0.5rem; + color: var(--ifm-color-emphasis-900); +} + +.giveaway-leaderboard-subtitle { + font-size: 1.1rem; + color: var(--ifm-color-emphasis-700); + margin: 0; +} + +.giveaway-loading { + text-align: center; + padding: 3rem; + color: var(--ifm-color-emphasis-700); +} + +.giveaway-leaderboard-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1.5rem; + max-width: 1200px; + margin: 0 auto; +} + +.giveaway-leaderboard-card { + background: var(--ifm-background-color); + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 16px; + padding: 1.5rem; + position: relative; + overflow: hidden; + transition: all 0.3s ease; + box-shadow: 0 4px 12px var(--ifm-color-emphasis-200); +} + +.giveaway-leaderboard-card:hover { + box-shadow: 0 8px 25px var(--ifm-color-emphasis-300); + border-color: var(--ifm-color-primary); + transform: translateY(-2px); +} + +.giveaway-leaderboard-card.rank-1 { + background: linear-gradient(135deg, #ffd700, #ffed4e); + border-color: #ffd700; +} + +.giveaway-leaderboard-card.rank-2 { + background: linear-gradient(135deg, #c0c0c0, #e8e8e8); + border-color: #c0c0c0; +} + +.giveaway-leaderboard-card.rank-3 { + background: linear-gradient(135deg, #cd7f32, #daa520); + border-color: #cd7f32; +} + +[data-theme='dark'] .giveaway-leaderboard-card { + background: var(--ifm-color-emphasis-100); + border-color: var(--ifm-color-emphasis-400); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +[data-theme='dark'] .giveaway-leaderboard-card:hover { + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4); +} + +[data-theme='dark'] .giveaway-leaderboard-card.rank-1 { + background: linear-gradient(135deg, #b8860b, #daa520); +} + +[data-theme='dark'] .giveaway-leaderboard-card.rank-2 { + background: linear-gradient(135deg, #708090, #a9a9a9); +} + +[data-theme='dark'] .giveaway-leaderboard-card.rank-3 { + background: linear-gradient(135deg, #8b4513, #cd853f); +} + +.giveaway-rank-badge { + position: absolute; + top: 1rem; + right: 1rem; + width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + font-size: 0.9rem; + background: var(--ifm-color-primary); + color: var(--ifm-color-primary-contrast-background); +} + +.giveaway-avatar { + position: relative; + width: 80px; + height: 80px; + margin: 0 auto 1rem; +} + +.giveaway-avatar img { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; + border: 3px solid var(--ifm-color-primary); +} + +.giveaway-badge { + position: absolute; + bottom: -5px; + left: 50%; + transform: translateX(-50%); + background: var(--ifm-color-primary); + color: var(--ifm-color-primary-contrast-background); + padding: 0.25rem 0.5rem; + border-radius: 12px; + font-size: 0.7rem; + font-weight: 600; + white-space: nowrap; +} + +.giveaway-info { + text-align: center; + margin-bottom: 1rem; +} + +.giveaway-name { + font-size: 1.2rem; + font-weight: 700; + margin-bottom: 0.5rem; + color: var(--ifm-color-emphasis-900); +} + +.giveaway-leaderboard-card.rank-1 .giveaway-name, +.giveaway-leaderboard-card.rank-2 .giveaway-name, +.giveaway-leaderboard-card.rank-3 .giveaway-name { + color: var(--ifm-color-emphasis-1000); +} + +.giveaway-stats { + display: flex; + justify-content: space-around; + gap: 1rem; +} + +.giveaway-stat { + text-align: center; +} + +.giveaway-stat .stat-value { + display: block; + font-size: 1.5rem; + font-weight: 700; + color: var(--ifm-color-primary); +} + +.giveaway-leaderboard-card.rank-1 .stat-value, +.giveaway-leaderboard-card.rank-2 .stat-value, +.giveaway-leaderboard-card.rank-3 .stat-value { + color: var(--ifm-color-emphasis-1000); +} + +.giveaway-stat .stat-label { + font-size: 0.8rem; + color: var(--ifm-color-emphasis-600); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.giveaway-leaderboard-card.rank-1 .stat-label, +.giveaway-leaderboard-card.rank-2 .stat-label, +.giveaway-leaderboard-card.rank-3 .stat-label { + color: var(--ifm-color-emphasis-800); +} + +.giveaway-profile-btn { + display: block; + width: 100%; + padding: 0.75rem; + background: var(--ifm-color-primary); + color: var(--ifm-color-primary-contrast-background); + text-decoration: none; + border-radius: 8px; + text-align: center; + font-weight: 600; + transition: all 0.3s ease; +} + +.giveaway-profile-btn:hover { + background: var(--ifm-color-primary-dark); + color: var(--ifm-color-primary-contrast-background); + text-decoration: none; + transform: translateY(-2px); +} + +.giveaway-leaderboard-card.rank-1 .giveaway-profile-btn, +.giveaway-leaderboard-card.rank-2 .giveaway-profile-btn, +.giveaway-leaderboard-card.rank-3 .giveaway-profile-btn { + background: var(--ifm-color-emphasis-800); + color: var(--ifm-color-emphasis-0); +} + +.giveaway-leaderboard-card.rank-1 .giveaway-profile-btn:hover, +.giveaway-leaderboard-card.rank-2 .giveaway-profile-btn:hover, +.giveaway-leaderboard-card.rank-3 .giveaway-profile-btn:hover { + background: var(--ifm-color-emphasis-900); + color: var(--ifm-color-emphasis-0); +} + +@media (max-width: 768px) { + .giveaway-stats-banner { + flex-direction: column; + gap: 0.5rem; + } + + .stat-item { + padding: 0.4rem; + } + + .stat-icon { + width: 24px; + height: 24px; + font-size: 0.8rem; + } + + .stat-value { + font-size: 1rem; + } + + .stat-content h3 { + font-size: 0.6rem; + } + + .stat-content p { + font-size: 0.5rem; + } + + .giveaway-leaderboard-grid { + grid-template-columns: 1fr; + gap: 1rem; + } + + .giveaway-leaderboard-title { + font-size: 2rem; + } +} +`; + +// Inject styles +if (typeof document !== 'undefined') { + const existingStyle = document.getElementById('giveaway-styles'); + if (!existingStyle) { + const styleSheet = document.createElement('style'); + styleSheet.id = 'giveaway-styles'; + styleSheet.textContent = giveawayStyles; + document.head.appendChild(styleSheet); + } +} + +interface GiveawayEntry { + rank: number; + name: string; + avatar: string; + points: number; + contributions: number; + github_url: string; + badge?: string; +} + const GiveawayPage: React.FC = () => { const history = useHistory(); const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false); const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false); + const [leaderboard, setLeaderboard] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + // Simulate fetching leaderboard data + const fetchLeaderboard = async () => { + setLoading(true); + // Simulate API delay + await new Promise(resolve => setTimeout(resolve, 1000)); + + const mockData: GiveawayEntry[] = [ + { + rank: 1, + name: "sanjay-kv", + avatar: "https://avatars.githubusercontent.com/u/30715153?v=4", + points: 2500, + contributions: 45, + github_url: "https://github.com/sanjay-kv", + badge: "🏆 Champion" + }, + { + rank: 2, + name: "vansh-codes", + avatar: "https://avatars.githubusercontent.com/u/114163734?v=4", + points: 2100, + contributions: 38, + github_url: "https://github.com/vansh-codes", + badge: "🥈 Runner-up" + }, + { + rank: 3, + name: "Hemu21", + avatar: "https://avatars.githubusercontent.com/u/106808387?v=4", + points: 1850, + contributions: 32, + github_url: "https://github.com/Hemu21", + badge: "🥉 Third Place" + }, + { + rank: 4, + name: "contributor4", + avatar: "https://avatars.githubusercontent.com/u/1?v=4", + points: 1600, + contributions: 28, + github_url: "https://github.com/contributor4" + }, + { + rank: 5, + name: "contributor5", + avatar: "https://avatars.githubusercontent.com/u/2?v=4", + points: 1400, + contributions: 24, + github_url: "https://github.com/contributor5" + } + ]; + + setLeaderboard(mockData); + setLoading(false); + }; + + fetchLeaderboard(); + }, []); const handleTabChange = ( - tab: "home" | "discuss" | "leaderboard" | "contributors" | "giveaway" + tab: "home" | "discuss" | "leaderboard" | "giveaway" ) => { setIsMobileSidebarOpen(false); if (tab === "discuss") { history.push("/dashboard#discuss"); } else if (tab === "leaderboard") { - history.push("/dashboard#leaderboard"); - } else if (tab === "contributors") { history.push("/dashboard#contributors"); } else if (tab === "home") { history.push("/dashboard"); @@ -58,7 +504,7 @@ const GiveawayPage: React.FC = () => { ); return ( - + 🎁 RecodeHive Giveaway @@ -97,39 +543,30 @@ const GiveawayPage: React.FC = () => {
  • handleTabChange("home")}> - + Home
  • handleTabChange("discuss")}> - + Discuss
  • -
  • handleTabChange("leaderboard")} - > - - - - Leaderboard -
  • - + Giveaway
  • handleTabChange("contributors")} + onClick={() => handleTabChange("leaderboard")} > - + - Contributors + Leaderboard
@@ -185,26 +622,104 @@ const GiveawayPage: React.FC = () => {
+ + {/* Giveaway Leaderboard */} + +
+

+ 🎁 Giveaway Leaderboard +

+

+ Top contributors competing for amazing prizes! +

+
+ + {loading ? ( +
+
Loading...
+

Fetching leaderboard data...

+
+ ) : ( +
+ {leaderboard.map((entry, index) => ( + +
+ {entry.rank <= 3 ? ( + entry.rank === 1 ? : + entry.rank === 2 ? : + + ) : ( + `#${entry.rank}` + )} +
+ +
+ {entry.name} + {entry.badge && ( +
{entry.badge}
+ )} +
+ +
+

{entry.name}

+
+
+ {entry.points} + Points +
+
+ {entry.contributions} + Contributions +
+
+
+ + + View Profile + +
+ ))} +
+ )} +
diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index 5ed2dc0d..cc1c9470 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -24,6 +24,7 @@ import { TrendingUp, Home, Trophy, + Users, Gift, Calendar, BarChart3, @@ -90,7 +91,7 @@ const DashboardContent: React.FC = () => { const location = useLocation(); const history = useHistory(); const [activeTab, setActiveTab] = useState< - "home" | "discuss" | "leaderboard" | "giveaway" | "contributors" + "home" | "discuss" | "giveaway" | "contributors" >("home"); // Discussion state management @@ -143,8 +144,6 @@ const DashboardContent: React.FC = () => { // Set active tab based on URL hash if (location.hash === "#discuss") { setActiveTab("discuss"); - } else if (location.hash === "#leaderboard") { - setActiveTab("leaderboard"); } else if (location.hash === "#contributors") { setActiveTab("contributors"); } else if (location.hash === "#giveaway") { @@ -177,13 +176,70 @@ const DashboardContent: React.FC = () => { } }; - // Fetch leaderboard data when leaderboard or contributors tab is active + // Fetch leaderboard data when contributors tab is active or on initial load useEffect(() => { - if (activeTab === "leaderboard" || activeTab === "contributors") { + if (activeTab === "contributors") { fetchLeaderboardData(); } }, [activeTab]); + // Load initial demo data if no data exists + useEffect(() => { + if (leaderboardData.length === 0) { + const initialData: LeaderboardEntry[] = [ + { + rank: 1, + name: "sanjay-kv", + username: "sanjay-kv", + avatar: "https://avatars.githubusercontent.com/u/30715153?v=4", + contributions: 250, + repositories: 25, + score: 2500, + achievements: ["Top Contributor", "Founder", "Maintainer"], + github_url: "https://github.com/sanjay-kv", + streak: 15, + postManTag: false, + web3hack: false, + weeklyContributions: 35, + monthlyContributions: 120, + }, + { + rank: 2, + name: "vansh-codes", + username: "vansh-codes", + avatar: "https://avatars.githubusercontent.com/u/114163734?v=4", + contributions: 180, + repositories: 22, + score: 1800, + achievements: ["Rising Star", "Active Contributor", "Star Contributor"], + github_url: "https://github.com/vansh-codes", + streak: 8, + postManTag: false, + web3hack: false, + weeklyContributions: 25, + monthlyContributions: 85, + }, + { + rank: 3, + name: "Hemu21", + username: "Hemu21", + avatar: "https://avatars.githubusercontent.com/u/106808387?v=4", + contributions: 120, + repositories: 18, + score: 1200, + achievements: ["Power User", "Star Contributor", "Consistent"], + github_url: "https://github.com/Hemu21", + streak: 5, + postManTag: false, + web3hack: false, + weeklyContributions: 18, + monthlyContributions: 60, + }, + ]; + setLeaderboardData(initialData); + } + }, []); + // Discussion handlers const handleDiscussionTabChange = (tab: DiscussionTab) => { setActiveDiscussionTab(tab); @@ -675,7 +731,7 @@ const DashboardContent: React.FC = () => { }; const handleTabChange = ( - tab: "home" | "discuss" | "leaderboard" | "giveaway" | "contributors" + tab: "home" | "discuss" | "giveaway" | "contributors" ) => { setActiveTab(tab); setIsMobileSidebarOpen(false); // Close mobile sidebar @@ -683,9 +739,6 @@ const DashboardContent: React.FC = () => { if (tab === "discuss") { history.push("#discuss"); window.scrollTo(0, 0); - } else if (tab === "leaderboard") { - history.push("#leaderboard"); - window.scrollTo(0, 0); } else if (tab === "giveaway") { history.push("/dashboard/giveaway"); } else if (tab === "contributors") { @@ -777,7 +830,7 @@ const DashboardContent: React.FC = () => { >

GitHub API Rate Limit Reached

- We've temporarily reached the GitHub API rate limit. The leaderboard + We've temporarily reached the GitHub API rate limit. The contributors page will automatically refresh when the limit resets.

{retryTimer && ( @@ -981,20 +1034,7 @@ const DashboardContent: React.FC = () => { Discuss -
{ - handleTabChange("leaderboard"); - setShowDashboardMenu(false); - }} - > - - - - Leaderboard -
+
{ @@ -1017,7 +1057,7 @@ const DashboardContent: React.FC = () => { }} > - + Contributors
@@ -1063,17 +1103,7 @@ const DashboardContent: React.FC = () => { Discuss -
  • handleTabChange("leaderboard")} - > - - - - Leaderboard -
  • +
  • handleTabChange("giveaway")} @@ -1090,7 +1120,7 @@ const DashboardContent: React.FC = () => { onClick={() => handleTabChange("contributors")} > - + Contributors
  • @@ -1114,22 +1144,7 @@ const DashboardContent: React.FC = () => { } ${isSidebarCollapsed ? "sidebar-collapsed" : ""}`} onClick={() => isSidebarCollapsed && setIsSidebarCollapsed(false)} > - {activeTab === "leaderboard" ? ( - /* Leaderboard Tab */ - -
    -

    - RecodeHive Leaderboard -

    -

    Coming soon...

    -
    -
    - ) : activeTab === "home" ? ( + {activeTab === "home" ? ( // Home tab content
    { >

    - Top Contributors Leaderboard + Top Contributors Board

    Celebrating our most active community members who make @@ -1605,7 +1620,7 @@ const DashboardContent: React.FC = () => { )}

    - Showing cached data below. The leaderboard will + Showing cached data below. The contributors page will automatically refresh when possible.

    diff --git a/src/pages/dashboard/leaderboard-page.css b/src/pages/dashboard/leaderboard-page.css new file mode 100644 index 00000000..3d8a7ad3 --- /dev/null +++ b/src/pages/dashboard/leaderboard-page.css @@ -0,0 +1,581 @@ +/* ===== MODERN LEADERBOARD PAGE STYLING ===== */ + +.leaderboard-page { + max-width: 1200px; + margin: 0 auto; + padding: 2rem; + min-height: 100vh; +} + +.leaderboard-page-header { + text-align: center; + margin-bottom: 3rem; + padding: 3rem 2rem; + background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%); + border-radius: 24px; + position: relative; + overflow: hidden; + box-shadow: 0 12px 40px rgba(102, 126, 234, 0.3); +} + +[data-theme="dark"] .leaderboard-page-header { + background: linear-gradient(135deg, #4c63d2 0%, #5a4b8c 50%, #d084e0 100%); + box-shadow: 0 12px 40px rgba(76, 99, 210, 0.4); +} + +.leaderboard-page-title { + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + font-size: 3.5rem; + font-weight: 800; + margin-bottom: 1rem; + color: #ffffff; + text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); +} + +.leaderboard-page-title .highlight { + background: linear-gradient(135deg, #ffd700, #ffed4e); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + filter: drop-shadow(0 2px 4px rgba(255, 215, 0, 0.3)); +} + +.leaderboard-page-subtitle { + color: rgba(255, 255, 255, 0.95); + font-size: 1.2rem; + margin-bottom: 2rem; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); +} + +.filter-section { + display: flex; + justify-content: center; + margin-bottom: 2rem; +} + +.filter-buttons { + display: flex; + gap: 0.5rem; + background: var(--ifm-card-background-color); + padding: 0.5rem; + border-radius: 20px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + border: 1px solid var(--ifm-color-emphasis-200); +} + +[data-theme="dark"] .filter-buttons { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-300); +} + +.filter-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.75rem 1.5rem; + border: none; + border-radius: 15px; + background: transparent; + color: var(--ifm-color-emphasis-700); + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + font-size: 0.9rem; +} + +.filter-btn:hover { + background: var(--ifm-color-emphasis-100); + color: var(--ifm-color-emphasis-900); +} + +.filter-btn.active { + background: linear-gradient(135deg, var(--ifm-color-primary), var(--ifm-color-primary-dark)); + color: white; + box-shadow: 0 4px 15px rgba(var(--ifm-color-primary-rgb), 0.3); +} + +.filter-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.stats-summary { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1.5rem; + margin-bottom: 3rem; +} + +.stat-card { + display: flex; + align-items: center; + gap: 1rem; + padding: 1.5rem; + background: var(--ifm-card-background-color); + border-radius: 20px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + border: 1px solid var(--ifm-color-emphasis-200); + transition: all 0.3s ease; +} + +[data-theme="dark"] .stat-card { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-300); +} + +.stat-card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); +} + +.stat-icon { + display: flex; + align-items: center; + justify-content: center; + width: 50px; + height: 50px; + border-radius: 15px; + background: linear-gradient(135deg, var(--ifm-color-primary), var(--ifm-color-primary-dark)); + color: white; +} + +.stat-info { + flex: 1; +} + +.stat-value { + font-size: 2rem; + font-weight: 800; + color: var(--ifm-color-emphasis-900); + line-height: 1; +} + +.stat-label { + font-size: 0.9rem; + color: var(--ifm-color-emphasis-600); + margin-top: 0.25rem; +} + +.leaderboard-table-wrapper { + background: var(--ifm-card-background-color); + border-radius: 24px; + overflow: hidden; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08); + border: 1px solid var(--ifm-color-emphasis-200); +} + +[data-theme="dark"] .leaderboard-table-wrapper { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-300); +} + +.leaderboard-table { + width: 100%; +} + +.leaderboard-table-header { + display: grid; + grid-template-columns: 100px 1fr 140px 120px; + background: var(--ifm-color-emphasis-100); + padding: 1.25rem 1.5rem; + font-weight: 700; + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.8px; + color: var(--ifm-color-emphasis-800); + border-bottom: 2px solid var(--ifm-color-emphasis-200); +} + +[data-theme="dark"] .leaderboard-table-header { + background: var(--ifm-color-emphasis-200); + color: var(--ifm-color-emphasis-600); +} + +.leaderboard-header-cell { + display: flex; + align-items: center; + justify-content: center; +} + +.leaderboard-header-cell.username-header { + justify-content: flex-start; +} + +.leaderboard-table-body { + display: flex; + flex-direction: column; +} + +.leaderboard-row { + display: grid; + grid-template-columns: 100px 1fr 140px 120px; + padding: 1.75rem 1.5rem; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + transition: all 0.3s ease; + position: relative; +} + +[data-theme="dark"] .leaderboard-row { + border-bottom: 1px solid var(--ifm-color-emphasis-300); +} + +.leaderboard-row:hover { + background: var(--ifm-color-emphasis-100); + transform: translateX(3px); +} + +[data-theme="dark"] .leaderboard-row:hover { + background: var(--ifm-color-emphasis-200); +} + +.leaderboard-row:last-child { + border-bottom: none; +} + +.leaderboard-row.top-1 { + background: linear-gradient(135deg, rgba(255, 215, 0, 0.12) 0%, rgba(255, 193, 7, 0.04) 100%); + border-left: 4px solid #ffd700; +} + +.leaderboard-row.top-2 { + background: linear-gradient(135deg, rgba(192, 192, 192, 0.12) 0%, rgba(169, 169, 169, 0.04) 100%); + border-left: 4px solid #c0c0c0; +} + +.leaderboard-row.top-3 { + background: linear-gradient(135deg, rgba(205, 127, 50, 0.12) 0%, rgba(184, 134, 11, 0.04) 100%); + border-left: 4px solid #cd7f32; +} + +.leaderboard-cell { + display: flex; + align-items: center; + justify-content: center; +} + +.leaderboard-rank-cell { + justify-content: center; +} + +.leaderboard-rank-badge { + display: flex; + align-items: center; + justify-content: center; + width: 50px; + height: 50px; + border-radius: 50%; + font-weight: 700; + background: var(--ifm-color-emphasis-200); + color: var(--ifm-color-emphasis-800); + transition: all 0.3s ease; +} + +.leaderboard-rank-badge.rank-1 { + background: linear-gradient(135deg, #ffd700, #ffed4e); + color: #1a1a1a; + box-shadow: 0 6px 20px rgba(255, 215, 0, 0.4); + transform: scale(1.1); +} + +.leaderboard-rank-badge.rank-2 { + background: linear-gradient(135deg, #c0c0c0, #e8e8e8); + color: #1a1a1a; + box-shadow: 0 6px 20px rgba(192, 192, 192, 0.4); + transform: scale(1.05); +} + +.leaderboard-rank-badge.rank-3 { + background: linear-gradient(135deg, #cd7f32, #daa520); + color: #ffffff; + box-shadow: 0 6px 20px rgba(205, 127, 50, 0.4); +} + +.leaderboard-user-cell { + justify-content: flex-start; +} + +.leaderboard-user-info { + display: flex; + align-items: center; + gap: 1rem; +} + +.leaderboard-user-avatar { + width: 48px; + height: 48px; + border-radius: 50%; + border: 3px solid var(--ifm-color-primary-light); + object-fit: cover; + transition: all 0.3s ease; +} + +.leaderboard-user-avatar:hover { + transform: scale(1.1); + border-color: var(--ifm-color-primary); +} + +.leaderboard-user-details { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.leaderboard-username { + font-weight: 600; + color: var(--ifm-color-emphasis-900); + font-size: 1rem; +} + +.leaderboard-user-achievements { + display: flex; + flex-wrap: wrap; + gap: 0.25rem; +} + +.leaderboard-achievement-badge { + background: var(--ifm-color-primary); + color: white; + padding: 0.2rem 0.6rem; + border-radius: 12px; + font-size: 0.65rem; + font-weight: 600; +} + +.leaderboard-points-cell { + flex-direction: column; + gap: 0.25rem; +} + +.leaderboard-points-value { + font-size: 1.75rem; + font-weight: 800; + color: var(--ifm-color-primary); +} + +.leaderboard-points-label { + font-size: 0.8rem; + color: var(--ifm-color-emphasis-600); +} + +.streak-indicator { + display: flex; + align-items: center; + gap: 0.25rem; + font-size: 0.7rem; + color: var(--ifm-color-warning); + margin-top: 0.25rem; +} + +.leaderboard-date-cell { + justify-content: center; +} + +.leaderboard-date-value { + font-size: 0.9rem; + color: var(--ifm-color-emphasis-700); + font-weight: 500; +} + +.leaderboard-cta { + margin-top: 4rem; + text-align: center; + padding: 3rem 2rem; + background: linear-gradient(135deg, var(--ifm-color-primary) 0%, var(--ifm-color-primary-dark) 100%); + border-radius: 24px; + color: white; +} + +.cta-content h3 { + font-size: 2rem; + font-weight: 700; + margin-bottom: 1rem; + color: white; +} + +.cta-content p { + font-size: 1.1rem; + margin-bottom: 2rem; + opacity: 0.9; + max-width: 600px; + margin-left: auto; + margin-right: auto; +} + +.cta-buttons { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; +} + +.cta-primary, +.cta-secondary { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.875rem 1.75rem; + border-radius: 25px; + font-weight: 600; + text-decoration: none; + transition: all 0.3s ease; +} + +.cta-primary { + background: rgba(255, 255, 255, 0.2); + color: white; + border: 2px solid rgba(255, 255, 255, 0.3); +} + +.cta-primary:hover { + background: rgba(255, 255, 255, 0.3); + transform: translateY(-2px); + color: white; + text-decoration: none; +} + +.cta-secondary { + background: transparent; + color: white; + border: 2px solid rgba(255, 255, 255, 0.5); +} + +.cta-secondary:hover { + background: rgba(255, 255, 255, 0.1); + transform: translateY(-2px); + color: white; + text-decoration: none; +} + +.error-message { + background: linear-gradient(135deg, #fee2e2, #fecaca); + border: 1px solid #fca5a5; + border-radius: 16px; + padding: 1.5rem; + margin-bottom: 2rem; + text-align: center; +} + +[data-theme="dark"] .error-message { + background: linear-gradient(135deg, #7f1d1d, #991b1b); + border: 1px solid #dc2626; + color: #fecaca; +} + +.error-content h3 { + color: #dc2626; + margin-bottom: 0.5rem; +} + +[data-theme="dark"] .error-content h3 { + color: #fca5a5; +} + +.error-note { + font-size: 0.9rem; + opacity: 0.8; + margin-top: 0.5rem; +} + +.leaderboard-loading { + text-align: center; + padding: 4rem 2rem; + background: var(--ifm-card-background-color); + border-radius: 24px; + border: 1px solid var(--ifm-color-emphasis-200); +} + +[data-theme="dark"] .leaderboard-loading { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-300); +} + +.leaderboard-loading-spinner { + width: 48px; + height: 48px; + border: 4px solid var(--ifm-color-emphasis-300); + border-top: 4px solid var(--ifm-color-primary); + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 1rem; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* Responsive Design */ +@media (max-width: 768px) { + .leaderboard-page { + padding: 1rem; + } + + .leaderboard-page-title { + font-size: 2.5rem; + flex-direction: column; + gap: 0.5rem; + } + + .stats-summary { + grid-template-columns: 1fr; + gap: 1rem; + } + + .leaderboard-table-header, + .leaderboard-row { + grid-template-columns: 60px 1fr 80px; + padding: 1rem 0.75rem; + } + + .leaderboard-date-cell, + .leaderboard-header-cell:last-child { + display: none; + } + + .leaderboard-user-info { + gap: 0.75rem; + } + + .leaderboard-user-avatar { + width: 40px; + height: 40px; + } + + .leaderboard-points-value { + font-size: 1.5rem; + } +} + +@media (max-width: 480px) { + .leaderboard-page-header { + padding: 2rem 1rem; + } + + .leaderboard-page-title { + font-size: 2rem; + } + + .filter-buttons { + flex-direction: column; + width: 100%; + } + + .filter-btn { + justify-content: center; + } + + .cta-buttons { + flex-direction: column; + align-items: center; + } + + .cta-primary, + .cta-secondary { + width: 100%; + max-width: 300px; + justify-content: center; + } +} \ No newline at end of file