This commit is contained in:
Kumaraguru 2024-06-15 19:58:47 +05:30
commit 4b51069e5b
No known key found for this signature in database
GPG Key ID: 4E4555A84ECD28F7
28 changed files with 9492 additions and 0 deletions

3
.eslintrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

40
README.md Normal file
View File

@ -0,0 +1,40 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

17
components.json Normal file
View File

@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": false,
"tailwind": {
"config": "tailwind.config.js",
"css": "styles/globals.css",
"baseColor": "stone",
"cssVariables": false,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}

View File

@ -0,0 +1,141 @@
"use client";
import React from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
export const BackgroundBeams = React.memo(
({ className }) => {
const paths = [
"M-380 -189C-380 -189 -312 216 152 343C616 470 684 875 684 875",
"M-373 -197C-373 -197 -305 208 159 335C623 462 691 867 691 867",
"M-366 -205C-366 -205 -298 200 166 327C630 454 698 859 698 859",
"M-359 -213C-359 -213 -291 192 173 319C637 446 705 851 705 851",
"M-352 -221C-352 -221 -284 184 180 311C644 438 712 843 712 843",
"M-345 -229C-345 -229 -277 176 187 303C651 430 719 835 719 835",
"M-338 -237C-338 -237 -270 168 194 295C658 422 726 827 726 827",
"M-331 -245C-331 -245 -263 160 201 287C665 414 733 819 733 819",
"M-324 -253C-324 -253 -256 152 208 279C672 406 740 811 740 811",
"M-317 -261C-317 -261 -249 144 215 271C679 398 747 803 747 803",
"M-310 -269C-310 -269 -242 136 222 263C686 390 754 795 754 795",
"M-303 -277C-303 -277 -235 128 229 255C693 382 761 787 761 787",
"M-296 -285C-296 -285 -228 120 236 247C700 374 768 779 768 779",
"M-289 -293C-289 -293 -221 112 243 239C707 366 775 771 775 771",
"M-282 -301C-282 -301 -214 104 250 231C714 358 782 763 782 763",
"M-275 -309C-275 -309 -207 96 257 223C721 350 789 755 789 755",
"M-268 -317C-268 -317 -200 88 264 215C728 342 796 747 796 747",
"M-261 -325C-261 -325 -193 80 271 207C735 334 803 739 803 739",
"M-254 -333C-254 -333 -186 72 278 199C742 326 810 731 810 731",
"M-247 -341C-247 -341 -179 64 285 191C749 318 817 723 817 723",
"M-240 -349C-240 -349 -172 56 292 183C756 310 824 715 824 715",
"M-233 -357C-233 -357 -165 48 299 175C763 302 831 707 831 707",
"M-226 -365C-226 -365 -158 40 306 167C770 294 838 699 838 699",
"M-219 -373C-219 -373 -151 32 313 159C777 286 845 691 845 691",
"M-212 -381C-212 -381 -144 24 320 151C784 278 852 683 852 683",
"M-205 -389C-205 -389 -137 16 327 143C791 270 859 675 859 675",
"M-198 -397C-198 -397 -130 8 334 135C798 262 866 667 866 667",
"M-191 -405C-191 -405 -123 0 341 127C805 254 873 659 873 659",
"M-184 -413C-184 -413 -116 -8 348 119C812 246 880 651 880 651",
"M-177 -421C-177 -421 -109 -16 355 111C819 238 887 643 887 643",
"M-170 -429C-170 -429 -102 -24 362 103C826 230 894 635 894 635",
"M-163 -437C-163 -437 -95 -32 369 95C833 222 901 627 901 627",
"M-156 -445C-156 -445 -88 -40 376 87C840 214 908 619 908 619",
"M-149 -453C-149 -453 -81 -48 383 79C847 206 915 611 915 611",
"M-142 -461C-142 -461 -74 -56 390 71C854 198 922 603 922 603",
"M-135 -469C-135 -469 -67 -64 397 63C861 190 929 595 929 595",
"M-128 -477C-128 -477 -60 -72 404 55C868 182 936 587 936 587",
"M-121 -485C-121 -485 -53 -80 411 47C875 174 943 579 943 579",
"M-114 -493C-114 -493 -46 -88 418 39C882 166 950 571 950 571",
"M-107 -501C-107 -501 -39 -96 425 31C889 158 957 563 957 563",
"M-100 -509C-100 -509 -32 -104 432 23C896 150 964 555 964 555",
"M-93 -517C-93 -517 -25 -112 439 15C903 142 971 547 971 547",
"M-86 -525C-86 -525 -18 -120 446 7C910 134 978 539 978 539",
"M-79 -533C-79 -533 -11 -128 453 -1C917 126 985 531 985 531",
"M-72 -541C-72 -541 -4 -136 460 -9C924 118 992 523 992 523",
"M-65 -549C-65 -549 3 -144 467 -17C931 110 999 515 999 515",
"M-58 -557C-58 -557 10 -152 474 -25C938 102 1006 507 1006 507",
"M-51 -565C-51 -565 17 -160 481 -33C945 94 1013 499 1013 499",
"M-44 -573C-44 -573 24 -168 488 -41C952 86 1020 491 1020 491",
"M-37 -581C-37 -581 31 -176 495 -49C959 78 1027 483 1027 483",
];
return (
<div
className={cn(
"absolute h-full w-full inset-0 [mask-size:40px] [mask-repeat:no-repeat] flex items-center justify-center",
className
)}
>
<svg
className=" z-0 h-full w-full pointer-events-none absolute "
width="100%"
height="100%"
viewBox="0 0 696 316"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M-380 -189C-380 -189 -312 216 152 343C616 470 684 875 684 875M-373 -197C-373 -197 -305 208 159 335C623 462 691 867 691 867M-366 -205C-366 -205 -298 200 166 327C630 454 698 859 698 859M-359 -213C-359 -213 -291 192 173 319C637 446 705 851 705 851M-352 -221C-352 -221 -284 184 180 311C644 438 712 843 712 843M-345 -229C-345 -229 -277 176 187 303C651 430 719 835 719 835M-338 -237C-338 -237 -270 168 194 295C658 422 726 827 726 827M-331 -245C-331 -245 -263 160 201 287C665 414 733 819 733 819M-324 -253C-324 -253 -256 152 208 279C672 406 740 811 740 811M-317 -261C-317 -261 -249 144 215 271C679 398 747 803 747 803M-310 -269C-310 -269 -242 136 222 263C686 390 754 795 754 795M-303 -277C-303 -277 -235 128 229 255C693 382 761 787 761 787M-296 -285C-296 -285 -228 120 236 247C700 374 768 779 768 779M-289 -293C-289 -293 -221 112 243 239C707 366 775 771 775 771M-282 -301C-282 -301 -214 104 250 231C714 358 782 763 782 763M-275 -309C-275 -309 -207 96 257 223C721 350 789 755 789 755M-268 -317C-268 -317 -200 88 264 215C728 342 796 747 796 747M-261 -325C-261 -325 -193 80 271 207C735 334 803 739 803 739M-254 -333C-254 -333 -186 72 278 199C742 326 810 731 810 731M-247 -341C-247 -341 -179 64 285 191C749 318 817 723 817 723M-240 -349C-240 -349 -172 56 292 183C756 310 824 715 824 715M-233 -357C-233 -357 -165 48 299 175C763 302 831 707 831 707M-226 -365C-226 -365 -158 40 306 167C770 294 838 699 838 699M-219 -373C-219 -373 -151 32 313 159C777 286 845 691 845 691M-212 -381C-212 -381 -144 24 320 151C784 278 852 683 852 683M-205 -389C-205 -389 -137 16 327 143C791 270 859 675 859 675M-198 -397C-198 -397 -130 8 334 135C798 262 866 667 866 667M-191 -405C-191 -405 -123 0 341 127C805 254 873 659 873 659M-184 -413C-184 -413 -116 -8 348 119C812 246 880 651 880 651M-177 -421C-177 -421 -109 -16 355 111C819 238 887 643 887 643M-170 -429C-170 -429 -102 -24 362 103C826 230 894 635 894 635M-163 -437C-163 -437 -95 -32 369 95C833 222 901 627 901 627M-156 -445C-156 -445 -88 -40 376 87C840 214 908 619 908 619M-149 -453C-149 -453 -81 -48 383 79C847 206 915 611 915 611M-142 -461C-142 -461 -74 -56 390 71C854 198 922 603 922 603M-135 -469C-135 -469 -67 -64 397 63C861 190 929 595 929 595M-128 -477C-128 -477 -60 -72 404 55C868 182 936 587 936 587M-121 -485C-121 -485 -53 -80 411 47C875 174 943 579 943 579M-114 -493C-114 -493 -46 -88 418 39C882 166 950 571 950 571M-107 -501C-107 -501 -39 -96 425 31C889 158 957 563 957 563M-100 -509C-100 -509 -32 -104 432 23C896 150 964 555 964 555M-93 -517C-93 -517 -25 -112 439 15C903 142 971 547 971 547M-86 -525C-86 -525 -18 -120 446 7C910 134 978 539 978 539M-79 -533C-79 -533 -11 -128 453 -1C917 126 985 531 985 531M-72 -541C-72 -541 -4 -136 460 -9C924 118 992 523 992 523M-65 -549C-65 -549 3 -144 467 -17C931 110 999 515 999 515M-58 -557C-58 -557 10 -152 474 -25C938 102 1006 507 1006 507M-51 -565C-51 -565 17 -160 481 -33C945 94 1013 499 1013 499M-44 -573C-44 -573 24 -168 488 -41C952 86 1020 491 1020 491M-37 -581C-37 -581 31 -176 495 -49C959 78 1027 483 1027 483M-30 -589C-30 -589 38 -184 502 -57C966 70 1034 475 1034 475M-23 -597C-23 -597 45 -192 509 -65C973 62 1041 467 1041 467M-16 -605C-16 -605 52 -200 516 -73C980 54 1048 459 1048 459M-9 -613C-9 -613 59 -208 523 -81C987 46 1055 451 1055 451M-2 -621C-2 -621 66 -216 530 -89C994 38 1062 443 1062 443M5 -629C5 -629 73 -224 537 -97C1001 30 1069 435 1069 435M12 -637C12 -637 80 -232 544 -105C1008 22 1076 427 1076 427M19 -645C19 -645 87 -240 551 -113C1015 14 1083 419 1083 419"
stroke="url(#paint0_radial_242_278)"
strokeOpacity="0.05"
strokeWidth="0.5"
></path>
{paths.map((path, index) => (
<motion.path
key={`path-` + index}
d={path}
stroke={`url(#linearGradient-${index})`}
strokeOpacity="0.4"
strokeWidth="0.5"
></motion.path>
))}
<defs>
{paths.map((path, index) => (
<motion.linearGradient
id={`linearGradient-${index}`}
key={`gradient-${index}`}
initial={{
x1: "0%",
x2: "0%",
y1: "0%",
y2: "0%",
}}
animate={{
x1: ["0%", "100%"],
x2: ["0%", "95%"],
y1: ["0%", "100%"],
y2: ["0%", `${93 + Math.random() * 8}%`],
}}
transition={{
duration: Math.random() * 10 + 10,
ease: "easeInOut",
repeat: Infinity,
delay: Math.random() * 10,
}}
>
<stop stopColor="#0EFF00" stopOpacity="0"></stop>
<stop stopColor="#0EFF00"></stop>
<stop offset="32.5%" stopColor="#0EFF00"></stop>
<stop offset="100%" stopColor="#0EFF00" stopOpacity="0"></stop>
</motion.linearGradient>
))}
<radialGradient
id="paint0_radial_242_278"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(352 34) rotate(90) scale(555 1560.62)"
>
<stop offset="0.0666667" stopColor="var(--neutral-300)"></stop>
<stop offset="0.243243" stopColor="var(--neutral-300)"></stop>
<stop offset="0.43594" stopColor="white" stopOpacity="0"></stop>
</radialGradient>
</defs>
</svg>
</div>
);
}
);
BackgroundBeams.displayName = "BackgroundBeams";

