Back to templates components
Support Inbox
A starting-point support helpdesk example built with Tailwind CSS, combining a ticket queue with filters and a ticket detail view with a conversation timeline and customer panel. Not a production-ready template.
Starting point — not a finished product
This template combines existing HyperUI components into a full page layout to help you move faster. It still needs real content, working functionality, accessibility checks, and testing before it's ready for production.
0/2 Dark Mode (Request)Updated: N/ANo commit information available.
<input type="checkbox" id="rail-toggle" class="peer sr-only" />
<header
class="flex h-14 shrink-0 items-center gap-4 border-b border-gray-200 bg-white px-4 sm:px-6"
>
<label
for="rail-toggle"
id="rail-toggle-label"
aria-expanded="false"
aria-controls="queue-rail"
class="cursor-pointer rounded-md p-2 text-gray-600 transition hover:bg-gray-100 lg:hidden"
>
<span class="sr-only">Toggle queues</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</label>
<p class="text-sm font-semibold text-gray-900">
Orbitly <span class="font-normal text-gray-400">/ Support</span>
</p>
<label for="TicketSearch" class="ml-4 hidden max-w-sm flex-1 sm:block">
<span class="sr-only">Search tickets</span>
<div class="relative">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-gray-400"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m21 21-5.2-5.2m0 0a7.2 7.2 0 1 0-10.18 0 7.2 7.2 0 0 0 10.18 0Z"
/>
</svg>
<input
type="search"
id="TicketSearch"
placeholder="Search tickets"
class="w-full rounded-md border-gray-200 pl-9 text-sm shadow-xs focus:border-indigo-600 focus:ring-indigo-600"
/>
</div>
</label>
<div class="ml-auto flex items-center gap-3">
<button
type="button"
class="hidden rounded-md bg-indigo-600 px-3 py-1.5 text-xs font-medium text-white transition hover:bg-indigo-700 sm:block"
>
New ticket
</button>
<img
alt=""
src="https://images.unsplash.com/photo-1600486913747-55e5470d6f40?auto=format&fit=crop&q=80&w=200"
class="size-8 rounded-full object-cover"
/>
</div>
</header>
<div class="flex flex-1 overflow-hidden">
<label
for="rail-toggle"
aria-hidden="true"
class="fixed inset-0 z-30 hidden bg-gray-900/50 peer-checked:block lg:hidden"
></label>
<nav
id="queue-rail"
aria-label="Queues"
class="fixed inset-y-14 start-0 z-40 w-56 -translate-x-full overflow-y-auto border-e border-gray-200 bg-white p-3 transition-transform duration-300 peer-checked:translate-x-0 lg:static lg:translate-x-0"
>
<ul class="space-y-1">
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg bg-indigo-50 px-3 py-2 text-sm font-medium text-indigo-700"
>
My tickets
<span class="rounded-full bg-white px-2 py-0.5 text-xs text-indigo-700">4</span>
</a>
</li>
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg px-3 py-2 text-sm text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
Unassigned
<span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-600">11</span>
</a>
</li>
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg px-3 py-2 text-sm text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
All open
<span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-600">37</span>
</a>
</li>
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg px-3 py-2 text-sm text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
Closed
</a>
</li>
</ul>
<p class="mt-6 px-3 text-xs font-medium tracking-wide text-gray-400 uppercase">Tags</p>
<ul class="mt-2 space-y-1">
<li>
<a
href="#"
class="flex items-center gap-2 rounded-lg px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100"
>
<span class="size-2 rounded-full bg-rose-500"></span>
Billing
</a>
</li>
<li>
<a
href="#"
class="flex items-center gap-2 rounded-lg px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100"
>
<span class="size-2 rounded-full bg-amber-500"></span>
Bug
</a>
</li>
<li>
<a
href="#"
class="flex items-center gap-2 rounded-lg px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100"
>
<span class="size-2 rounded-full bg-emerald-500"></span>
Onboarding
</a>
</li>
</ul>
</nav>
<main class="flex-1 overflow-y-auto">
<div class="border-b border-gray-200 bg-white px-4 py-4 sm:px-6">
<h1 class="text-lg font-semibold text-gray-900">My tickets</h1>
<div role="tablist" class="mt-3 flex gap-1">
<button
role="tab"
aria-selected="true"
class="rounded-md bg-gray-900 px-3 py-1.5 text-xs font-medium text-white"
>
All
</button>
<button
role="tab"
aria-selected="false"
class="rounded-md px-3 py-1.5 text-xs font-medium text-gray-600 hover:bg-gray-100"
>
Open
</button>
<button
role="tab"
aria-selected="false"
class="rounded-md px-3 py-1.5 text-xs font-medium text-gray-600 hover:bg-gray-100"
>
Pending
</button>
<button
role="tab"
aria-selected="false"
class="rounded-md px-3 py-1.5 text-xs font-medium text-gray-600 hover:bg-gray-100"
>
Closed
</button>
</div>
</div>
<div class="p-4 sm:p-6">
<div class="overflow-hidden rounded-lg border border-gray-200 bg-white">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr class="*:px-4 *:py-3 *:text-left *:text-xs *:font-medium *:text-gray-500">
<th scope="col">Ticket</th>
<th scope="col" class="hidden sm:table-cell">Requester</th>
<th scope="col">Status</th>
<th scope="col" class="hidden md:table-cell">Priority</th>
<th scope="col" class="hidden md:table-cell">Updated</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr class="cursor-pointer hover:bg-gray-50">
<td class="px-4 py-3">
<p class="text-sm font-medium text-gray-900">Can't export invoices as CSV</p>
<p class="text-xs text-gray-500">#4821</p>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-600 sm:table-cell">Marcus Boyle</td>
<td class="px-4 py-3">
<span class="rounded-full bg-blue-100 px-2.5 py-0.5 text-xs text-blue-700">
Open
</span>
</td>
<td class="hidden px-4 py-3 md:table-cell">
<span class="rounded-full bg-red-100 px-2.5 py-0.5 text-xs text-red-700">
High
</span>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-500 md:table-cell">
12 minutes ago
</td>
</tr>
<tr class="cursor-pointer bg-indigo-50/60 hover:bg-indigo-50">
<td class="px-4 py-3">
<p class="text-sm font-medium text-gray-900">
Team seats not syncing after upgrade
</p>
<p class="text-xs text-gray-500">#4819</p>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-600 sm:table-cell">
Priya Natarajan
</td>
<td class="px-4 py-3">
<span class="rounded-full bg-blue-100 px-2.5 py-0.5 text-xs text-blue-700">
Open
</span>
</td>
<td class="hidden px-4 py-3 md:table-cell">
<span class="rounded-full bg-red-100 px-2.5 py-0.5 text-xs text-red-700">
High
</span>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-500 md:table-cell">
41 minutes ago
</td>
</tr>
<tr class="cursor-pointer hover:bg-gray-50">
<td class="px-4 py-3">
<p class="text-sm font-medium text-gray-900">
Question about annual billing discount
</p>
<p class="text-xs text-gray-500">#4812</p>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-600 sm:table-cell">
Owen Baptiste
</td>
<td class="px-4 py-3">
<span class="rounded-full bg-amber-100 px-2.5 py-0.5 text-xs text-amber-700">
Pending
</span>
</td>
<td class="hidden px-4 py-3 md:table-cell">
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs text-gray-600">
Low
</span>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-500 md:table-cell">3 hours ago</td>
</tr>
<tr class="cursor-pointer hover:bg-gray-50">
<td class="px-4 py-3">
<p class="text-sm font-medium text-gray-900">
Feature request: dark mode for reports
</p>
<p class="text-xs text-gray-500">#4790</p>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-600 sm:table-cell">
Freya Lindqvist
</td>
<td class="px-4 py-3">
<span class="rounded-full bg-amber-100 px-2.5 py-0.5 text-xs text-amber-700">
Pending
</span>
</td>
<td class="hidden px-4 py-3 md:table-cell">
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs text-gray-600">
Low
</span>
</td>
<td class="hidden px-4 py-3 text-sm text-gray-500 md:table-cell">1 day ago</td>
</tr>
</tbody>
</table>
</div>
<nav aria-label="Pagination" class="mt-4 flex items-center justify-between">
<p class="text-xs text-gray-500">Showing 4 of 37 open tickets</p>
<div class="flex gap-1">
<a
href="#"
class="inline-flex size-8 items-center justify-center rounded-md border border-gray-200 text-gray-400"
>
<span class="sr-only">Previous</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-3 rtl:rotate-180"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
</a>
<a
href="#"
class="inline-flex size-8 items-center justify-center rounded-md border border-gray-200 text-gray-600"
>
<span class="sr-only">Next</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-3 rtl:rotate-180"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
/>
</svg>
</a>
</div>
</nav>
</div>
</main>
</div>
<script>
const railToggleCheckbox = document.getElementById('rail-toggle')
const railToggleLabel = document.getElementById('rail-toggle-label')
railToggleCheckbox.addEventListener('change', () => {
railToggleLabel.setAttribute('aria-expanded', String(railToggleCheckbox.checked))
})
</script><input type="checkbox" id="rail-toggle" class="peer sr-only" />
<input type="checkbox" id="details-toggle" class="peer/details sr-only" />
<header
class="flex h-14 shrink-0 items-center gap-4 border-b border-gray-200 bg-white px-4 sm:px-6"
>
<label
for="rail-toggle"
id="rail-toggle-label"
aria-expanded="false"
aria-controls="queue-rail"
class="cursor-pointer rounded-md p-2 text-gray-600 transition hover:bg-gray-100 lg:hidden"
>
<span class="sr-only">Toggle queues</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</label>
<a href="#" class="flex items-center gap-1 text-sm text-gray-500 hover:text-gray-900">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-4 rtl:rotate-180"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"
/>
</svg>
My tickets
</a>
<div class="ml-auto flex items-center gap-3">
<label
for="details-toggle"
id="details-toggle-label"
aria-expanded="false"
aria-controls="ticket-details"
class="cursor-pointer rounded-md p-2 text-gray-600 transition hover:bg-gray-100 xl:hidden"
>
<span class="sr-only">Toggle ticket details</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M11.25 4.5l7.5 7.5-7.5 7.5m-6-15l7.5 7.5-7.5 7.5"
/>
</svg>
</label>
<img
alt=""
src="https://images.unsplash.com/photo-1600486913747-55e5470d6f40?auto=format&fit=crop&q=80&w=200"
class="size-8 rounded-full object-cover"
/>
</div>
</header>
<div class="flex flex-1 overflow-hidden">
<label
for="rail-toggle"
aria-hidden="true"
class="fixed inset-0 z-30 hidden bg-gray-900/50 peer-checked:block lg:hidden"
></label>
<nav
id="queue-rail"
aria-label="Queues"
class="fixed inset-y-14 start-0 z-40 w-56 -translate-x-full overflow-y-auto border-e border-gray-200 bg-white p-3 transition-transform duration-300 peer-checked:translate-x-0 lg:static lg:translate-x-0"
>
<ul class="space-y-1">
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg bg-indigo-50 px-3 py-2 text-sm font-medium text-indigo-700"
>
My tickets
<span class="rounded-full bg-white px-2 py-0.5 text-xs text-indigo-700">4</span>
</a>
</li>
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg px-3 py-2 text-sm text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
Unassigned
<span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-600">11</span>
</a>
</li>
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg px-3 py-2 text-sm text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
All open
<span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-600">37</span>
</a>
</li>
<li>
<a
href="#"
class="flex items-center justify-between rounded-lg px-3 py-2 text-sm text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
Closed
</a>
</li>
</ul>
</nav>
<main class="flex flex-1 flex-col overflow-y-auto">
<div class="border-b border-gray-200 bg-white px-4 py-4 sm:px-6">
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<p class="text-xs text-gray-500">Ticket #4819</p>
<h1 class="mt-0.5 text-lg font-semibold text-gray-900">
Team seats not syncing after upgrade
</h1>
</div>
<div class="flex items-center gap-2">
<span class="rounded-full bg-blue-100 px-2.5 py-0.5 text-xs text-blue-700">
Open
</span>
<span class="rounded-full bg-red-100 px-2.5 py-0.5 text-xs text-red-700">
High priority
</span>
</div>
</div>
</div>
<div class="flex-1 space-y-6 p-4 sm:p-6">
<ol
class="relative space-y-6 before:absolute before:-ms-px before:h-full before:w-0.5 before:rounded-full before:bg-gray-200"
>
<li class="relative -ms-1.5 flex items-start gap-4">
<span class="size-3 shrink-0 rounded-full bg-gray-400"></span>
<div class="-mt-2 w-full">
<div class="flex items-center gap-2">
<p class="text-sm font-medium text-gray-900">Priya Natarajan</p>
<time class="text-xs text-gray-500">Today at 09:12</time>
</div>
<div class="mt-1.5 rounded-lg rounded-tl-none border border-gray-200 bg-white p-4">
<p class="text-sm text-gray-700">
We upgraded to the Team plan yesterday but two of the five seats we paid for
still show as pending. Tried removing and re-inviting one person, still stuck.
</p>
</div>
</div>
</li>
<li class="relative -ms-1.5 flex items-start gap-4">
<span class="size-3 shrink-0 rounded-full bg-indigo-600"></span>
<div class="-mt-2 w-full">
<div class="flex items-center gap-2">
<p class="text-sm font-medium text-gray-900">You</p>
<time class="text-xs text-gray-500">Today at 09:41</time>
</div>
<div
class="mt-1.5 rounded-lg rounded-tl-none border border-indigo-100 bg-indigo-50 p-4"
>
<p class="text-sm text-gray-700">
Thanks for flagging — looks like the seat sync job is stuck on your
account specifically. I'm re-running it manually now and will confirm once both
seats show as active.
</p>
</div>
</div>
</li>
<li class="relative -ms-1.5 flex items-start gap-4">
<span class="size-3 shrink-0 rounded-full bg-gray-300"></span>
<div class="-mt-2">
<p class="text-xs text-gray-500">
<time>Today at 09:42</time> · Internal note added by you
</p>
</div>
</li>
</ol>
</div>
<div class="border-t border-gray-200 bg-white p-4 sm:p-6">
<div role="tablist" class="flex gap-1">
<button
role="tab"
aria-selected="true"
class="rounded-t-md border border-b-0 border-gray-200 bg-white px-3 py-1.5 text-xs font-medium text-gray-900"
>
Reply
</button>
<button
role="tab"
aria-selected="false"
class="rounded-t-md px-3 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700"
>
Internal note
</button>
</div>
<label for="ReplyMessage" class="sr-only">Reply to Priya</label>
<textarea
id="ReplyMessage"
rows="3"
placeholder="Type your reply…"
class="w-full resize-none rounded-tr-md rounded-b-md border-gray-200 text-sm shadow-xs focus:border-indigo-600 focus:ring-indigo-600"
></textarea>
<div class="mt-3 flex items-center justify-between">
<p class="text-xs text-gray-500">Priya will see this by email.</p>
<button
type="button"
class="rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium text-white transition hover:bg-indigo-700"
>
Send reply
</button>
</div>
</div>
</main>
<label
for="details-toggle"
aria-hidden="true"
class="fixed inset-0 z-30 hidden bg-gray-900/50 peer-checked/details:block xl:hidden"
></label>
<aside
id="ticket-details"
class="fixed inset-y-14 end-0 z-40 w-72 translate-x-full space-y-6 overflow-y-auto border-s border-gray-200 bg-white p-4 transition-transform duration-300 peer-checked/details:translate-x-0 xl:static xl:translate-x-0"
>
<div class="flex items-center gap-3">
<img
alt=""
src="https://images.unsplash.com/photo-1601412436009-d964bd02edbc?auto=format&fit=crop&q=80&w=200"
class="size-10 rounded-full object-cover"
/>
<div>
<p class="text-sm font-medium text-gray-900">Priya Natarajan</p>
<p class="text-xs text-gray-500">priya@orbitly.com</p>
</div>
</div>
<dl class="space-y-3 border-t border-gray-200 pt-4 text-sm">
<div class="flex items-center justify-between">
<dt class="text-gray-500">Plan</dt>
<dd class="font-medium text-gray-900">Team, 5 seats</dd>
</div>
<div class="flex items-center justify-between">
<dt class="text-gray-500">Customer since</dt>
<dd class="font-medium text-gray-900">Feb 2024</dd>
</div>
<div class="flex items-center justify-between">
<dt class="text-gray-500">Open tickets</dt>
<dd class="font-medium text-gray-900">1</dd>
</div>
</dl>
<div class="space-y-3 border-t border-gray-200 pt-4">
<label for="TicketStatus" class="block text-xs font-medium text-gray-700">Status</label>
<select
id="TicketStatus"
class="w-full rounded-md border-gray-200 text-sm shadow-xs focus:border-indigo-600 focus:ring-indigo-600"
>
<option>Open</option>
<option>Pending</option>
<option>Closed</option>
</select>
<label for="TicketPriority" class="block text-xs font-medium text-gray-700">
Priority
</label>
<select
id="TicketPriority"
class="w-full rounded-md border-gray-200 text-sm shadow-xs focus:border-indigo-600 focus:ring-indigo-600"
>
<option>Low</option>
<option selected>High</option>
<option>Urgent</option>
</select>
<label for="TicketAssignee" class="block text-xs font-medium text-gray-700">
Assignee
</label>
<select
id="TicketAssignee"
class="w-full rounded-md border-gray-200 text-sm shadow-xs focus:border-indigo-600 focus:ring-indigo-600"
>
<option>You</option>
<option>Marcus Boyle</option>
<option>Unassigned</option>
</select>
</div>
<div class="border-t border-gray-200 pt-4">
<p class="text-xs font-medium text-gray-700">Tags</p>
<div class="mt-2 flex flex-wrap gap-1.5">
<span class="rounded-full bg-amber-100 px-2.5 py-0.5 text-xs text-amber-700">
Bug
</span>
<span class="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs text-gray-600">
Billing
</span>
</div>
</div>
</aside>
</div>
<script>
const railToggleCheckbox = document.getElementById('rail-toggle')
const railToggleLabel = document.getElementById('rail-toggle-label')
railToggleCheckbox.addEventListener('change', () => {
railToggleLabel.setAttribute('aria-expanded', String(railToggleCheckbox.checked))
})
const detailsToggleCheckbox = document.getElementById('details-toggle')
const detailsToggleLabel = document.getElementById('details-toggle-label')
detailsToggleCheckbox.addEventListener('change', () => {
detailsToggleLabel.setAttribute('aria-expanded', String(detailsToggleCheckbox.checked))
})
</script>