make real integration attempt, settingsdialog errors
This commit is contained in:
parent
bfbe7b8325
commit
5c24bb64da
|
|
@ -0,0 +1,52 @@
|
|||
import { TldrawUiButton, useDialogs } from 'tldraw'
|
||||
import { useMakeReal } from '../hooks/useMakeReal'
|
||||
import { SettingsDialog } from './SettingsDialog'
|
||||
|
||||
export function MakeRealButton() {
|
||||
const { addDialog } = useDialogs()
|
||||
const makeReal = useMakeReal()
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex' }}>
|
||||
{/* Settings Button */}
|
||||
<TldrawUiButton
|
||||
type="icon"
|
||||
style={{ height: 52, width: 52, padding: 'var(--space-2)' }}
|
||||
onClick={() => {
|
||||
addDialog({
|
||||
id: 'api keys',
|
||||
component: SettingsDialog,
|
||||
})
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 15 15"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style={{ backgroundColor: 'var(--color-background)', borderRadius: '100%' }}
|
||||
>
|
||||
{/* Settings icon path */}
|
||||
<path
|
||||
d="M7.07095 0.650238C6.67391 0.650238 6.32977 0.925096 6.24198 1.31231L6.0039 2.36247C5.6249 2.47269 5.26335 2.62363 4.92436 2.81013L4.01335 2.23585C3.67748 2.02413 3.23978 2.07312 2.95903 2.35386L2.35294 2.95996C2.0722 3.2407 2.0232 3.6784 2.23493 4.01427L2.80942 4.92561C2.62307 5.2645 2.47227 5.62594 2.36216 6.00481L1.31209 6.24287C0.924883 6.33065 0.650024 6.6748 0.650024 7.07183V7.92897C0.650024 8.32601 0.924883 8.67015 1.31209 8.75794L2.36228 8.99603C2.47246 9.375 2.62335 9.73652 2.80979 10.0755L2.2354 10.9867C2.02367 11.3225 2.07267 11.7602 2.35341 12.041L2.95951 12.6471C3.24025 12.9278 3.67795 12.9768 4.01382 12.7651L4.92506 12.1907C5.26384 12.377 5.62516 12.5278 6.0039 12.6379L6.24198 13.6881C6.32977 14.0753 6.67391 14.3502 7.07095 14.3502H7.92809C8.32512 14.3502 8.66927 14.0753 8.75705 13.6881L8.99505 12.6383C9.37411 12.5282 9.73573 12.3773 10.0748 12.1909L10.986 12.7653C11.3218 12.977 11.7595 12.928 12.0403 12.6473L12.6464 12.0412C12.9271 11.7604 12.9761 11.3227 12.7644 10.9869L12.1902 10.076C12.3768 9.73688 12.5278 9.37515 12.638 8.99596L13.6879 8.75794C14.0751 8.67015 14.35 8.32601 14.35 7.92897V7.07183C14.35 6.6748 14.0751 6.33065 13.6879 6.24287L12.6381 6.00488C12.528 5.62578 12.3771 5.26414 12.1906 4.92507L12.7648 4.01407C12.9766 3.6782 12.9276 3.2405 12.6468 2.95975L12.0407 2.35366C11.76 2.07292 11.3223 2.02392 10.9864 2.23565L10.0755 2.80989C9.73622 2.62328 9.37437 2.47229 8.99505 2.36209L8.75705 1.31231C8.66927 0.925096 8.32512 0.650238 7.92809 0.650238H7.07095Z"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</TldrawUiButton>
|
||||
|
||||
{/* Make Real Button */}
|
||||
<button
|
||||
onClick={makeReal}
|
||||
className="pt-2 pb-2 pr-2"
|
||||
style={{ cursor: 'pointer', zIndex: 100000, pointerEvents: 'all' }}
|
||||
>
|
||||
<div className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
||||
Add AI API
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
import {
|
||||
TLUiDialogProps,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonLabel,
|
||||
TldrawUiDialogBody,
|
||||
TldrawUiDialogCloseButton,
|
||||
TldrawUiDialogFooter,
|
||||
TldrawUiDialogHeader,
|
||||
TldrawUiDialogTitle,
|
||||
TldrawUiIcon,
|
||||
TldrawUiInput,
|
||||
useReactor,
|
||||
useValue,
|
||||
} from 'tldraw'
|
||||
import { Provider, makeRealSettings } from '../makeRealSettings'
|
||||
|
||||
export function SettingsDialog({ onClose }: TLUiDialogProps) {
|
||||
// Get settings and set up local storage sync
|
||||
const settings = useValue('settings', () => makeRealSettings.get(), [])
|
||||
|
||||
useReactor(
|
||||
'update settings local storage',
|
||||
() => {
|
||||
localStorage.setItem('makereal_settings_2', JSON.stringify(makeRealSettings.get()))
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<TldrawUiDialogHeader>
|
||||
<TldrawUiDialogTitle>Settings</TldrawUiDialogTitle>
|
||||
<TldrawUiDialogCloseButton />
|
||||
</TldrawUiDialogHeader>
|
||||
|
||||
<TldrawUiDialogBody
|
||||
style={{ maxWidth: 350, display: 'flex', flexDirection: 'column', gap: 8 }}
|
||||
>
|
||||
{/* Provider Selection */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 4, marginTop: 8 }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'row', gap: 4 }}>
|
||||
<label style={{ flexGrow: 2 }}>Provider</label>
|
||||
</div>
|
||||
<select
|
||||
className="apikey_select"
|
||||
value={settings.provider}
|
||||
onChange={(e) => {
|
||||
makeRealSettings.set({
|
||||
...settings,
|
||||
provider: e.target.value as any
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option value="anthropic">Anthropic</option>
|
||||
<option value="openai">OpenAI</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* API Keys Section */}
|
||||
<hr style={{ margin: '12px 0px' }} />
|
||||
{Provider.map((provider: any) => {
|
||||
if (provider.id === 'google') return null
|
||||
const value = settings.keys[provider.id]
|
||||
return (
|
||||
<ApiKeyInput
|
||||
key={provider.name + 'key'}
|
||||
provider={provider}
|
||||
value={value}
|
||||
warning={
|
||||
value === '' &&
|
||||
(settings.provider === provider.id || settings.provider === 'any')
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
|
||||
{/* Save Button */}
|
||||
<TldrawUiDialogFooter className="tlui-dialog__footer__actions">
|
||||
<TldrawUiButton
|
||||
type="primary"
|
||||
onClick={async () => {
|
||||
onClose()
|
||||
}}
|
||||
>
|
||||
<TldrawUiButtonLabel>Save</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
</TldrawUiDialogFooter>
|
||||
</TldrawUiDialogBody>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// Helper component for API key inputs
|
||||
function ApiKeyInput({
|
||||
provider,
|
||||
value,
|
||||
warning,
|
||||
}: {
|
||||
provider: (typeof Provider)[number]
|
||||
value: string
|
||||
warning: boolean
|
||||
}) {
|
||||
const isValid = value.length === 0 || provider.validate(value)
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'row', gap: 4, alignItems: 'center' }}>
|
||||
<label style={{ flexGrow: 2, color: warning ? 'red' : 'var(--color-text)' }}>
|
||||
{provider.name} API key
|
||||
</label>
|
||||
<a style={{ cursor: 'pointer', pointerEvents: 'all' }} target="_blank" href={provider.help}>
|
||||
<TldrawUiIcon
|
||||
className="apikey_help_icon"
|
||||
small
|
||||
icon={provider.validate(value) ? 'check' : 'question-mark-circle'}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<TldrawUiInput
|
||||
className={`apikey_input ${isValid ? '' : 'apikey_input__invalid'}`}
|
||||
value={value}
|
||||
placeholder="Enter API key"
|
||||
onValueChange={(value) => {
|
||||
makeRealSettings.update((s) => ({
|
||||
...s,
|
||||
keys: { ...s.keys, [provider.id]: value }
|
||||
}))
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import { useCallback } from 'react'
|
||||
import { useEditor } from 'tldraw'
|
||||
import { makeRealSettings } from '../makeRealSettings'
|
||||
|
||||
export function useMakeReal() {
|
||||
const editor = useEditor()
|
||||
|
||||
return useCallback(async () => {
|
||||
const settings = makeRealSettings.get()
|
||||
|
||||
// Get the current selection from the canvas
|
||||
const shapes = editor.getSelectedShapes()
|
||||
|
||||
try {
|
||||
// Make API request with the selected shapes
|
||||
const response = await fetch('/api/make-real', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
shapes,
|
||||
apiKey: settings.apiKey,
|
||||
provider: settings.provider,
|
||||
}),
|
||||
})
|
||||
|
||||
const result = await response.json()
|
||||
// Handle the result
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error making real:', error)
|
||||
}
|
||||
}, [editor])
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
type Settings = {
|
||||
apiKey: string
|
||||
provider: 'anthropic' | 'openai'
|
||||
}
|
||||
|
||||
class MakeRealSettings {
|
||||
private settings: Settings = {
|
||||
apiKey: '',
|
||||
provider: 'anthropic',
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.settings
|
||||
}
|
||||
|
||||
set(settings: Partial<Settings>) {
|
||||
this.settings = { ...this.settings, ...settings }
|
||||
localStorage.setItem('makereal_settings_2', JSON.stringify(this.settings))
|
||||
}
|
||||
}
|
||||
|
||||
export const makeRealSettings = new MakeRealSettings()
|
||||
export const Provider = makeRealSettings.get().provider
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -2,9 +2,11 @@ import { CustomMainMenu } from "./CustomMainMenu"
|
|||
import { CustomToolbar } from "./CustomToolbar"
|
||||
import { CustomContextMenu } from "./CustomContextMenu"
|
||||
import { TLComponents } from "tldraw"
|
||||
import { MakeRealButton } from "../../components/MakeRealButton"
|
||||
|
||||
export const components: TLComponents = {
|
||||
Toolbar: CustomToolbar,
|
||||
MainMenu: CustomMainMenu,
|
||||
ContextMenu: CustomContextMenu,
|
||||
SharePanel: MakeRealButton,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue