Skip to content

Commit f5552b8

Browse files
committed
add agent create dialog
1 parent fc3d100 commit f5552b8

7 files changed

Lines changed: 245 additions & 15 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"@radix-ui/react-accordion": "^1.2.11",
2020
"@radix-ui/react-alert-dialog": "^1.1.14",
2121
"@radix-ui/react-avatar": "^1.1.10",
22+
"@radix-ui/react-dialog": "^1.1.14",
2223
"@radix-ui/react-dropdown-menu": "^2.1.15",
2324
"@radix-ui/react-label": "^2.1.7",
2425
"@radix-ui/react-popover": "^1.1.14",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Agent" ADD COLUMN "description" TEXT;

prisma/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ model Agent {
9393
user User @relation(fields: [userId], references: [id])
9494
userId String
9595
name String
96+
description String?
9697
createdAt DateTime @default(now())
9798
updatedAt DateTime @updatedAt
9899

src/app/dashboard/agents/page.tsx

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
'use client'
22
import { BotMessageSquare } from 'lucide-react'
33
import Link from 'next/link'
4+
import { useRouter } from 'next/navigation.js'
45
import { Button } from '@/components/ui/button'
6+
import {
7+
Dialog,
8+
DialogClose,
9+
DialogContent,
10+
DialogDescription,
11+
DialogFooter,
12+
DialogHeader,
13+
DialogTitle,
14+
DialogTrigger,
15+
} from '@/components/ui/dialog'
16+
import { Input } from '@/components/ui/input'
17+
import { Label } from '@/components/ui/label'
518

619
const agents: { id: number; name: string; description: string }[] = [
720
// {
@@ -12,13 +25,67 @@ const agents: { id: number; name: string; description: string }[] = [
1225
]
1326

1427
const AgentsPage = () => {
28+
const router = useRouter()
29+
30+
const createAgentHandler = (event: React.FormEvent<HTMLFormElement>) => {
31+
event.preventDefault()
32+
const formData = new FormData(event.currentTarget)
33+
const name = formData.get('name') as string
34+
const description = formData.get('description') as string
35+
36+
// Here you would typically send the data to your backend to create the agent
37+
console.log('Creating agent:', { name, description })
38+
39+
// Reset the form or close the dialog after creation
40+
event.currentTarget.reset()
41+
42+
router.push('/dashboard/agents/create-agent/file')
43+
}
44+
1545
return (
1646
<div className="flex flex-col gap-10">
1747
<div className="flex items-center justify-between px-10">
1848
<h1 className="font-extrabold text-3xl">AI Agents</h1>
19-
<Button asChild>
20-
<Link href="/dashboard/create-agent">Create Agent</Link>
21-
</Button>
49+
50+
<Dialog>
51+
<form>
52+
<DialogTrigger asChild>
53+
<Button variant="default">Create Agent</Button>
54+
</DialogTrigger>
55+
<DialogContent className="sm:max-w-[425px]">
56+
<DialogHeader>
57+
<DialogTitle>Create Agent</DialogTitle>
58+
<DialogDescription>
59+
Provide the name and description of the Agent.
60+
</DialogDescription>
61+
</DialogHeader>
62+
<div className="grid gap-4">
63+
<div className="grid gap-3">
64+
<Label htmlFor="name-1">Name</Label>
65+
<Input
66+
id="name-1"
67+
name="name"
68+
placeholder="Customer Support"
69+
/>
70+
</div>
71+
<div className="grid gap-3">
72+
<Label htmlFor="username-1">Description (optional)</Label>
73+
<Input
74+
id="username-1"
75+
name="username"
76+
placeholder="This agent is responsible for customer support."
77+
/>
78+
</div>
79+
</div>
80+
<DialogFooter>
81+
<DialogClose asChild>
82+
<Button variant="outline">Cancel</Button>
83+
</DialogClose>
84+
<Button type="submit">Create</Button>
85+
</DialogFooter>
86+
</DialogContent>
87+
</form>
88+
</Dialog>
2289
</div>
2390
{agents.length === 0 ? (
2491
<div className="flex h-full flex-1 flex-center">

src/app/dashboard/create-agent/layout.tsx

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
1-
import NavLink from "@/components/common/NavLink";
2-
import { Button } from "@/components/ui/button";
3-
import { File, Globe, MessageCircle, Text } from "lucide-react";
1+
'use client'
2+
import { ArrowLeft, File, Globe, MessageCircle, Text } from 'lucide-react'
3+
import { useRouter } from 'next/navigation'
4+
import NavLink from '@/components/common/NavLink'
5+
import { Button } from '@/components/ui/button'
46

57
const trainOptions = [
6-
{ option: "File", icon: <File className="size-5" />, link: "file" },
7-
{ option: "Text", icon: <Text className="size-5" />, link: "text" },
8-
{ option: "Website", icon: <Globe className="size-5" />, link: "website" },
9-
{ option: "Q&A", icon: <MessageCircle className="size-5" />, link: "qna" },
10-
];
8+
{ option: 'File', icon: <File className="size-5" />, link: 'file' },
9+
{ option: 'Text', icon: <Text className="size-5" />, link: 'text' },
10+
{ option: 'Website', icon: <Globe className="size-5" />, link: 'website' },
11+
{ option: 'Q&A', icon: <MessageCircle className="size-5" />, link: 'qna' },
12+
]
1113

1214
const CreateAgentLayout = ({ children }: { children: React.ReactNode }) => {
15+
const router = useRouter()
16+
17+
const handleBackClick = () => {
18+
router.push('/dashboard/agents')
19+
}
20+
1321
return (
1422
<div className="flex flex-col gap-10">
15-
<h1 className="font-extrabold text-3xl">Create New Agent</h1>
23+
<div className="flex gap-4 ">
24+
<Button variant={'ghost'} onClick={handleBackClick} size={'icon'}>
25+
<ArrowLeft />
26+
</Button>
27+
<h1 className="font-extrabold text-3xl">Create New Agent</h1>
28+
</div>
1629
<div className="flex gap-10">
1730
<div className="flex w-1/6 flex-col items-start gap-3 self-start">
1831
{trainOptions.map((option) => (
@@ -52,7 +65,7 @@ const CreateAgentLayout = ({ children }: { children: React.ReactNode }) => {
5265
</div>
5366
</div>
5467
</div>
55-
);
56-
};
68+
)
69+
}
5770

58-
export default CreateAgentLayout;
71+
export default CreateAgentLayout

src/components/ui/dialog.tsx

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as DialogPrimitive from "@radix-ui/react-dialog"
5+
import { XIcon } from "lucide-react"
6+
7+
import { cn } from "@/lib/utils"
8+
9+
function Dialog({
10+
...props
11+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
12+
return <DialogPrimitive.Root data-slot="dialog" {...props} />
13+
}
14+
15+
function DialogTrigger({
16+
...props
17+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
18+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
19+
}
20+
21+
function DialogPortal({
22+
...props
23+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
24+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
25+
}
26+
27+
function DialogClose({
28+
...props
29+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
30+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
31+
}
32+
33+
function DialogOverlay({
34+
className,
35+
...props
36+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
37+
return (
38+
<DialogPrimitive.Overlay
39+
data-slot="dialog-overlay"
40+
className={cn(
41+
"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/50",
42+
className
43+
)}
44+
{...props}
45+
/>
46+
)
47+
}
48+
49+
function DialogContent({
50+
className,
51+
children,
52+
showCloseButton = true,
53+
...props
54+
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
55+
showCloseButton?: boolean
56+
}) {
57+
return (
58+
<DialogPortal data-slot="dialog-portal">
59+
<DialogOverlay />
60+
<DialogPrimitive.Content
61+
data-slot="dialog-content"
62+
className={cn(
63+
"bg-background 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
64+
className
65+
)}
66+
{...props}
67+
>
68+
{children}
69+
{showCloseButton && (
70+
<DialogPrimitive.Close
71+
data-slot="dialog-close"
72+
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
73+
>
74+
<XIcon />
75+
<span className="sr-only">Close</span>
76+
</DialogPrimitive.Close>
77+
)}
78+
</DialogPrimitive.Content>
79+
</DialogPortal>
80+
)
81+
}
82+
83+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
84+
return (
85+
<div
86+
data-slot="dialog-header"
87+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
88+
{...props}
89+
/>
90+
)
91+
}
92+
93+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
94+
return (
95+
<div
96+
data-slot="dialog-footer"
97+
className={cn(
98+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
99+
className
100+
)}
101+
{...props}
102+
/>
103+
)
104+
}
105+
106+
function DialogTitle({
107+
className,
108+
...props
109+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
110+
return (
111+
<DialogPrimitive.Title
112+
data-slot="dialog-title"
113+
className={cn("text-lg leading-none font-semibold", className)}
114+
{...props}
115+
/>
116+
)
117+
}
118+
119+
function DialogDescription({
120+
className,
121+
...props
122+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
123+
return (
124+
<DialogPrimitive.Description
125+
data-slot="dialog-description"
126+
className={cn("text-muted-foreground text-sm", className)}
127+
{...props}
128+
/>
129+
)
130+
}
131+
132+
export {
133+
Dialog,
134+
DialogClose,
135+
DialogContent,
136+
DialogDescription,
137+
DialogFooter,
138+
DialogHeader,
139+
DialogOverlay,
140+
DialogPortal,
141+
DialogTitle,
142+
DialogTrigger,
143+
}

0 commit comments

Comments
 (0)