# Project export: BrainHive

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: a more personalized touch to your notes.
- Devpost: https://devpost.com/software/brainhive
- GitHub: https://github.com/Nikko-Adrian-Pacleb/CalHacks11v1
- Demo: https://cal-hacks11v1.vercel.app/
- Team: 3 GitHub contributor(s) — Nikko Adrian Pacleb (30 commits), yxngles13 (11 commits), Julyd03 (5 commits)

## Devpost submission (written by the team)

### Inspiration

As a student, note-taking is an integral part of our lives. Due to different teaching styles, we often encounter a cluttered organization when it comes to notes. This makes it extremely hard for us to retrieve existing information, find additional resources, and accelerate our learning process. We aim to tackle the tedious process of note-taking with a fast-action note-taking application that assists your every word.

### What it does

This note-taking application generates a "map" graph for your notes to build connections between contents throughout the notes. You will be able to walk through every single detail that you make in this app. Also, it can make a summarization of your note content, which can help you keep checking what you have taken in notes, and help you preview your notes when you are trying to find some content. Other than that, it can offer users expanded note-related information, and check if there are any mistakes in the note.

### How we built it

-For the development of the website, we used nextJS and tailwindCSS. -For all the AI Implementation we used Gemini 1.5 and implemented it using the Google library. -For the graph, we used d3 and Gemini response for the connection data. -For the web design, we used Figma.

### Challenges we ran into

We had a hard time making a dynamic connection node but we were able to solve it through d3 network graphs Generating consistent output that follows a certain format was also difficult. Gemini helped a lot as it provides very accurate and consistent results with engineered prompts

### Accomplishments we're proud of

We are proud to be able to utilize AI to create a personalized note-taking app that assists academia. We were able to create a visualization that allows users to reference all the notes that are related to the current topic in real time.

### What we learned

We learned D3.js library: and how to effectively utilize the the library to create dynamic, interactive visualizations that enhance the organization of notes. Communication is the absolute key to a successful team. We learned to work with each other, especially on the division of tasks. Design has been one of the challenging parts but the most rewarding. We were able to learn more about UX/UI designs and try to elevate user experience.

### What's next

Add a button for live audio recording/converting to text, along with a button where we can click for a mark/highlight that we are confused about during the lecture/have questions to ask later. Refer more useful page for the note from Google (outside of the note) Improve based on user-friendliness

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 14 recognized source files, 56 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
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (22 of 22)

```
.DS_Store
.gitignore
frontend/.gitignore
frontend/app/api/getMistakes/route.js
frontend/app/api/getMore/route.js
frontend/app/api/getNotesConnections/route.js
frontend/app/api/getSummary/route.js
frontend/app/api/test/route.js
frontend/app/components/NetworkDiagram.tsx
frontend/app/components/Tiptap.jsx
frontend/app/components/Toolbar.jsx
frontend/app/globals.css
frontend/app/layout.tsx
frontend/app/page.tsx
frontend/app/productPage/page.jsx
frontend/next.config.mjs
frontend/package.json
frontend/postcss.config.mjs
frontend/README.md
frontend/tailwind.config.ts
frontend/tsconfig.json
LICENSE
```

### Dependencies

- frontend/package.json: @fortawesome/free-solid-svg-icons@^6.6.0, @fortawesome/react-fontawesome@^0.2.2, @google/generative-ai@^0.21.0, @tiptap/react@^2.8.0, @tiptap/starter-kit@^2.8.0, @types/d3@^7.4.3, @types/node@^20, @types/react@^18, @types/react-dom@^18, d3@^7.9.0, marked@^14.1.3, next@14.2.15, postcss@^8, react@^18, react-dom@^18, tailwindcss@^3.4.1, typescript@^5

### Recent commits (newest first)

