diff --git a/packages/nextjs/app/builders/0x8Bb563DC969cC3b3e7275474c3847b44dBCB9441/page.tsx b/packages/nextjs/app/builders/0x8Bb563DC969cC3b3e7275474c3847b44dBCB9441/page.tsx
index 2bd3ddf..4ea5e0f 100644
--- a/packages/nextjs/app/builders/0x8Bb563DC969cC3b3e7275474c3847b44dBCB9441/page.tsx
+++ b/packages/nextjs/app/builders/0x8Bb563DC969cC3b3e7275474c3847b44dBCB9441/page.tsx
@@ -13,7 +13,7 @@ const MichaelEsenwa: NextPage = () => {
Hi there, I am Kachukwu Michael Esenwa{" "}
+
{children}
);
@@ -39,8 +59,8 @@ const CardHeader = ({ children, className = "" }: Props) => (
{children}
);
-const CardTitle = ({ children }: Props) => (
-
{children}
+const CardTitle = ({ children, className }: Props) => (
+
{children}
);
const CardContent = ({ children, className = "" }: Props) =>
{children}
;
@@ -52,8 +72,8 @@ const StatusSection = ({ connectedAddress, isAllowListed, isCheckedIn, isLoading
-
-
Checking your status...
+
+
Checking your status...
@@ -64,8 +84,10 @@ const StatusSection = ({ connectedAddress, isAllowListed, isCheckedIn, isLoading
if (!connectedAddress) {
return (
- Connect Your Wallet
- Please connect your wallet to view your Batch 10 status
+ Connect Your Wallet
+
+ Please connect your wallet to view your Batch 10 status
+
);
}
@@ -75,12 +97,12 @@ const StatusSection = ({ connectedAddress, isAllowListed, isCheckedIn, isLoading
- Your Status
- Not a Member
+ Your Status
+ Not a Member
- You are not currently a member of Batch 10
+ You are not currently a member of Batch 10
);
@@ -91,29 +113,31 @@ const StatusSection = ({ connectedAddress, isAllowListed, isCheckedIn, isLoading
- Your Status
-
+ Your Status
+
Ready to Check In
- You are a Batch 10 member! Deploy your contract to check in
+
+ You are a Batch 10 member! Deploy your contract to check in
+
);
}
return (
-
+
- Your Status
- Checked In
+ Your Status
+ Checked In
-
+
Active with wallet address:
@@ -158,62 +182,79 @@ const Home: NextPage = () => {
const isCheckedIn = userContractAddress && userContractAddress !== "0x0000000000000000000000000000000000000000";
return (
-
-
-
- Welcome to
- Batch 10
-
-
Get started by taking a look at your batch GitHub repository.
-
- {error ? (
-
-
Error fetching contract data: {error.message}
-
- ) : (
-
-
-
Checked in builders count:
- {counterLoading ? (
-
-
-
- ) : (
-
{checkedInCounter !== undefined ? Number(checkedInCounter) : "0"}
- )}
+
+
+
+
+
+ {images.map((image, index) => (
+
+
-
-
+ ))}
+
+
+
+ BATCH 10
+
+
+
Buidl Guidl
- )}
+
+
+
+
+ {error ? (
+
+
Error fetching contract data: {error.message}
+
+ ) : (
+
+
+
Checked in builders count:
+ {counterLoading ? (
+
+
+
+ ) : (
+
+ {checkedInCounter !== undefined ? Number(checkedInCounter) : "0"}
+
+ )}
+
-
-
-
-
-
- Tinker with your smart contract using the{" "}
-
- Debug Contracts
- {" "}
- tab.
-
-
-
-
-
- Explore your local transactions with the{" "}
-
- Block Explorer
- {" "}
- tab.
-
+
+
+ )}
+
+
+
+
+
+
+ Tinker with your smart contract using the{" "}
+
+ Debug Contracts
+ {" "}
+ tab.
+
+
+
+
+
+ Explore your local transactions with the{" "}
+
+ Block Explorer
+ {" "}
+ tab.
+
+
diff --git a/packages/nextjs/components/StarsBg.tsx b/packages/nextjs/components/StarsBg.tsx
new file mode 100644
index 0000000..f542896
--- /dev/null
+++ b/packages/nextjs/components/StarsBg.tsx
@@ -0,0 +1,113 @@
+"use client";
+
+import React, { RefObject, useCallback, useEffect, useRef, useState } from "react";
+
+interface StarProps {
+ x: number;
+ y: number;
+ radius: number;
+ opacity: number;
+ twinkleSpeed: number | null;
+}
+
+interface StarBackgroundProps {
+ starDensity?: number;
+ allStarsTwinkle?: boolean;
+ twinkleProbability?: number;
+ minTwinkleSpeed?: number;
+ maxTwinkleSpeed?: number;
+ className?: string;
+}
+
+export const StarsBackground: React.FC
= ({
+ starDensity = 0.00015,
+ allStarsTwinkle = true,
+ twinkleProbability = 0.7,
+ minTwinkleSpeed = 0.5,
+ maxTwinkleSpeed = 1,
+ className,
+}) => {
+ const [stars, setStars] = useState([]);
+ const canvasRef: RefObject = useRef(null);
+
+ const generateStars = useCallback(
+ (width: number, height: number): StarProps[] => {
+ const area = width * height;
+ const numStars = Math.floor(area * starDensity);
+ return Array.from({ length: numStars }, () => {
+ const shouldTwinkle = allStarsTwinkle || Math.random() < twinkleProbability;
+ return {
+ x: Math.random() * width,
+ y: Math.random() * height,
+ radius: Math.random() * 0.05 + 0.5,
+ opacity: Math.random() * 0.5 + 0.5,
+ twinkleSpeed: shouldTwinkle ? minTwinkleSpeed + Math.random() * (maxTwinkleSpeed - minTwinkleSpeed) : null,
+ };
+ });
+ },
+ [starDensity, allStarsTwinkle, twinkleProbability, minTwinkleSpeed, maxTwinkleSpeed],
+ );
+
+ useEffect(() => {
+ const updateStars = () => {
+ if (canvasRef.current) {
+ const canvas = canvasRef.current;
+ const ctx = canvas.getContext("2d");
+ if (!ctx) return;
+
+ const { width, height } = canvas.getBoundingClientRect();
+ canvas.width = width;
+ canvas.height = height;
+ setStars(generateStars(width, height));
+ }
+ };
+
+ updateStars();
+
+ const resizeObserver = new ResizeObserver(updateStars);
+ const currentCanvas = canvasRef.current; // Copy the ref value to a variable
+ if (currentCanvas) {
+ resizeObserver.observe(currentCanvas);
+ }
+
+ return () => {
+ if (currentCanvas) {
+ resizeObserver.unobserve(currentCanvas);
+ }
+ };
+ }, [starDensity, allStarsTwinkle, twinkleProbability, minTwinkleSpeed, maxTwinkleSpeed, generateStars]);
+
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+
+ const ctx = canvas.getContext("2d");
+ if (!ctx) return;
+
+ let animationFrameId: number;
+
+ const render = () => {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ stars.forEach(star => {
+ ctx.beginPath();
+ ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2);
+ ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity})`;
+ ctx.fill();
+
+ if (star.twinkleSpeed !== null) {
+ star.opacity = 0.5 + Math.abs(Math.sin((Date.now() * 0.001) / star.twinkleSpeed) * 0.5);
+ }
+ });
+
+ animationFrameId = requestAnimationFrame(render);
+ };
+
+ render();
+
+ return () => {
+ cancelAnimationFrame(animationFrameId);
+ };
+ }, [stars]);
+
+ return ;
+};
diff --git a/packages/nextjs/public/cherry/cherrypfp.png b/packages/nextjs/public/cherry/cherrypfp.png
new file mode 100644
index 0000000..cda0c79
Binary files /dev/null and b/packages/nextjs/public/cherry/cherrypfp.png differ
diff --git a/packages/nextjs/public/guild.png b/packages/nextjs/public/guild.png
new file mode 100755
index 0000000..f0322f9
Binary files /dev/null and b/packages/nextjs/public/guild.png differ
diff --git a/packages/nextjs/styles/LandingPage.css b/packages/nextjs/styles/LandingPage.css
new file mode 100644
index 0000000..47a2086
--- /dev/null
+++ b/packages/nextjs/styles/LandingPage.css
@@ -0,0 +1,133 @@
+@import url("https://fonts.cdnfonts.com/css/ica-rubrik-black");
+@import url("https://fonts.cdnfonts.com/css/poppins");
+
+.banner {
+ width: 100%;
+ height: 100vh;
+ text-align: center;
+ overflow: hidden;
+ position: relative;
+ background: #25283b22;
+}
+.banner .slider {
+ position: absolute;
+ width: 200px;
+ height: 200px;
+ top: 10%;
+ left: calc(50% - 100px);
+ transform-style: preserve-3d;
+ transform: perspective(1000px);
+ animation: autoRun 20s linear infinite;
+ z-index: 2;
+ -webkit-transform: perspective(1000px);
+ -moz-transform: perspective(1000px);
+ -ms-transform: perspective(1000px);
+ -o-transform: perspective(1000px);
+}
+@keyframes autoRun {
+ from {
+ transform: perspective(1000px) rotateX(-16deg) rotateY(0deg);
+ }
+ to {
+ transform: perspective(1000px) rotateX(-16deg) rotateY(360deg);
+ }
+}
+
+.banner .slider .item {
+ position: absolute;
+ inset: 0 0 0 0;
+ transform: rotateY(calc((var(--position) - 1) * (360 / var(--quantity)) * 1deg)) translateZ(550px);
+}
+.banner .slider .item img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+.banner .content {
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: min(1400px, 100vw);
+ height: max-content;
+ padding-bottom: 100px;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ z-index: 1;
+}
+.banner .content h1 {
+ font-family: "ICA Rubrik";
+ font-size: 16em;
+ line-height: 1em;
+ color: #25283b;
+ position: relative;
+}
+.banner .content h1::after {
+ position: absolute;
+ inset: 0 0 0 0;
+ content: attr(data-content);
+ z-index: 2;
+ -webkit-text-stroke: 2px #d2d2d2;
+ color: transparent;
+}
+.banner .content .author {
+ font-family: Poppins;
+ text-align: right;
+ max-width: 200px;
+}
+.banner .content h2 {
+ font-size: 3em;
+}
+.banner .content .model {
+ background-image: url(/guild.png);
+ width: 100%;
+ height: 75vh;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ background-size: auto 100%;
+ background-repeat: no-repeat;
+ background-position: top center;
+ z-index: 1;
+}
+@media screen and (max-width: 1023px) {
+ .banner .slider {
+ width: 160px;
+ height: 200px;
+ left: calc(50% - 80px);
+ }
+ .banner .slider .item {
+ transform: rotateY(calc((var(--position) - 1) * (360 / var(--quantity)) * 1deg)) translateZ(300px);
+ }
+ .banner .content h1 {
+ text-align: center;
+ width: 100%;
+ text-shadow: 0 10px 20px #000;
+ font-size: 7em;
+ }
+ .banner .content .author {
+ color: #fff;
+ padding: 20px;
+ text-shadow: 0 10px 20px #000;
+ z-index: 2;
+ max-width: unset;
+ width: 100%;
+ text-align: center;
+ padding: 0 30px;
+ }
+}
+@media screen and (max-width: 767px) {
+ .banner .slider {
+ width: 100px;
+ height: 150px;
+ left: calc(50% - 50px);
+ }
+ .banner .slider .item {
+ transform: rotateY(calc((var(--position) - 1) * (360 / var(--quantity)) * 1deg)) translateZ(180px);
+ }
+ .banner .content h1 {
+ font-size: 5em;
+ }
+}