├── .env.example ├── .eslintrc.cjs ├── .gitignore ├── README.md ├── index.html ├── package.json ├── public ├── screenshot.png └── vite.svg ├── src ├── App.css ├── App.tsx ├── assets │ └── react.svg ├── index.css ├── main.tsx ├── prompt.ts └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | VITE_OPENAI_API_KEY= -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Welcome to gpt-flow 2 | 3 | We're using [React Flow](https://reactflow.dev) + GPT-4 to make this possible, the app offers a user-friendly interface for users to input their ideas, concepts, or data, which is then processed by AI to create visually engaging and informative diagrams. 4 | 5 | ![Screenshoot showing a diagram, a prompt field and api key field](public/screenshot.png) 6 | 7 | ## Getting Started 8 | To get started with gpt-flow, you will need to install the necessary dependencies and run the application locally. 9 | 10 | ## Prerequisites 11 | - Node.js v14.x.x or higher 12 | - Yarn package manager 13 | ## Installation 14 | 1.Clone the repository 15 | ```bash 16 | git clone https://github.com/EmanuelCampos/gpt-flow.git 17 | ``` 18 | 2.Change directory 19 | ```bash 20 | cd gpt-flow 21 | ``` 22 | 3.Install dependencies 23 | ```bash 24 | yarn install 25 | ``` 26 | 4.Start the development server 27 | ```bash 28 | yarn dev 29 | ``` 30 | Now, navigate to http://localhost:PORT in your browser to see the application in action! 31 | 32 | ## Usage 33 | After launching the application, setup your OpenAI API Key and let our AI do the work of creating the diagram for you. 34 | 35 | ## Contributing 36 | We welcome contributions from the open-source community. If you'd like to contribute, please fork the repository and create a new branch for your features or bug fixes. Once your changes are ready, create a pull request. 37 | 38 | ## Support 39 | If you encounter any problems or have any suggestions, please open an issue on our GitHub page. -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gpt-flow", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "axios": "^1.4.0", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0", 16 | "reactflow": "^11.7.4" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.2.15", 20 | "@types/react-dom": "^18.2.7", 21 | "@typescript-eslint/eslint-plugin": "^6.0.0", 22 | "@typescript-eslint/parser": "^6.0.0", 23 | "@vitejs/plugin-react": "^4.0.3", 24 | "eslint": "^8.45.0", 25 | "eslint-plugin-react-hooks": "^4.6.0", 26 | "eslint-plugin-react-refresh": "^0.4.3", 27 | "typescript": "^5.0.2", 28 | "vite": "^4.4.5" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /public/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmanuelCampos/gpt-flow/55cf3c8cae914af2d271e5ea60b10d16aad7e23b/public/screenshot.png -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback, useState } from 'react'; 2 | import ReactFlow, { applyEdgeChanges, applyNodeChanges } from 'reactflow'; 3 | 4 | import axios from 'axios'; 5 | 6 | import 'reactflow/dist/style.css'; 7 | import { generatePrompt } from './prompt'; 8 | 9 | const initialNodes = [ 10 | { id: '1', position: { x: 250, y: 0 }, data: { label: 'Entry' } }, 11 | { id: '2', position: { x: 250, y: 100 }, data: { label: 'General (Introduce Yourself)' } }, 12 | { id: '3', position: { x: 100, y: 200 }, data: { label: 'Open-Source' } }, 13 | { id: '4', position: { x: 400, y: 200 }, data: { label: 'Business and Startups' } }, 14 | { id: '5', position: { x: 250, y: 300 }, data: { label: 'Finished Onboarding' } }, 15 | ]; 16 | 17 | const initialEdges = [ 18 | { id: 'e1-2', source: '1', target: '2' }, 19 | { id: 'e2-3', source: '2', target: '3' }, 20 | { id: 'e2-4', source: '2', target: '4' }, 21 | { id: 'e3-5', source: '3', target: '5' }, 22 | { id: 'e4-5', source: '4', target: '5' }, 23 | ]; 24 | 25 | export default function App() { 26 | const [prompt, setPrompt] = useState('') 27 | const [apiKey, setApiKey] = useState('') 28 | const [loading, setLoading] = useState(false) 29 | const [nodes, setNodes] = useState(initialNodes) 30 | const [edges, setEdges] = useState(initialEdges) 31 | 32 | const generateNodes = async () => { 33 | setLoading(true) 34 | 35 | const messages = [{ 36 | role: 'user', 37 | content: generatePrompt(prompt) 38 | }] 39 | 40 | try { 41 | const response = await axios.post( 42 | "https://api.openai.com/v1/chat/completions", 43 | { 44 | messages, 45 | model: 'gpt-4', 46 | }, 47 | { 48 | headers: { 49 | "Content-Type": "application/json", 50 | Authorization: `Bearer ${apiKey}`, 51 | }, 52 | } 53 | ); 54 | 55 | const newEdges = JSON.parse(response.data.choices[0].message.content).edges 56 | const newNodes = JSON.parse(response.data.choices[0].message.content).nodes 57 | 58 | setLoading(false) 59 | 60 | setEdges(newEdges) 61 | setNodes(newNodes) 62 | setPrompt('') 63 | } catch (e) { 64 | console.log(e) 65 | setLoading(false) 66 | } 67 | } 68 | 69 | const onNodesChange = useCallback( 70 | (changes: any) => setNodes((nds) => applyNodeChanges(changes, nds)), 71 | [setNodes, nodes] 72 | ); 73 | const onEdgesChange = useCallback( 74 | (changes: any) => setEdges((eds) => applyEdgeChanges(changes, eds)), 75 | [setEdges, edges] 76 | ); 77 | 78 | return ( 79 |
80 | 90 |
97 |

98 | OpenAI Api Key 99 |

100 | { 109 | setApiKey(e.target.value) 110 | } 111 | } 112 | /> 113 |

Prompt

116 |