Skip to content

Commit

Permalink
Added Documentation and refactors (#16)
Browse files Browse the repository at this point in the history
* added: inline comments

* updated: used ttf over woff2 fonts
deleted: unused woff2 fonts

* refactor: removed unsued imports
refactor: inline prop types to interface
deleted: unused components

* renamed: useIsMobile to useResponsive

* refactor: removed unused imports

* deleted: unused file

* added: comments
removed: unused css styles

* removed: unused pa
ckage react-icons
                                                  added: package description, repo
                                                  updated: package name
                                                  release: 1.0.0

* added:  env example

* added: docs for OSS

* removed: unused code
updated: todos and error messages
added: comments

* 🚧 Minor Nits;

* 📄 Add License

* 📝 Update readme

---------

Co-authored-by: Preet Parekh <[email protected]>
  • Loading branch information
prathamVaidya and preetjdp authored Jun 5, 2024
1 parent e7f4b1d commit eebd55c
Show file tree
Hide file tree
Showing 28 changed files with 201 additions and 310 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NEYNAR_API_KEY=abcd # get from https://docs.neynar.com/
NEYNAR_SIGNER=abcd # get from https://docs.neynar.com/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Devfolio

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
83 changes: 63 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,79 @@
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).
# Onchain Summer Jesse Campaign

## Getting Started
![Preview GIF](https://letsgetjessebald.com/nft-fc.gif)

First, run the development server:
This repository contains the website and frame for the "Let's get Jesse Bald" campaign by [Devfolio](https://devfolio.co/) for the [Onchain Summer Buildathon](https://onchain-summer.devfolio.co/)

Deployed at https://letsgetjessebald.com/

# Getting Started

### Prerequisites

- Node 18 +
- Yarn

### Environment Variables

- Create .env.local from .env.example
- Get Neynar API Keys from https://docs.neynar.com

### Installation

```bash
npm run dev
# or
# Using yarn (Recommended)
yarn
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
# Tech Stack

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
- NextJS with the App Router - https://nextjs.org/
- Frog.JS for Farcaster Frames - https://frog.fm/
- TailwindCSS - tailwindcss.com/
- Framer Motion - https://framer.com/motion/
- Prettier / ESlint - https://prettier.io/ https://eslint.org/

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
# Project Structure

## Learn More
```bash
├── .next/
├── node_modules/
├── public/
├── src/
│ ├── app/
│ │ ├── api/ # Endpoints for the farcaster frames
│ │ ├── components/ # all resuable small components
│ │ ├── fonts/
│ │ ├── frog/ # contains frog ui for farcaster frames
│ │ ├── hooks/ # common components logic as hooks
│ │ ├── sections/ # Landing page sections
│ │ ├── styles/ # all css
│ │ ├── utils/ # common helper methods
│ │ ├── globals.css
│ │ ├── layout.tsx # html layout
│ │ ├── page.tsx # main page
├── .env.local # local env
├── .eslintrc.json
├── .gitignore
├── .prettierrc.js
├── next-env.d.ts
├── next.config.mjs
├── package.json
├── postcss.config.mjs
├── README.md
├── tailwind.config.ts
├── tsconfig.json
├── yarn.lock

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.
# Contributing

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
Feel free to open [issues](https://github.com/devfolioco/onchain-summer-jesse-campaign/issues/new/choose) and [pull requests](https://github.com/devfolioco/onchain-summer-jesse-campaign/pulls)!

## Deploy on Vercel
## License

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.
[![LICENSE](https://img.shields.io/github/license/devfolioco/onchain-summer-jesse-campaign)](https://github.com/devfolioco/onchain-summer-jesse-campaign/blob/main/LICENSE)

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"name": "jesse-bald-campaign",
"version": "0.1.0",
"name": "onchain-summer-jesse-campaign",
"description": "The website that helps build the next based experience at the Onchain Summer Buildathon and make Jesse go bald",
"repository": "https://github.com/devfolioco/onchain-summer-jesse-campaign",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"frog": "frog dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
Expand All @@ -20,7 +21,6 @@
"next": "14.2.3",
"react": "^18",
"react-dom": "^18",
"react-icons": "^5.2.1",
"react-player": "^2.16.0",
"satori": "^0.10.13",
"uuid": "^9.0.1"
Expand All @@ -38,5 +38,6 @@
"prettier": "^3.2.5",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
},
"packageManager": "[email protected]"
}
73 changes: 12 additions & 61 deletions src/app/api/[[...routes]]/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { handle } from 'frog/next';
import { neynar as neynarMiddleware, NeynarUser as NeynarMiddlewareUser } from 'frog/middlewares';
import { devtools } from 'frog/dev';
import { serveStatic } from 'frog/serve-static';
import { v4 } from "uuid"
import { v4 } from 'uuid';

import { NeynarAPIClient } from '@neynar/nodejs-sdk';
import type { User as NeynarUserV1 } from '@neynar/nodejs-sdk/build/neynar-api/v1';
import type { User as NeynarUserV2 } from '@neynar/nodejs-sdk/build/neynar-api/v2';

import { Box, HStack, Heading, Image, Spacer, Text, VStack, vars } from '../../frog';
import { Box, Heading, Text, VStack, vars } from '../../frog';

import { APP_URL, OPENSEA_COLLECTION, isNumeric } from '../../utils/shared';

Expand All @@ -34,14 +34,13 @@ const app = new Frog<{ State: State }>({
initialState: {},
headers: {
'cache-control': 'max-age=0',
}
})
.use(
neynarMiddleware({
apiKey: NEYNAR_API_KEY,
features: ['interactor'],
})
);
},
}).use(
neynarMiddleware({
apiKey: NEYNAR_API_KEY,
features: ['interactor'],
})
);

