diff --git a/src/components/GiveawayLeaderboard/GiveawayLeaderboard.tsx b/src/components/GiveawayLeaderboard/GiveawayLeaderboard.tsx new file mode 100644 index 00000000..9e0daacd --- /dev/null +++ b/src/components/GiveawayLeaderboard/GiveawayLeaderboard.tsx @@ -0,0 +1,558 @@ +import { GiveawayEntry } from "@site/src/pages/dashboard/giveaway"; +import { motion } from "framer-motion"; +import { Award, Crown, Star } from "lucide-react"; +import { useEffect, useState } from "react"; + +const giveawayStyles = ` +.dashboard-stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 24px; + margin-bottom: 40px; +} + +.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; + } +} + +/* Dashboard styles for consistency */ +.dashboard-stats-section { + margin-bottom: 60px; +} + +.section-title { + font-size: 1.8rem; + font-weight: 700; + margin-bottom: 30px; + text-align: center; + color: var(--ifm-color-content); +} + +.dashboard-stat-card { + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 16px; + padding: 32px 24px; + text-align: center; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.dashboard-stat-value { + font-size: 2.5rem; + font-weight: 800; + margin-bottom: 10px; + color: var(--ifm-color-primary); + min-height: 60px; + display: flex; + align-items: center; + justify-content: center; +} + +@media (max-width: 996px) { + .dashboard-main-content { + padding: 80px 20px 40px; + } +} +`; + +// 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); + } +} + +const GiveawayLeaderboard = () => { + + 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" + } + ]; + + setLeaderboard(mockData); + setLoading(false); + }; + + fetchLeaderboard(); + }, []); + + return ( + +
+