- Changed website name
- on node click generate ai
- force added
- Button Changed
- Merge branch 'main' of https://github.com/Nikko-Adrian-Pacleb/CalHacks11v1
- added data
- Merge branch 'main' of https://github.com/Nikko-Adrian-Pacleb/CalHacks11v1
- changetitle
- hope it works
- Merge pull request #8 from Nikko-Adrian-Pacleb/julyfrontend
- Merge branch 'main' into julyfrontend
- july's style edit: landing page bg full,
- h3 linking
- Style
- onclick change on nodes added
- Diff Color on active note in graph
- Merge pull request #7 from Nikko-Adrian-Pacleb/AddD3
- Merge branch 'main' into AddD3
- graph somehow worked
- Merge branch 'main' of https://github.com/Nikko-Adrian-Pacleb/CalHacks11v1

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

### frontend/package.json

```
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@fortawesome/free-solid-svg-icons": "^6.6.0",
    "@fortawesome/react-fontawesome": "^0.2.2",
    "@google/generative-ai": "^0.21.0",
    "@tiptap/react": "^2.8.0",
    "@tiptap/starter-kit": "^2.8.0",
    "@types/d3": "^7.4.3",
    "d3": "^7.9.0",
    "marked": "^14.1.3",
    "next": "14.2.15",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "postcss": "^8",
    "tailwindcss": "^3.4.1",
    "typescript": "^5"
  }
}

```

### frontend/app/layout.tsx

```typescript
import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";

const geistSans = localFont({
  src: "./fonts/GeistVF.woff",
  variable: "--font-geist-sans",
  weight: "100 900",
});
const geistMono = localFont({
  src: "./fonts/GeistMonoVF.woff",
  variable: "--font-geist-mono",
  weight: "100 900",
});

export const metadata: Metadata = {
  title: "Brain Hive",
  description: "CalHacks11.0 Project",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        {children}
      </body>
    </html>
  );
}

```

### frontend/app/page.tsx

```typescript
"use client";
import Link from "next/link";
export default function Home() {
  return (
    <main
      className="w-full mx-auto min-h-screen flex flex-col items-center justify-center text-center"
      style={{
        backgroundImage: "url('/images/bg.jpeg')", // Correctly referencing the image
        backgroundSize: "cover", // Ensure the image covers the entire area
        backgroundPosition: "center", // Center the image
        backgroundRepeat: "no-repeat",
      }}
    >
      <div>
        <h1 className="font-bold font-title  text-9xl text-cDarkBlue ">BrainHive</h1>
        <p className="font-para text-cDarkBlue">A more personalized touch to your notes</p>
      </div>
      <Link href="./productPage">
        <button className="mt-8 bg-mbWhite hover:bg-nWhite text-black font-bold py-2 px-4 rounded">
          Try now
        </button>
      </Link>
    </main>
  );
}

```

### frontend/app/api/test/route.js

```javascript
import { GoogleGenerativeAI } from "@google/generative-ai";
import { NextResponse } from "next/server";

export async function POST(req, res) {
  try {
    const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
    const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
    const data = await req.json();
    const prompt = data.htmlContent;
    console.log(["start the sentence with Hello", prompt]);
    const result = await model.generateContent([
      "You are a AI in a note taking app.",
      "Your job is to give a short summary about the topic the user is typing.",
      "User Input: ",
      prompt,
    ]);

    const response = await result.response;
    const output = await response.text();
    return NextResponse.json({ output: output });
  } catch (error) {
    console.error("Error generating content: ", error);
    return NextResponse.json(
      { error: "Failed to generate content" },
      { status: 500 }
    );
  }
}

```

### frontend/app/api/getSummary/route.js

```javascript
import { GoogleGenerativeAI } from "@google/generative-ai";
import { NextResponse } from "next/server";

export async function POST(req, res) {
  try {
    const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
    const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
    const data = await req.json();
    const prompt = data.htmlContent;
    const result = await model.generateContent([
      "You are an AI assistant in a note-taking app.",
      "Your role is to provide a brief and accurate summary of the user's notes in strict Markdown format.",
      "Do not add any new information or provide external context.",
      "Focus only on the key points and main ideas from the user's input.",
      "Ensure the summary is clear and concise, using proper Markdown elements (e.g., headers, lists, bold, italic) where appropriate.",
      "Keep the tone neutral and informative.",
      "Ensure all output adheres to Markdown formatting rules strictly.",
      "User Input: ",
      prompt,
    ]);

    const response = await result.response;
    const output = await response.text();
    return NextResponse.json({ output: output });
  } catch (error) {
    console.error("Error generating content: ", error);
    return NextResponse.json(
      { error: "Failed to generate content" },
      { status: 500 }
    );
  }
}

```

