Staaarter

Sales Pipeline

A sales-CRM dashboard: a sidebar and search topbar, three-up pipeline KPIs, a four-stage kanban board of deal cards flagged for hot leads, a revenue-vs-forecast area chart, a team-quota radial gauge, and a rep leaderboard with quota progress bars.

By Staaarter Team
Dashboard
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its button, avatar, avatar-initials dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/sales-pipeline.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/dashboard/dashboard9.tsx instead.

Usage

The file also exports dashboard9Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Dashboard9, dashboard9Demo } from "@/components/blocks/dashboard/dashboard9";

export default function Page() {
  return <Dashboard9 {...dashboard9Demo} />;
}

Props

PropTypeDefaultDescription
navItemsNavItem[]noneSidebar nav entries. Icons are assigned by position, not passed in as data.
kpisKpiItem[]noneThree-up KPI tiles: total pipeline value, deals in progress, win rate.
stagesPipelineStage[]noneKanban columns in display order, each holding its own deal cards.
revenue{ actual: number[]; forecast: number[] }noneEqual-length series plotted on the revenue-vs-forecast chart; actual renders as a solid filled line, forecast as a dashed line.
teamQuotaPercentnumbernoneValue shown on the team-quota radial gauge, 0 to 100 (values above 100 render as a full ring).
repsRepProgress[]noneLeaderboard rows, rendered in the order given (not re-sorted by quota or deal count).
classNamestringnoneExtra classes for the outer section element.

Types

type NavItem = { label: string; href: string; active?: boolean };

type KpiItem = { label: string; value: string; delta: string; trend: "up" | "down" };

type Deal = { company: string; value: string; owner: string; hot?: boolean };

type PipelineStage = { name: string; deals: Deal[] };

type RepProgress = { name: string; quotaPercent: number; dealCount: number };

Behavior notes

  • The kanban board is a static, decorative layout: cards are not draggable between columns and there is no column-filter toggle. It's a server component with zero client-side interaction.
  • The flame icon on a deal card is driven purely by that deal's own `hot` flag; there's no threshold logic tying it to deal value.
  • Rep quota percentages above 100 (reps who beat quota) still render their progress bar clipped to the container width via a min(100) clamp in the width style, so the bar never overflows the row.
  • The revenue-vs-forecast chart is two overlaid polylines sharing one min/max scale computed across both series, so actual and forecast are always comparable on the same axis rather than each normalized independently.
  • The search control in the topbar is a static, non-functional affordance (matching the ⌘K trigger convention used elsewhere in this category), not a working search box.