# Project export: CodeForge Pages

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2025
- Tagline: Aesthetic React Landing Pages in Minutes – AI, Code Preview / Export, OAuth, Databases
- Devpost: https://devpost.com/software/codeforge-pages
- GitHub: https://github.com/KshitijTeotia06/frontendTreeHacks
- Demo: https://github.com/KshitijTeotia06/backendTreeHacks
- Video: https://www.youtube.com/embed/hpqaYIGAKYQ?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Result: winner (Delve: Most Intuitive UX (AirPods + Delve Founder Numbers + Onsite))
- Team: 1 GitHub contributor(s) — Kshitij Teotia (1 commits)

## Devpost submission (written by the team)

### Inspiration

We love to build, but design is hard. To make something visually appealing, it requires a lot of experimentation and research into what needs to be added. Landing pages are often the first thing a customer sees about a business. We thought current AI tools fall short of our needs. They were either too rigid, didn't integrate well into our workflow of Next.JS, or didn't have enough complexity. So, we thought, why not automate it?

### What it does

CodeForge Pages asks users to enter information about their company along with the name of the company. Based on this information, CodeForge generates a multi–component landing page in React that contains beautiful layout, text, and style. Users can view the rendered code in either the web-view or a simulated mobile view. When pleased with the website, they can export it–which will download a zip of all the react components. All users are also authenticated – meaning when you create a project, we associate it with your profile and it can be accessed at any time through the dashboard.

### How we built it

CodeForge Pages is built in Next.JS. The AI pipeline is quite intricate. We first recorded the data of existing landing pages and then extracted images of every single component of that page (header, hero, feature, etc). Every landing page was then added to an Elasticsearch serverless vector database with a corresponding description generated automatically. Now, when the user prompts the app, it finds the most similar company and generates components through a section-by-section workflow. This backend operation is all coded in Python and utilizes FastAPI. To render the generated component, we use Sandpack from CodeSandbox. In order to authenticate each user, we use Supabase – allowing GitHub, Google, and verified email log-in. To save the data about each project for every user, we use Firebase. Specifically, every component is stored as a String and is rendered every time the user opens the project.

### Challenges we ran into

It was quite difficult to render the generated React components on the screen. At first, we created an implementation using Babel. This nearly took 5 hours and was quite complicated as there were many issues with UI libraries we were using such as Tailwind. Later, we experimented with some other features and asked those at the booths for help. After some more research, we found CodeSandbox. Additionally, the model was glitching – generating white text on white background or dark text on dark backgrounds. To fix this, we utilized Tailwind to ensure the model was accurately placing classes on elements. Additionally, we improved the prompting through iteration.

### Accomplishments we're proud of

The app generates beautiful and aesthetic components as shown in the images. These designs can be implemented at a real business with a great level of acceptance. Additionally, the code also displays code and an accurate preview. Preview at first seemed difficult to generate accurately, but now it is quite accurate and rarely errors.

### What we learned

We gained many insights about UI / UX automation through AI and what it takes to generate such components. Additionally, we learned more about how code rendering really works in React projects. In the future, we should check if there are any libraries to simplify our tasks.

### What's next

We plan to add more features to the app and ship it to the public. Some of the features we plan to add are chat to add features, an interactive no-code editor, on-demand hosting, and image generation / implementation.

## README (from the GitHub repository)

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
```

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

You can start editing the page by modifying `app/page.tsx`. 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.ts`.

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.


## Detected evidence (automated analysis)

