Getting Started
Components
- Agent Status
- Agent Template Card
- API Key Card
- Audio Player
- Bar Visualizer
- Channel Status Card
- Chat Composer
- Code Editor
- Condition Builder
- Confirm Dialog
- Conversation
- Conversation Bar
- Dataset Card
- Document Status Badge
- Extraction Strategy Select
- File Icon
- File Upload
- Indexing Progress
- Live Waveform
- Matrix
- Message
- Mic Selector
- Model Diff View
- Model Selector
- Model Type Filter
- Node Catalog
- Option Editor
- Orb
- Output Variables View
- Package Card
- Prompt Editor
- Provider Status Card
- Radio Card
- Resource Card
- Resource Sidebar
- Response
- Run Node List
- Scrub Bar
- Segment Card
- Shimmering Text
- Speech Input
- Token Trend Chart
- Tool Call Card
- Transcript Viewer
- Usage Stat Card
- Variable Binding Editor
- Variable Selector
- Voice Button
- Voice Picker
- Waveform
- Workflow Node Card
- Workspace Selector
Support Router
Published
Routes support requests to the right workflow, tool, or human handoff.
Workflow agent8 tools
Product Knowledge
Indexing
Indexed docs, FAQs, release notes, and support playbooks.
142 docs18.4k chunks
import {
BotIcon,
BoxesIcon,
DatabaseIcon,
FileTextIcon,
WorkflowIcon,
} from "lucide-react"
import { DocumentStatusBadge } from "@/components/ui/document-status-badge"
import { ResourceCard } from "@/components/ui/resource-card"
export function ResourceCardDemo() {
return (
<div className="grid w-full max-w-3xl gap-3 sm:grid-cols-2">
<ResourceCard
icon={<BotIcon className="size-5" />}
title="Support Router"
description="Routes support requests to the right workflow, tool, or human handoff."
status={<DocumentStatusBadge status="ready" label="Published" />}
meta={[
{ icon: <WorkflowIcon />, label: "Workflow agent" },
{ icon: <BoxesIcon />, label: "8 tools" },
]}
/>
<ResourceCard
icon={<DatabaseIcon className="size-5" />}
title="Product Knowledge"
description="Indexed docs, FAQs, release notes, and support playbooks."
status={<DocumentStatusBadge status="indexing" />}
meta={[
{ icon: <FileTextIcon />, label: "142 docs" },
{ label: "18.4k chunks" },
]}
/>
</div>
)
}
Installation
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/resource-card.jsonpnpm dlx shadcn@latest add https://ui.zgi.ai/r/resource-card.json
yarn dlx shadcn@latest add https://ui.zgi.ai/r/resource-card.jsonComponent
"use client"
import * as React from "react"
import { MoreHorizontalIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
export interface ResourceCardMetaItem {
icon?: React.ReactNode
label: React.ReactNode
}
export interface ResourceCardAction {
icon?: React.ReactNode
label: React.ReactNode
onSelect?: () => void
}
export interface ResourceCardProps
extends Omit<React.ComponentProps<typeof Card>, "title"> {
icon?: React.ReactNode
title: React.ReactNode
description?: React.ReactNode
status?: React.ReactNode
meta?: ResourceCardMetaItem[]
actions?: ResourceCardAction[]
href?: string
onOpen?: () => void
}
function ResourceCardInner({
icon,
title,
description,
status,
meta = [],
actions = [],
}: Pick<
ResourceCardProps,
"actions" | "description" | "icon" | "meta" | "status" | "title"
>) {
return (
<CardContent className="flex h-full min-h-40 flex-col gap-3 p-4">
<div className="flex items-start gap-3">
{icon ? (
<div className="bg-muted text-muted-foreground flex size-10 shrink-0 items-center justify-center rounded-lg">
{icon}
</div>
) : null}
<div className="min-w-0 flex-1">
<div className="flex min-w-0 items-center gap-2">
<h3 className="truncate text-sm font-medium">{title}</h3>
{status ? <div className="shrink-0">{status}</div> : null}
</div>
{description ? (
<p className="text-muted-foreground mt-1 line-clamp-2 text-xs leading-5">
{description}
</p>
) : null}
</div>
{actions.length ? (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="button"
variant="ghost"
size="icon"
className="size-8 shrink-0 rounded-md"
onClick={(event) => event.preventDefault()}
aria-label="Open resource actions"
>
<MoreHorizontalIcon className="size-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{actions.map((action, index) => (
<DropdownMenuItem
key={index}
onSelect={(event) => {
event.preventDefault()
action.onSelect?.()
}}
>
{action.icon ? (
<span className="[&_svg]:size-4">{action.icon}</span>
) : null}
{action.label}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
) : null}
</div>
{meta.length ? (
<div className="mt-auto flex flex-wrap gap-1.5">
{meta.map((item, index) => (
<Badge
key={index}
variant="secondary"
className="h-6 gap-1 rounded-md px-2 font-normal"
>
{item.icon ? (
<span className="[&_svg]:size-3.5">{item.icon}</span>
) : null}
{item.label}
</Badge>
))}
</div>
) : null}
</CardContent>
)
}
export function ResourceCard({
icon,
title,
description,
status,
meta,
actions,
href,
onOpen,
className,
...props
}: ResourceCardProps) {
const content = (
<ResourceCardInner
icon={icon}
title={title}
description={description}
status={status}
meta={meta}
actions={actions}
/>
)
return (
<Card
className={cn(
"hover:border-primary/40 hover:bg-accent/20 relative h-full overflow-hidden rounded-lg transition-colors",
(href || onOpen) && "cursor-pointer",
className
)}
onClick={onOpen}
{...props}
>
{href ? (
<a href={href} className="block h-full">
{content}
</a>
) : (
content
)}
</Card>
)
}
Usage
import { BotIcon } from "lucide-react"
import { ResourceCard } from "@/components/ui/resource-card"
export function Example() {
return (
<ResourceCard
icon={<BotIcon className="size-5" />}
title="Support Router"
description="Routes requests to the right workflow, tool, or human handoff."
meta={[{ label: "Workflow agent" }, { label: "8 tools" }]}
/>
)
}Props
| Prop | Type | Default |
|---|---|---|
| title | ReactNode | required |
| icon | ReactNode | - |
| description | ReactNode | - |
| status | ReactNode | - |
| meta | ResourceCardMetaItem[] | [] |
| actions | ResourceCardAction[] | [] |
| href | string | - |
| onOpen | () => void | - |
Deploy and Scale Agents with ZGI
ZGI delivers the infrastructure and developer experience you need to ship reliable audio & agent applications at scale.
Talk to an expert