View File

@ -0,0 +1,183 @@
import React, {useState, useEffect} from 'react'
import { ArrowRightIcon, ChevronsRight, Github, Rocket } from "lucide-react";
import Prometheus from '@/utils/prometheus';
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
const Rocketdashboard = ({ avgPing, connectablePeers }) => {
return (
<div>
<div className='flex justify-center p-5'>
<div className='p-5 border border-[#0EFF00] bg-[#0EFF00] bg-opacity-5 h-96 w-full flex space-x-20'>
<div className='w-8/12 mt-10'>
<h1 className='text-[#0EFF00] text-xs mb-10'>// Leaderboard</h1>
<div className="flex flex-col gap-7">
<div className="flex items-center gap-2">
<div className="relative w-full h-2 bg-gray-200 rounded-none dark:bg-transparent">
<div className="absolute left-0 top-0 h-full rounded-none w-[80%] flex items-center justify-end pr-2 border-b-2 border-dashed border-opacity-30 border-green-500">
<HoverCard>
<HoverCardTrigger><img className='w-10 h-10 rotate-90' src='rocket.svg' />
</HoverCardTrigger>
<HoverCardContent>
<div className='flex space-x-5 items-center'>
<img className="w-8 h-8" src="https://api.dicebear.com/8.x/identicon/svg?seed=0x..abc" />
<h1>0x...abc</h1>
</div>
</HoverCardContent>
</HoverCard>
</div>
</div>
<span className="text-sm text-[#0EFF00]">1000km</span>
</div>
<div className="flex items-center gap-2">
<div className="relative w-full h-2 bg-gray-200 rounded-none dark:bg-transparent">
<div className="absolute left-0 top-0 h-full rounded-none w-[60%] flex items-center justify-end pr-2 border-b-2 border-dashed border-opacity-30 border-green-500">
<img className='w-10 h-10 rotate-90' src='rocket.svg' />
</div>
</div>
<span className="text-sm text-[#0EFF00]">700km</span>
</div>
<div className="flex items-center gap-2">
<div className="relative w-full h-2 bg-gray-200 rounded-none dark:bg-transparent">
<div className="absolute left-0 top-0 h-full rounded-none w-[30%] flex items-center justify-end pr-2 border-b-2 border-dashed border-opacity-30 border-green-500">
<img className='w-10 h-10 rotate-90' src='rocket.svg' />
</div>
</div>
<span className="text-sm text-[#0EFF00]">400km</span>
</div>
<div className="flex items-center gap-2">
<div className="relative w-full h-2 bg-gray-200 rounded-none dark:bg-transparent">
<div className="absolute left-0 top-0 h-full rounded-none w-[30%] flex items-center justify-end pr-2 border-b-2 border-dashed border-opacity-30 border-green-500">
<img className='w-10 h-10 rotate-90' src='rocket.svg' />
</div>
</div>
<span className="text-sm text-[#0EFF00]">400km</span>
</div>
<div className="flex items-center gap-2">
<div className="relative w-full h-2 bg-gray-200 rounded-none dark:bg-transparent">
<div className="absolute left-0 top-0 h-full rounded-none w-[30%] flex items-center justify-end pr-2 border-b-2 border-dashed border-opacity-30 border-green-500">
<img className='w-10 h-10 rotate-90' src='rocket.svg' />
</div>
</div>
<span className="text-sm text-[#0EFF00]">400km</span>
</div>
</div>
</div>
<div className='flex w-4/12'>
<div className='border border-[#0EFF00] bg-[#0EFF00] bg-opacity-5 h-92 w-full p-5 text-[#0EFF00] '>
<h1 className='text-[#0EFF00] text-xs'>// Process</h1>
<div className='text-[#0EFF00] mt-5 text-sm'>Initializing the node... [Success]</div>
<div className='text-[#0EFF00] mt-2 text-sm'>Discovering and connecting to peers... [Success]</div>
<div className='text-[#0EFF00] mt-2 text-sm'>Initializing encoders and decoders... [Success]</div>
<div className='text-[#0EFF00] mt-2 text-sm'>Setting up Telemetry... [Success]</div>
<div className='border border-[#0EFF00] bg-[#0EFF00] bg-opacity-5 h-32 w-full mt-7 p-5 text-[#0EFF00] '>
<h1 className='text-[#0EFF00] text-xs'>// Your spaceship</h1>
<div className="flex items-center gap-2 mt-7">
<div className="relative w-full h-2 bg-gray-200 rounded-none dark:bg-transparent">
<div className="absolute left-0 top-0 h-full rounded-none w-[10%] flex items-center justify-end pr-2 border-b-2 border-dashed border-opacity-30 border-green-500">
<img className='w-10 h-10 rotate-90' src='rocket.svg' />
</div>
</div>
<span className="text-sm text-[#0EFF00]">400km</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div className='flex justify-center p-5 space-x-10'>
<div className='p-5 border border-[#0EFF00] h-96 w-1/2'>
<h1 className='text-[#0EFF00] text-xs'>// Benchmarks</h1>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 mt-10">
<div className="border-[#0EFF00] border hover:bg-[#0EFF00] hover:bg-opacity-10">
<div className="p-4 space-y-7">
<h3 className="text-xs text-[#0EFF00]">// Number of nodes</h3>
<p className="text-[#0EFF00] text-xl">{connectablePeers}</p>
</div>
</div>
<div className="border-[#0EFF00] border hover:bg-[#0EFF00] hover:bg-opacity-10">
<div className="p-4 space-y-7">
<h3 className="text-xs text-[#0EFF00]">// Latency in messages</h3>
<p className="text-[#0EFF00] text-xl">{avgPing}</p>
</div>
</div>
<div className="border-[#0EFF00] border hover:bg-[#0EFF00] hover:bg-opacity-10">
<div className="p-4 space-y-7">
<h3 className="text-xs text-[#0EFF00]">// Connected peers</h3>
<p className="text-[#0EFF00] text-xl">742</p>
</div>
</div>
<div className="border-[#0EFF00] border hover:bg-[#0EFF00] hover:bg-opacity-10">
<div className="p-4 space-y-7">
<h3 className="text-xs text-[#0EFF00]">// % of succesful delivery</h3>
<p className="text-[#0EFF00] text-xl">742</p>
</div>
</div>
<div className="border-[#0EFF00] border hover:bg-[#0EFF00] hover:bg-opacity-10">
<div className="p-4 space-y-7">
<h3 className="text-xs text-[#0EFF00]">// % of failed delivery</h3>
<p className="text-[#0EFF00] text-xl">742</p>
</div>
</div>
<div className="border-[#0EFF00] border hover:bg-[#0EFF00] hover:bg-opacity-10">
<div className="p-4 space-y-7">
<h3 className="text-xs text-[#0EFF00]">// Sucess : Failure</h3>
<p className="text-[#0EFF00] text-xl">742</p>
</div>
</div>
</div>
</div>
<div className='p-5 border border-[#0EFF00] h-96 w-1/2 space-y-4'>
<h1 className='text-[#0EFF00] text-xs'>// Status</h1>
<div className=' border border-[#0EFF00] flex justify-between'>
<div className='m-5'>
<h1 className='text-[#0EFF00]'>Node status</h1>
</div>
<div className='bg-[#0EFF00] h-full p-5 text-[#032B00] w-40'>Active</div>
</div>
<div className=' border border-[#0EFF00] flex justify-between'>
<div className='m-5'>
<h1 className='text-[#0EFF00]'>Peer discovery</h1>
</div>
<div className='bg-[#0EFF00] h-full p-5 text-[#032B00] w-40'>Completed</div>
</div>
<div className=' border border-[#0EFF00] flex justify-between'>
<div className='m-5'>
<h1 className='text-[#0EFF00]'>Initializing encoders and decoders</h1>
</div>
<div className='bg-[#0EFF00] h-full p-5 text-[#032B00] w-40'>Completed</div>
</div>
<div className=' border border-[#0EFF00] flex justify-between'>
<div className='m-5'>
<h1 className='text-[#0EFF00]'>Telemetry</h1>
</div>
<div className='bg-[#0EFF00] h-full p-5 text-[#032B00] w-40'>Ready</div>
</div>
</div>
</div>
</div>
)
}
export const getServerSideProps = async () => {
const avgPing = await Prometheus.getAvgPing();
const connectablePeers = await Prometheus.getConnectablePeers();
return {
props: {
avgPing,
connectablePeers,
},
};
};
export default Rocketdashboard;

