@@ -6,6 +6,7 @@ import { Footer } from '../components/Footer/Footer';
66import styled from 'styled-components' ;
77// import Marquee from 'react-fast-marquee';
88import { ArrowLeft } from 'lucide-react' ;
9+ import { useNavigate } from 'react-router-dom' ;
910
1011const StyledButton = styled . button `
1112 cursor: pointer;
@@ -150,6 +151,8 @@ const ProjectsPage = () => {
150151
151152 const projectsPerPage = 9 ;
152153
154+ const navigate = useNavigate ( ) ;
155+
153156 // ...shuffleArray and useEffect for loading projects...
154157
155158 useEffect ( ( ) => {
@@ -382,7 +385,10 @@ const ProjectsPage = () => {
382385 </ div >
383386 </ StyledWrapper >
384387 </ div >
385- < div className = "my-8" > </ div >
388+ < div className = "my-6" > </ div >
389+ < div className = "mb-6 flex flex-col items-center gap-4 sm:flex-row sm:justify-center" >
390+ < StyledLeaderboardButton onClick = { ( ) => navigate ( '/leaderboard' ) } />
391+ </ div >
386392 < div className = "mb-6 flex flex-col items-center gap-4 sm:flex-row sm:justify-center" >
387393 < input
388394 type = "text"
@@ -532,6 +538,41 @@ const LoadingSkeleton = () => {
532538 ) ;
533539} ;
534540
541+ const StyledLeaderboardButton = ( { onClick } ) => (
542+ < StyledWrapper >
543+ < button type = "button" className = "button" onClick = { onClick } >
544+ < span className = "fold" />
545+ < div className = "points_wrapper" >
546+ < i className = "point" />
547+ < i className = "point" />
548+ < i className = "point" />
549+ < i className = "point" />
550+ < i className = "point" />
551+ < i className = "point" />
552+ < i className = "point" />
553+ < i className = "point" />
554+ < i className = "point" />
555+ < i className = "point" />
556+ </ div >
557+ < span className = "inner" >
558+ < svg
559+ className = "icon"
560+ fill = "none"
561+ stroke = "currentColor"
562+ viewBox = "0 0 24 24"
563+ xmlns = "http://www.w3.org/2000/svg"
564+ strokeLinecap = "round"
565+ strokeLinejoin = "round"
566+ strokeWidth = "2.5"
567+ >
568+ < polyline points = "13.18 1.37 13.18 9.64 21.45 9.64 10.82 22.63 10.82 14.36 2.55 14.36 13.18 1.37" />
569+ </ svg >
570+ Top Project Builder Leaderboard
571+ </ span >
572+ </ button >
573+ </ StyledWrapper >
574+ ) ;
575+
535576const StyledWrapper = styled . div `
536577 .relative {
537578 position: relative;
@@ -721,6 +762,215 @@ const StyledWrapper = styled.div`
721762 .style-VG2eL {
722763 animation-delay: 1.7s;
723764 }
765+
766+ // for the button styles
767+
768+ .button {
769+ --h-button: 48px;
770+ --w-button: 102px;
771+ --round: 0.75rem;
772+ cursor: pointer;
773+ position: relative;
774+ display: inline-flex;
775+ align-items: center;
776+ justify-content: center;
777+ overflow: hidden;
778+ transition: all 0.25s ease;
779+ background:
780+ radial-gradient(65.28% 65.28% at 50% 100%, rgba(223, 113, 255, 0.8) 0%, rgba(223, 113, 255, 0) 100%),
781+ linear-gradient(0deg, #7a5af8, #7a5af8);
782+ border-radius: var(--round);
783+ border: none;
784+ outline: none;
785+ padding: 12px 18px;
786+ }
787+ .button::before,
788+ .button::after {
789+ content: '';
790+ position: absolute;
791+ inset: var(--space);
792+ transition: all 0.5s ease-in-out;
793+ border-radius: calc(var(--round) - var(--space));
794+ z-index: 0;
795+ }
796+ .button::before {
797+ --space: 1px;
798+ background: linear-gradient(177.95deg, rgba(255, 255, 255, 0.19) 0%, rgba(255, 255, 255, 0) 100%);
799+ }
800+ .button::after {
801+ --space: 2px;
802+ background:
803+ radial-gradient(65.28% 65.28% at 50% 100%, rgba(223, 113, 255, 0.8) 0%, rgba(223, 113, 255, 0) 100%),
804+ linear-gradient(0deg, #7a5af8, #7a5af8);
805+ }
806+ .button:active {
807+ transform: scale(0.95);
808+ }
809+
810+ .fold {
811+ z-index: 1;
812+ position: absolute;
813+ top: 0;
814+ right: 0;
815+ height: 1rem;
816+ width: 1rem;
817+ display: inline-block;
818+ transition: all 0.5s ease-in-out;
819+ background: radial-gradient(100% 75% at 55%, rgba(223, 113, 255, 0.8) 0%, rgba(223, 113, 255, 0) 100%);
820+ box-shadow: 0 0 3px black;
821+ border-bottom-left-radius: 0.5rem;
822+ border-top-right-radius: var(--round);
823+ }
824+ .fold::after {
825+ content: '';
826+ position: absolute;
827+ top: 0;
828+ right: 0;
829+ width: 150%;
830+ height: 150%;
831+ transform: rotate(45deg) translateX(0%) translateY(-18px);
832+ background-color: #e8e8e8;
833+ pointer-events: none;
834+ }
835+ .button:hover .fold {
836+ margin-top: -1rem;
837+ margin-right: -1rem;
838+ }
839+
840+ .points_wrapper {
841+ overflow: hidden;
842+ width: 100%;
843+ height: 100%;
844+ pointer-events: none;
845+ position: absolute;
846+ z-index: 1;
847+ }
848+
849+ .points_wrapper .point {
850+ bottom: -10px;
851+ position: absolute;
852+ animation: floating-points infinite ease-in-out;
853+ pointer-events: none;
854+ width: 2px;
855+ height: 2px;
856+ background-color: #fff;
857+ border-radius: 9999px;
858+ }
859+ @keyframes floating-points {
860+ 0% {
861+ transform: translateY(0);
862+ }
863+ 85% {
864+ opacity: 0;
865+ }
866+ 100% {
867+ transform: translateY(-55px);
868+ opacity: 0;
869+ }
870+ }
871+ .points_wrapper .point:nth-child(1) {
872+ left: 10%;
873+ opacity: 1;
874+ animation-duration: 2.35s;
875+ animation-delay: 0.2s;
876+ }
877+ .points_wrapper .point:nth-child(2) {
878+ left: 30%;
879+ opacity: 0.7;
880+ animation-duration: 2.5s;
881+ animation-delay: 0.5s;
882+ }
883+ .points_wrapper .point:nth-child(3) {
884+ left: 25%;
885+ opacity: 0.8;
886+ animation-duration: 2.2s;
887+ animation-delay: 0.1s;
888+ }
889+ .points_wrapper .point:nth-child(4) {
890+ left: 44%;
891+ opacity: 0.6;
892+ animation-duration: 2.05s;
893+ }
894+ .points_wrapper .point:nth-child(5) {
895+ left: 50%;
896+ opacity: 1;
897+ animation-duration: 1.9s;
898+ }
899+ .points_wrapper .point:nth-child(6) {
900+ left: 75%;
901+ opacity: 0.5;
902+ animation-duration: 1.5s;
903+ animation-delay: 1.5s;
904+ }
905+ .points_wrapper .point:nth-child(7) {
906+ left: 88%;
907+ opacity: 0.9;
908+ animation-duration: 2.2s;
909+ animation-delay: 0.2s;
910+ }
911+ .points_wrapper .point:nth-child(8) {
912+ left: 58%;
913+ opacity: 0.8;
914+ animation-duration: 2.25s;
915+ animation-delay: 0.2s;
916+ }
917+ .points_wrapper .point:nth-child(9) {
918+ left: 98%;
919+ opacity: 0.6;
920+ animation-duration: 2.6s;
921+ animation-delay: 0.1s;
922+ }
923+ .points_wrapper .point:nth-child(10) {
924+ left: 65%;
925+ opacity: 1;
926+ animation-duration: 2.5s;
927+ animation-delay: 0.2s;
928+ }
929+
930+ .inner {
931+ z-index: 2;
932+ gap: 6px;
933+ position: relative;
934+ width: auto;
935+ white-space: nowrap;
936+ color: white;
937+ display: inline-flex;
938+ align-items: center;
939+ justify-content: center;
940+ font-size: 16px;
941+ font-weight: 500;
942+ line-height: 1.5;
943+ transition: color 0.2s ease-in-out;
944+ }
945+
946+ .inner svg.icon {
947+ width: 18px;
948+ height: 18px;
949+ transition: fill 0.1s linear;
950+ }
951+
952+ .button:focus svg.icon {
953+ fill: white;
954+ }
955+ .button:hover svg.icon {
956+ fill: transparent;
957+ animation:
958+ dasharray 1s linear forwards,
959+ filled 0.1s linear forwards 0.95s;
960+ }
961+ @keyframes dasharray {
962+ from {
963+ stroke-dasharray: 0 0 0 0;
964+ }
965+ to {
966+ stroke-dasharray: 68 68 0 0;
967+ }
968+ }
969+ @keyframes filled {
970+ to {
971+ fill: white;
972+ }
973+ }
724974` ;
725975
726976export default ProjectsPage ;
0 commit comments