Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Customer Support Sidebar Block for React

A shared-inbox support tool in a fixed-height window: a Reply within select, four queues showing their oldest wait and a derived risk word, and the oldest conversation's thread in the page.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show which queue is about to miss its promise with this customer support sidebar for React with Base UI. A window framed by a hairline with a plus mark on each corner holds the Sidebar at a wider width: the product's mark, a Select for the reply target (1 h, 4 h or 24 h), four queues (Open, Pending, Waiting on customer and Resolved), each with its conversation count, how long its oldest conversation has waited and a risk word with a glyph (On track, At risk or Breached), and the signed-in agent at the foot. Beside it, a top bar names the queue and holds Assign to me, a Shine Button and the only colored control. The page is the queue's oldest conversation: its subject, who wrote, how long they've waited against the target, the risk, and the thread in real text. Change the target and every queue's risk changes with it; assigning the conversation says so and keeps the button answering. The rail collapses to one icon per queue with tooltips, and below the medium breakpoint it becomes a sheet. It's built from Sidebar, Select, Avatar, Shine Button and Guides, with a CSS entrance only. For help desks, shared inboxes, on-call queues and any app with a promise to keep.

FAQ

How is the risk worked out?

Each queue's oldest wait is the time from its oldest conversation's last customer message to a fixed "now" in the file. Divide it by the target and read the result: under a half is On track, from a half up to the whole is At risk, and the whole or more is Breached. Resolved queues have nothing waiting. The word and its glyph are drawn from that one calculation, so the rail, the page and the status line always agree, and the glyph is a different shape for each word, never a color alone.

What stays in the page, and how do I connect it?

Everything. The conversations are typed in the block, "now" is a constant so the demo reads the same whenever it loads, and Assign to me only changes the block's state; nothing is sent, assigned or stored, and reloading starts over. Replace the typed list with your queue API and the constant with the current time. The queues are links to # whose handler opens the queue instead of navigating. They're SidebarMenuButtons with render set to an a element.

What does the Reply within select change?

Only the target the waits are measured against: at 1 h the Pending and Waiting queues are breached, at 4 h Pending is at risk and Waiting is breached, and at 24 h all three are on track. The queues, counts and threads don't change. The choice is controlled state, so the rail, the page's meta line and the status line all follow it at once.

How does it work on a phone?

Below the medium breakpoint the sidebar becomes a sheet that the menu button in the top bar opens from the start edge, the right in a right-to-left layout. The target and the queues live in the sheet, so the status line at the foot of the window states the live result ("Reply within 4 h: Pending is at risk."). Escape or choosing a queue closes the sheet and focus goes back to the menu button.

What happens when the sidebar collapses?

The menu button or the rail along the sidebar's edge folds it to icons: one for each queue, with a tooltip that carries its oldest wait and risk. The select has no folded form, so it gives way. The provider is set with persist={false} and shortcut={false}, so the block writes no cookie and leaves Ctrl and Command with B to the page it sits on.

Is it accessible?

The sidebar is a navigation landmark named after the product, and the open queue is marked as the current page. Each link's name reads its count, oldest wait and risk in words ("Open, 4 conversations. Oldest 25 min, On track."). The select is named Reply within, the thread names each sender and says whether they are the customer or an agent, and one polite status line reports each change. Times are isolated so they read right in a right-to-left layout.