Skip to content

Commit

Permalink
Merge pull request #32 from supabase-community/feat/themes
Browse files Browse the repository at this point in the history
Themes support and improved UI
  • Loading branch information
gregnr authored Aug 9, 2024
2 parents 11dde05 + 3cf8f98 commit ad70e55
Show file tree
Hide file tree
Showing 26 changed files with 954 additions and 681 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ next-env.d.ts
dbs/
tls/
dist/

.env
397 changes: 68 additions & 329 deletions apps/postgres-new/app/globals.css

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions apps/postgres-new/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import 'katex/dist/katex.min.css'
import './globals.css'

import 'katex/dist/katex.min.css'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import { Inter as FontSans } from 'next/font/google'
import Layout from '~/components/layout'
import Providers from '~/components/providers'
import { cn } from '~/lib/utils'

const inter = Inter({ subsets: ['latin'] })
const fontSans = FontSans({
subsets: ['latin'],
variable: '--font-sans',
})

export const metadata: Metadata = {
title: 'Postgres Sandbox',
Expand All @@ -21,7 +23,7 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={cn(inter.className)}>
<body className={cn('bg-background font-sans antialiased', fontSans.variable)}>
<Providers>
<Layout>{children}</Layout>
</Providers>
Expand Down
11 changes: 8 additions & 3 deletions apps/postgres-new/components/chat-message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function ChatMessage({ message, isLast }: ChatMessageProps) {
x: 0,
},
}}
className="self-end px-5 py-2.5 text-base rounded-3xl bg-neutral-100 whitespace-pre-wrap"
className="self-end px-5 py-2.5 text-base rounded-3xl bg-border text-foreground whitespace-pre-wrap"
>
{message.content}
</m.div>
Expand All @@ -50,7 +50,7 @@ function ChatMessage({ message, isLast }: ChatMessageProps) {
remarkPlugins={[remarkGfm, [remarkMath, { singleDollarTextMath: false }]]}
rehypePlugins={[[rehypeKatex, { output: 'html' }]]}
components={{ ...markdownComponents, img: () => null }}
className="prose [&_.katex-display>.katex]:text-left"
className="prose prose-xs text-base [&_.katex-display>.katex]:text-left"
>
{message.content}
</ReactMarkdown>
Expand Down Expand Up @@ -111,8 +111,13 @@ const NextImageHandler = (props: any) => {
}

const markdownComponents = {
mono: (props: any) => <code className="text-sm">{props.children}</code>,
mono: (props: any) => <code className="text-sm not-prose">{props.children}</code>,
code: (props: any) => <CodeBlock {...props} />,
pre: (props: any) => (
<pre className="not-prose">
<CodeBlock {...props} />
</pre>
),
img: (props: any) => NextImageHandler(props),
Image: (props: any) => NextImageHandler(props),
}
23 changes: 18 additions & 5 deletions apps/postgres-new/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function getInitialMessages(tables: TablesData): Message[] {

export default function Chat() {
const { user, isLoadingUser } = useApp()
const [inputFocusState, setInputFocusState] = useState(false)

const {
databaseId,
Expand Down Expand Up @@ -125,7 +126,7 @@ export default function Chat() {
cursorElement: (
<m.div
layoutId={nextMessageId}
className="px-5 py-2.5 text-base rounded-full bg-neutral-100 flex gap-2 items-center shadow-xl z-50"
className="px-5 py-2.5 text-foreground rounded-full bg-border flex gap-2 items-center shadow-xl z-50"
>
<Paperclip size={14} /> Add file to chat
</m.div>
Expand Down Expand Up @@ -343,7 +344,11 @@ export default function Chat() {
)}
</AnimatePresence>
<form
className="flex items-end py-2 px-3 rounded-[28px] bg-neutral-100 w-full max-w-4xl"
className={cn(
'flex py-2 px-3 rounded-[28px] bg-muted/50 border w-full max-w-4xl items-center gap-3',
inputFocusState && 'border-muted-foreground',
'transition'
)}
onSubmit={handleFormSubmit}
>
{/*
Expand All @@ -366,8 +371,10 @@ export default function Chat() {
</m.div>
)}
<Button
className="w-8 h-8 p-1.5 my-1 bg-inherit transition-colors"
type="button"
variant={'ghost'}
className="w-8 h-8 text-muted-foreground hover:text-foreground focus:text-foreground"
size="icon"
onClick={(e) => {
e.preventDefault()

Expand Down Expand Up @@ -400,17 +407,23 @@ export default function Chat() {
}}
disabled={isLoading || !user}
>
<Paperclip size={20} />
<Paperclip size={16} strokeWidth={1.3} />
</Button>
<textarea
ref={inputRef}
id="input"
name="prompt"
autoComplete="off"
className="flex-grow border-none focus-visible:ring-0 text-base bg-inherit placeholder:text-neutral-400 resize-none"
className="flex-grow border-none focus-visible:ring-0 text-base placeholder:text-muted-foreground/50 bg-transparent resize-none outline-none"
value={input}
onChange={handleInputChange}
placeholder="Message AI or write SQL"
onFocus={(e) => {
setInputFocusState(true)
}}
onBlur={(e) => {
setInputFocusState(false)
}}
autoFocus
disabled={!user}
rows={Math.min(input.split('\n').length, 10)}
Expand Down
33 changes: 25 additions & 8 deletions apps/postgres-new/components/code-accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DatabaseZap } from 'lucide-react'
import { CircleX, DatabaseZap } from 'lucide-react'
import {
Accordion,
AccordionContent,
Expand Down Expand Up @@ -28,26 +28,43 @@ export default function CodeAccordion({
<AccordionItem
value="item-1"
className={cn(
'border-2 border-neutral-100 bg-neutral-50 px-3 py-2 rounded-md',
error ? 'bg-destructive-300' : undefined,
'border rounded-md overflow-hidden',
error ? 'border-destructive' : undefined,
className
)}
>
<AccordionTrigger className="p-0 gap-2">
<AccordionTrigger
className={cn(
'p-0 gap-2 px-3 py-2',
error
? 'bg-destructive border-destructive [&_svg]:text-destructive-foreground'
: undefined
)}
>
<div className="flex gap-2 items-center font-normal text-lighter text-sm">
<DatabaseZap size={14} />
{title}
{error ? (
<CircleX
size={14}
className={cn('text-muted-foreground', error && 'text-destructive-foreground')}
/>
) : (
<DatabaseZap
size={14}
className={cn('text-muted-foreground', error && 'text-destructive-foreground')}
/>
)}
<span className={cn(error ? 'text-destructive-foreground' : undefined)}>{title}</span>
</div>
</AccordionTrigger>
<AccordionContent className="py-2 [&_>div]:pb-0 flex flex-col gap-2">
<AccordionContent className="py-2 [&_>div]:pb-0 flex flex-col gap-2 bg-background px-3">
<CodeBlock
className={cn(`language-${language}`, 'border-none px-0 pb-4 !bg-inherit')}
hideLineNumbers
hideCopy
>
{code}
</CodeBlock>
{error && <div className="text-destructive-600 text-xs">{error}</div>}
{error && <div className="text-red-600 text-xs">{error}</div>}
</AccordionContent>
</AccordionItem>
</Accordion>
Expand Down
75 changes: 49 additions & 26 deletions apps/postgres-new/components/ide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { cn } from '~/lib/utils'
import { useApp } from './app-provider'
import SchemaGraph from './schema/graph'
import { useWorkspace } from './workspace'
import { buttonVariants } from './ui/button'

const initialMigrationSql = '-- Migrations will appear here as you chat with AI\n'
const initialSeedSql = '-- Seeds will appear here as you chat with AI\n'
Expand Down Expand Up @@ -105,28 +106,56 @@ export default function IDE({ children, className }: IDEProps) {
value={tab}
onValueChange={(tab) => setTab(tabsSchema.parse(tab))}
>
<TabsList className="grid w-full grid-cols-3 lg:grid-cols-2">
<TabsList className="grid w-full grid-cols-3 lg:grid-cols-2 !h-min bg-muted">
{isSmallBreakpoint && (
<TabsTrigger value="chat" className="flex items-center gap-1">
<TabsTrigger
value="chat"
className={cn(
buttonVariants({ variant: tab === 'chat' ? 'default' : 'ghost' }),
tab === 'chat' && '!shadow-sm',
'gap-2'
)}
>
<MessageSquareMore size={14} />
<span className="hidden xs:inline">Chat</span>
<span className="hidden sm:inline">Chat</span>
</TabsTrigger>
)}
<TabsTrigger value="diagram" className="flex items-center gap-1">
<TabsTrigger
value="diagram"
className={cn(
buttonVariants({ variant: tab === 'diagram' ? 'default' : 'ghost' }),
tab === 'diagram' && '!shadow-sm',
'gap-2'
)}
>
<Workflow size={14} />
<span className="hidden xs:inline">Diagram</span>
<span className="hidden sm:inline">Diagram</span>
</TabsTrigger>
<TabsTrigger value="migrations" className="flex items-center gap-1">
<TabsTrigger
value="migrations"
className={cn(
buttonVariants({ variant: tab === 'migrations' ? 'default' : 'ghost' }),
tab === 'migrations' && '!shadow-sm',
'gap-2'
)}
>
<FileCode size={14} />
<span className="hidden xs:inline">Migrations</span>
<span className="hidden sm:inline">Migrations</span>
</TabsTrigger>
{/* Temporarily hide seeds until we get pg_dump working */}
{false && (
<TabsTrigger value="seeds" className="flex items-center gap-1">
{/* {false && (
<TabsTrigger
value="seeds"
className={cn(
buttonVariants({ variant: tab === 'seeds' ? 'default' : 'ghost' }),
tab === 'seeds' && '!shadow-sm',
'gap-2'
)}
>
<Sprout size={14} />
<span className="hidden xs:inline">Seeds</span>
<span className="hidden sm:inline">Seeds</span>
</TabsTrigger>
)}
)} */}
</TabsList>

{isSmallBreakpoint && (
Expand Down Expand Up @@ -234,22 +263,16 @@ export default function IDE({ children, className }: IDEProps) {
}

function Footer() {
const { pgliteVersion, pgVersion } = useApp()
return (
<div className="flex flex-col pb-1 text-xs text-neutral-500 text-center justify-center">
{pgliteVersion && (
<span>
<a
className="underline"
href="https://github.com/electric-sql/pglite"
target="_blank"
rel="noopener noreferrer"
>
PGlite
</a>{' '}
{pgliteVersion} {pgVersion && <>(PG {pgVersion})</>}
</span>
)}
<div className="flex flex-row gap-1 pb-1 text-xs text-neutral-500 text-center justify-center">
<a
className="underline cursor-pointer"
href="https://github.com/supabase-community/postgres-new"
target="_blank"
rel="noopener noreferrer"
>
Learn about postgres.new
</a>
</div>
)
}
4 changes: 2 additions & 2 deletions apps/postgres-new/components/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ export default function Layout({ children }: LayoutProps) {
there.
</div>
)}
<div className="flex-1 flex flex-col lg:flex-row min-h-0">
<main className="flex-1 flex flex-col lg:flex-row min-h-0">
{/* TODO: make sidebar available on mobile */}
{!isSmallBreakpoint && <Sidebar />}
<m.div layout="position" className="w-full h-full min-w-0 min-h-0">
{children}
</m.div>
</div>
</main>
</div>
</TooltipProvider>
</LazyMotion>
Expand Down
33 changes: 25 additions & 8 deletions apps/postgres-new/components/markdown-accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DatabaseZap } from 'lucide-react'
import { CircleX, Move3D } from 'lucide-react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import {
Expand Down Expand Up @@ -27,25 +27,42 @@ export default function MarkdownAccordion({
<AccordionItem
value="item-1"
className={cn(
'border-2 border-neutral-100 bg-neutral-50 px-3 py-2 rounded-md',
error ? 'bg-destructive-300' : undefined,
'border rounded-md overflow-hidden',
error ? 'border-destructive' : undefined,
className
)}
>
<AccordionTrigger className="p-0 gap-2">
<AccordionTrigger
className={cn(
'p-0 gap-2 px-3 py-2',
error
? 'bg-destructive border-destructive [&_svg]:text-destructive-foreground'
: undefined
)}
>
<div className="flex gap-2 items-center font-normal text-lighter text-sm">
<DatabaseZap size={14} />
{title}
{error ? (
<CircleX
size={14}
className={cn('text-muted-foreground', error && 'text-destructive-foreground')}
/>
) : (
<Move3D
size={14}
className={cn('text-muted-foreground', error && 'text-destructive-foreground')}
/>
)}
<span className={cn(error ? 'text-destructive-foreground' : undefined)}>{title}</span>
</div>
</AccordionTrigger>
<AccordionContent className="py-2 [&_>div]:pb-0 flex flex-col gap-2">
<AccordionContent className="py-2 [&_>div]:pb-0 flex flex-col gap-2 bg-background px-3">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
className="prose text-xs mt-2 [&_ul>li::before]:top-2 [&_ol>li::before]:top-0"
>
{content}
</ReactMarkdown>
{error && <div className="text-destructive-600 text-xs">{error}</div>}
{error && <div className="text-red-600 text-xs">{error}</div>}
</AccordionContent>
</AccordionItem>
</Accordion>
Expand Down
10 changes: 8 additions & 2 deletions apps/postgres-new/components/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
'use client'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ThemeProvider } from 'next-themes'

import { PropsWithChildren } from 'react'
import AppProvider from './app-provider'
import { ThemeProvider } from './theme-provider'

const queryClient = new QueryClient()

export default function Providers({ children }: PropsWithChildren) {
return (
// Force theme until we implement dark mode
<ThemeProvider forcedTheme="light">
<ThemeProvider
attribute="class"
defaultTheme="system"
storageKey="jonny"
disableTransitionOnChange
>
<QueryClientProvider client={queryClient}>
<AppProvider>{children}</AppProvider>
</QueryClientProvider>
Expand Down
Loading

0 comments on commit ad70e55

Please sign in to comment.