# Project export: Storyboarding

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: Plan your story scene by scene before beginning to write.
- Devpost: https://devpost.com/software/storyboarding
- GitHub: https://github.com/Kit-Kat31415926/Storyboard
- Team: 2 GitHub contributor(s) — Kaitlyn C (12 commits), Alex (10 commits)

## Devpost submission (written by the team)

### Inspiration

As writers, we were inspired to streamline the writing process by creating a storyboarding app. We wanted to help people write freely without having to draw their own storyboards by using AI to generate images instead.

### What it does

Our application allows users to create a text description by writing or using speech-to-text. The user can then upload an image from their own file system or choose to generate an image based on the text. The scene will then be added to the main screen for the user to peruse while writing their story. Users can also rearrange panels to flexibly adjust the order of their story and plan their plot progression easier.

### How we built it

We used React to create the web application. Using Chakra, we were able to render components on the browser. Deepgram's API was used for the text-to-speech. Stable Diffusion was used to generate images based on the text. By utilizing AI, we were able to streamline the process of creating the storyboard.

### Challenges we ran into

The most significant challenge we ran into was figuring out the drag and drop component of the application. The panels displayed on the screen should have been able to be moved around by the user. However, the components kept glitching, and it was difficult to debug, as the dnd module's documentation was not complete enough to understand.

### Accomplishments we're proud of

We are proud of successfully using Deepgram's API to generate text based on speech and using Stable Diffusion to successfully generate images based on text entered by the user.

### What we learned

We learned that we should modularize our code.

### What's next

We plan to add combine and split features using Gemini in the future.

## README (from the GitHub repository)

# Storyboard

## Detected evidence (automated analysis)

Indexed codebase: 12 recognized source files, 25 KB.
- CSS (language) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code

## Codebase structure (from repository index)

### Files (18 of 18)

```
LICENSE
README.md
storyboard/.env
storyboard/.gitignore
storyboard/package.json
storyboard/public/index.html
storyboard/public/manifest.json
storyboard/public/robots.txt
storyboard/src/App.css
storyboard/src/App.js
storyboard/src/components/SceneCard.jsx
storyboard/src/components/SideBar.jsx
storyboard/src/components/TitleBar.jsx
storyboard/src/index.css
storyboard/src/index.js
storyboard/src/pages/Home.jsx
storyboard/src/pages/LandingPage.jsx
storyboard/tailwind.config.js
```

### Dependencies

- storyboard/package.json: @chakra-ui/react@^2.10.3, @emotion/react@^11.13.3, @emotion/styled@^11.13.0, @hello-pangea/dnd@^17.0.0, @testing-library/jest-dom@^5.17.0, @testing-library/react@^13.4.0, @testing-library/user-event@^13.5.0, dnd-kit@^0.0.2, framer-motion@^11.11.9, react@^18.3.1, react-beautiful-dnd@^13.1.1, react-dom@^18.3.1, react-draggable@^4.4.6, react-router-dom@^6.27.0, react-scripts@5.0.1, tailwindcss@^3.4.14, web-vitals@^2.1.4

### Recent commits (newest first)

- cute but useless animation
- removed old method comment
- Added recording ability
- Finished sidebar
- Added upload image functionality
- Finished delete
- Finished beautiful stuff
- Fixed stuff YAY
- Update content
- Adjust routers
- Fix merge conflict
- Start side bar
- Added new features
- Fix favicon
- Added chakra
- Fix errors with web vitals
- Fix Tailwind
- Add components folder
- Get basic page working
- Add Tailwind

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

### storyboard/package.json

```
{
  "name": "storyboard",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@chakra-ui/react": "^2.10.3",
    "@emotion/react": "^11.13.3",
    "@emotion/styled": "^11.13.0",
    "@hello-pangea/dnd": "^17.0.0",
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "dnd-kit": "^0.0.2",
    "framer-motion": "^11.11.9",
    "react": "^18.3.1",
    "react-beautiful-dnd": "^13.1.1",
    "react-dom": "^18.3.1",
    "react-draggable": "^4.4.6",
    "react-router-dom": "^6.27.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "tailwindcss": "^3.4.14"
  }
}

```