### frontend/app/api/getMore/route.js

```javascript
import { GoogleGenerativeAI } from "@google/generative-ai";
import { NextResponse } from "next/server";

export async function POST(req, res) {
  try {
    const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
    const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
    const data = await req.json();
    const prompt = data.htmlContent;
    const result = await model.generateContent([
      "You are an AI assistant in a note-taking app.",
      "Your role is to provide additional relevant information, context, or background to supplement the user's notes, adhering strictly to Markdown formatting.",
      "Utilize general knowledge to fill in missing details or add important information that enhances clarity or completeness.",
      "Avoid summarizing the user's input; instead, enrich the content with pertinent insights.",
      "If no relevant information can be added, respond with 'Nothing relevant to add.'",
      "Ensure all content is accurate, well-structured, and complies with Markdown syntax.",
      "Maintain a neutral and informative tone throughout.",
      "Use at least 2-3 reliable sources to support your content.",
      "Format the sources as a bulleted list at the end of the response in the following format: [Source Title](URL).",
      "User Input: ",
      prompt,
    ]);

    const response = await result.response;
    const citation = await response.candidates[0].citationMetadata;
    await console.log(citation);
    const output = await response.text();
    return NextResponse.json({ output: output });
  } catch (error) {
    console.error("Error generating content: ", error);
    return NextResponse.json(
      { error: "Failed to generate content" },
      { status: 500 }
    );
  }
}

```

### frontend/app/api/getMistakes/route.js

```javascript
import { GoogleGenerativeAI } from "@google/generative-ai";
import { NextResponse } from "next/server";

export async function POST(req, res) {
  try {
    const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
    const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
    const data = await req.json();
    const prompt = data.htmlContent;
    const result = await model.generateContent([
      "You are an AI assistant in a note-taking app.",
      "Your role is to find mistakes in the user's notes and correct them.",
      "For each mistake, quote the incorrect part of the text in **bold** and provide the correction on the next line.",
      "Keep both the mistake and correction very short and concise.",
      "If any important context, background information, or details are missing, supplement them to provide a complete understanding.",
      "You can reference external information or general knowledge if needed to enhance the correction.",
      "If you are correcting grammar mistakes, make sure to mention it.",
      "If you are trying to correct a set of code, make sure to mention that as well.",
      "Try to group and categorize mistakes and output them in an organized manner.",
      "If there is no mistake, do not output anything.",
      "Ensure the correction is clear, informative, and focused only on the key points.",
      "Keep the tone neutral and concise.",
      "User Input: ",
      prompt,
    ]);

    const response = await result.response;
    const output = await response.text();
    return NextResponse.json({ output: output });
  } catch (error) {
    console.error("Error generating content: ", error);
    return NextResponse.json(
      { error: "Failed to generate content" },
      { status: 500 }
    );
  }
}

```

### frontend/app/api/getNotesConnections/route.js

```javascript
import { GoogleGenerativeAI } from "@google/generative-ai";
import { NextResponse } from "next/server";

function cleanAndConvertToJson(inputString) {
  // Remove the triple backticks and the '```json' tags
  let cleanedString = inputString.replace(/```json|```/g, "");

  // Remove the escape characters and extra spaces or line breaks
  cleanedString = cleanedString.replace(/\\n/g, "").replace(/\\t/g, "").trim();

  // Convert the cleaned string to a valid JSON object
  try {
    const jsonObject = JSON.parse(cleanedString);
    console.log("Valid JSON Object:", jsonObject);
    return jsonObject;
  } catch (error) {
    console.error("Error parsing JSON:", error);
  }
}

