diff --git a/next.config.js b/next.config.js index cb1bc28..f7b521d 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,6 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: false, // creates problems for chat -} +}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/package.json b/package.json index cf4ee3c..7b04d7e 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,10 @@ "react": "18.2.0", "react-dom": "18.2.0", "tailwindcss": "3.3.3", - "typescript": "5.2.2" + "typescript": "5.2.2", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@types/uuid": "^9.0.2" } } diff --git a/postcss.config.js b/postcss.config.js index 33ad091..12a703d 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -3,4 +3,4 @@ module.exports = { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/src/components/auth/ErrorAlert.tsx b/src/components/auth/ErrorAlert.tsx index ebdaa1e..47f49bc 100644 --- a/src/components/auth/ErrorAlert.tsx +++ b/src/components/auth/ErrorAlert.tsx @@ -1,13 +1,9 @@ -import { AuthError } from "@supabase/supabase-js"; +import { AuthError } from '@supabase/supabase-js'; interface ErrorAlertProps { - error: AuthError + error: AuthError; } export default function ErrorAlert(props: ErrorAlertProps) { - return ( -

- {props.error.message} -

- ) + return

{props.error.message}

; } diff --git a/src/components/auth/SignInForm.tsx b/src/components/auth/SignInForm.tsx index 72f5aa0..8b0c3f5 100644 --- a/src/components/auth/SignInForm.tsx +++ b/src/components/auth/SignInForm.tsx @@ -1,97 +1,109 @@ -'use client' -import { Database } from '../../../types/supabase' -import React, { useState } from 'react' +'use client'; +import { Database } from '../../../types/supabase'; +import React, { useState } from 'react'; import { AuthError } from '@supabase/supabase-js'; -import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' +import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; import ErrorAlert from './ErrorAlert'; import { useRouter } from 'next/router'; - export default function SignInForm() { - const supabase = createClientComponentClient() - const [error, setError] = useState(null); - const [isMainButtonDisabled, setIsMainButtonDisabled] = useState(false); - const { push } = useRouter(); - - async function signInWithPassword(email: string, password: string) { - setIsMainButtonDisabled(true); - const { data, error } = await supabase.auth.signInWithPassword({ - email, - password, - }) - setIsMainButtonDisabled(false); - if (error) { - setError(error) - } else { - push('/home'); - } - } - - async function onFormSubmit(event: React.FormEvent) { - event.preventDefault() - const target = event.target as typeof event.target & { - email: { value: string } - password: { value: string } - } - const email = target.email.value - const password = target.password.value - await signInWithPassword(email, password) + const supabase = createClientComponentClient(); + const [error, setError] = useState(null); + const [isMainButtonDisabled, setIsMainButtonDisabled] = + useState(false); + const { push } = useRouter(); + + async function signInWithPassword(email: string, password: string) { + setIsMainButtonDisabled(true); + const { data, error } = await supabase.auth.signInWithPassword({ + email, + password, + }); + setIsMainButtonDisabled(false); + if (error) { + setError(error); + } else { + push('/home'); } + } - return ( - <> - {error && } -
-
- -
- -
+ async function onFormSubmit(event: React.FormEvent) { + event.preventDefault(); + const target = event.target as typeof event.target & { + email: { value: string }; + password: { value: string }; + }; + const email = target.email.value; + const password = target.password.value; + await signInWithPassword(email, password); + } + + return ( + <> + {error && } + +
+ +
+
+
-
-
- - -
-
- +
+
+ +
-
- +
+
- - - - ) - } - \ No newline at end of file +
+
+ +
+ + + ); +} diff --git a/src/components/auth/SignUpForm.tsx b/src/components/auth/SignUpForm.tsx index aaa6a51..e6589e4 100644 --- a/src/components/auth/SignUpForm.tsx +++ b/src/components/auth/SignUpForm.tsx @@ -1,96 +1,102 @@ -'use client' -import { Database } from '../../../types/supabase' -import React, { useState } from 'react' +'use client'; +import { Database } from '../../../types/supabase'; +import React, { useState } from 'react'; import { AuthError } from '@supabase/supabase-js'; -import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' +import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; import ErrorAlert from './ErrorAlert'; import { useRouter } from 'next/router'; - - - export default function SignUpForm() { + const supabase = createClientComponentClient(); + const [error, setError] = useState(null); + const [isMainButtonDisabled, setIsMainButtonDisabled] = + useState(false); + const { push } = useRouter(); - const supabase = createClientComponentClient() - const [error, setError] = useState(null); - const [isMainButtonDisabled, setIsMainButtonDisabled] = useState(false); - const { push } = useRouter(); - - async function signUp(email: string, password: string) { - setIsMainButtonDisabled(true); - const { data, error } = await supabase.auth.signUp({ - email, - password, - }) - setIsMainButtonDisabled(false); - if (error) { - setError(error) - } else { - supabase.auth.signInWithPassword({ email, password }); - push('/home'); - } - } - - async function onFormSubmit(event: React.FormEvent) { - event.preventDefault() - const target = event.target as typeof event.target & { - email: { value: string } - password: { value: string } - } - const email = target.email.value - const password = target.password.value - await signUp(email, password) + async function signUp(email: string, password: string) { + setIsMainButtonDisabled(true); + const { data, error } = await supabase.auth.signUp({ + email, + password, + }); + setIsMainButtonDisabled(false); + if (error) { + setError(error); + } else { + supabase.auth.signInWithPassword({ email, password }); + push('/home'); } + } - return ( - <> - {error && } -
-
- -
- -
-
+ async function onFormSubmit(event: React.FormEvent) { + event.preventDefault(); + const target = event.target as typeof event.target & { + email: { value: string }; + password: { value: string }; + }; + const email = target.email.value; + const password = target.password.value; + await signUp(email, password); + } -
-
- -
-
- -
+ return ( + <> + {error && } + +
+ +
+
-
- + Password +
- - - - ) - } - \ No newline at end of file +
+ +
+
+
+ +
+ + + ); +} diff --git a/src/components/chat.tsx b/src/components/chat.tsx index fb4cdba..542d8bc 100644 --- a/src/components/chat.tsx +++ b/src/components/chat.tsx @@ -1,9 +1,15 @@ -import { ChatMessage } from "@/types"; +import { ChatMessage } from '@/types'; export const MessageUI = (message: ChatMessage) => { return ( -
+
{message.content}
); -}; \ No newline at end of file +}; diff --git a/src/components/home/AppShell.tsx b/src/components/home/AppShell.tsx index 4b60801..b5e4887 100644 --- a/src/components/home/AppShell.tsx +++ b/src/components/home/AppShell.tsx @@ -1,45 +1,55 @@ -import { Fragment } from 'react' -import { Disclosure, Menu, Transition } from '@headlessui/react' -import { Bars3Icon, BellIcon, XMarkIcon } from '@heroicons/react/24/outline' -import { Session } from '@supabase/supabase-js' -import { useRouter } from 'next/router' -import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' -import { Database } from '../../../types/supabase' +import { Fragment } from 'react'; +import { Disclosure, Menu, Transition } from '@headlessui/react'; +import { Bars3Icon, BellIcon, XMarkIcon } from '@heroicons/react/24/outline'; +import { Session } from '@supabase/supabase-js'; +import { useRouter } from 'next/router'; +import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; +import { Database } from '../../../types/supabase'; function classNames(...classes: string[]) { - return classes.filter(Boolean).join(' ') + return classes.filter(Boolean).join(' '); } -type User = Database['public']['Tables']['users']['Row'] +type User = Database['public']['Tables']['users']['Row']; type AppShellProps = { user: User; -} - +}; + export default function AppShell(props: AppShellProps) { const { push } = useRouter(); - const supabase = createClientComponentClient() + const supabase = createClientComponentClient(); const userNavigation = [ { name: 'Settings', href: '#' }, - { name: 'Sign out', href: '#', onClick: () => { - supabase.auth.signOut(); - push('/'); - } }, - ] + { + name: 'Sign out', + href: '#', + onClick: () => { + supabase.auth.signOut(); + push('/'); + }, + }, + ]; const getAvatar = (size: number) => { if (props.user.avatar_url) { - return + return ( + + ); } - return
-
- {props.user.email[0]} + return ( +
+
+ {props.user.email[0]} +
-
- } - - + ); + }; return ( <> @@ -92,7 +102,9 @@ export default function AppShell(props: AppShellProps) { {({ active }) => ( {}} + onClick={ + item.onClick ? item.onClick : () => {} + } className={classNames( active ? 'bg-gray-100' : '', 'block px-4 py-2 text-sm text-gray-700' @@ -114,9 +126,15 @@ export default function AppShell(props: AppShellProps) { Open main menu {open ? ( -
@@ -124,15 +142,16 @@ export default function AppShell(props: AppShellProps) {
-
-
- {getAvatar(10)} -
+
{getAvatar(10)}
-
{props.user.email}
-
{props.user.email}
+
+ {props.user.email} +
+
+ {props.user.email} +
- ) + ); } diff --git a/src/components/home/ErrorMode.tsx b/src/components/home/ErrorMode.tsx index 062d155..6d2e824 100644 --- a/src/components/home/ErrorMode.tsx +++ b/src/components/home/ErrorMode.tsx @@ -1,15 +1,10 @@ -import { AuthError, Session } from '@supabase/supabase-js' - +import { AuthError, Session } from '@supabase/supabase-js'; type ErrorModeProps = { - session: Session | null, - error: AuthError | null -} - + session: Session | null; + error: AuthError | null; +}; + export default function ErrorMode(props: ErrorModeProps) { - return ( -

- {JSON.stringify(props.error?.message)} -

- ) + return

{JSON.stringify(props.error?.message)}

; } diff --git a/src/components/home/Spinner.tsx b/src/components/home/Spinner.tsx index 2878d7d..b7ea149 100644 --- a/src/components/home/Spinner.tsx +++ b/src/components/home/Spinner.tsx @@ -6,4 +6,4 @@ const Spinner = () => (
); -export default Spinner; \ No newline at end of file +export default Spinner; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index e8b9d41..d09eb07 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,16 +1,17 @@ -import '@/styles/globals.css' -import type { AppProps } from 'next/app' -import { Session, SessionContextProvider } from '@supabase/auth-helpers-react' -import { createPagesBrowserClient } from '@supabase/auth-helpers-nextjs' -import { useState } from 'react' - +import '@/styles/globals.css'; +import type { AppProps } from 'next/app'; +import { Session, SessionContextProvider } from '@supabase/auth-helpers-react'; +import { createPagesBrowserClient } from '@supabase/auth-helpers-nextjs'; +import { useState } from 'react'; export default function App({ Component, pageProps }: AppProps) { - const [supabaseClient] = useState(() => createPagesBrowserClient()) - return - - + const [supabaseClient] = useState(() => createPagesBrowserClient()); + return ( + + + + ); } diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 54e8bf3..e1e9cbb 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -1,4 +1,4 @@ -import { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document'; export default function Document() { return ( @@ -9,5 +9,5 @@ export default function Document() { - ) + ); } diff --git a/src/pages/api/hello.ts b/src/pages/api/hello.ts index f8bcc7e..89e4d6b 100644 --- a/src/pages/api/hello.ts +++ b/src/pages/api/hello.ts @@ -1,13 +1,13 @@ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from 'next' +import type { NextApiRequest, NextApiResponse } from 'next'; type Data = { - name: string -} + name: string; +}; export default function handler( req: NextApiRequest, res: NextApiResponse ) { - res.status(200).json({ name: 'John Doe' }) + res.status(200).json({ name: 'John Doe' }); } diff --git a/src/pages/api/llm.ts b/src/pages/api/llm.ts index 75cd9bc..0b19c20 100644 --- a/src/pages/api/llm.ts +++ b/src/pages/api/llm.ts @@ -1,5 +1,5 @@ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from 'next' +import type { NextApiRequest, NextApiResponse } from 'next'; import OpenAI from 'openai'; import { LLMRequest, LLMResponse } from '../../types'; @@ -7,8 +7,8 @@ const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, baseURL: 'https://oai.hconeai.com/v1', defaultHeaders: { - "Helicone-Cache-Enabled": "true", - "Helicone-Auth": `Bearer ${process.env.HELICONE_API_KEY}`, + 'Helicone-Cache-Enabled': 'true', + 'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`, }, }); @@ -18,8 +18,10 @@ export default async function handler( ) { const llmRequest: LLMRequest = req.body; console.log(`LLM middleware: got request: ${JSON.stringify(llmRequest)}`); - const completion = await openai.chat.completions.create(llmRequest.completion_create); + const completion = await openai.chat.completions.create( + llmRequest.completion_create + ); console.log(`LLM middleware: got completion: ${JSON.stringify(completion)}`); - const response: LLMResponse = { completion } + const response: LLMResponse = { completion }; res.status(200).json(response); } diff --git a/src/pages/auth.tsx b/src/pages/auth.tsx index 0f4ee1e..e8cfa98 100644 --- a/src/pages/auth.tsx +++ b/src/pages/auth.tsx @@ -1,18 +1,16 @@ -'use client' -import React, { useState } from 'react' -import SignUpForm from '../components/auth/SignUpForm' -import SignInForm from '@/components/auth/SignInForm' - +'use client'; +import React, { useState } from 'react'; +import SignUpForm from '../components/auth/SignUpForm'; +import SignInForm from '@/components/auth/SignInForm'; export default function AuthPage() { - - const [mode, setMode] = useState<'sign_in' | 'sign_up'>('sign_up') + const [mode, setMode] = useState<'sign_in' | 'sign_up'>('sign_up'); function switchMode() { if (mode === 'sign_in') { - setMode('sign_up') + setMode('sign_up'); } else { - setMode('sign_in') + setMode('sign_in'); } } @@ -26,20 +24,27 @@ export default function AuthPage() { alt="Your Company" />

- {mode == 'sign_in' ? 'Sign in to your account' : 'Create an account'} + {mode == 'sign_in' + ? 'Sign in to your account' + : 'Create an account'}

- ) + ); } diff --git a/src/pages/forms/fill.tsx b/src/pages/forms/fill.tsx index 40a265d..664f361 100644 --- a/src/pages/forms/fill.tsx +++ b/src/pages/forms/fill.tsx @@ -4,7 +4,6 @@ import { FAKE_SCHEMA, PROMPT_FILL } from '@/prompts'; import { MessageUI } from '@/components/chat'; import { callLLM } from '@/utils'; - export default function CreateForm() { const schema = FAKE_SCHEMA; // TODO hydrate from route after page loads const systemPrompt = PROMPT_FILL(schema); @@ -19,15 +18,21 @@ export default function CreateForm() { const inputRef = useRef(null); // Initialize the ref const handleSubmit = async (userMessage?: string) => { - const messagesToSend = userMessage && userMessage.trim() ? [...messages, { - role: "user" as const, - content: userMessage.trim() - }] : messages; + const messagesToSend = + userMessage && userMessage.trim() + ? [ + ...messages, + { + role: 'user' as const, + content: userMessage.trim(), + }, + ] + : messages; setMessages(messagesToSend); setInputValue(''); setIsWaiting(true); const assistantResponse = await callLLM(systemPrompt, messagesToSend); - setMessages(prev => [...prev, assistantResponse]); + setMessages((prev) => [...prev, assistantResponse]); setIsWaiting(false); }; const handleCancel = () => { @@ -56,14 +61,18 @@ export default function CreateForm() {

Fill a form

{messages.map((message, index) => ( - + ))}
setInputValue(e.target.value)} + onChange={(e) => setInputValue(e.target.value)} disabled={isWaiting} onKeyPress={handleKeyPress} ref={inputRef} diff --git a/src/pages/forms/new.tsx b/src/pages/forms/new.tsx index 1ff2b8a..59545c8 100644 --- a/src/pages/forms/new.tsx +++ b/src/pages/forms/new.tsx @@ -1,11 +1,72 @@ -import React, { useState } from 'react'; +import { User } from '@/types'; +import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; +import { useSessionContext } from '@supabase/auth-helpers-react'; +import { useEffect, useState } from 'react'; +import { v4 } from 'uuid'; +import { Database } from '../../../types/supabase'; +import { useRouter } from 'next/router'; +import { getUserFromSupabase } from '@/utils'; -export default function CreateForm() { +export default function CreateFormComponent() { + const [desiredFields, setDesiredFields] = useState(''); + const { isLoading, session, error } = useSessionContext(); + const supabase = createClientComponentClient(); + const [user, setUser] = useState(null); + const { push } = useRouter(); + + useEffect(() => { + if (!isLoading && !session) { + push('/auth'); + } + if (!isLoading && session) { + getUserFromSupabase(session, supabase, setUser); + } + }, [isLoading, session]); + + const handleCreateForm = async () => { + console.log(`Creating form with desired fields: ${desiredFields}`); + if (!user) { + console.error('User is not set.'); + return; + } + + const form = { + id: v4(), + user_id: user.id, + desired_fields_schema: desiredFields, + }; + const { error } = await supabase.from('forms').insert(form); + + if (error) { + console.error(`Error creating form`, { form, error }); + } else { + console.log('Successfully created form', form); + } + }; return ( -
-

Create a Form

-

[coming soon]

+
+

Create Form

+ {user ? ( + <> + setDesiredFields(e.target.value)} + /> +

Create Form

+ + + ) : ( +

Loading user...

+ )}
); } diff --git a/src/pages/home.tsx b/src/pages/home.tsx index ef5e4bd..4812601 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -1,61 +1,34 @@ -import React, { useState } from 'react' -import { useEffect } from 'react'; -import { useSessionContext } from '@supabase/auth-helpers-react' -import { useRouter } from 'next/router'; import AppShell from '@/components/home/AppShell'; -import Spinner from '@/components/home/Spinner'; import ErrorMode from '@/components/home/ErrorMode'; -import { Database } from '../../types/supabase'; +import Spinner from '@/components/home/Spinner'; +import { User } from '@/types'; +import { getUserFromSupabase } from '@/utils'; import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; - -type User = Database['public']['Tables']['users']['Row'] +import { useSessionContext } from '@supabase/auth-helpers-react'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { Database } from '../../types/supabase'; export default function AuthPage() { const { isLoading, session, error } = useSessionContext(); - const supabase = createClientComponentClient() + const supabase = createClientComponentClient(); const [user, setUser] = useState(null); const { push } = useRouter(); - useEffect(() => { - const getUserFromSupabase = async () => { - if (!session) { - return; - } - const { data, error } = await supabase - .from('users') - .select() - .eq('id', session?.user.id) - .maybeSingle(); - if (error) { - console.error(error); - return; - } else if (data === null) { - console.error('No user found'); - return; - } else { - setUser(data); - } - } if (!isLoading && !session) { push('/auth'); } if (!isLoading && session) { - getUserFromSupabase(); + getUserFromSupabase(session, supabase, setUser); } }, [isLoading, session]); - + if (isLoading) { - return (); + return ; } else if (user) { - return () + return ; } else { - return () + return ; } - } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 00b12b8..c98fafb 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,22 +1,28 @@ -import { Inter } from 'next/font/google' -import Link from 'next/link' +import { Inter } from 'next/font/google'; +import Link from 'next/link'; -const inter = Inter({ subsets: ['latin'] }) +const inter = Inter({ subsets: ['latin'] }); export default function Home() { return (

- TalkForm AI + TalkForm AI

- Create and fill forms with chat. It just works. + Create and fill forms with chat.{' '} + + It just works. +

- + Create a form ›
- ) + ); } diff --git a/src/prompts.ts b/src/prompts.ts index 17394f3..898386c 100644 --- a/src/prompts.ts +++ b/src/prompts.ts @@ -1,4 +1,4 @@ -export const PROMPT_BUILD = `TODO` +export const PROMPT_BUILD = `TODO`; export function PROMPT_FILL(schema: string) { return `You are FormGPT, a helpful, honest, and harmless AI assistant helping gather information from users and using it to populate forms. Your job: Given a form schema to populate, continue your conversation with the user until you have enough information to fill out the form. @@ -24,7 +24,6 @@ ${schema} `; } - export const FAKE_SCHEMA = ` { "rsvpForm": { @@ -69,4 +68,4 @@ export const FAKE_SCHEMA = ` ] } } -` \ No newline at end of file +`; diff --git a/src/types.ts b/src/types.ts index 530d169..cd8b121 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,11 +1,15 @@ -import OpenAI from 'openai'; +import type OpenAI from 'openai'; +import type { Database } from '../types/supabase'; export type LLMRequest = { - completion_create: OpenAI.Chat.CompletionCreateParamsNonStreaming -} + completion_create: OpenAI.Chat.CompletionCreateParamsNonStreaming; +}; export type LLMResponse = { - completion: OpenAI.Chat.Completions.ChatCompletion -} + completion: OpenAI.Chat.Completions.ChatCompletion; +}; -export type ChatMessage = OpenAI.Chat.Completions.CreateChatCompletionRequestMessage \ No newline at end of file +export type ChatMessage = + OpenAI.Chat.Completions.CreateChatCompletionRequestMessage; + +export type User = Database['public']['Tables']['users']['Row']; diff --git a/src/utils.ts b/src/utils.ts index ca03a09..4deb45e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,21 +1,54 @@ -import { ChatMessage, LLMRequest, LLMResponse } from "@/types"; +import { ChatMessage, LLMRequest, LLMResponse, User } from '@/types'; +import { + Session, + SupabaseClient, + createClientComponentClient, +} from '@supabase/auth-helpers-nextjs'; +import { Database } from '../types/supabase'; -export const callLLM = async (systemPrompt: string, messages: ChatMessage[]) => { +export const callLLM = async ( + systemPrompt: string, + messages: ChatMessage[] +) => { const data: LLMRequest = { completion_create: { - model: "gpt-3.5-turbo", + model: 'gpt-3.5-turbo', temperature: 0, - messages: [{ role: "system", content: systemPrompt }, ...messages], + messages: [{ role: 'system', content: systemPrompt }, ...messages], }, }; - const response = await fetch("/api/llm", { - method: "POST", + const response = await fetch('/api/llm', { + method: 'POST', body: JSON.stringify(data), headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, }); const json: LLMResponse = await response.json(); const text = json.completion.choices[0].message; return text; }; + +export async function getUserFromSupabase( + session: Session | null, + supabase: SupabaseClient, + setUser: React.Dispatch> +): Promise { + if (!session) { + return; + } + const { data, error } = await supabase + .from('users') + .select() + .eq('id', session?.user.id) + .maybeSingle(); + if (error) { + console.error(error); + return; + } else if (data === null) { + console.error('No user found'); + return; + } else { + setUser(data); + } +} diff --git a/tailwind.config.ts b/tailwind.config.ts index a46f0b4..19ddf04 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,4 +1,4 @@ -import type { Config } from 'tailwindcss' +import type { Config } from 'tailwindcss'; const config: Config = { content: [ @@ -15,8 +15,6 @@ const config: Config = { }, }, }, - plugins: [ - require('@tailwindcss/forms'), - ], -} -export default config + plugins: [require('@tailwindcss/forms')], +}; +export default config; diff --git a/types/supabase.ts b/types/supabase.ts index d704adc..9c0c5d2 100644 --- a/types/supabase.ts +++ b/types/supabase.ts @@ -4,115 +4,115 @@ export type Json = | boolean | null | { [key: string]: Json | undefined } - | Json[] + | Json[]; export interface Database { public: { Tables: { forms: { Row: { - created_at: string | null - desired_fields_schema: string - id: string - updated_at: string | null - user_id: string | null - } + created_at: string | null; + desired_fields_schema: string; + id: string; + updated_at: string | null; + user_id: string | null; + }; Insert: { - created_at?: string | null - desired_fields_schema: string - id: string - updated_at?: string | null - user_id?: string | null - } + created_at?: string | null; + desired_fields_schema: string; + id: string; + updated_at?: string | null; + user_id?: string | null; + }; Update: { - created_at?: string | null - desired_fields_schema?: string - id?: string - updated_at?: string | null - user_id?: string | null - } + created_at?: string | null; + desired_fields_schema?: string; + id?: string; + updated_at?: string | null; + user_id?: string | null; + }; Relationships: [ { - foreignKeyName: "forms_user_id_fkey" - columns: ["user_id"] - referencedRelation: "users" - referencedColumns: ["id"] - } - ] - } + foreignKeyName: 'forms_user_id_fkey'; + columns: ['user_id']; + referencedRelation: 'users'; + referencedColumns: ['id']; + }, + ]; + }; responses: { Row: { - created_at: string | null - form_id: string | null - id: string - is_complete: boolean - results: Json - updated_at: string | null - } + created_at: string | null; + form_id: string | null; + id: string; + is_complete: boolean; + results: Json; + updated_at: string | null; + }; Insert: { - created_at?: string | null - form_id?: string | null - id: string - is_complete: boolean - results: Json - updated_at?: string | null - } + created_at?: string | null; + form_id?: string | null; + id: string; + is_complete: boolean; + results: Json; + updated_at?: string | null; + }; Update: { - created_at?: string | null - form_id?: string | null - id?: string - is_complete?: boolean - results?: Json - updated_at?: string | null - } + created_at?: string | null; + form_id?: string | null; + id?: string; + is_complete?: boolean; + results?: Json; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "responses_form_id_fkey" - columns: ["form_id"] - referencedRelation: "forms" - referencedColumns: ["id"] - } - ] - } + foreignKeyName: 'responses_form_id_fkey'; + columns: ['form_id']; + referencedRelation: 'forms'; + referencedColumns: ['id']; + }, + ]; + }; users: { Row: { - avatar_url: string - created_at: string | null - email: string - full_name: string - id: string - updated_at: string | null - } + avatar_url: string; + created_at: string | null; + email: string; + full_name: string; + id: string; + updated_at: string | null; + }; Insert: { - avatar_url: string - created_at?: string | null - email: string - full_name: string - id: string - updated_at?: string | null - } + avatar_url: string; + created_at?: string | null; + email: string; + full_name: string; + id: string; + updated_at?: string | null; + }; Update: { - avatar_url?: string - created_at?: string | null - email?: string - full_name?: string - id?: string - updated_at?: string | null - } - Relationships: [] - } - } + avatar_url?: string; + created_at?: string | null; + email?: string; + full_name?: string; + id?: string; + updated_at?: string | null; + }; + Relationships: []; + }; + }; Views: { - [_ in never]: never - } + [_ in never]: never; + }; Functions: { - [_ in never]: never - } + [_ in never]: never; + }; Enums: { - [_ in never]: never - } + [_ in never]: never; + }; CompositeTypes: { - [_ in never]: never - } - } + [_ in never]: never; + }; + }; } diff --git a/yarn.lock b/yarn.lock index 29bb706..18dd6b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -362,6 +362,11 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== +"@types/uuid@^9.0.2": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.2.tgz#ede1d1b1e451548d44919dc226253e32a6952c4b" + integrity sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ== + "@types/websocket@^1.0.3": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.6.tgz#ec8dce5915741632ac3a4b1f951b6d4156e32d03" @@ -2794,6 +2799,11 @@ util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + watchpack@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"