Xzero UI
Pro library

Ticket routerPro

A support ticket router where messages from Gmail, Intercom, Slack and Zendesk come in one at a time. An AI classifier labels each one with intent, sentiment and confidence, and the ticket moves into a team lane with an assignee. Low confidence tickets wait in a review lane, and one click there routes them to the suggested team.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/ticket-router
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/ticket-router

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { TicketRouter } from "@/components/xzero/ticket-router/ticket-router";

export function SupportInbox({ tickets }) {
  return (
    <TicketRouter
      tickets={tickets}
      reviewThreshold={0.75}
      classify={async (ticket, { signal }) => {
        const res = await fetch("/api/classify", { method: "POST", body: JSON.stringify(ticket), signal });
        return res.json(); // { intent, sentiment, confidence }
      }}
      onRoute={ticket => assignInHelpdesk(ticket.id, ticket.lane, ticket.assignee)}
    />
  );
}

API reference

TicketRouter

A support ticket router card. Messages from Gmail, Intercom, Slack and Zendesk arrive one at a time, an AI classifier labels intent, sentiment and confidence, and the ticket lands in a team lane with a round robin assignee. Low confidence tickets go to the review lane, where a click confirms the suggested lane. With no props it plays a simulated inbox.

PropTypeDefaultDescription
ticketsTicketMessage[]ticketRouterSamplesIncoming messages, processed in order. Each has id, channel (email, intercom, slack, zendesk), customer, company, subject, preview and an optional receivedAt label.
lanesTicketLane[]Billing, Engineering, Success, Needs reviewTeam lanes left to right: id, label, assignees for round robin, count for tickets routed earlier, and review: true on the lane that collects low confidence tickets.
initialRoutedRoutedTicket[]samples when tickets is unsetTickets already in the lanes on first render, newest first.
classify(ticket, { signal }) => Promise<TicketClassification>–Your classifier. Resolve { intent, sentiment, confidence }; throw to show the error state with Retry and Send to review. The signal aborts on pause, off screen and unmount. Without it a simulated classifier reads each ticket's sample.
route(ticket, classification) => stringbilling and refund to billing, bug to engineering, feature to successPicks the lane id for a confident classification.
reviewThresholdnumber0.7Confidence below this sends the ticket to the review lane with the picked lane as a suggestion.
loopbooleantrue for samples, false for your ticketsStarts over when the queue runs out. Without it the card shows All caught up, and resumes when you append tickets.
pausedboolean–Controls the flow. Pair with onPausedChange.
defaultPausedbooleanfalseStarts paused when uncontrolled.
onPausedChange(paused: boolean) => void–Called by the Pause and Resume button.
onRoute(ticket: RoutedTicket) => void–Called when a ticket lands in a lane, with its classification, lane, assignee and suggested lane.
onReview(ticket: RoutedTicket, lane: string) => void–Called when someone confirms a review ticket's suggested lane.
onError(ticket: TicketMessage, error: unknown) => void–Called when the classifier throws.
maxVisiblenumber3Rows shown per lane. Narrow containers show at most 2.
speednumber1Playback speed multiplier for the simulated flow.
titlestring"Ticket routing"Card title.
modelstring"Claude Haiku 5.5"Classifier model name in the header and the classifying label.
modelMarkReactNodeClaude markMark shown before the title.
classNamestring–Extra class on the root section.

Keyboard interactions

KeysAction
TabMoves between Pause, the error actions and review tickets.
Enter / SpacePauses or resumes, retries a failed classification, or confirms a review ticket's suggested lane.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in ai

Guidance for AI tools

Ticket router: A support ticket router where messages from Gmail, Intercom, Slack and Zendesk come in one at a time. An AI classifier labels each one with intent, sentiment and confidence, and the ticket moves into a team lane with an assignee. Low confidence tickets wait in a review lane, and one click there routes them to the suggested team. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components