### storyboard/src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
```

### storyboard/src/App.js

```javascript
import React from 'react';
import { ChakraProvider } from '@chakra-ui/react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import LandingPage from './pages/LandingPage';

function App() {
  return (
    <ChakraProvider>
      <Router>
        <div className='Storyboard'>
          <Routes>
            <Route path='/Home' element={<Home />} />
            <Route path='/LandingPage' element={<LandingPage />} />
            <Route path='/' element={<LandingPage />} />
          </Routes>
        </div>
      </Router>
    </ChakraProvider>
  );
}

export default App;

```

### storyboard/tailwind.config.js

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}


```

### storyboard/src/index.css

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

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

```

### storyboard/src/App.css

```css
.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

```

### storyboard/public/index.html

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/icon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

```

### storyboard/src/pages/LandingPage.jsx

```javascript
const LandingPage = () => {
    return (
        <div className='LandingPage'>
            <p>This is the landing page</p>
        </div>
    );
}

export default LandingPage;
```

### storyboard/src/components/SceneCard.jsx

```javascript
import React from 'react';
import { Box, Text, Button, Image } from '@chakra-ui/react';
import { motion } from 'framer-motion';

export const SceneCard = ({ scene, isSelected, onSelect, onToggleDescription }) => (
  <Box
    as={motion.div}
    whileHover={{ scale: 1.02 }}
    p={4}
    bg={isSelected ? 'blue.50' : 'white'}
    borderRadius="md"
    boxShadow="md"
    width="250px"
    height="300px"
    overflow="hidden"
    position="relative"
    onClick={onSelect}
  >
    {scene.image && (
      <Image
        src={scene.image}
        alt={scene.title}
        boxSize="150px"
        objectFit="cover"
        mb={2}
        borderRadius="md"
      />
    )}
    
    <Text fontSize="lg" fontWeight="bold" mb={1}>
      {scene.title}
    </Text>
    <Text fontSize="sm" color="gray.600" noOfLines={scene.expanded ? undefined : 2}>
      {scene.description}
    </Text>
    <Button
      size="xs"
      position="absolute"
      bottom={2}
      right={2}
      onClick={(e) => {
        e.stopPropagation();
        onToggleDescription(scene.id);
      }}
    >
      {scene.expanded ? 'Less' : 'More'}
    </Button>
  </Box>
);

```

### storyboard/src/components/TitleBar.jsx

```javascript
// import React from 'react';
// import { Button, Flex } from '@chakra-ui/react';

// const TitleBar = ({ onCreate, onSave }) => {
//     return (
//         <Flex justifyContent="space-between" p={4} bg="gray.200">
//             <h1>Your Title</h1>
//             <div>
//                 <Button onClick={onCreate} colorScheme="teal">Create</Button>
//                 <Button onClick={onSave} colorScheme="blue">Save</Button>
//             </div>
//         </Flex>
//     );
// };

// export default TitleBar;

import React from 'react';
import { Flex, Text, Button } from '@chakra-ui/react';

export const TitleBar = ({ scenes, selectedSceneIndex, createNewScene }) => { 
  return (
    <Flex
      justifyContent="space-between"
      alignItems="center"
      p={4}
      bg="white"
      borderBottom="1px"
      borderColor="gray.200"
    >
      <Text fontSize="2xl" fontWeight="bold" fontFamily="'Poppins', sans-serif">
        StoryBoard
      </Text>
      <Flex alignItems="center">
        <Text mr={4} fontFamily="'Roboto', sans-serif">
          {selectedSceneIndex !== null ? `Scene #${selectedSceneIndex + 1}` : 'No scene selected'}
        </Text>
        <Button
          onClick={() => createNewScene()}
          colorScheme="blue"
          size="sm"
          _hover={{ transform: 'scale(1.05)' }}
          transition="all 0.2s"
        >
          Add
        </Button>
      </Flex>
    </Flex>
  )
};
```

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