+ 🎁 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 + +
+ ))} +
+ )} +
+ ); +} + +export default GiveawayLeaderboard \ No newline at end of file diff --git a/src/components/giscus.tsx b/src/components/giscus.tsx index f26d0ca8..e77d3c1e 100644 --- a/src/components/giscus.tsx +++ b/src/components/giscus.tsx @@ -1,74 +1,3 @@ -// import React, { useEffect, useRef } from "react"; - -// const GiscusComments: React.FC = () => { -// const ref = useRef(null); - -// useEffect(() => { -// if (!ref.current) return; -// // Prevent duplicate script injection -// if (ref.current.querySelector("iframe")) return; - -// const script = document.createElement("script"); -// script.src = "https://giscus.app/client.js"; -// script.setAttribute("data-repo", "recodehive/Support"); -// script.setAttribute("data-repo-id", "R_kgDOL9urew"); -// script.setAttribute("data-category", "General"); -// script.setAttribute("data-category-id", "DIC_kwDOL9ure84Cqizj"); -// script.setAttribute("data-mapping", "og:title"); -// script.setAttribute("data-strict", "0"); -// script.setAttribute("data-reactions-enabled", "1"); -// script.setAttribute("data-emit-metadata", "0"); -// script.setAttribute("data-input-position", "top"); -// script.setAttribute("data-theme", "preferred_color_scheme"); -// script.setAttribute("data-lang", "en"); -// script.crossOrigin = "anonymous"; -// script.async = true; -// ref.current.appendChild(script); -// }, []); - -// return
; -// }; - -// export default GiscusComments; - -// import React, { useEffect, useRef } from "react"; -// import { useColorMode } from "@docusaurus/theme-common" - -// const GiscusComments: React.FC = () => { -// const ref = useRef(null); -// const { colorMode } = useColorMode(); -// console.log(colorMode) -// useEffect(() => { -// if (!ref.current) return; -// // Prevent duplicate script injection -// if (ref.current.querySelector("iframe")) return; - -// const script = document.createElement("script"); -// script.src = "https://giscus.app/client.js"; -// script.setAttribute("data-repo", "recodehive/Support"); -// script.setAttribute("data-repo-id", "R_kgDOL9urew"); -// script.setAttribute("data-category", "General"); -// script.setAttribute("data-category-id", "DIC_kwDOL9ure84Cqizj"); -// script.setAttribute("data-mapping", "og:title"); -// script.setAttribute("data-strict", "0"); -// script.setAttribute("data-reactions-enabled", "1"); -// script.setAttribute("data-emit-metadata", "0"); -// script.setAttribute("data-input-position", "top"); - -// // Set the default theme to "light" -// script.setAttribute("data-theme", colorMode); - -// script.setAttribute("data-lang", "en"); -// script.crossOrigin = "anonymous"; -// script.async = true; -// ref.current.appendChild(script); -// }, [colorMode]); - -// return
; -// }; - -// export default GiscusComments; - import React, { useEffect, useRef } from "react"; import { useColorMode } from "@docusaurus/theme-common"; diff --git a/src/pages/dashboard/giveaway/index.tsx b/src/pages/dashboard/giveaway/index.tsx index 80f9307b..ab22f45f 100644 --- a/src/pages/dashboard/giveaway/index.tsx +++ b/src/pages/dashboard/giveaway/index.tsx @@ -7,6 +7,7 @@ import NavbarIcon from "../../../components/navbar/NavbarIcon"; import { useHistory } from "@docusaurus/router"; import { Home, MessageCircle, Gift, Trophy, Crown, Star, Award, Clock, Users, TrendingUp, Medal, ArrowLeft } from "lucide-react"; import "../dashboard.css"; +import GiveawayLeaderboard from "@site/src/components/GiveawayLeaderboard/GiveawayLeaderboard"; // Giveaway-specific styles const giveawayStyles = ` @@ -432,7 +433,7 @@ if (typeof document !== 'undefined') { } } -interface GiveawayEntry { +export interface GiveawayEntry { rank: number; name: string; avatar: string; @@ -454,10 +455,10 @@ const GiveawayPage: React.FC = () => { const handleClickOutside = (event: MouseEvent) => { const target = event.target as Element; // Close menu when clicking on overlay or anywhere outside the menu - if (showDashboardMenu && - (!target.closest('.dashboard-mobile-menu > div:last-child') && - !target.closest('.dashboard-menu-btn') || - target.closest('.dashboard-menu-overlay'))) { + if (showDashboardMenu && + (!target.closest('.dashboard-mobile-menu > div:last-child') && + !target.closest('.dashboard-menu-btn') || + target.closest('.dashboard-menu-overlay'))) { setShowDashboardMenu(false); } }; @@ -470,57 +471,13 @@ const GiveawayPage: React.FC = () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [showDashboardMenu]); - + // Ensure active tab is set correctly when page loads useEffect(() => { // We're on the giveaway page, so the active tab should be "giveaway" setActiveTab("giveaway"); }, []); - 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" - } - ]; - - setLeaderboard(mockData); - setLoading(false); - }; - - fetchLeaderboard(); - }, []); - const handleTabChange = ( tab: "home" | "discuss" | "contributors" | "giveaway" ) => { @@ -587,11 +544,11 @@ const GiveawayPage: React.FC = () => { > {showDashboardMenu ? : } - + {/* Dashboard Mobile Menu */}
{/* Overlay - always present but opacity controlled by CSS */} -
setShowDashboardMenu(false)} /> @@ -606,7 +563,7 @@ const GiveawayPage: React.FC = () => { ✕
- + {/* Dashboard navigation items */}
{ />
+ {/* Giveaway Leaderboard Component */} - {/* 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 3fb7c1e6..f94d0de2 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -35,6 +35,7 @@ import NavbarIcon from "@site/src/components/navbar/NavbarIcon"; import "@site/src/components/discussions/discussions.css"; import "./dashboard.css"; import LeaderBoard from "@site/src/components/dashboard/LeaderBoard/leaderboard"; +import GiveawayLeaderboard from "@site/src/components/GiveawayLeaderboard/GiveawayLeaderboard"; type DiscussionTab = "discussions" | "trending" | "unanswered"; type SortOption = "most_popular" | "latest" | "oldest"; @@ -84,9 +85,9 @@ const DashboardContent: React.FC = () => { useEffect(() => { const handleClickOutside = (event: MouseEvent) => { const target = event.target as Element; - if (showDashboardMenu && - !target.closest('.dashboard-mobile-menu') && - !target.closest('.dashboard-menu-btn')) { + if (showDashboardMenu && + !target.closest('.dashboard-mobile-menu') && + !target.closest('.dashboard-menu-btn')) { setShowDashboardMenu(false); } }; @@ -358,77 +359,77 @@ const DashboardContent: React.FC = () => { return (
- {/* Dashboard Menu Button - Only visible on mobile */} - - - {/* Dashboard Mobile Menu */} -
- {/* Overlay */} - {showDashboardMenu && ( -
setShowDashboardMenu(!showDashboardMenu)} + aria-label="Toggle dashboard menu" + > + {showDashboardMenu ? "✕" : "☰"} + + + {/* Dashboard Mobile Menu */} +
+ {/* Overlay */} + {showDashboardMenu && ( +
setShowDashboardMenu(false)} + /> + )} +
+
+

Dashboard Menu

+ + aria-label="Close menu" + > + ✕ + +
+ + {/* Dashboard navigation items */} +
+
{ + handleTabChange("home"); + setShowDashboardMenu(false); + }} + > + Home
- - {/* Dashboard navigation items */} -
-
{ - handleTabChange("home"); - setShowDashboardMenu(false); - }} - > - Home -
-
{ - handleTabChange("discuss"); - setShowDashboardMenu(false); - }} - > - Discussions -
-
{ - handleTabChange("contributors"); - setShowDashboardMenu(false); - }} - > - LeaderBoard -
-
{ - handleTabChange("giveaway"); - setShowDashboardMenu(false); - }} - > - Giveaways -
+
{ + handleTabChange("discuss"); + setShowDashboardMenu(false); + }} + > + Discussions +
+
{ + handleTabChange("contributors"); + setShowDashboardMenu(false); + }} + > + LeaderBoard +
+
{ + handleTabChange("giveaway"); + setShowDashboardMenu(false); + }} + > + Giveaways
+
@@ -518,6 +519,7 @@ const DashboardContent: React.FC = () => { />
+ )} diff --git a/tsconfig.json b/tsconfig.json index 2adcebc7..5335307a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,10 @@ "esModuleInterop": true, "moduleResolution": "node", "resolveJsonModule": true, - "types": ["@docusaurus/module-type-aliases", "node"] + "types": [ + "@docusaurus/module-type-aliases", + "node" + ] }, "include": [ "src", @@ -18,5 +21,9 @@ "plugins", "docs" ], - "exclude": [".docusaurus", "build", "node_modules"] -} + "exclude": [ + ".docusaurus", + "build", + "node_modules" + ] +} \ No newline at end of file