# Project export: Study Buddy

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: Cal Hacks 11.0
- Tagline: Study Buddy is your personalized AI companion that transforms learning into a supportive and engaging experience, providing emotional intelligence and real-time feedback using Hume AI
- Devpost: https://devpost.com/software/study-buddy-537fyg
- GitHub: https://github.com/geedbee/calhacks24
- Team: 4 GitHub contributor(s) — dlee6018 (9 commits), goofybugga (6 commits), geedbee (5 commits), H3nky (3 commits)

## Devpost submission (written by the team)

### Inspiration

We wanted to create a study bot that felt less invasive into our studying environments. Do you ever just wish your friend would just sit there and respond occasionally to your monologue? We wanted to create an idea off of that.

### What it does

Using 3 personas that we have built, we can tailor our study environments and vibes to match what we are feeling. Simply just use the voice controls and talk to our Study Buddy AI. It can understand how you feel through your tone and offer feedback specifically to your perceived emotions.

### How we built it

with love. (and hume.ai+gemini+love)

### Challenges we ran into

We had the most trouble with merge conflicts. Some of us occasionally thought about pivoting majors.

### Accomplishments we're proud of

We got one of our buttons to be the most beautiful color.

### What we learned

Perseverance.

### What's next

More tailored study models.

## README (from the GitHub repository)

This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/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 `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## 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/app/building-your-application/deploying) for more details.


## Detected evidence (automated analysis)

Indexed codebase: 44 recognized source files, 48 KB.
- CSS (language) — detected in the code
- Google Gemini (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

## Codebase structure (from repository index)

### Files (52 of 52)

```
.eslintrc.json
.gitignore
.idea/.gitignore
.idea/calhacks24.iml
.idea/inspectionProfiles/Project_Default.xml
.idea/modules.xml
.idea/vcs.xml
app/components/Controls.tsx
app/components/Message.tsx
app/components/Model.tsx
app/components/VoiceComponent.tsx
app/components2/Assistant.tsx
app/components2/ClientComponent.tsx
app/components2/Controls.tsx
app/components2/Messages.tsx
app/components2/Sentiment.tsx
app/components2/startpage.css
app/components2/StartPage.tsx
app/components2/User.tsx
app/ConversationContext.jsx
app/data.js
app/globals.css
app/layout.tsx
app/page.tsx
app/page1/page.tsx
app/page1/VoicePage.tsx
app/page2/components/Hero.jsx
app/page2/components/Learn.jsx
app/page2/components/Navbar.jsx
app/page2/components/Notes.jsx
app/page2/components/Talk.jsx
app/page2/components/Teach.jsx
app/page2/otherPage/page.jsx
app/page2/otherPage/Selection.jsx
app/page2/otherPage/Session.jsx
app/page2/page.jsx
app/page3/page.tsx
app/page3/webscraper.ts
app/page5/components/AvatarPage.jsx
app/page5/components/Chat.jsx
app/page5/page.jsx
app/ui/button.tsx
app/ui/toggle.tsx
next.config.mjs
package.json
postcss.config.mjs
README.md
tailwind.config.ts
tsconfig.json
utils/expressionColors.ts
utils/expressionLabels.ts
utils/supabase.js
```

### Dependencies

- package.json: @emotion/react@^11.13.3, @emotion/styled@^11.13.0, @google/generative-ai@^0.21.0, @humeai/voice-react@^0.1.16, @langchain/google-genai@^0.1.0, @mui/icons-material@^6.1.4, @mui/material@^6.1.4, @supabase/supabase-js@^2.45.6, @types/node@^20, @types/react@^18, @types/react-dom@^18, axios@^1.7.7, cheerio@^1.0.0, eslint@^8, eslint-config-next@14.2.15, hume@^0.9.1, next@14.2.15, postcss@^8, react@^18, react-awesome-reveal@^4.2.14, react-dom@^18, remeda@^2.15.2, tailwindcss@^3.4.14, typescript@^5

### Recent commits (newest first)

- Added css and image elements.
- Now
- colorblindness
- rawwwwwrrrrr
- rawr final
- added styling
- pushingP
- integrate ui with ai
- Merge branch 'main' of https://github.com/geedbee/calhacks24
- finalize model
- mpage
- model prep
- basic oshawott
- 123
- Delete .env
- fix material ui imports
- sexyui
- Updated webscraper.ts
- Added webscraper demo.
- very basic input/output on page 4

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

### package.json

```
{
  "name": "nextjs",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@emotion/react": "^11.13.3",
    "@emotion/styled": "^11.13.0",
    "@google/generative-ai": "^0.21.0",
    "@humeai/voice-react": "^0.1.16",
    "@langchain/google-genai": "^0.1.0",
    "@mui/icons-material": "^6.1.4",
    "@mui/material": "^6.1.4",
    "@supabase/supabase-js": "^2.45.6",
    "axios": "^1.7.7",
    "cheerio": "^1.0.0",
    "hume": "^0.9.1",
    "next": "14.2.15",
    "react": "^18",
    "react-awesome-reveal": "^4.2.14",
    "react-dom": "^18",
    "remeda": "^2.15.2"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "eslint": "^8",
    "eslint-config-next": "14.2.15",
    "postcss": "^8",
    "tailwindcss": "^3.4.14",
    "typescript": "^5"
  }
}