Indexed codebase: 42 recognized source files, 189 KB.
- CSS (language) — detected in the code
- Firebase (technology) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- React (technology) — detected in the code
- Supabase (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- FastAPI (technology) — claimed on Devpost, not found in the code
- Python (language) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (46 of 46)

```
.gitignore
.vscode/settings.json
app/(auth)/auth-logo.tsx
app/(auth)/layout.tsx
app/(auth)/new-project/page.tsx
app/(auth)/reset-password/page.tsx
app/(auth)/signin/page.tsx
app/(auth)/signup/page.tsx
app/(auth)/update-password/page.tsx
app/(auth)/verification-pending/page.tsx
app/(default)/layout.tsx
app/(default)/page.tsx
app/api/hello/route.ts
app/css/additional-styles/theme.css
app/css/additional-styles/utility-patterns.css
app/css/style.css
app/dashboard/layout.tsx
app/dashboard/page.tsx
app/layout.tsx
CHANGELOG.md
components/clients.tsx
components/cta.tsx
components/features-02.tsx
components/features-03.tsx
components/features-04.tsx
components/features.tsx
components/hero.tsx
components/highlighter.tsx
components/particles.tsx
components/pricing.tsx
components/ProtectedRoute.tsx
components/testimonials-carousel.tsx
components/testimonials.tsx
components/ui/footer.tsx
components/ui/header.tsx
components/ui/logo.tsx
components/utils/mouse-position.tsx
components/utils/supabase.ts
contexts/AuthContext.tsx
next.config.js
package.json
postcss.config.js
README.md
tailwind.config.js
tsconfig.json
utils/supabase.ts
```

### Dependencies

- package.json: @babel/standalone@^7.26.9, @codesandbox/sandpack-react@^2.20.0, @headlessui/react@^1.7.14, @supabase/auth-helpers-nextjs@^0.10.0, @supabase/supabase-js@^2.48.1, @tailwindcss/forms@^0.5.3, @types/aos@^3.0.4, @types/node@^20.1.0, @types/react@^18.2.5, @types/react-dom@^18.2.4, aos@^3.0.0-beta.6, autoprefixer@^10.4.14, babel@^6.23.0, file-saver@^2.0.5, firebase@^11.3.1, jszip@^3.10.1, next@^13.4.1, postcss@^8.4.23, react@18.2.0, react-dom@18.2.0, swiper@^8.4.7, tailwindcss@^3.3.2, typescript@^5.0.4

### Recent commits (newest first)

- safe

## Key source files (fetched from GitHub, selected and truncated for size)

### CHANGELOG.md

```markdown
# CHANGELOG.md

## [1.0.2] - 2023-05-06

- Dependencies update

## [1.0.1] - 2023-05-06

- Dependencies update

## [1.0.0] - 2023-04-19

First release

```

### package.json

```
{
  "name": "stellar-next",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@babel/standalone": "^7.26.9",
    "@codesandbox/sandpack-react": "^2.20.0",
    "@headlessui/react": "^1.7.14",
    "@supabase/auth-helpers-nextjs": "^0.10.0",
    "@supabase/supabase-js": "^2.48.1",
    "@types/node": "^20.1.0",
    "@types/react": "^18.2.5",
    "@types/react-dom": "^18.2.4",
    "aos": "^3.0.0-beta.6",
    "babel": "^6.23.0",
    "file-saver": "^2.0.5",
    "firebase": "^11.3.1",
    "jszip": "^3.10.1",
    "next": "^13.4.1",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "swiper": "^8.4.7",
    "typescript": "^5.0.4"
  },
  "devDependencies": {
    "@tailwindcss/forms": "^0.5.3",
    "@types/aos": "^3.0.4",
    "autoprefixer": "^10.4.14",
    "postcss": "^8.4.23",
    "tailwindcss": "^3.3.2"
  }
}

```

### app/layout.tsx

```typescript
import './css/style.css'
import { Inter } from 'next/font/google'
import { AuthProvider } from '@/contexts/AuthContext'

const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
  display: 'swap'
})

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={`${inter.variable} font-inter antialiased bg-slate-900 text-slate-100 tracking-tight`}>
        <AuthProvider>
          <div className="flex flex-col min-h-screen overflow-hidden">
            {children}
          </div>
        </AuthProvider>
      </body>
    </html>
  )
}

```

### app/dashboard/layout.tsx

```typescript
import Header from '@/components/ui/header'
import ProtectedRoute from '@/components/ProtectedRoute'

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <ProtectedRoute>
      <Header />
      <main className="grow">
        {children}
      </main>
    </ProtectedRoute>
  )
}
```

### app/(default)/layout.tsx

```typescript
'use client'

import { useEffect } from 'react'

import AOS from 'aos'
import 'aos/dist/aos.css'

import Header from '@/components/ui/header'
import Footer from '@/components/ui/footer'

export default function DefaultLayout({
  children,
}: {
  children: React.ReactNode
}) {  

  useEffect(() => {
    AOS.init({
      once: true,
      disable: 'phone',
      duration: 1000,
      easing: 'ease-out-cubic',
    })
  })

  return (
    <>
      <Header />
      
      <main className="grow">

        {children}

      </main>
    </>
  )
}

```

### app/(default)/page.tsx

```typescript
export const metadata = {
  title: 'Generate Landing Page - Treehacks 2025',
  description: 'Generate a landing page for your business in minutes',
}

import Hero from '@/components/hero'
import Clients from '@/components/clients'
import Features from '@/components/features'
import Features02 from '@/components/features-02'
import Features03 from '@/components/features-03'
import TestimonialsCarousel from '@/components/testimonials-carousel'
import Features04 from '@/components/features-04'
import Pricing from '@/components/pricing'
import Testimonials from '@/components/testimonials'
import Cta from '@/components/cta'

export default function Home() {
  return (
    <>
      <Hero />
    </>
  )
}

```

### app/(auth)/layout.tsx

```typescript
import Image from 'next/image'
import Illustration from '@/public/images/auth-illustration.svg'

export default function AuthLayout({
  children,
}: {
  children: React.ReactNode
}) {  
  return (
    <main className="grow">

      <section className="relative">

        { /* Illustration */}
        <div className="md:block absolute left-1/2 -translate-x-1/2 -mt-36 blur-2xl opacity-70 pointer-events-none -z-10" aria-hidden="true">
          <Image src={Illustration} className="max-w-none" width={1440} height={450} priority alt="Page Illustration" />
        </div>

        <div className="relative max-w-6xl mx-auto px-4 sm:px-6">
          <div className="pt-32 pb-12 md:pt-40 md:pb-20">

            {children}

          </div>
        </div>

      </section>

    </main>
  )
}

```

### app/dashboard/page.tsx

```typescript
'use client'

import { useEffect, useState } from 'react'
import Image from 'next/image'
import Particles from '@/components/particles'
import Highlighter, { HighlighterItem } from '@/components/highlighter'
import Illustration from '@/public/images/glow-bottom.svg'
import Link from 'next/link'
import { initializeApp } from "firebase/app";
import { getFirestore, collection, getDocs } from "firebase/firestore";
import { useAuth } from '@/contexts/AuthContext'
import { useRouter } from 'next/navigation'

const firebaseConfig = {
  apiKey: "AIzaSyDmDQDPdms_JzWAk8YustiubZYQzdxJWqY",
  authDomain: "treehacks-fdceb.firebaseapp.com",
  projectId: "treehacks-fdceb",
  storageBucket: "treehacks-fdceb.firebasestorage.app",
  messagingSenderId: "835479226896",
  appId: "1:835479226896:web:b27a58a9fd5cf05fa69895",
  measurementId: "G-X787L62HGH"
};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

interface Project {
  id: string
  companyName: string
  websiteDescription: string
  createdAt: string
  updatedAt: string
  components?: Record<string, string>
}

export default function Dashboard() {
  const [projects, setProjects] = useState<Project[]>([])
  const [loading, setLoading] = useState(true)
  const { user } = useAuth()
  const router = useRouter()

  useEffect(() => {
    const fetchProjects = async () => {
      if (!user) return

      try {
        const projectsRef = collection(db, `users/${user.id}/projects`)
        const querySnapshot = await getDocs(projectsRef)
        
        const projectsData = querySnapshot.docs.map(doc => ({
          id: doc.id,
          ...doc.data(),
        })) as Project[]

        setProjects(projectsData)
      } catch (error) {
        console.error('Error fetching projects:', error)
      } finally {
        setLoading(false)
      }
    }

    fetchProjects()
  }, [user])

  const handleProjectClick = (project: Project) => {
    localStorage.setItem('editingProject', JSON.stringify(project))
    router.push(`/new-project?edit=${project.id}`)
  }

  if (loading) {
    return <div className="text-center pt-32">Loading...</div>
  }

  return (
    <section className="relative">
      <div className="relative max-w-6xl mx-auto px-4 sm:px-6 rounded-b-2xl">
        {/* Particles animation */}
        <Particles className="absolute inset-0 -z-10" />

        {/* Illustration - Keeping only the bottom glow */}
        <div className="absolute inset-0 -z-10 pointer-events-none overflow-hidden rounded-b-2xl" aria-hidden="true">
          <div className="absolute left-1/2 -translate-x-1/2 bottom-0 -z-10">
            <Image 
              src={Illustration} 
              className="max-w-none opacity-50" 
              width={2146} 
              height={774} 
              priority 
              alt="Hero Illustration" 
            />
          </div>
        </div>

        {/* Dashboard header - No background glow */}
        <div className="pt-32 pb-12 md:pt-40 md:pb-20">
          <div className="max-w-3xl mx-auto text-center">
            <h1 className="h1 bg-clip-text text-transparent bg-gradient-to-r from-slate-200/60 via-slate-200 to-slate-200/60 pb-4" data-aos="fade-down">Your Projects</h1>
            <p className="text-lg text-slate-300 mb-8" data-aos="fade-down" data-aos-delay="200">Manage and monitor all your landing pages in one place.</p>
            <div className="max-w-xs mx-auto sm:max-w-none sm:inline-flex sm:justify-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-down" data-aos-delay="400">
              <div>
                <Link href="/new-project">
                  <button className="btn text-slate-900 bg-gradient-to-r from-white/80 via-white to-white/80 hover:bg-white w-full transition duration-150 ease-in-out group">
                    New Project <span className="tracking-normal text-purple-500 group-hover:translate-x-0.5 transition-transform duration-150 ease-in-out ml-1">-&gt;</span>
                  </button>
                </Link>
              </div>
            </div>
          </div>
        </div>

        <div className="h-px bg-white"></div>

      </div>

      {/* Projects Grid */}
      <div className="max-w-6xl mx-auto px-4 sm:px-6 pt-8">
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
            {projects.map((project) => (
              <HighlighterItem key={project.id} className="h-full group/slide relative">
                <div 
                  className="relative h-full bg-slate-900 rounded-[inherit] z-20 overflow-hidden p-6 cursor-pointer" 
                  onClick={() => handleProjectClick(project)}
                >
                  {/* Particles animation */}
                  <Particles 
                    className="absolute inset-0 -z-10 opacity-0 group-hover/slide:opacity-100 transition-opacity duration-500 ease-in-out" 
                    quantity={3} 
                  /> 
                  
                  {/* Radial gradient - Modified for fade effect */}
                  <div className="absolute inset-0 -z-10" aria-hidden="true">
                    <div className="absolute inset-0 translate-z-0 bg-slate-800 opacity-0 group-hover/slide:opacity-100 group-hover/slide:bg-purple-900/30 transition-all duration-700 ease-out blur-[40px] rounded-[inherit]" />
                  </div>
                  
                  <div className="flex flex-col h-full relative">
                    <div className="grow">
                      <div className="flex items-center justify-between mb-1">
                        <div className="font-bold text-lg text-slate-200">{project.companyName}</div>
                        {/* Active status indicator */}
                        <div className="flex items-center">
                          <div className="h-2.5 w-2.5 rounded-full bg-green-500 mr-2 animate-pulse"></div>
                          <span className="text-sm text-green-500">Active</span>
                        </div>
  
[truncated — 1216 more characters]
```

### app/api/hello/route.ts

```typescript
export async function GET(request: Request) {
  return new Response('Hello, Next.js!')
}

```

### app/(auth)/reset-password/page.tsx

```typescript
'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import AuthLogo from '../auth-logo'
import { supabase } from '@/utils/supabase'

export default function ResetPassword() {
  const router = useRouter()
  const [email, setEmail] = useState('')
  const [error, setError] = useState<string | null>(null)
  const [success, setSuccess] = useState<string | null>(null)
  const [loading, setLoading] = useState(false)

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    try {
      setError(null)
      setSuccess(null)
      setLoading(true)

      const { error } = await supabase.auth.resetPasswordForEmail(email, {
        redirectTo: `${window.location.origin}/update-password`,
      })

      if (error) throw error

      setSuccess('Check your email for the password reset link')
      setEmail('')
    } catch (err) {
      setError('Failed to send reset password email. Please try again.')
      console.error(err)
    } finally {
      setLoading(false)
    }
  }

  return (
    <>
      <div className="max-w-3xl mx-auto text-center pb-12">
        <AuthLogo />
        <h1 className="h2 bg-clip-text text-transparent bg-gradient-to-r from-slate-200/60 via-slate-200 to-slate-200/60">Reset your password</h1>
      </div>

      <div className="max-w-sm mx-auto">
        {error && (
          <div className="text-red-500 text-sm mb-4 text-center">
            {error}
          </div>
        )}
        {success && (
          <div className="text-green-500 text-sm mb-4 text-center">
            {success}
          </div>
        )}

        <form onSubmit={handleSubmit}>
          <div className="space-y-4">
            <div>
              <label className="block text-sm text-slate-300 font-medium mb-1" htmlFor="email">Email</label>
              <input 
                id="email" 
                className="form-input w-full" 
                type="email" 
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                required 
              />
            </div>
          </div>
          <div className="mt-6">
            <button 
              type="submit"
              disabled={loading}
              className="btn text-sm text-white bg-purple-500 hover:bg-purple-600 w-full shadow-sm group disabled:opacity-70"
            >
              {loading ? 'Sending...' : 'Reset Password'} 
              {!loading && <span className="tracking-normal text-purple-300 group-hover:translate-x-0.5 transition-transform duration-150 ease-in-out ml-1">-&gt;</span>}
            </button>
          </div>
        </form>

      </div>
    </>
  )
}

```

[32 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]