// POST request handler to generate note connections using Gemini AI
export async function POST(req, res) {
  try {
    const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); // Initialize the AI client
    const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); // Load the Gemini model
    const notes = await req.json(); // Parse incoming request JSON
    // console.log(await data);
    // const notes = data.notes; // Assume the notes are passed in the request body

    // Prepare a structured prompt for generating connections between the notes
    const prompt = [
      "You are an AI assistant in a note-taking app.",
      "Your task is to analyze a list of notes and generate connections between the notes.",
      "Strictly follow the format below when creating the output.",
      "Ensure that each note is represented as a node in the 'nodes' array and that the conceptual connections between the notes are represented as links in the 'links' array.",
      "Each connection in the 'links' array must have a source note, a target note, and a value representing the strength of the connection (1 for weak, 2 for moderate, and 3 for strong).",

      "Do not add any additional formatting like backticks or code blocks. Output the JSON object directly.",

      "Output Format:",
      "{",
      '"nodes": [',
      '{ "id": "Note Title 1", "group": "category" },',
      '{ "id": "Note Title 2", "group": "category" },',
      '{ "id": "Note Title 3", "group": "category" },',
      "...",
      "],",
      '"links": [',
      '{ "source": "Note Title 1", "target": "Note Title 2", "value": 1 },',
      '{ "source": "Note Title 1", "target": "Note Title 3", "value": 2 },',
      '{ "source": "Note Title 2", "target": "Note Title 3", "value": 1 },',
      "...",
      "]",
      "}",

      "Make sure the 'id' in the nodes corresponds to the titles of the notes provided.",
      "The 'group' should be based on the conceptual category of the note, such as 'concepts', 'benefits', or 'skills'.",
      "The 'links' array should show how the notes are conceptually connected, with the 'value' field representing the strength of the connection.",
      "Here is the list of notes:",

      ...notes.map((note) => `- ${note.title}: ${note.content}`),
    ];
    // console.log(prompt);
    // Generate content using Gemini
    const result = await model.generateContent(prompt);
    const response = await result.response;
    const output = await response.text();
    console.log(await response.text());
    // Assuming Gemini's response will be a JSON array of connections
    return NextResponse.json({ connections: JSON.parse(output) });
  } catch (error) {
    console.error("Error generating connections: ", error);
    return NextResponse.json(
      { error: "Failed to generate connections" },
      { status: 500 }
    );
  }
}