View File

@ -0,0 +1,36 @@
import React from 'react'
export default function Rocketlaunch() {
return (
<div>
<div className="mt-20 flex justify-center">
<img className='w-60 h-60' src='rocket.svg' />
</div>
<div className="mt-10 flex justify-center">
<button className="text-[#032B00] bg-[#0EFF00] p-4">Launch spaceship</button>
</div>
<div className='flex justify-evenly mt-20'>
<div className='border-[#0EFF00] p-4 border text-[#0EFF00] w-1/2'>
<h1 className='arcade mb-4'>How to play?</h1>
<div className='space-y-2'>
<h3>- Press the 'Launch spaceship' button to begin</h3>
<h3>- A Waku light node automatically starts running in your device</h3>
<h3>- For every 10s, your Waku node automatically sends fuel for spaceship to travel 1km</h3>
<h3>- Keep your browser tab open to make the spaceship travel farther</h3>
<h3>- The spaceship traveling to the farthest distance would be on the top of the leaderboard</h3>
</div>
</div>
<div className='border-[#0EFF00] p-4 border text-[#0EFF00] w-1/3'>
<h1 className='arcade mb-4'>But why?</h1>
<div className='space-y-2'>
<h3>This is a dogfooding experiment to aggregate data related to Waku's reliability. Data collected by this experiment would be helpful in analyzing and benchmarking Waku's communicaiton reliability.</h3>
</div>
<h1 className='arcade mb-4 mt-8'>Is there a reward?</h1>
<div className='space-y-2'>
<h3>No, this campaign is voluntary and does not promise any kind of reward</h3>
</div>
</div>
</div>
</div>
)
}

