@@ -5,11 +5,18 @@ import { motion } from "framer-motion";
55import SlotCounter from "react-slot-counter" ;
66import NavbarIcon from "../../../components/navbar/NavbarIcon" ;
77import { useHistory } from "@docusaurus/router" ;
8- import { Home , MessageCircle , Gift , Trophy , Crown , Star , Award , Clock , Users , TrendingUp , Medal } from "lucide-react" ;
8+ import { Home , MessageCircle , Gift , Trophy , Crown , Star , Award , Clock , Users , TrendingUp , Medal , ArrowLeft } from "lucide-react" ;
99import "../dashboard.css" ;
1010
1111// Giveaway-specific styles
1212const giveawayStyles = `
13+ .dashboard-stats-grid {
14+ display: grid;
15+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
16+ gap: 24px;
17+ margin-bottom: 40px;
18+ }
19+
1320.giveaway-stats-banner {
1421 display: flex;
1522 justify-content: space-between;
@@ -370,6 +377,48 @@ const giveawayStyles = `
370377 font-size: 2rem;
371378 }
372379}
380+
381+ /* Dashboard styles for consistency */
382+ .dashboard-stats-section {
383+ margin-bottom: 60px;
384+ }
385+
386+ .section-title {
387+ font-size: 1.8rem;
388+ font-weight: 700;
389+ margin-bottom: 30px;
390+ text-align: center;
391+ color: var(--ifm-color-content);
392+ }
393+
394+ .dashboard-stat-card {
395+ background: var(--ifm-background-surface-color);
396+ border: 1px solid var(--ifm-color-emphasis-200);
397+ border-radius: 16px;
398+ padding: 32px 24px;
399+ text-align: center;
400+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
401+ transition: all 0.3s ease;
402+ position: relative;
403+ overflow: hidden;
404+ }
405+
406+ .dashboard-stat-value {
407+ font-size: 2.5rem;
408+ font-weight: 800;
409+ margin-bottom: 10px;
410+ color: var(--ifm-color-primary);
411+ min-height: 60px;
412+ display: flex;
413+ align-items: center;
414+ justify-content: center;
415+ }
416+
417+ @media (max-width: 996px) {
418+ .dashboard-main-content {
419+ padding: 80px 20px 40px;
420+ }
421+ }
373422` ;
374423
375424// Inject styles
@@ -395,10 +444,38 @@ interface GiveawayEntry {
395444
396445const GiveawayPage : React . FC = ( ) => {
397446 const history = useHistory ( ) ;
398- const [ isSidebarCollapsed , setIsSidebarCollapsed ] = useState ( false ) ;
399- const [ isMobileSidebarOpen , setIsMobileSidebarOpen ] = useState ( false ) ;
447+ const [ showDashboardMenu , setShowDashboardMenu ] = useState ( false ) ;
400448 const [ leaderboard , setLeaderboard ] = useState < GiveawayEntry [ ] > ( [ ] ) ;
401449 const [ loading , setLoading ] = useState ( true ) ;
450+ const [ activeTab , setActiveTab ] = useState < "home" | "discuss" | "contributors" | "giveaway" > ( "giveaway" ) ;
451+
452+ // Close dashboard menu when clicking outside
453+ useEffect ( ( ) => {
454+ const handleClickOutside = ( event : MouseEvent ) => {
455+ const target = event . target as Element ;
456+ // Close menu when clicking on overlay or anywhere outside the menu
457+ if ( showDashboardMenu &&
458+ ( ! target . closest ( '.dashboard-mobile-menu > div:last-child' ) &&
459+ ! target . closest ( '.dashboard-menu-btn' ) ||
460+ target . closest ( '.dashboard-menu-overlay' ) ) ) {
461+ setShowDashboardMenu ( false ) ;
462+ }
463+ } ;
464+
465+ if ( showDashboardMenu ) {
466+ document . addEventListener ( 'mousedown' , handleClickOutside ) ;
467+ }
468+
469+ return ( ) => {
470+ document . removeEventListener ( 'mousedown' , handleClickOutside ) ;
471+ } ;
472+ } , [ showDashboardMenu ] ) ;
473+
474+ // Ensure active tab is set correctly when page loads
475+ useEffect ( ( ) => {
476+ // We're on the giveaway page, so the active tab should be "giveaway"
477+ setActiveTab ( "giveaway" ) ;
478+ } , [ ] ) ;
402479
403480 useEffect ( ( ) => {
404481 // Simulate fetching leaderboard data
@@ -463,13 +540,22 @@ const GiveawayPage: React.FC = () => {
463540 const handleTabChange = (
464541 tab : "home" | "discuss" | "contributors" | "giveaway"
465542 ) => {
466- setIsMobileSidebarOpen ( false ) ;
543+ setActiveTab ( tab ) ;
544+ setShowDashboardMenu ( false ) ;
545+ // When navigating from giveaway page to other tabs, we need to
546+ // ensure we're using consistent paths with the dashboard page
467547 if ( tab === "discuss" ) {
548+ // Navigate to main dashboard page with discuss hash
468549 history . push ( "/dashboard#discuss" ) ;
469550 } else if ( tab === "contributors" ) {
470- history . push ( "/dashboard#contributors" ) ;
551+ // Navigate to main dashboard page with leaderboard hash
552+ history . push ( "/dashboard#leaderboard" ) ;
471553 } else if ( tab === "home" ) {
554+ // Navigate to main dashboard page
472555 history . push ( "/dashboard" ) ;
556+ } else if ( tab === "giveaway" ) {
557+ // Already on giveaway page, just scroll to top
558+ window . scrollTo ( 0 , 0 ) ;
473559 }
474560 } ;
475561
@@ -508,85 +594,123 @@ const GiveawayPage: React.FC = () => {
508594 < Head >
509595 < title > 🎁 RecodeHive Giveaway</ title >
510596 </ Head >
511- < div
512- className = { `dashboard-layout ${
513- isMobileSidebarOpen ? "sidebar-open" : ""
514- } `}
515- >
516- { /* Mobile Menu Button */ }
597+ < div className = "dashboard-layout" >
598+ { /* Dashboard Menu Button - Only visible on mobile */ }
517599 < button
518- className = { `mobile-menu-btn ${ isMobileSidebarOpen ? "open" : "" } ` }
519- onClick = { ( ) => setIsMobileSidebarOpen ( ! isMobileSidebarOpen ) }
520- aria-label = "Toggle mobile menu"
521- />
522-
523- { /* Sidebar Navigation */ }
524- < nav
525- className = { `dashboard-sidebar ${
526- isSidebarCollapsed ? "collapsed" : ""
527- } ${ isMobileSidebarOpen ? "show" : "" } `}
600+ className = { `dashboard-menu-btn ${ showDashboardMenu ? "open" : "" } ` }
601+ onClick = { ( ) => setShowDashboardMenu ( ! showDashboardMenu ) }
602+ aria-label = "Toggle dashboard menu"
528603 >
529- < div className = "sidebar-header" >
530- < div className = "sidebar-logo" >
531- < h2 > RecodeHive</ h2 >
604+ { showDashboardMenu ? < span aria-hidden = "true" > ✕</ span > : < span aria-hidden = "true" > ☰</ span > }
605+ </ button >
606+
607+ { /* Dashboard Mobile Menu */ }
608+ < div className = { `dashboard-mobile-menu ${ showDashboardMenu ? "show" : "" } ` } >
609+ { /* Overlay - always present but opacity controlled by CSS */ }
610+ < div
611+ className = "dashboard-menu-overlay"
612+ onClick = { ( ) => setShowDashboardMenu ( false ) }
613+ />
614+ < div >
615+ < div className = "dashboard-menu-header" >
616+ < h3 > Dashboard Menu</ h3 >
617+ < button
618+ className = "close-menu-btn"
619+ onClick = { ( ) => setShowDashboardMenu ( false ) }
620+ aria-label = "Close menu"
621+ >
622+ ✕
623+ </ button >
624+ </ div >
625+
626+ { /* Dashboard navigation items */ }
627+ < div className = "dashboard-menu-items" >
628+ < div
629+ className = { `menu-item ${ activeTab === "home" ? "active" : "" } ` }
630+ onClick = { ( ) => {
631+ handleTabChange ( "home" ) ;
632+ setShowDashboardMenu ( false ) ;
633+ } }
634+ >
635+ < span className = "menu-icon" > < Home size = { 18 } /> </ span > Home
636+ </ div >
637+ < div
638+ className = { `menu-item ${ activeTab === "discuss" ? "active" : "" } ` }
639+ onClick = { ( ) => {
640+ handleTabChange ( "discuss" ) ;
641+ setShowDashboardMenu ( false ) ;
642+ } }
643+ >
644+ < span className = "menu-icon" > < MessageCircle size = { 18 } /> </ span > Discussions
645+ </ div >
646+ < div
647+ className = { `menu-item ${ activeTab === "contributors" ? "active" : "" } ` }
648+ onClick = { ( ) => {
649+ handleTabChange ( "contributors" ) ;
650+ setShowDashboardMenu ( false ) ;
651+ } }
652+ >
653+ < span className = "menu-icon" > < Trophy size = { 18 } /> </ span > LeaderBoard
654+ </ div >
655+ < div
656+ className = { `menu-item ${ activeTab === "giveaway" ? "active" : "" } ` }
657+ onClick = { ( ) => {
658+ handleTabChange ( "giveaway" ) ;
659+ setShowDashboardMenu ( false ) ;
660+ } }
661+ >
662+ < span className = "menu-icon" > < Gift size = { 18 } /> </ span > Giveaways
663+ </ div >
532664 </ div >
665+ </ div >
666+ </ div >
667+
668+ < div className = "dashboard-sidebar" >
669+ < div className = "sidebar-header" >
533670 < button
534- className = "sidebar-toggle"
535- onClick = { ( ) => setIsSidebarCollapsed ( ! isSidebarCollapsed ) }
536- aria-label = {
537- isSidebarCollapsed ? "Expand sidebar" : "Collapse sidebar"
538- }
671+ className = "back-button"
672+ onClick = { ( ) => {
673+ // If we came from the dashboard, go back, otherwise go to dashboard
674+ if ( history . length > 2 ) {
675+ history . goBack ( ) ;
676+ } else {
677+ history . push ( '/dashboard' ) ;
678+ }
679+ } }
680+ aria-label = "Go back to dashboard"
539681 >
540- { isSidebarCollapsed ? "→" : "←" }
682+ < ArrowLeft size = { 20 } />
541683 </ button >
542684 </ div >
543- < ul className = "sidebar-nav" >
544- < li className = "nav-item" onClick = { ( ) => handleTabChange ( "home" ) } >
545- < span className = "nav-icon" >
546- < Home size = { 18 } />
547- </ span >
548- < span className = "nav-text" > Home</ span >
549- </ li >
550- < li className = "nav-item" onClick = { ( ) => handleTabChange ( "discuss" ) } >
551- < span className = "nav-icon" >
552- < MessageCircle size = { 18 } />
553- </ span >
554- < span className = "nav-text" > Discuss</ span >
555- </ li >
556- < li className = "nav-item active" >
557- < span className = "nav-icon" >
558- < Gift size = { 18 } />
559- </ span >
560- < span className = "nav-text" > Giveaway</ span >
561- </ li >
562- < li
563- className = "nav-item"
685+ < div className = "sidebar-nav" >
686+ < NavbarIcon
687+ icon = { < Home size = { 20 } /> }
688+ text = "Home"
689+ active = { activeTab === "home" }
690+ onClick = { ( ) => handleTabChange ( "home" ) }
691+ />
692+ < NavbarIcon
693+ icon = { < MessageCircle size = { 20 } /> }
694+ text = "Discussions"
695+ active = { activeTab === "discuss" }
696+ onClick = { ( ) => handleTabChange ( "discuss" ) }
697+ />
698+ < NavbarIcon
699+ icon = { < Trophy size = { 20 } /> }
700+ text = "LeaderBoard"
701+ active = { activeTab === "contributors" }
564702 onClick = { ( ) => handleTabChange ( "contributors" ) }
565- >
566- < span className = "nav-icon" >
567- < Trophy size = { 18 } />
568- </ span >
569- < span className = "nav-text" > Contributors</ span >
570- </ li >
571- </ ul >
572- < div className = "sidebar-footer" >
573- < button
574- className = "sidebar-toggle bottom-toggle"
575- onClick = { ( ) => setIsSidebarCollapsed ( ! isSidebarCollapsed ) }
576- aria-label = {
577- isSidebarCollapsed ? "Expand sidebar" : "Collapse sidebar"
578- }
579- >
580- { isSidebarCollapsed ? "→" : "←" }
581- </ button >
703+ />
704+ < NavbarIcon
705+ icon = { < Gift size = { 20 } /> }
706+ text = "Giveaways"
707+ active = { activeTab === "giveaway" }
708+ onClick = { ( ) => handleTabChange ( "giveaway" ) }
709+ />
582710 </ div >
583- </ nav >
711+ </ div >
584712
585- < main
586- className = { `dashboard-main ${
587- isSidebarCollapsed ? "sidebar-collapsed" : ""
588- } `}
589- >
713+ < div className = "dashboard-main-content" >
590714 < motion . section
591715 className = "dashboard-hero"
592716 initial = { { opacity : 0 , y : 10 } }
@@ -720,7 +844,7 @@ const GiveawayPage: React.FC = () => {
720844 </ div >
721845 ) }
722846 </ motion . section >
723- </ main >
847+ </ div >
724848 </ div >
725849 </ Layout >
726850 ) ;
0 commit comments