diff --git a/apps/database-new/app/NewThreadInput.tsx b/apps/database-new/app/NewThreadInput.tsx
new file mode 100644
index 00000000000..ca63cbc3c60
--- /dev/null
+++ b/apps/database-new/app/NewThreadInput.tsx
@@ -0,0 +1,81 @@
+'use client'
+import { ChatInputAtom } from '@/components/Chat/ChatInput'
+import { CHAT_EXAMPLES } from '@/data/chat-examples'
+import { useMutation } from '@tanstack/react-query'
+import { ExternalLink } from 'lucide-react'
+import { useRouter } from 'next/navigation'
+import { useState } from 'react'
+import { cn } from 'ui'
+
+interface ChatInputParams {
+ userID: string | undefined
+}
+
+const suggestions = CHAT_EXAMPLES
+
+const NewThreadInput = ({ userID }: ChatInputParams) => {
+ const router = useRouter()
+ const [value, setValue] = useState('')
+
+ const { mutate, isPending, isSuccess } = useMutation({
+ mutationFn: async (prompt: string) => {
+ const body = { prompt, userID } // Include userID in the body object
+
+ const response = await fetch('/api/ai/sql/threads/create', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(body),
+ })
+ const result = await response.json()
+ return result
+ },
+ onSuccess(data) {
+ const url = `/${data.threadId}/${data.runId}`
+ router.push(url)
+ },
+ })
+
+ return (
+ <>
+
+ {
+ if (value.length > 0) mutate(value)
+ }}
+ autoFocus
+ value={value}
+ rows={1}
+ contentEditable
+ aria-expanded={false}
+ placeholder="e.g Create a Telegram-like chat application"
+ disabled={isPending || isSuccess}
+ loading={isPending || isSuccess}
+ onChange={(e) => setValue(e.target.value)}
+ />
+
+
+ {suggestions.map((suggestion, idx) => (
+
+ ))}
+
+ >
+ )
+}
+
+export default NewThreadInput
diff --git a/apps/database-new/components/Chat/BottomMarker.tsx b/apps/database-new/app/[threadId]/BottomMarker.tsx
similarity index 100%
rename from apps/database-new/components/Chat/BottomMarker.tsx
rename to apps/database-new/app/[threadId]/BottomMarker.tsx
diff --git a/apps/database-new/components/Chat/Chat.tsx b/apps/database-new/app/[threadId]/Chat.tsx
similarity index 88%
rename from apps/database-new/components/Chat/Chat.tsx
rename to apps/database-new/app/[threadId]/Chat.tsx
index d0a44e2a695..0f802dae565 100644
--- a/apps/database-new/components/Chat/Chat.tsx
+++ b/apps/database-new/app/[threadId]/Chat.tsx
@@ -10,6 +10,7 @@ import { useMessagesQuery } from '@/data/messages-query'
import { AssistantMessage, UserMessage } from '@/lib/types'
import BottomMarker from './BottomMarker'
import UserChat from './UserChat'
+import { ChatInputAtom } from '../../components/Chat/ChatInput'
export const Chat = () => {
const router = useRouter()
@@ -94,30 +95,22 @@ export const Chat = () => {
)}
-
}
onChange={(v) => setValue(v.target.value)}
- onKeyDown={(e) => {
- if (e.code === 'Enter' && value.length > 0) {
+ handleSubmit={() => {
+ if (value && value.length > 0) {
mutate(value)
setInputEntered(true)
}
}}
- actions={
- loading || inputEntered ? (
-
-
-
- ) : null
- }
/>
diff --git a/apps/database-new/components/Chat/UserChat.tsx b/apps/database-new/app/[threadId]/UserChat.tsx
similarity index 100%
rename from apps/database-new/components/Chat/UserChat.tsx
rename to apps/database-new/app/[threadId]/UserChat.tsx
diff --git a/apps/database-new/app/[threadId]/layout.tsx b/apps/database-new/app/[threadId]/layout.tsx
index a16244fc4c6..85b76e12e95 100644
--- a/apps/database-new/app/[threadId]/layout.tsx
+++ b/apps/database-new/app/[threadId]/layout.tsx
@@ -1,5 +1,5 @@
'use client'
-import { Chat } from '@/components/Chat/Chat'
+import { Chat } from '@/app/[threadId]/Chat'
import SaveSchemaDropdown from '@/components/Header/SaveSchemaDropdown'
import ToggleCodeEditorButton from '@/components/Header/ToggleCodeEditorButton'
@@ -7,7 +7,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
return (
-
+
diff --git a/apps/database-new/app/new/page.tsx b/apps/database-new/app/page.tsx
similarity index 85%
rename from apps/database-new/app/new/page.tsx
rename to apps/database-new/app/page.tsx
index 7744aee341d..598ff665fc6 100644
--- a/apps/database-new/app/new/page.tsx
+++ b/apps/database-new/app/page.tsx
@@ -1,7 +1,7 @@
-import type { Metadata } from 'next'
-import ChatInput from '@/components/Chat/ChatInput'
import { createClient } from '@/lib/supabase/server'
+import type { Metadata } from 'next'
import { cookies } from 'next/headers'
+import NewThreadInput from './NewThreadInput'
export const metadata: Metadata = {
title: 'database.design | Create',
@@ -17,7 +17,7 @@ const NewThread = async () => {
return (
-
+
)
}
diff --git a/apps/database-new/app/profile/EmptyState.tsx b/apps/database-new/app/profile/EmptyState.tsx
index 8532c728c3a..c799079a9e7 100644
--- a/apps/database-new/app/profile/EmptyState.tsx
+++ b/apps/database-new/app/profile/EmptyState.tsx
@@ -7,7 +7,7 @@ const EmptyState = () => {
No conversations created yet
)
diff --git a/apps/database-new/components/Chat/ChatInput.tsx b/apps/database-new/components/Chat/ChatInput.tsx
index 3d6cb4774a1..6ba663f5eac 100644
--- a/apps/database-new/components/Chat/ChatInput.tsx
+++ b/apps/database-new/components/Chat/ChatInput.tsx
@@ -1,111 +1,85 @@
-'use client'
-import { useMutation } from '@tanstack/react-query'
import { Loader2 } from 'lucide-react'
-import { useRouter } from 'next/navigation'
-import { useState } from 'react'
+import { createRef, forwardRef, useEffect } from 'react'
+import { TextArea_Shadcn_, cn } from 'ui'
-import { Input } from 'ui'
-
-interface ChatInputParams {
- userID: string | undefined
+export interface TextAreaProps extends React.TextareaHTMLAttributes
{
+ loading: boolean
+ handleSubmit: () => void
}
-const suggestions = [
- { label: 'Twitter clone', prompt: 'Create a twitter clone' },
- {
- label: 'Chat application',
- prompt:
- 'Create a chat application that supports sending messages either through channels or directly between users',
- },
- {
- label: 'User management',
- prompt: 'Create a simple user management schema that supports role based access control',
- },
- { label: 'To do list', prompt: 'Create a simple schema for me to track a to do list' },
-]
+const ChatInputAtom = ({ className, loading, handleSubmit, ...props }: TextAreaProps) => {
+ const ref = createRef()
-const ChatInput = ({ userID }: ChatInputParams) => {
- const router = useRouter()
- const [value, setValue] = useState('')
+ useEffect(() => {
+ if (!props.value && ref && ref.current) {
+ ref.current.style.height = '40px'
+ } else if (ref && ref.current) {
+ console.log('ref.current.scrollHeight', ref.current.scrollHeight)
+ const newHeight = ref.current.scrollHeight + 'px'
+ console.log('new height', newHeight)
+ ref.current.style.height = newHeight
+ }
+ }, [props.value, ref])
- const { mutate, isPending, isSuccess } = useMutation({
- mutationFn: async (prompt: string) => {
- const body = { prompt, userID } // Include userID in the body object
+ useEffect(() => {
+ ref?.current?.focus()
+ }, [props.value, ref])
- const response = await fetch('/api/ai/sql/threads/create', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(body),
- })
- const result = await response.json()
- return result
- },
- onSuccess(data) {
- const url = `/${data.threadId}/${data.runId}`
- router.push(url)
- },
- })
+ const handleKeyDown = (event: React.KeyboardEvent) => {
+ // Check if the pressed key is "Enter" (key code 13)
+ if (event.key === 'Enter' && !event.shiftKey) {
+ event.preventDefault()
+ // Manually submit the form
+ // value is handled by parent component
+ handleSubmit()
+ }
+ }
return (
- <>
-
-
+
+ {
- if (e.code === 'Enter') {
- if (value.length > 0) mutate(value)
- }
- }}
- onChange={(e) => setValue(e.target.value)}
- actions={
- isPending || isSuccess ? (
-
-
-
- ) : (
-
- )
+ className={
+ 'transition-all text-sm pl-12 pr-10 rounded-[18px] resize-none box-border leading-6'
}
+ ref={ref}
+ spellCheck={false}
+ onKeyDown={handleKeyDown}
+ {...props}
/>
-
-
- {suggestions.map((suggestion, idx) => (
-