```

### app/page.tsx

```typescript
import Page2 from "./page2/page";

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

```

### app/layout.tsx

```typescript
// app/layout.tsx
import { ConversationProvider } from "./ConversationContext";
import Navbar from "./page2/components/Navbar";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <ConversationProvider>
          <Navbar /> {/* Navbar stays visible on all pages */}
          <main>{children}</main>
        </ConversationProvider>
      </body>
    </html>
  );
}

```

### app/page1/page.tsx

```typescript
// app/page1/page.tsx
import Model from "../components/Model";
import VoicePage from "./VoicePage";
export default function Page1() {
  //<Model />
  return (
    <div style={{ display: "flex", flexDirection: "row", marginTop: "200px", justifyContent:"center"}}>
      <VoicePage />
      <Model />
    </div>
  );
}

```

### app/page2/page.jsx

```javascript
import {
  Fade, Container, Box, Button
} from '@mui/material';
import Hero from './components/Hero'
import Teach from './components/Teach'
import Learn from './components/Learn'
import Talk from './components/Talk'
import Selection from './otherPage/Selection';


function Page2() { 
  const mainContainerStyle = {
    mt: 2,
  }
  return (
    <Box>
    <Container maxWidth="lg" sx={mainContainerStyle}>
      <Fade in timeout={1000}>
        <Hero />
      </Fade>
      <Fade in timeout={1000}>
        <Teach />
      </Fade>
      <Fade in timeout={1000}>
        <Learn />
        </Fade>
        <Fade in timeout={1000}>
        <Talk />
        </Fade>
    </Container>
      <Selection/>
    </Box>
  )
}

export default Page2
```

### app/page3/page.tsx

```typescript
"use client";
import ScraperView from "@/app/page3/webscraper";
import { useEffect, useState } from "react";
export default function Page3() {
  let [scrapedPage, setScrapedPage] = useState("Loading...");
  const [inputValue, setInputValue] = useState("");

  const handleChange = (e) => {
    setInputValue(e.target.value);
  };

  const scrapePage = (input) => {
    input.preventDefault(); // Prevent the default form submission
    alert(inputValue);
    ScraperView(inputValue)
      .then((response) => setScrapedPage(response))
      .catch((error) => setScrapedPage("Failed to load: " + error));
  };

  return (
    <div>
      <form onSubmit={scrapePage}>
        <label>
          Text Input:
          <input type="text" value={inputValue} onChange={handleChange} />
        </label>
        <button type="submit">Submit</button>
      </form>
      {scrapedPage}
    </div>
  );
}

```

### app/page5/page.jsx

```javascript
"use client";
import { Container, Box } from '@mui/material';
import { useState, useCallback, useEffect } from 'react';
import VoicePage from '../page1/VoicePage';
import Model from '../components/Model';

export default function Page5() {
    const [leftWidth, setLeftWidth] = useState(50);
    const [isDragging, setIsDragging] = useState(false);

    const handleMouseDown = useCallback(() => {
        setIsDragging(true);
    }, []);

    const handleMouseUp = useCallback(() => {
        setIsDragging(false);
    }, []);

    const handleMouseMove = useCallback(
        (e) => {
            if (isDragging) {
                const newLeftWidth = (e.clientX / window.innerWidth) * 100;
                setLeftWidth(Math.max(10, Math.min(90, newLeftWidth)));
            }
        },
        [isDragging]
    );

    useEffect(() => {
        document.addEventListener('mousemove', handleMouseMove);
        document.addEventListener('mouseup', handleMouseUp);
        return () => {
            document.removeEventListener('mousemove', handleMouseMove);
            document.removeEventListener('mouseup', handleMouseUp);
        };
    }, [handleMouseMove, handleMouseUp]);

    const marginTopLeft = '30px'
    const marginTopRight = '90px'
    return (
        <Container maxWidth={false} disableGutters sx={{height: '100vh', display: 'flex', overflow: 'hidden' }}>
            <Box sx={{marginTop: {marginTopLeft}, width: `${leftWidth}%`, p: 2, overflow: 'auto', marginTop:"100px" }}>
                <VoicePage/>
                {/* <AvatarPage /> */}
            </Box>
            <Box
                sx={{
                    width: '10px',
                    backgroundColor: 'white',
                    cursor: 'col-resize',
                    boxShadow: '-8px 0px 10px 1px lightgrey',
                    transition: 'border 0.1s',
                    '&:hover': {
                        border: '1px solid lightgrey'
                    },
                }}
                onMouseDown={handleMouseDown}
            />
            <Box sx={{marginTop: marginTopRight, width: `${100 - leftWidth}%`, p: 2, overflow: 'auto' }}>
                <Model/>
            </Box>
        </Container>
    );
}


```

### app/page2/otherPage/page.jsx

```javascript
import React from 'react'
import Session from './Session'

export default function page() {
  return (
    <div>
        <Session />
    </div>
  )
}

```

### tailwind.config.ts

```typescript
import type { Config } from "tailwindcss";

const config: Config = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        background: "var(--background)",
        foreground: "var(--foreground)",
      },
    },
  },
  plugins: [],
};
export default config;

```

### app/globals.css

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

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