View File

@ -0,0 +1,8 @@
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
export function ThemeProvider({ children, ...props }) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}

47
components/ui/button.jsx Normal file
View File

@ -0,0 +1,47 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva } from "class-variance-authority";
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stone-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 dark:ring-offset-stone-950 dark:focus-visible:ring-stone-300",
{
variants: {
variant: {
default: "bg-stone-900 text-stone-50 hover:bg-stone-900/90 dark:bg-stone-50 dark:text-stone-900 dark:hover:bg-stone-50/90",
destructive:
"bg-red-500 text-stone-50 hover:bg-red-500/90 dark:bg-red-900 dark:text-stone-50 dark:hover:bg-red-900/90",
outline:
"border border-stone-200 bg-white hover:bg-stone-100 hover:text-stone-900 dark:border-stone-800 dark:bg-stone-950 dark:hover:bg-stone-800 dark:hover:text-stone-50",
secondary:
"bg-stone-100 text-stone-900 hover:bg-stone-100/80 dark:bg-stone-800 dark:text-stone-50 dark:hover:bg-stone-800/80",
ghost: "hover:bg-stone-100 hover:text-stone-900 dark:hover:bg-stone-800 dark:hover:text-stone-50",
link: "text-stone-900 underline-offset-4 hover:underline dark:text-stone-50",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 px-3",
lg: "h-11 px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
(<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props} />)
);
})
Button.displayName = "Button"
export { Button, buttonVariants }

