mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-10 07:27:57 -05:00
Cleaned up repo
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useCallback, useEffect } from 'react'
|
||||
import { BlockProps } from '../components/block'
|
||||
import { BlockProps } from '../components/block/block'
|
||||
|
||||
const ZOOM_SPEED = 0.005
|
||||
const MIN_ZOOM = 0.5
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import { AgentIcon, ApiIcon, ConditionalIcon } from '@/components/icons'
|
||||
import type { BlockConfig } from './blocks'
|
||||
|
||||
export interface BlockProps {
|
||||
title: string
|
||||
description: string
|
||||
type: 'agent' | 'api' | 'conditional'
|
||||
bgColor: string
|
||||
}
|
||||
|
||||
const BLOCK_ICONS = {
|
||||
agent: AgentIcon,
|
||||
api: ApiIcon,
|
||||
conditional: ConditionalIcon,
|
||||
} as const
|
||||
|
||||
export function Block({ title, description, type, bgColor }: BlockProps) {
|
||||
const Icon = BLOCK_ICONS[type]
|
||||
export type BlockProps = BlockConfig
|
||||
|
||||
export function Block({
|
||||
title,
|
||||
description,
|
||||
type,
|
||||
bgColor,
|
||||
icon: Icon,
|
||||
}: BlockProps) {
|
||||
const handleDragStart = (e: React.DragEvent) => {
|
||||
e.dataTransfer.setData(
|
||||
'application/json',
|
||||
@@ -32,7 +25,7 @@ export function Block({ title, description, type, bgColor }: BlockProps) {
|
||||
<div
|
||||
draggable
|
||||
onDragStart={handleDragStart}
|
||||
className="group flex items-center gap-3 rounded-lg border bg-card p-4 shadow-sm transition-colors hover:bg-accent/50 cursor-grab active:cursor-grabbing"
|
||||
className="group flex items-center gap-3 rounded-lg border bg-card p-4 shadow-sm transition-colors hover:bg-accent/50 cursor-pointer active:cursor-grabbing"
|
||||
>
|
||||
<div
|
||||
className="relative flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg"
|
||||
37
app/w/components/block/blocks.ts
Normal file
37
app/w/components/block/blocks.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { AgentIcon, ApiIcon, ConditionalIcon } from '@/components/icons'
|
||||
|
||||
export interface BlockConfig {
|
||||
type: string
|
||||
title: string
|
||||
description: string
|
||||
bgColor: string
|
||||
icon: any
|
||||
category: 'basic' | 'advanced'
|
||||
}
|
||||
|
||||
export const BLOCKS: BlockConfig[] = [
|
||||
{
|
||||
type: 'agent',
|
||||
title: 'Agent',
|
||||
description: 'Use any LLM',
|
||||
bgColor: '#7F2FFF',
|
||||
icon: AgentIcon,
|
||||
category: 'basic',
|
||||
},
|
||||
{
|
||||
type: 'api',
|
||||
title: 'API',
|
||||
description: 'Connect to any API',
|
||||
bgColor: '#2F55FF',
|
||||
icon: ApiIcon,
|
||||
category: 'basic',
|
||||
},
|
||||
{
|
||||
type: 'conditional',
|
||||
title: 'Conditional',
|
||||
description: 'Create branching logic',
|
||||
bgColor: '#FF972F',
|
||||
icon: ConditionalIcon,
|
||||
category: 'basic',
|
||||
},
|
||||
]
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { History, Bell, Play } from 'lucide-react'
|
||||
|
||||
export function WorkflowControlBar() {
|
||||
export function ControlBar() {
|
||||
return (
|
||||
<div className="flex h-16 w-full items-center justify-between bg-background px-6 border-b">
|
||||
{/* Left Section - Workflow Info */}
|
||||
@@ -24,7 +24,7 @@ export function WorkflowControlBar() {
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<History className="h-5 w-5" />
|
||||
<History />
|
||||
<span className="sr-only">Version History</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
@@ -37,7 +37,7 @@ export function WorkflowControlBar() {
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<Bell className="h-5 w-5" />
|
||||
<Bell />
|
||||
<span className="sr-only">Notifications</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
@@ -1,57 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { ToolbarTabs } from './toolbar-tabs'
|
||||
import { Block } from './block'
|
||||
|
||||
const BLOCK_COLORS = {
|
||||
agent: '#7F2FFF',
|
||||
api: '#2F55FF',
|
||||
conditional: '#FF972F',
|
||||
} as const
|
||||
|
||||
const BASIC_BLOCKS = [
|
||||
{
|
||||
type: 'agent',
|
||||
title: 'Agent',
|
||||
description: 'Use any LLM',
|
||||
bgColor: BLOCK_COLORS.agent,
|
||||
},
|
||||
{
|
||||
type: 'api',
|
||||
title: 'API',
|
||||
description: 'Connect to any API',
|
||||
bgColor: BLOCK_COLORS.api,
|
||||
},
|
||||
{
|
||||
type: 'conditional',
|
||||
title: 'Conditional',
|
||||
description: 'Create branching logic',
|
||||
bgColor: BLOCK_COLORS.conditional,
|
||||
},
|
||||
] as const
|
||||
|
||||
export function DesktopToolbar() {
|
||||
const [activeTab, setActiveTab] = useState<'basic' | 'advanced'>('basic')
|
||||
|
||||
return (
|
||||
<div className="fixed left-14 top-0 z-1 hidden h-full w-72 border-r bg-background sm:block">
|
||||
<ToolbarTabs activeTab={activeTab} onTabChange={setActiveTab} />
|
||||
|
||||
<div className="p-4">
|
||||
{activeTab === 'basic' ? (
|
||||
<div className="flex flex-col gap-3">
|
||||
{BASIC_BLOCKS.map((block) => (
|
||||
<Block key={block.type} {...block} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
{/* Advanced tab content */}
|
||||
Advanced Content Here
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { useTransition } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Spinner } from '@/components/icons'
|
||||
import { Search } from 'lucide-react'
|
||||
|
||||
export function SearchInput() {
|
||||
const router = useRouter()
|
||||
const [isPending, startTransition] = useTransition()
|
||||
|
||||
function searchAction(formData: FormData) {
|
||||
let value = formData.get('q') as string
|
||||
let params = new URLSearchParams({ q: value })
|
||||
startTransition(() => {
|
||||
router.replace(`/?${params.toString()}`)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<form action={searchAction} className="relative ml-auto flex-1 md:grow-0">
|
||||
<Search className="absolute left-2.5 top-[.75rem] h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
name="q"
|
||||
type="search"
|
||||
placeholder="Search..."
|
||||
className="w-full rounded-lg bg-background pl-8 md:w-[200px] lg:w-[336px]"
|
||||
/>
|
||||
{isPending && <Spinner />}
|
||||
</form>
|
||||
)
|
||||
}
|
||||
61
app/w/components/sidebar.tsx
Normal file
61
app/w/components/sidebar.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import Link from 'next/link'
|
||||
import { NavItem } from './nav-item'
|
||||
import {
|
||||
Home,
|
||||
ShoppingCart,
|
||||
Package,
|
||||
Users2,
|
||||
LineChart,
|
||||
Settings,
|
||||
PanelLeft,
|
||||
Package2,
|
||||
Plus,
|
||||
} from 'lucide-react'
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip'
|
||||
import { AgentIcon } from '@/components/icons'
|
||||
|
||||
export function Sidebar() {
|
||||
return (
|
||||
<aside className="fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex">
|
||||
<nav className="flex flex-col items-center gap-4 px-2 sm:py-5">
|
||||
<Link
|
||||
href="#"
|
||||
className="group flex h-8 w-8 items-center justify-center rounded-lg bg-[#7F2FFF]"
|
||||
>
|
||||
<AgentIcon className="text-white transition-all group-hover:scale-110 -translate-y-[0.5px] w-5 h-5" />
|
||||
<span className="sr-only">Sim Studio</span>
|
||||
</Link>
|
||||
|
||||
<NavItem href="#" label="Add Workflow">
|
||||
<Plus className="h-5 w-5" />
|
||||
</NavItem>
|
||||
|
||||
<NavItem href="#" label="Workflow 1">
|
||||
<div className="h-4 w-4 rounded-full bg-[#3972F6]" />
|
||||
</NavItem>
|
||||
|
||||
<NavItem href="#" label="Workflow 2">
|
||||
<div className="h-4 w-4 rounded-full bg-[#F639DD]" />
|
||||
</NavItem>
|
||||
</nav>
|
||||
<nav className="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Link
|
||||
href="#"
|
||||
className="flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8"
|
||||
>
|
||||
<Settings className="h-5 w-5" />
|
||||
<span className="sr-only">Settings</span>
|
||||
</Link>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">Settings</TooltipContent>
|
||||
</Tooltip>
|
||||
</nav>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
26
app/w/components/toolbar/toolbar.tsx
Normal file
26
app/w/components/toolbar/toolbar.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { ToolbarTabs } from './toolbar-tabs'
|
||||
import { Block } from '../block/block'
|
||||
import { BLOCKS } from '../block/blocks'
|
||||
|
||||
export function Toolbar() {
|
||||
const [activeTab, setActiveTab] = useState<'basic' | 'advanced'>('basic')
|
||||
|
||||
return (
|
||||
<div className="fixed left-14 top-0 z-1 hidden h-full w-72 border-r bg-background sm:block">
|
||||
<ToolbarTabs activeTab={activeTab} onTabChange={setActiveTab} />
|
||||
|
||||
<div className="p-4">
|
||||
<div className="flex flex-col gap-3">
|
||||
{BLOCKS.filter((block) => block.category === activeTab).map(
|
||||
(block) => (
|
||||
<Block key={block.type} {...block} />
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
import { Button } from '@/components/ui/button'
|
||||
// import { auth, signOut } from '@/lib/auth'
|
||||
import Image from 'next/image'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import Link from 'next/link'
|
||||
|
||||
export async function User() {
|
||||
// let session = await auth()
|
||||
// let user = session?.user
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="overflow-hidden rounded-full"
|
||||
>
|
||||
<Image
|
||||
// src={user?.image ?? '/placeholder-user.jpg'}
|
||||
src={'/placeholder-user.jpg'}
|
||||
width={36}
|
||||
height={36}
|
||||
alt="Avatar"
|
||||
className="overflow-hidden rounded-full"
|
||||
/>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>Settings</DropdownMenuItem>
|
||||
<DropdownMenuItem>Support</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
{/* {user ? (
|
||||
<DropdownMenuItem>
|
||||
<form
|
||||
action={async () => {
|
||||
'use server'
|
||||
await signOut()
|
||||
}}
|
||||
>
|
||||
<button type="submit">Sign Out</button>
|
||||
</form>
|
||||
</DropdownMenuItem>
|
||||
) : (
|
||||
<DropdownMenuItem>
|
||||
<Link href="/login">Sign In</Link>
|
||||
</DropdownMenuItem>
|
||||
)} */}
|
||||
<DropdownMenuItem>
|
||||
<Link href="/login">Sign In</Link>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
}
|
||||
159
app/w/layout.tsx
159
app/w/layout.tsx
@@ -1,33 +1,7 @@
|
||||
import Providers from './providers'
|
||||
import Link from 'next/link'
|
||||
import { NavItem } from './components/nav-item'
|
||||
import {
|
||||
Home,
|
||||
ShoppingCart,
|
||||
Package,
|
||||
Users2,
|
||||
LineChart,
|
||||
Settings,
|
||||
PanelLeft,
|
||||
Package2,
|
||||
Plus,
|
||||
} from 'lucide-react'
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetTrigger,
|
||||
SheetTitle,
|
||||
} from '@/components/ui/sheet'
|
||||
import Image from 'next/image'
|
||||
import { DesktopToolbar } from './components/desktop-toolbar'
|
||||
import { WorkflowControlBar } from './components/workflow-control-bar'
|
||||
import { AgentIcon } from '@/components/icons'
|
||||
import { Toolbar } from './components/toolbar/toolbar'
|
||||
import { ControlBar } from './components/control-bar'
|
||||
import { Sidebar } from './components/sidebar'
|
||||
|
||||
export default function WorkspaceLayout({
|
||||
children,
|
||||
@@ -36,125 +10,18 @@ export default function WorkspaceLayout({
|
||||
}) {
|
||||
return (
|
||||
<Providers>
|
||||
<main className="flex min-h-screen w-full flex-col bg-muted/40">
|
||||
<div className="flex">
|
||||
<DesktopNav />
|
||||
<DesktopToolbar />
|
||||
<div className="flex min-h-screen w-full flex-col bg-muted/40">
|
||||
<nav className="flex">
|
||||
<Sidebar />
|
||||
<Toolbar />
|
||||
<div className="fixed top-0 left-[344px] right-0 z-30">
|
||||
<WorkflowControlBar />
|
||||
<ControlBar />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col sm:gap-4 sm:pt-[56px] sm:pl-[344px]">
|
||||
<header className="sticky top-0 z-30 flex h-14 items-center border-b bg-background sm:static sm:hidden">
|
||||
<MobileNav />
|
||||
</header>
|
||||
<main className="grid flex-1 items-start gap-2 sm:py-0 md:gap-4 bg-muted/40">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</main>
|
||||
</nav>
|
||||
<main className="flex-1 grid items-start gap-2 sm:gap-4 sm:py-0 md:gap-4 sm:pt-[56px] sm:pl-[344px] bg-muted/40">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</Providers>
|
||||
)
|
||||
}
|
||||
|
||||
function DesktopNav() {
|
||||
return (
|
||||
<aside className="fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex">
|
||||
<nav className="flex flex-col items-center gap-4 px-2 sm:py-5">
|
||||
<Link
|
||||
href="#"
|
||||
className="group flex h-8 w-8 items-center justify-center rounded-lg bg-[#7F2FFF]"
|
||||
>
|
||||
<AgentIcon className="text-white transition-all group-hover:scale-110 -translate-y-[0.5px] w-5 h-5" />
|
||||
<span className="sr-only">Sim Studio</span>
|
||||
</Link>
|
||||
|
||||
<NavItem href="#" label="Add Workflow">
|
||||
<Plus className="h-5 w-5" />
|
||||
</NavItem>
|
||||
|
||||
<NavItem href="#" label="Workflow 1">
|
||||
<div className="h-4 w-4 rounded-full bg-[#3972F6]" />
|
||||
</NavItem>
|
||||
|
||||
<NavItem href="#" label="Workflow 2">
|
||||
<div className="h-4 w-4 rounded-full bg-[#F639DD]" />
|
||||
</NavItem>
|
||||
</nav>
|
||||
<nav className="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Link
|
||||
href="#"
|
||||
className="flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8"
|
||||
>
|
||||
<Settings className="h-5 w-5" />
|
||||
<span className="sr-only">Settings</span>
|
||||
</Link>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">Settings</TooltipContent>
|
||||
</Tooltip>
|
||||
</nav>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
||||
function MobileNav() {
|
||||
return (
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
<Button size="icon" variant="outline" className="sm:hidden">
|
||||
<PanelLeft className="h-5 w-5" />
|
||||
<span className="sr-only">Toggle Menu</span>
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left" className="sm:max-w-xs">
|
||||
<SheetTitle className="sr-only">Navigation Menu</SheetTitle>
|
||||
<nav className="grid gap-6 text-lg font-medium">
|
||||
<Link
|
||||
href="#"
|
||||
className="group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base"
|
||||
>
|
||||
<Package2 className="h-5 w-5 transition-all group-hover:scale-110" />
|
||||
<span className="sr-only">Vercel</span>
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Home className="h-5 w-5" />
|
||||
Dashboard
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<ShoppingCart className="h-5 w-5" />
|
||||
Orders
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="flex items-center gap-4 px-2.5 text-foreground"
|
||||
>
|
||||
<Package className="h-5 w-5" />
|
||||
Products
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Users2 className="h-5 w-5" />
|
||||
Customers
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<LineChart className="h-5 w-5" />
|
||||
Settings
|
||||
</Link>
|
||||
</nav>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user