Skip to content

Commit

Permalink
ui settings wip (#9)
Browse files Browse the repository at this point in the history
* ui settings wip

* a

* done
  • Loading branch information
BrianP8701 authored Oct 14, 2024
1 parent ff4d0b1 commit 4cdad23
Show file tree
Hide file tree
Showing 43 changed files with 1,218 additions and 187 deletions.
10 changes: 5 additions & 5 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { TooltipProvider } from '@/components/ui/tooltip'
import './App.css'
import HomePage from './views/HomePage'
import { ApolloClientProvider } from './providers/ApolloClientProvider'
import MainLayout from '@/components/layouts/MainLayout'
import AuthWrapper from './components/custom/AuthWrapper'
import { ThemeProvider } from './providers/ThemeProvider'

const App = () => {
return (
Expand All @@ -29,12 +29,12 @@ const Providers = (props: PropsWithChildren<NonNullable<unknown>>) => {
<ClerkProvider publishableKey={clerkPubKey}>
<ClerkLoaded>
<ApolloClientProvider url={import.meta.env.VITE_GRAPHQL_URL}>
<TooltipProvider>
<MainLayout>
<ThemeProvider>
<TooltipProvider>
{/* Remove the WebSocketHandler component from here */}
{props.children}
</MainLayout>
</TooltipProvider>
</TooltipProvider>
</ThemeProvider>
</ApolloClientProvider>
</ClerkLoaded>
</ClerkProvider>
Expand Down
41 changes: 41 additions & 0 deletions client/src/components/custom/CardList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// src/components/custom/CardList.tsx
import * as React from 'react'
import { cn } from '@/utils/cn'
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card'

type CardProps = {
title?: string
description?: string
footer?: React.ReactNode
headerRight?: React.ReactNode
content?: React.ReactNode
contentClassName?: string // Added contentClassName prop
className?: string
}

type CardListProps = {
cards: CardProps[]
className?: string
}

export default function CardList({ cards, className }: CardListProps) {
return (
<div className={cn('w-full space-y-4', className)}>
{cards.map((card, index) => (
<Card key={index} className={cn('flex flex-col', card.className)}>
{(card.title || card.description || card.headerRight) && (
<CardHeader>
<div className='flex items-center justify-between'>
{card.title && <CardTitle>{card.title}</CardTitle>}
{card.headerRight && <div>{card.headerRight}</div>}
</div>
{card.description && <CardDescription>{card.description}</CardDescription>}
</CardHeader>
)}
{card.content && <CardContent className={card.contentClassName}>{card.content}</CardContent>}
{card.footer && <CardFooter>{card.footer}</CardFooter>}
</Card>
))}
</div>
)
}
6 changes: 3 additions & 3 deletions client/src/components/custom/DialogPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ interface DialogPreviewProps {

export default function DialogPreview({ previewComponent, dialogContent, dialogProps }: DialogPreviewProps) {
return (
<div className='relative w-full h-full bg-neutral-800 rounded-xl'>
<div className='relative w-full h-full bg-secondary rounded-xl'>
<div className='w-full h-full'>{previewComponent}</div>
<Dialog>
<DialogTrigger asChild>
<Button className='absolute top-2 right-2 px-1 py-2 z-30' variant='ghost'>
<Expand size={20} />
<Expand size={20} strokeWidth={1} />
</Button>
</DialogTrigger>
<DialogContent className='w-[95vw] h-[95vh] max-w-[95vw] p-0 rounded-xl bg-neutral-800'>
<DialogContent className='w-[95vw] h-[95vh] max-w-[95vw] p-0 rounded-xl bg-secondary'>
{React.cloneElement(dialogContent, { ...dialogProps, isDialogMode: true })}
</DialogContent>
</Dialog>
Expand Down
108 changes: 108 additions & 0 deletions client/src/components/custom/PanelLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// src/components/custom/PanelLayout.tsx
import React from 'react'
import { PanelNode, PanelNodeCreateInput, SplitDirectionEnum } from '@/graphql/generated/graphql'
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from '@/components/ui/resizable'
import { cn } from '@/utils/cn'

interface PanelLayoutProps {
nodes: (PanelNodeCreateInput | PanelNode)[]
rootNodeId: string
renderContent: (node: PanelNodeCreateInput | PanelNode) => React.ReactNode
showBorders?: boolean
className?: string
}

export function PanelLayout({ nodes, rootNodeId, renderContent, showBorders = true, className }: PanelLayoutProps) {
// Create a mapping from node IDs to nodes for quick access
const nodeMap = React.useMemo(() => {
const map: { [id: string]: PanelNodeCreateInput | PanelNode } = {}
nodes.forEach(node => {
if (node.id) {
map[node.id] = node
}
})
return map
}, [nodes])

const renderNode = (
nodeId: string,
parentSplit: SplitDirectionEnum | null = null,
position: 'first' | 'second' | null = null
): React.ReactNode => {
const node = nodeMap[nodeId]
if (!node) return null

if (node.split) {
const direction = node.split === SplitDirectionEnum.Horizontal ? 'horizontal' : 'vertical'

// Determine border classes based on position and showBorders prop
let borderClasses = ''
if (showBorders) {
if (parentSplit === SplitDirectionEnum.Horizontal) {
if (position === 'first') {
borderClasses = 'border-r'
}
} else if (parentSplit === SplitDirectionEnum.Vertical) {
if (position === 'first') {
borderClasses = 'border-b'
}
} else {
borderClasses = 'border'
}
}

const firstChildNodeId = node.firstChildId
const secondChildNodeId = node.secondChildId

// Ensure ResizablePanelGroup and ResizablePanel have correct flex properties
return (
<ResizablePanelGroup
key={node.id}
direction={direction}
className={borderClasses}
style={{ flex: 1, display: 'flex', flexDirection: direction === 'horizontal' ? 'row' : 'column' }}
>
<ResizablePanel style={{ flex: 1, display: 'flex' }}>
{firstChildNodeId ? renderNode(firstChildNodeId, node.split, 'first') : null}
</ResizablePanel>
<ResizableHandle />
<ResizablePanel style={{ flex: 1, display: 'flex' }}>
{secondChildNodeId ? renderNode(secondChildNodeId, node.split, 'second') : null}
</ResizablePanel>
</ResizablePanelGroup>
)
} else {
// Leaf node
let borderClasses = ''
if (showBorders) {
if (parentSplit === SplitDirectionEnum.Horizontal) {
if (position === 'first') {
borderClasses = 'border-r'
}
} else if (parentSplit === SplitDirectionEnum.Vertical) {
if (position === 'first') {
borderClasses = 'border-b'
}
} else {
borderClasses = 'border'
}
}

return (
<div
key={node.id}
className={cn(borderClasses, 'flex')}
style={{ flex: 1, position: 'relative', display: 'flex', flexDirection: 'column' }}
>
{renderContent(node)}
</div>
)
}
}

return (
<div className={cn('flex overflow-hidden', className)} style={{ flex: 1, position: 'relative' }}>
{renderNode(rootNodeId)}
</div>
)
}
25 changes: 7 additions & 18 deletions client/src/components/custom/SelectTheme.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
'use client'

import * as React from 'react'
import { Palette } from 'lucide-react'
import { useTheme } from 'next-themes'

import { Button } from '@/components/ui/button'
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'

export default function SelectTheme() {
const { setTheme, resolvedTheme } = useTheme()

React.useEffect(() => {
if (resolvedTheme) {
document.documentElement.classList.forEach(className => {
if (className.endsWith('_theme')) {
document.documentElement.classList.remove(className)
}
})
document.documentElement.classList.add(resolvedTheme)
}
}, [resolvedTheme])
const { setTheme } = useTheme()

return (
<DropdownMenu>
Expand All @@ -30,17 +18,18 @@ export default function SelectTheme() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align='end'>
<DropdownMenuItem onClick={() => setTheme('snow_theme')}>Snow</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('snow')}>Snow</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('midnight')}>Midnight</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('neutral')}>Neutral</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('ice')}>Ice</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('volcano')}>Volcano</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('green')}>Green</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('elixir')}>Elixir</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('forest')}>Forest</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('red')}>Red</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('blue')}>Blue</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('purple')}>Purple</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('concrete')}>Concrete</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('green_theme')}>Green</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('red_theme')}>Red</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('blue_theme')}>Blue</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('purple_theme')}>Purple</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ import { Button } from '@/components/ui/button'