View File

@ -0,0 +1,23 @@
import * as React from "react"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
import { cn } from "@/lib/utils"
const HoverCard = HoverCardPrimitive.Root
const HoverCardTrigger = HoverCardPrimitive.Trigger
const HoverCardContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<HoverCardPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-64 border bg-[#032B00] border-[#0EFF00] text-[#0EFF00] p-4 outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props} />
))
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName
export { HoverCard, HoverCardTrigger, HoverCardContent }

7
jsconfig.json Normal file
View File

@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}

6
lib/utils.js Normal file
View File

@ -0,0 +1,6 @@
import { clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs) {
return twMerge(clsx(inputs))
}

6
next.config.mjs Normal file
View File

@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
};
export default nextConfig;

8606
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

34
package.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "spacerace.waku.org",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-slot": "^1.0.2",
"@web3modal/ethers5": "^4.2.3",
"axios": "^1.7.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"ethers": "^5.7.2",
"framer-motion": "^11.2.10",
"lucide-react": "^0.387.0",
"next": "14.2.3",
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"eslint": "^8",
"eslint-config-next": "14.2.3",
"postcss": "^8",
"tailwindcss": "^3.4.1"
}
}

49
pages/_app.js Normal file
View File

@ -0,0 +1,49 @@
import "@/styles/globals.css";
import { createWeb3Modal, defaultConfig } from '@web3modal/ethers5/react'
export default function App({ Component, pageProps }) {
// 1. Get projectId at https://cloud.walletconnect.com
const projectId = "61dbe39faec65ada87d98ccd933ebdaa"
// 2. Set chains
const mainnet = {
chainId: 1,
name: 'Ethereum',
currency: 'ETH',
explorerUrl: 'https://etherscan.io',
rpcUrl: 'https://cloudflare-eth.com'
}
// 3. Create a metadata object
const metadata = {
name: 'SpaceRace',
description: 'Gamified dogfooding for Waku reliability',
url: '', // origin must match your domain & subdomain
icons: ['https://avatars.mywebsite.com/']
}
// 4. Create Ethers config
const ethersConfig = defaultConfig({
/*Required*/
metadata,
/*Optional*/
enableEIP6963: true, // true by default
enableInjected: true, // true by default
enableCoinbase: true, // true by default
rpcUrl: '...', // used for the Coinbase SDK
defaultChainId: 1 // used for the Coinbase SDK
})
// 5. Create a Web3Modal instance
createWeb3Modal({
ethersConfig,
chains: [mainnet],
projectId,
enableAnalytics: false, // Optional - defaults to your Cloud configuration
enableOnramp: false // Optional - false as default
})
return <Component {...pageProps} />;
}

