Skip to content

Commit

Permalink
feat:add landing page
Browse files Browse the repository at this point in the history
  • Loading branch information
karlavasquez8 committed Apr 10, 2024
1 parent 739ff58 commit 9ee786c
Show file tree
Hide file tree
Showing 24 changed files with 256 additions and 160 deletions.
1 change: 1 addition & 0 deletions packages/nextjs/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ScaffoldStarkAppWithProviders } from "~~/components/ScaffoldStarkAppWit
import "~~/styles/globals.css";
import { ThemeProvider } from "~~/components/ThemeProvider";


export const metadata: Metadata = {
title: "Starknet Speedrun",
description: "Fast track your starknet journey",
Expand Down
139 changes: 65 additions & 74 deletions packages/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,88 +1,79 @@
"use client";

import Link from "next/link";
import type { NextPage } from "next";
import { BugAntIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
// import { Address } from "~~/components/scaffold-eth";
import Image from "next/image";
import StepInstruction from "~~/components/StepInstruction/StepInstruction";
import ChallengeCard from "~~/components/ChallengeCard/ChallengeCard";

const Home: NextPage = () => {
// const { data } = useScaffoldContractRead({
// contractName: "HelloStarknet",
// functionName: "get_balance6",
// });
return (
<div>
<div className="w-full flex items-center justify-center flex-col bg-[#E7F0FE] bg-landing gap-20 ">
<div className="w-full flex flex-col items-center gap-10 ">
<div className="w-full flex items-center justify-center flex-col gap-10">
<Image src={"/Starknet-icon.svg"} alt={"icon starknet"} width={50} height={50}/>
<span>Learn how to build on Starknet; the superpowers and the gotchas.</span>
<h1 className=" text-7xl font-black text-center max-w-[500px]">SPEEDRUN STARKNET</h1>
</div>

// console.log(data);
<div className="flex flex-col gap-5 ">
<StepInstruction number={1} text="Watch this quick video as an Intro to Starknet Development."/>
<StepInstruction number={2}
text="Then use Scaffold-Stark to copy/paste each Cairo concept and tinker: global units, primitives, mappings, structs, modifiers, events, inheritance, sending eth, and payable/fallback functions."/>
<StepInstruction number={3}
text="Watch this getting started playlist to become a power user and eth scripter."/>
<StepInstruction number={4} text="When you are ready to test your knowledge, Speed Run Starknet"/>
</div>
</div>
<div className="footer-header-landing">
</div>
</div>
<div className="w-full flex justify-center text-lg flex-col items-center">

<ChallengeCard challenge="Challenge #0" title="🎟 Simple NFT Example" description="🎫 Create a simple NFT to learn basics of scaffold-Stark. You'll use 👷‍♀️ HardHat to compile and deploy smart contracts.
Then, you'll use a template React app full of important Ethereum components and hooks.
Finally, you'll deploy an NFT to a public network to share with friends! 🚀" imageUrl="/simpleNFT.png" buttonText="QUEST" onButtonClick={()=>{}} end={true}/>
<ChallengeCard challenge="Challenge #1" title="🥩 Decentralized Staking App" description="🦸 A superpower of Ethereum is allowing you, the builder, to create a simple set of rules that an adversarial group of players can use to work together.
In this challenge, you create a decentralized application where users can coordinate a group funding effort. The users only have to trust the code." imageUrl="/stakingToken.png" buttonText="QUEST" onButtonClick={()=>{}}/>
<ChallengeCard challenge="Challenge #2" title="🏵 Token Vendor" description="🤖 Smart contracts are kind of like always on vending machines that anyone can access. Let's make a decentralized, digital currency (an ERC20 token).
Then, let's build an unstoppable vending machine that will buy and sell the currency. We'll learn about the approve pattern for ERC20s and how contract to contract interactions work."
imageUrl="/tokenVendor.png" buttonText="QUEST" onButtonClick={()=>{}} border={false}/>

<div className="bg-[#E7F0FE] bg-ft-join h-[600px] flex justify-center ">
<div className="max-w-[1280px] flex justify-around flex-col w-full border-l-[5px] border-[#191972] ">
<div className="bg-banner-join flex justify-center h-[130px] w-full text-[#0C0C4F] font-black text-6xl ">
<span>JOIN BUILDGUILD</span>
</div>
<div className="flex ">
<div className="max-w-[430px] w-full py-20 pl-20">
<span>The BuidlGuidl is a curated group of Ethereum builders creating products, prototypes, and tutorials to enrich the web3 ecosystem. A place to show off your builds and meet other builders. Start crafting your Web3 portfolio by submitting your DEX, Multisig or SVG NFT build.</span>
</div>
</div>
</div>


</div>
<ChallengeCard challenge="Challenge #3" title="🎲 Dice Game" description="🎰 Randomness is tricky on a public deterministic blockchain. The block hash is the result proof-of-work (for now) and some builders use this as a weak form of randomness.
In this challenge you will take advantage of a Dice Game contract by predicting the randomness in order to only roll winning dice!"
imageUrl="/diceGame.png" buttonText="QUEST" onButtonClick={() => {
}}/>
<ChallengeCard challenge="Challenge #4" title="⚖️ Build a DEX" description="💵 Build an exchange that swaps ETH to tokens and tokens to ETH. 💰 This is possible because the smart contract holds reserves of both assets and has a price function based on the ratio of the reserves. Liquidity providers are issued a token that represents their share of the reserves and fees..."
imageUrl="/dex.png" buttonText="LOCK" onButtonClick={()=>{}}/>
<ChallengeCard challenge="Challenge #5" title="📺 A State Channel Application" description="🛣️ The Ethereum blockchain has great decentralization & security properties but these properties come at a price: transaction throughput is low, and transactions can be expensive.
This makes many traditional web applications infeasible on a blockchain... or does it? State channels look to solve these problems by allowing participants to securely transact off-chain while keeping interaction with Ethereum Mainnet at a minimum." imageUrl="/state.png" buttonText="QUEST" onButtonClick={()=>{}}/>
<ChallengeCard challenge="Challenge #6" title="👛 Multisig Wallet Challenge" description="🛣️ The Ethereum blockchain has great decentralization & security properties but these properties come at a price: transaction throughput is low, and transactions can be expensive. This makes many traditional web applications infeasible on a blockchain... or does it? State channels look to solve these problems by allowing participants to securely transact off-chain while keeping interaction with Ethereum Mainnet at a minimum."
imageUrl="/multiSig.png" buttonText="LOCK" onButtonClick={()=>{}}/>
<ChallengeCard challenge="Challenge #7" title="🎁 SVG NFT 🎫 Building Cohort Challenge" description="🧙 Tinker around with cutting edge smart contracts that render SVGs in Solidity.
🧫 We quickly discovered that the render function needs to be public... 🤔 This allows NFTs that own other NFTs to render their stash.
Just wait until you see an Optimistic Loogie and a Fancy Loogie swimming around in the same Loogie Tank!" imageUrl="/dynamicSvgNFT.png" buttonText="LOCK" onButtonClick={()=>{}} border={false}/>

// const { writeAsync } = useScaffoldContractWrite({
// contractName: "HelloStarknet",
// functionName: "increase_balance",
// args: [1],
// });

// console.log(data, isLoading);
return (
<>
<div className="flex items-center flex-col flex-grow pt-10">
<div className="px-5">
<h1 className="text-center">
<span className="block text-2xl mb-2">Welcome to</span>
<span className="block text-4xl font-bold">Scaffold-Stark 2</span>
</h1>
<div className="flex justify-center items-center space-x-2">
<p className="my-2 font-medium">Connected Address:</p>
{/* <Address address={connectedAddress} /> */}
</div>
<p className="text-center text-lg">
Get started by editing{" "}
<code className="italic bg-base-300 text-base font-bold max-w-full break-words break-all inline-block">
packages/nextjs/app/page.tsx
</code>
</p>
<p className="text-center text-lg">
Edit your smart contract{" "}
<code className="italic bg-base-300 text-base font-bold max-w-full break-words break-all inline-block">
YourContract.sol
</code>{" "}
in{" "}
<code className="italic bg-base-300 text-base font-bold max-w-full break-words break-all inline-block">
packages/hardhat/contracts
</code>
</p>
</div>

<div className="flex-grow bg-base-300 w-full mt-16 px-8 py-12">
<div className="flex justify-center items-center gap-12 flex-col sm:flex-row">
<div className="flex flex-col bg-base-100 px-10 py-10 text-center items-center max-w-xs rounded-3xl">
<BugAntIcon className="h-8 w-8 fill-secondary" />
<p>
Tinker with your smart contract using the{" "}
<Link href="/debug" passHref className="link">
Debug Contracts
</Link>{" "}
tab.
</p>
</div>
<div className="flex flex-col bg-base-100 px-10 py-10 text-center items-center max-w-xs rounded-3xl">
<MagnifyingGlassIcon className="h-8 w-8 fill-secondary" />
<p>
Explore your local transactions with the{" "}
<Link href="/blockexplorer" passHref className="link">
Block Explorer
</Link>{" "}
tab.
</p>
</div>
</div>
</div>
{/* <div
onClick={() => {
writeAsync();
}}
>
TEST TX
</div> */}

</div>
</>


);
};

Expand Down
16 changes: 16 additions & 0 deletions packages/nextjs/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, { ReactNode } from 'react';

interface ButtonProps {
onClick: () => void;
children: ReactNode;
}

const Button: React.FC<ButtonProps> = ({ onClick, children }) => {
return (
<button className="py-[10px] px-[20px] bg-[#0C0C4F] text-white rounded-[8px]" onClick={onClick} type="button">
{children}
</button>
);
};

export default Button;
44 changes: 44 additions & 0 deletions packages/nextjs/components/ChallengeCard/ChallengeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import Image from 'next/image';
import Button from "~~/components/Button/Button";

interface ChallengeCardProps {
challenge: string;
title: string;
description:string;
imageUrl: string;
buttonText: string;
onButtonClick: () => void;
border?:boolean;
end?:boolean

}

const ChallengeCard: React.FC<ChallengeCardProps> = ({ challenge, title, imageUrl, buttonText, onButtonClick,description,border=true, end=false }) => {
return (
<div className={`flex max-w-[1280px] w-full ${border ? 'border-b border-[#191972]' : ''}`}>
<div className="flex">
<div className={`w-[34px] ${end? "h-[50%] self-end":"flex"} border-l-[5px] border-[#191972]`}>
<div
className="w-[30px] h-[30px] rounded-full border-[#191972] border-[5px] self-center traslate-circule bg-white"></div>
</div>
</div>
<div className=" flex flex-1 justify-between py-10 px-10 ">
<div className="max-w-[500px] flex flex-col gap-4">
<span>{challenge}</span>
<h2 className="text-2xl">{title}</h2>
<p>{description}</p>
<div>
<Button onClick={onButtonClick}>{buttonText}</Button>
</div>
</div>
<div>
<Image src={imageUrl} alt="image challenge" width={500} height={340}/>
</div>
</div>

</div>
);
};

export default ChallengeCard;
2 changes: 1 addition & 1 deletion packages/nextjs/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const Footer = () => {
const isLocalNetwork = false;

return (
<div className="min-h-0 py-5 px-1 mb-11 lg:mb-0">
<div className="min-h-0 py-5 px-1 mb-11 lg:mb-0 bg-[#E7F0FE]">
<div>
<div className="fixed flex justify-between items-center w-full z-10 p-4 bottom-0 left-0 pointer-events-none">
<div className="flex flex-col md:flex-row gap-2 pointer-events-auto">
Expand Down
106 changes: 27 additions & 79 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
"use client";

import React, { useCallback, useRef, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {Bars3Icon, BugAntIcon} from "@heroicons/react/24/outline";
// import {
// FaucetButton,
// RainbowKitCustomConnectButton,
// } from "~~/components/scaffold-eth";
import { BugAntIcon} from "@heroicons/react/24/outline";
import { useOutsideClick } from "~~/hooks/scaffold-stark";
import {CustomConnectButton} from "~~/components/scaffold-stark/CustomConnectButton";

Expand All @@ -30,31 +25,31 @@ export const menuLinks: HeaderMenuLink[] = [
},
];

export const HeaderMenuLinks = () => {
const pathname = usePathname();

return (
<>
{menuLinks.map(({ label, href, icon }) => {
const isActive = pathname === href;
return (
<li key={href}>
<Link
href={href}
passHref
className={`${
isActive ? "bg-secondary shadow-md" : ""
} hover:bg-secondary hover:shadow-md focus:!bg-secondary active:!text-neutral py-1.5 px-3 text-sm rounded-full gap-2 grid grid-flow-col`}
>
{icon}
<span>{label}</span>
</Link>
</li>
);
})}
</>
);
};
// export const HeaderMenuLinks = () => {
// const pathname = usePathname();
//
// return (
// <>
// {menuLinks.map(({ label, href, icon }) => {
// const isActive = pathname === href;
// return (
// <li key={href}>
// <Link
// href={href}
// passHref
// className={`${
// isActive ? "bg-secondary shadow-md" : ""
// } hover:bg-secondary hover:shadow-md focus:!bg-secondary active:!text-neutral py-1.5 px-3 text-sm rounded-full gap-2 grid grid-flow-col`}
// >
// {icon}
// <span>{label}</span>
// </Link>
// </li>
// );
// })}
// </>
// );
// };

/**
* Site header
Expand All @@ -68,54 +63,7 @@ export const Header = () => {
);

return (
<div className="sticky lg:static top-0 navbar bg-base-100 min-h-0 flex-shrink-0 justify-between z-20 shadow-md shadow-secondary px-0 sm:px-2">
<div className="navbar-start w-auto lg:w-1/2">
<div className="lg:hidden dropdown" ref={burgerMenuRef}>
<label
tabIndex={0}
className={`ml-1 btn btn-ghost ${
isDrawerOpen ? "hover:bg-secondary" : "hover:bg-transparent"
}`}
onClick={() => {
setIsDrawerOpen((prevIsOpenState) => !prevIsOpenState);
}}
>
<Bars3Icon className="h-1/2" />
</label>
{isDrawerOpen && (
<ul
tabIndex={0}
className="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52"
onClick={() => {
setIsDrawerOpen(false);
}}
>
<HeaderMenuLinks />
</ul>
)}
</div>
<Link
href="/"
passHref
className="hidden lg:flex items-center gap-2 ml-4 mr-6 shrink-0"
>
<div className="flex relative w-10 h-10">
<Image
alt="SE2 logo"
className="cursor-pointer"
fill
src="/logo.svg"
/>
</div>
<div className="flex flex-col">
<span className="font-bold leading-tight">Scaffold-Stark</span>
<span className="text-xs">Starknet dev stack</span>
</div>
</Link>
<ul className="hidden lg:flex lg:flex-nowrap menu menu-horizontal px-1 gap-2">
<HeaderMenuLinks />
</ul>
</div>
<div className="sticky lg:static top-0 navbar min-h-0 flex-shrink-0 justify-between z-20 px-0 sm:px-2 bg-[#E7F0FE]">
<div className="navbar-end flex-grow mr-4">
<CustomConnectButton/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {ProgressBar} from "~~/components/scaffold-stark/ProgressBar";
import {appChains} from "~~/services/web3/connectors";
import {BurnerConnector} from "~~/services/web3/stark-burner/BurnerConnector";


const ScaffoldStarkApp = ({children}: { children: React.ReactNode }) => {
return (
<>
Expand Down
19 changes: 19 additions & 0 deletions packages/nextjs/components/StepInstruction/StepInstruction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

interface StepInstructionProps {
number: number;
text: string;
}

const StepInstruction: React.FC<StepInstructionProps> = ({ number, text }) => {
return (
<div className=" flex flex-col items-center gap-3 max-w-[500px] justify-center ">
<div className="w-6 h-6 rounded-full bg-gradient-linear text-white text-center">
{number}
</div>
<span className="text-center text-[16px]">{text}</span>
</div>
);
};

export default StepInstruction;
Loading

0 comments on commit 9ee786c

Please sign in to comment.