diff --git a/packages/web/src/components/cells/code.tsx b/packages/web/src/components/cells/code.tsx index d17c9044..75e9e695 100644 --- a/packages/web/src/components/cells/code.tsx +++ b/packages/web/src/components/cells/code.tsx @@ -1,4 +1,5 @@ import { useEffect, useRef, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import { useHotkeys } from 'react-hotkeys-hook'; import CodeMirror, { keymap, Prec } from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; @@ -34,6 +35,7 @@ export default function CodeCell(props: { channel: SessionChannel; onUpdateCell: (cell: CodeCellType, attrs: CodeCellUpdateAttrsType) => Promise; onDeleteCell: (cell: CellType) => void; + hasOpenaiKey: boolean; }) { const { session, cell, channel, onUpdateCell, onDeleteCell } = props; const [filenameError, _setFilenameError] = useState(null); @@ -42,11 +44,14 @@ export default function CodeCell(props: { const [prompt, setPrompt] = useState(''); const [newSource, setNewSource] = useState(''); + const navigate = useNavigate(); + useHotkeys( 'mod+enter', () => { if (!prompt) return; if (promptMode !== 'idle') return; + if (!props.hasOpenaiKey) return; generate(); }, { enableOnFormTags: ['textarea'] }, @@ -194,7 +199,12 @@ export default function CodeCell(props: { {promptMode === 'idle' && ( - )} @@ -221,34 +231,48 @@ export default function CodeCell(props: { {promptMode !== 'off' && ( -
-
- - setPrompt(e.target.value)} - /> -
-
- - + + - - +
+ + {!props.hasOpenaiKey && ( +
+

API key required

+ navigate('/settings')} + > + Settings + +
+ )} )} diff --git a/packages/web/src/index.css b/packages/web/src/index.css index 726cefb4..082b9364 100644 --- a/packages/web/src/index.css +++ b/packages/web/src/index.css @@ -64,6 +64,8 @@ --inline-code-foreground: var(--foreground); --error: var(--sb-red-30); --error-foreground: var(--sb-red-80); + --warning: var(--sb-yellow-20); + --warning-foreground: var(--sb-yellow-80); } .dark { @@ -78,6 +80,8 @@ --inline-code-foreground: var(--foreground); --error: var(--sb-red-30); --error-foreground: var(--sb-red-80); + --warning: var(--sb-yellow-20); + --warning-foreground: var(--sb-yellow-80); } /* shadcn variables light */ diff --git a/packages/web/src/routes/session.tsx b/packages/web/src/routes/session.tsx index 89b3bd29..52fd3f41 100644 --- a/packages/web/src/routes/session.tsx +++ b/packages/web/src/routes/session.tsx @@ -218,6 +218,7 @@ function Session(props: { session: SessionType; channel: SessionChannel; config: channel={channel} onUpdateCell={onUpdateCell} onDeleteCell={onDeleteCell} + hasOpenaiKey={!!props.config.openaiKey} /> )} diff --git a/packages/web/tailwind.config.js b/packages/web/tailwind.config.js index cbf080bc..1e2602b4 100644 --- a/packages/web/tailwind.config.js +++ b/packages/web/tailwind.config.js @@ -90,6 +90,10 @@ module.exports = { DEFAULT: 'hsl(var(--error))', foreground: 'hsl(var(--error-foreground))', }, + warning: { + DEFAULT: 'hsl(var(--warning))', + foreground: 'hsl(var(--warning-foreground))', + }, sb: { 'core-0': 'hsl(var(--sb-core-0))', 'core-10': 'hsl(var(--sb-core-10))',