// COMPONENTS START

Expand Down Expand Up @@ -72,7 +71,6 @@ const ErrorResponse = (error: string): FrameResponse => {
app.frame('/', c => {
return c.res({
title: 'SupaBald Jesse',
// image: `/nft-fc.gif`,
image: `${APP_URL}/nft-fc.gif`,
intents: [
<Button.Link key={1} href={APP_URL}>
Expand All @@ -94,7 +92,6 @@ app.frame('/nominate/:id', c => {
image: (
<Box grow alignVertical="center" backgroundColor="background" padding="32" position="relative">
<VStack gap="16">
{/* <Heading>🛠️ Cast from {state.confirm?.devfolio.username} on behalf of {state.confirm?.interactor.username} to {state.confirm?.searchUser?.username} 🛠️</Heading> */}
<Heading size={'48'} weight="500" font={'nyght'}>
Nominate a fren
</Heading>
Expand All @@ -118,21 +115,19 @@ app.frame('/nominate/:id', c => {
app.frame('/confirm/:id', async c => {
const interactor = c.var.interactor;
if (!interactor) {
// @todo Update Error Message
return c.res(ErrorResponse('Invalid Interactor'));
return c.res(ErrorResponse('Interactor is not set!'));
}

const devfolioLookupResponse = await neynarClient.lookupUserByUsername('devfolio').catch(() => false);
if (typeof devfolioLookupResponse === 'boolean') {
return c.res(ErrorResponse('Invalid Devfolio'));
return c.res(ErrorResponse('Devfolio profile not found!'));
}
const devfolio = devfolioLookupResponse.result.user;

let searchUser: NeynarUserV2 | undefined;

if (!c.inputText) {
// @todo Update Error Message
return c.res(ErrorResponse('Empty Input'));
return c.res(ErrorResponse('Farcaster username is required!'));
}

const isSearchInputNumber = isNumeric(c.inputText);
Expand Down Expand Up @@ -172,48 +167,12 @@ app.frame('/confirm/:id', async c => {
return c.res(ErrorResponse('Invalid State'));
}

// console.log("TEST TEST TEST", confirmState)

// return c.res({
// title: 'SupaBald Jesse | Preview Cast',
// image: (
// <Box
// grow
// alignVertical="center"
// alignHorizontal="center"
// backgroundColor="background"
// padding="32"
// position="relative"
// >
// <VStack gap="8">
// <Heading size={'32'} weight="500" font={'nyght'}>
// Preview Cast
// </Heading>
// </VStack>
// </Box>
// ),
// intents: [
// <Button key={1} action="/nominate">
// Back
// </Button>,
// <Button key={2} action="/cast">
// Cast!
// </Button>,
// ],
// });

const cast = `🔵 gm @${confirmState.searchUser.username}. @${confirmState.interactor.username} thinks you're a super based builder, and has nominated you for the Onchain Summer Buildathon.
Hop in, mint your SupaBald Jesse NFT, and just build it. LFG
https://letsgetjessebald.com/`;

// const cast = `🔵 gm @${confirmState.searchUser.username}. Someone thinks you're a super based builder, and has nominated you for the Onchain Summer Buildathon.

// Hop in, mint your SupaBald Jesse NFT, and just build it. LFG

// https://letsgetjessebald.com/`;

await neynarClient.publishCast(NEYNAR_SIGNER, cast, {
embeds: [{ url: 'https://letsgetjessebald.com/' }],
});
Expand All @@ -223,7 +182,6 @@ https://letsgetjessebald.com/`;
image: (
<Box grow alignVertical="center" backgroundColor="background" padding="32" position="relative">
<VStack gap="16">
{/* <Heading>🛠️ Cast from {state.confirm?.devfolio.username} on behalf of {state.confirm?.interactor.username} to {state.confirm?.searchUser?.username} 🛠️</Heading> */}
<Heading size={'48'} weight="500" font={'nyght'}>
Cast sent!
</Heading>
Expand Down Expand Up @@ -257,12 +215,6 @@ Hop in, mint your SupaBald Jesse NFT, and just build it. LFG
https://letsgetjessebald.com/`;

// const cast = `🔵 gm @${confirmState.searchUser.username}. Someone thinks you're a super based builder, and has nominated you for the Onchain Summer Buildathon.

// Hop in, mint your SupaBald Jesse NFT, and just build it. LFG

// https://letsgetjessebald.com/`;

neynarClient.publishCast(NEYNAR_SIGNER, cast, {
embeds: [{ url: 'https://letsgetjessebald.com/' }],
});
Expand All @@ -272,7 +224,6 @@ https://letsgetjessebald.com/`;
image: (
<Box grow alignVertical="center" backgroundColor="background" padding="32" position="relative">
<VStack gap="16">
{/* <Heading>🛠️ Cast from {state.confirm?.devfolio.username} on behalf of {state.confirm?.interactor.username} to {state.confirm?.searchUser?.username} 🛠️</Heading> */}
<Heading size={'48'} weight="500" font={'nyght'}>
Cast sent!
</Heading>
Expand Down
7 changes: 5 additions & 2 deletions src/app/components/ApplePeekArea.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// In Apple devices, scroll has elastic effect and you can scroll beneath the end of page. Here you can customize that area
/* In Apple devices, scroll has elastic effect and you can scroll beneath the end of page. Here you can customize that area */

import { inter } from '../fonts/fonts';

const ApplePeekArea = () => {
return <div className="ui-text ios-peek tracking-widest">Never Stop Building</div>;
/* Our little easter egg */
return <div className={`${inter.className} ui-text ios-peek text-sm`}>Never Stop Building</div>;
};

export default ApplePeekArea;
12 changes: 4 additions & 8 deletions src/app/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import Link from 'next/link';
import { nyghtBold } from '../fonts/fonts';

const Button = ({
children,
className,
href = '/',
variant,
sameTab = false,
}: {
interface ButtonProps {
children: React.ReactNode;
className?: string;
href?: string;
variant: 'outlined' | 'primary' | 'secondary';
sameTab?: boolean;
}) => {
}

const Button = ({ children, className, href = '/', variant, sameTab = false }: ButtonProps) => {
return (
<Link
href={href}
Expand Down
9 changes: 7 additions & 2 deletions src/app/components/Heading.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { nyghtMedium, nyghtRegular } from '../fonts/fonts';
import { nyghtMedium } from '../fonts/fonts';

const Heading = ({ children, className }: { children: React.ReactNode; className?: string }) => {
interface HeadingProps {
children: React.ReactNode;
className?: string;
}

const Heading = ({ children, className }: HeadingProps) => {
return (
<h1 className={`text-[56px] md:text-[68px] hero-heading ${nyghtMedium.className} ${className ?? ''}`}>
{children}
Expand Down
5 changes: 4 additions & 1 deletion src/app/components/OnchainTypography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { Variants, motion, useScroll, useTransform } from 'framer-motion';

const OnchainTypography = () => {
const { isMobile, isTablet, isDesktop, is2K } = useResponsive();

/* Typography left and right animation on scroll */
const { scrollYProgress } = useScroll();
const scrollYProgressInverted = useTransform(scrollYProgress, [0, 1], [1, 0]);
const objectPositionMoveLeft = useTransform(scrollYProgress, value => `${-1 * value * 1000}px 100%`);
Expand Down Expand Up @@ -35,7 +37,7 @@ const OnchainTypography = () => {
once: true,
}}
>
{/* Desktop */}
{/* All Desktop Screens */}
{isDesktop && (
<>
{/* Desktop 1080p */}
Expand Down Expand Up @@ -89,6 +91,7 @@ const OnchainTypography = () => {
style={{ width: '100%', height: 'auto' }}
/>
)}

{/* Mobile */}
{isMobile && (
<>
Expand Down
Loading

0 comments on commit eebd55c

Please sign in to comment.