interface ChatSidebarProps {
options: { value: string; label: string }[]
selectedChatId: string | null
setSelectedChatId: (value: string | null) => void
selectedOptionId: string | null
setSelectedOptionId: (value: string | null) => void
}

const ChatSidebar: React.FC<ChatSidebarProps> = ({ options, selectedChatId, setSelectedChatId }) => {
const SlideSidebar: React.FC<ChatSidebarProps> = ({ options, selectedOptionId, setSelectedOptionId }) => {
return (
<div className='bg-background h-full p-4 rounded-xl'>
<div className='mt-8'>
{options.map(option => (
<Button
key={option.value}
className={`w-full justify-start py-2 px-4 hover:bg-accent hover:text-accent-foreground rounded-xl ${selectedChatId === option.value ? 'bg-accent text-accent-foreground' : ''}`}
onClick={() => setSelectedChatId(option.value)}
className={`w-full justify-start py-2 px-4 hover:bg-accent hover:text-accent-foreground rounded-xl ${selectedOptionId === option.value ? 'bg-accent text-accent-foreground' : ''}`}
onClick={() => setSelectedOptionId(option.value)}
variant='ghost'
>
{option.label}
Expand All @@ -26,4 +26,4 @@ const ChatSidebar: React.FC<ChatSidebarProps> = ({ options, selectedChatId, setS
)
}

export default ChatSidebar
export default SlideSidebar
2 changes: 1 addition & 1 deletion client/src/components/custom/graph/GraphVisualizer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export const GraphVisualizer: React.FC<GraphVisualizerProps> = ({ nodes, edges,
}, [])

return (
<div ref={containerRef} className='w-full h-full rounded-xl'>
<div ref={containerRef} className='relative flex flex-col h-full rounded-xl bg-secondary'>
{graphData.nodes.length > 0 && (
<Graph key={key} graph={graphData} options={options} style={{ width: '100%', height: '100%' }} />
)}
Expand Down
23 changes: 0 additions & 23 deletions client/src/components/layouts/MainLayout.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions client/src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef<
<DialogPrimitive.Overlay
ref={ref}
className={cn(
'fixed inset-0 z-50 bg-black/90 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
'fixed inset-0 z-50 bg-black/90 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 pointer-events-none',
className
)}
{...props}
Expand All @@ -34,11 +34,11 @@ const DialogContent = React.forwardRef<
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<div className='fixed inset-0 z-50 bg-black/50 backdrop-blur-sm' aria-hidden='true' />
<DialogPrimitive.Content
ref={ref}
className={cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-xl',
'fixed left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-xl',
className
)}
{...props}
Expand Down
5 changes: 3 additions & 2 deletions client/src/components/ui/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CaretSortIcon, CheckIcon, ChevronDownIcon, ChevronUpIcon } from '@radix
import * as SelectPrimitive from '@radix-ui/react-select'

import { cn } from '@/utils/cn'
import { prettifyString } from '@/utils/strings'

const Select = SelectPrimitive.Root

Expand All @@ -19,7 +20,7 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
'flex h-9 items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
'flex h-9 items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 hover:bg-accent hover:text-accent-foreground',
className
)}
{...props}
Expand Down Expand Up @@ -115,7 +116,7 @@ const SelectItem = React.forwardRef<
<CheckIcon className='h-4 w-4' />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
<SelectPrimitive.ItemText>{prettifyString(children as string)}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName
Expand Down
Loading

0 comments on commit 4cdad23

Please sign in to comment.