```

### frontend/app/productPage/page.jsx

```javascript
"use client";
import { useState, useCallback, act } from "react";
import { useEffect } from "react";
import Tiptap from "../components/Tiptap";
import { marked } from "marked";
import { NetworkDiagram } from "../components/NetworkDiagram";
export default function Home() {
  const [notes, setNotes] = useState([
    {
      noteId: 0,
      title: "The Importance of Mind Mapping",
      content: `
        Mind mapping is a powerful note-taking technique that involves creating a visual representation of information, usually in the form of a diagram. 
        It's essential for capturing ideas, organizing them logically, and visually representing the relationships between concepts. 
        This method helps in structuring thoughts and allows for a more holistic understanding of a topic.
      `,
      htmlContent: marked(`
        # The Importance of Mind Mapping
        Mind mapping is a powerful note-taking technique that involves creating a visual representation of information, usually in the form of a diagram.
        It's essential for capturing ideas, organizing them logically, and visually representing the relationships between concepts. 
        This method helps in structuring thoughts and allows for a more holistic understanding of a topic.
      `),
    },
    {
      noteId: 1,
      title: "Why Connecting Ideas is Important",
      content: `
        Connecting ideas when taking notes is crucial because it helps to reveal the underlying patterns and relationships between topics. 
        This not only aids in memory retention but also fosters a deeper understanding of the subject matter. 
        When ideas are connected, it becomes easier to build on existing knowledge, make connections to real-world scenarios, and solve problems more effectively.
      `,
      htmlContent: marked(`
        # Why Connecting Ideas is Important
        Connecting ideas when taking notes is crucial because it helps to reveal the underlying patterns and relationships between topics.
        This not only aids in memory retention but also fosters a deeper understanding of the subject matter. 
        When ideas are connected, it becomes easier to build on existing knowledge, make connections to real-world scenarios, and solve problems more effectively.
      `),
    },
    {
      noteId: 2,
      title: "Mind Mapping and Active Learning",
      content: `
        Mind mapping encourages active learning by forcing you to process and reorganize information as you take notes. 
        It prompts critical thinking by asking you to evaluate how different concepts fit together, 
        making it a great tool for problem-solving and creative thinking.
      `,
      htmlContent: marked(`
        # Mind Mapping and Active Learning
        Mind mapping encourages active learning by forcing you to process and reorganize information as you take notes. 
        It prompts critical thinking by asking you to evaluate how different concepts fit together, 
        making it a great tool for problem-solving and creative thinking.
      `),
    },
    {
      noteId: 3,
      title: "Visual Representation",
      content: `
        A visual representation of information helps in understanding complex ideas by breaking them down into simpler, more digestible components. 
        It leverages the brain's natural tendency to process visual information faster than text. 
        Mind maps are a perfect example of visual representation, as they make it easier to see relationships between ideas.
      `,
      htmlContent: marked(`
        # Visual Representation
        A visual representation of information helps in understanding complex ideas by breaking them down into simpler, more digestible components. 
        It leverages the brain's natural tendency to process visual information faster than text. 
        Mind maps are a perfect example of visual representation, as they make it easier to see relationships between ideas.
      `),
    },
    {
      noteId: 4,
      title: "Organizing Information",
      content: `
        Organizing information is a critical part of note-taking and learning. 
        It allows you to structure ideas in a logical flow, making it easier to recall later. 
        Mind mapping helps with organizing information by giving each idea a clear place in relation to others.
      `,
      htmlContent: marked(`
        # Organizing Information
        Organizing information is a critical part of note-taking and learning. 
        It allows you to structure ideas in a logical flow, making it easier to recall later. 
        Mind mapping helps with organizing information by giving each idea a clear place in relation to others.
      `),
    },
    {
      noteId: 5,
      title: "Memory Retention",
      content: `
        Memory retention is the ability to store and recall information over time. 
        By connecting ideas and creating a structured note-taking system, like mind mapping, you reinforce connections in the brain, 
        making it easier to retrieve information later.
      `,
      htmlContent: marked(`
        # Memory Retention
        Memory retention is the ability to store and recall information over time. 
        By connecting ideas and creating a structured note-taking system, like mind mapping, you reinforce connections in the brain, 
        making it easier to retrieve information later.
      `),
    },
    {
      noteId: 6,
      title: "Critical Thinking",
      content: `
        Critical thinking involves analyzing and evaluating information to form a judgment. 
        Mind mapping encourages this process by making you break down information into its core components, 
        assess relationships between concepts, and come to conclusions based on connections.
      `,
      htmlContent: marked(`
        # Critical Thinking
        Critical thinking involves analyzing and evaluating information to form a judgment. 
        Mind mapping encourages this proces
[truncated — 23427 more characters]
```

### frontend/tailwind.config.ts

```typescript
/** @type {import('tailwindcss').Config} **/
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      fontFamily:{
        title:["Bodoni Moda", "serif"],
        noteTitle: ["Didact Gothic", "sans-serif"],
        para:["Gothic A1", "sans-serif"],
      },

    
      colors: {
        background: "var(--background)",
        foreground: "var(--foreground)",
        rightside: '#F2EBE3',
        cBeige: '#f6f7f2',
        cBlue: '#3c4f6d', 
        cLighBlue: '#A5B5C4',
        cLeft: '#E9E2CF',
        mbWhite: '#F8F6F0',
        mWhite: '#F5F5F5',
        buttonB: '#F7E7CE',
        nWhite: '#E9E2CF',
      },
    },
  },
  plugins: [],
};

```

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