KQ-1326 · INTEGRATION/HUB

Integration Hub

A directory of integrations built from data, each with a seeded glyph and a connect switch that does not flip at once: its knob waits halfway on snap while the permissions step slides in as a sheet — from the side or the bottom on glide, or a dialog rising in the centre on snap — listing required scopes locked and the rest as checkboxes, and completes its travel when onConnect's promise lands. Connected cards read their sync (synced, syncing, paused, needing attention) with the time since the last one, and the search filters as you type: cards that stay glide to their new cells, cards that go fade and shrink on the exit ease, and returning ones rise on snap. The sheet is a modal dialog with a focus trap, Escape and focus returned to its opener; categories are a radiogroup, "/" jumps to the search and Escape clears it.

KQ-1326 · INTEGRATION/HUB

Integrations

Connect the tools you already use.

3 connected1 needs attention
  • Basinworks Drive

    Storage · Basinworks

    Sync shared folders and attach files to routes and depots.

    SyncedLast sync 4 min ago
  • Waylight Chat

    Messaging · Waylight

    Post route alerts and the daily digest to team channels.

    PausedLast sync 38 min ago
  • Gaugeworks Metrics

    Analytics · Gaugeworks

    Send product events and pin live dashboards to projects.

    Token expiredLast sync 2 h ago
  • Fernworks CI

    Developer · Fernworks

    Run checks on every change and report status on the route.

    Asks for 3 permissions, 1 optional

  • Coldbrook Ledger

    Finance · Coldbrook

    Reconcile depot invoices and payouts every night.

    Asks for 2 permissions, 1 optional

  • Waylight Mail

    Messaging · Waylight

    Send delivery updates from your own domain.

    Asks for 2 permissions, 1 optional

  • Fernworks Deploy

    Developer · Fernworks

    Promote builds and roll back from the release view.

    Asks for 2 permissions

  • Basinworks Calendar

    Productivity · Basinworks

    Show shift schedules and book loading bays.

    Asks for 2 permissions, 1 optional

  • Gaugeworks Warehouse

    Analytics · Gaugeworks

    Stream route and fleet tables to your warehouse hourly.

    Asks for 2 permissions, 1 optional

  • Coldbrook Payroll

    Finance · Coldbrook

    Export driver hours at the end of each pay period.

    Asks for 2 permissions

  • Basinworks Notes

    Productivity · Basinworks

    Link specs and depot notes to the routes they describe.

    Asks for 2 permissions, 1 optional

  • Fernworks Tickets

    Productivity · Fernworks

    Turn driver feedback into tracked tickets.

    Asks for 3 permissions, 1 optional

Opens a step to confirm.

3 of 12 connected · gaugeworks metrics needs attention

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/integration-hub

Props

integrations
Integration[]
default defaultIntegrations
The directory: id, name, category, a line of description, the maker, the scopes it asks for (required or optional), a glyph tint and mark, and its sync while connected.
connected / defaultConnected
string[]
default defaultIntegrationConnected
The ids that are connected. Controlled or uncontrolled.
onConnectedChange
(ids: string[]) => void
default —
Fires when a connect or disconnect lands, with every connected id.
onConnect
(id: string, scopes: string[]) => void | Promise<unknown>
default —
Allow and connect was pressed, with the scopes granted (required plus the optional ones left ticked). A promise holds the sheet in Connecting…; a rejection shows the error in the sheet.
onDisconnect
(id: string) => void | Promise<unknown>
default —
Disconnect was confirmed. A promise holds the sheet until it lands.
onSync
(id: string) => void | Promise<unknown>
default —
Sync now was pressed on a connected card. A promise keeps it syncing until it lands, then it reads synced just now.
query / defaultQuery
string
default ""
The search text. Controlled or uncontrolled.
onQueryChange
(query: string) => void
default —
Fires on every keystroke in the search, on Clear and on Escape.
category / defaultCategory
string
default "all"
The category filter: "all", "connected", or a category's name in lower-case with dashes. Controlled or uncontrolled.
onCategoryChange
(category: string) => void
default —
Fires when a category is chosen by click or arrow key.
grid
"cards" | "compact" | "list"
default "cards"
The directory's layout: cards with a description and a sync footer, compact tiles, or a list of rows.
sheet
"side" | "bottom" | "center"
default "side"
Where the permissions step comes from: a side sheet or a bottom sheet sliding in on glide, or a dialog rising in the centre on snap.
status
"dot" | "pill" | "bar"
default "pill"
How a connected card reads its sync: a coloured dot with words, a tinted pill with the last sync time, or a stripe down the card's edge that pulses while it syncs.
now
number | Date
default defaultIntegrationNow
Now, for "Last sync 4 min ago". Pass a ticking value to keep the times fresh.
formatAgo
(ms: number) => string
default —
How long ago, from a span in ms. Defaults to just now, 4 min ago, 2 h ago, yesterday.
account
string
default "dana@fieldline.app"
The account the permissions step says it signs in as.
appName
string
default "Fieldline"
Your product's name in the permissions step: "Fieldline will be able to".
loading
boolean
default false
The directory has not arrived: a skeleton of cards.
error
string | null
default —
The directory failed to load: this message, with Try again when onRetry is given.
onRetry
() => void
default —
Try again was pressed after an error.
title
string
default "Integrations"
The panel's heading; also its accessible name unless label is given.
description
string
default "Connect the tools you already use."
A line under the heading.
label
string
default —
The panel's accessible name. Defaults to the title.
sound
boolean
default false
A clack for each switch press and category choice, a pop for Allow and connect, Disconnect and Sync now.
disabled
boolean
default false
Read only: nothing connects, syncs or filters.
className
string
default —
Classes for the root. It is 560px tall with the directory scrolling inside and the sheet laid over it; pass a height class to change it.