22
pages/_document.js Normal file
View File

@ -0,0 +1,22 @@
import { ThemeProvider } from "@/components/theme-provider";
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<ThemeProvider
attribute="class"
defaultTheme="dark"
enableSystem
disableTransitionOnChange
>
<Main />
<NextScript />
</ThemeProvider>
</body>
</Html>
);
}

5
pages/api/hello.js Normal file
View File

@ -0,0 +1,5 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: "John Doe" });
}

89
pages/index.js Normal file
View File

@ -0,0 +1,89 @@
import Image from "next/image";
import { BackgroundBeams } from "@/components/background-beams";
import { Button } from "@/components/ui/button";
import { ArrowRightIcon, ChevronsRight, Github, Rocket } from "lucide-react";
import { useWeb3Modal, useWeb3ModalAccount } from '@web3modal/ethers5/react'
import Rocketlaunch from "@/components/rocket-launch";
import Rocketdashboard from "@/components/rocket-dashboard";
import {useState} from "react"
import Prometheus from '@/utils/prometheus';
export default function Home({ avgPing, connectablePeers }) {
const { open } = useWeb3Modal()
const { address, chainId, isConnected } = useWeb3ModalAccount()
const [rocket, setRocket] = useState(true)
return (
<main
className="min-h-screen bg-[#032B00] w-full"
>
{
!isConnected ?
<div className="z-30">
<div className="flex justify-between items-center p-5">
<Rocket className="text-[#0EFF00]" />
<button onClick={() => open()} className="border-[#0EFF00] border text-[#0EFF00] p-2">{!isConnected ? "Connect Wallet" : address}</button>
</div>
<div>
<h1 className="arcade text-center text-9xl mt-40 text-[#0EFF00]">SpaceRace</h1>
<h3 className="text-center mt-5 text-xl text-[#0EFF00] space-mono">A gamified dogfooding campaign for improving Waku's reliability</h3>
</div>
<div className="flex justify-center mt-20 space-x-5">
<button onClick={() => open()} className="text-[#032B00] bg-[#0EFF00] p-4">Connect Wallet</button>
<button className="text-[#032B00] bg-[#0EFF00] p-4 flex items-center space-x-3">
<Github />
<h1>Github</h1></button>
</div>
<div className="flex space-x-10 justify-center items-center mt-20">
<div className="border p-3 w-1/5 border-[#0EFF00]">
<h1 className="arcade text-md mb-4 space-mono text-[#0EFF00]">Step 1</h1>
<h3 className="text-xs text-[#0EFF00]">Get started by connecting your ETH Wallet</h3>
</div>
<ChevronsRight className="text-[#0EFF00]" />
<div className="border p-3 w-1/5 border-[#0EFF00]">
<h1 className="arcade text-md mb-4 space-mono text-[#0EFF00]">Step 2</h1>
<h3 className="text-xs text-[#0EFF00]">Press the launch button to discover beyond the sky</h3>
</div>
<ChevronsRight className="text-[#0EFF00]" />
<div className="border p-3 w-1/5 border-[#0EFF00]">
<h1 className="arcade text-md mb-4 space-mono text-[#0EFF00]">Step 3</h1>
<h3 className="text-xs text-[#0EFF00]">Top the leader board and win a surprise reward</h3>
</div>
</div>
</div>
:
<div className="z-30">
<div className="flex justify-between items-center p-5">
<Rocket className="text-[#0EFF00]" />
<button onClick={() => open()} className="border-[#0EFF00] items-center border text-[#0EFF00] p-2 flex space-x-3">{!isConnected ? <h1>Connect wallet</h1> : <h1>0x...{address.slice(-4)}</h1>}
<img className="w-8 h-8" src="https://api.dicebear.com/8.x/identicon/svg?seed=${address}" />
</button>
</div>
{rocket == false ?
<Rocketlaunch /> :
<Rocketdashboard avgPing={avgPing} connectablePeers={connectablePeers} />
}
</div>
}
</main>
);
}
export const getServerSideProps = async () => {
const avgPing = await Prometheus.getAvgPing();
const connectablePeers = await Prometheus.getConnectablePeers();
return {
props: {
avgPing,
connectablePeers,
},
};
};

25
pages/metrics.js Normal file
View File

@ -0,0 +1,25 @@
import React from 'react';
import Prometheus from '@/utils/prometheus';
const MetricsPage = ({ avgPing, connectablePeers }) => {
return (
<div>
<p>Average Ping: {avgPing}</p>
<p>Connectable Peers: {connectablePeers}</p>
</div>
);
};
export const getServerSideProps = async () => {
const avgPing = await Prometheus.getAvgPing();
const connectablePeers = await Prometheus.getConnectablePeers();
return {
props: {
avgPing,
connectablePeers,
},
};
};
export default MetricsPage;

8
postcss.config.mjs Normal file
View File

@ -0,0 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

1
public/next.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

3
public/rocket.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

1
public/vercel.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>

After

Width:  |  Height:  |  Size: 629 B

19
styles/globals.css Normal file
View File

@ -0,0 +1,19 @@
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
.arcade {
font-family: "Press Start 2P", system-ui;
font-weight: 400;
font-style: normal;
}
.space-mono {
font-family: "Space Mono", monospace;
font-weight: 400;
font-style: normal;
}

53
tailwind.config.js Normal file
View File

@ -0,0 +1,53 @@
const colors = require("tailwindcss/colors");
const {
default: flattenColorPalette,
} = require("tailwindcss/lib/util/flattenColorPalette");
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: [
'./pages/**/*.{js,jsx}',
'./components/**/*.{js,jsx}',
'./app/**/*.{js,jsx}',
'./src/**/*.{js,jsx}',
],
prefix: "",
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate"), addVariablesForColors],
}
function addVariablesForColors({ addBase, theme }) {
let allColors = flattenColorPalette(theme("colors"));
let newVars = Object.fromEntries(
Object.entries(allColors).map(([key, val]) => [`--${key}`, val])
);
addBase({
":root": newVars,
});
}

24
utils/prometheus.ts Normal file
View File

@ -0,0 +1,24 @@
import axios from "@/node_modules/axios/index";
const promUrl: string = "https://metrics-proxy.infra.status.im";
export default class Prometheus {
static async getMetric(metric: string) {
const data = (await axios.get('/' + metric, {baseURL: promUrl})).data
if (data.status != "success") return NaN
return data
}
static async getAvgPing(): Promise<number> {
const data = await this.getMetric("avg_ping")
console.log(data)
return data.data.result[0].value[1]
}
static async getConnectablePeers(): Promise<number> {
const data = await this.getMetric("connectable_peers")
console.log(data)
return data.data.result[0].value[1]
}
}