Sahyadri Clinics
Patient booking app
₹3,20,000·TodayRS
Dashboards
A deal board for a services team, with stage totals, owners, due dates and a card mid-drag.
sidebar · pipeline totals · filters · 4-stage board · tags · drag state
import { ChevronDown, Filter, Home, Inbox, KanbanSquare, LineChart, Plus, Search, Building2, Users } from "lucide-react";
import { cn } from "@/lib/utils";
const nav = [
{ label: "Home", icon: Home },
{ label: "Pipeline", icon: KanbanSquare, current: true },
{ label: "Contacts", icon: Users, count: 248 },
{ label: "Companies", icon: Building2 },
{ label: "Inbox", icon: Inbox, count: 5 },
{ label: "Reports", icon: LineChart },
];
type Deal = { company: string; project: string; value: string; owner: string; due: string; tag?: { label: string; tone: "danger" | "info" | "success" } };
const stages: { name: string; dot: string; total: string; deals: Deal[] }[] = [
{ name: "New lead", dot: "bg-fg-subtle", total: "₹6.8L", deals: [
{ company: "Sahyadri Clinics", project: "Patient booking app", value: "₹3,20,000", owner: "RS", due: "Today" },
{ company: "Mehta Textiles", project: "B2B order portal", value: "₹2,10,000", owner: "AK", due: "Fri" },
{ company: "Pinecrest School", project: "Fee collection", value: "₹1,50,000", owner: "RS", due: "Oct 22" },
] },
{ name: "Qualified", dot: "bg-info", total: "₹9.4L", deals: [
{ company: "Kaveri Foods", project: "Distributor dashboard", value: "₹4,80,000", owner: "MN", due: "Mon", tag: { label: "Hot", tone: "danger" } },
{ company: "Orbit Logistics", project: "Driver tracking", value: "₹4,60,000", owner: "AK", due: "Oct 24" },
] },
{ name: "Proposal sent", dot: "bg-warning", total: "₹12.1L", deals: [
{ company: "Bluefern Studio", project: "Website redesign", value: "₹1,90,000", owner: "MN", due: "Waiting 3d", tag: { label: "Viewed twice", tone: "info" } },
{ company: "Coastal Spice Co.", project: "D2C store + app", value: "₹7,40,000", owner: "RS", due: "Oct 19" },
{ company: "Nilgiri Traders", project: "Inventory sync", value: "₹2,80,000", owner: "AK", due: "Oct 25" },
] },
{ name: "Won", dot: "bg-success", total: "₹8.2L", deals: [
{ company: "Sharma Hardware", project: "Billing + GST", value: "₹2,40,000", owner: "MN", due: "Signed 12 Oct", tag: { label: "Paid 50%", tone: "success" } },
{ company: "Lotus Yoga Studio", project: "Class booking", value: "₹1,10,000", owner: "RS", due: "Signed 9 Oct" },
] },
];
const tagTone = { danger: "bg-danger-soft text-danger-fg", info: "bg-info-soft text-info-fg", success: "bg-success-soft text-success-fg" };
const summary = [
{ label: "Open pipeline", value: "₹28,30,000" },
{ label: "Weighted", value: "₹11,64,000" },
{ label: "Won this month", value: "₹8,20,000" },
];
export default function PipelinePage() {
return (
<div className="flex min-h-screen bg-bg font-sans text-sm text-fg">
<aside aria-label="Main" className="hidden w-56 shrink-0 flex-col gap-0.5 border-r border-border bg-surface p-3 lg:flex">
<p className="mb-2 flex h-8 items-center gap-2 px-1.5 font-medium">
<span className="grid size-6 place-items-center rounded-sm bg-primary text-xs font-semibold text-primary-fg">N</span>Northwind Studio
</p>
<nav className="grid gap-0.5">
{nav.map(({ label, icon: Icon, current, count }) => (
<a key={label} href="#" aria-current={current ? "page" : undefined}
className={cn("flex h-8 items-center gap-2.5 rounded px-2 font-medium text-fg-muted hover:bg-surface-2 hover:text-fg",
current && "bg-bg text-fg shadow-sm ring-1 ring-border")}>
<Icon className="size-4" aria-hidden />{label}
{count && <span className="ml-auto text-xs tabular-nums text-fg-subtle">{count}</span>}
</a>
))}
</nav>
</aside>
<div className="flex min-w-0 flex-1 flex-col">
<header className="flex h-14 items-center gap-3 border-b border-border px-4 sm:px-6">
<p className="text-fg-muted">Pipelines <span className="text-fg-subtle">/</span> <span className="font-medium text-fg">Projects</span></p>
<label className="ml-auto hidden h-9 w-64 items-center gap-2 rounded border border-border bg-surface px-2.5 text-fg-subtle md:flex">
<Search className="size-4" aria-hidden />
<input placeholder="Search deals and people" className="w-full bg-transparent text-[13px] text-fg outline-none placeholder:text-fg-subtle" />
</label>
<button type="button" className="inline-flex h-9 items-center gap-1.5 rounded bg-primary px-3 font-medium text-primary-fg hover:bg-primary-hover">
<Plus className="size-4" aria-hidden /> Add deal
</button>
</header>
<main className="flex min-h-0 flex-1 flex-col gap-4 p-4 sm:p-6">
<h1 className="sr-only">Projects pipeline</h1>
<div className="flex flex-wrap items-center justify-between gap-4">
<dl className="flex flex-wrap gap-6">
{summary.map((s) => (
<div key={s.label}><dt className="text-xs text-fg-subtle">{s.label}</dt><dd className="text-xl font-medium tracking-tight tabular-nums">{s.value}</dd></div>
))}
</dl>
<div className="flex items-center gap-2">
<button type="button" className="inline-flex h-8 items-center gap-1.5 rounded-full border border-border bg-surface px-3 text-xs font-medium">
<Users className="size-3.5" aria-hidden /> Owner: Everyone <ChevronDown className="size-3.5" aria-hidden />
</button>
<button type="button" className="inline-flex h-8 items-center gap-1.5 rounded-full border border-dashed border-border-strong px-3 text-xs font-medium text-fg-muted">
<Filter className="size-3.5" aria-hidden /> Filter
</button>
</div>
</div>
<div className="-mx-4 flex snap-x gap-3 overflow-x-auto px-4 pb-2 sm:mx-0 sm:px-0 lg:grid lg:grid-cols-4">
{stages.map((stage) => (
<section key={stage.name} aria-label={stage.name} className="flex w-72 shrink-0 snap-start flex-col gap-2 rounded-lg bg-surface p-2 lg:w-auto">
<div className="flex items-center gap-1.5 px-1 py-0.5 text-[13px] font-medium">
<span className={cn("size-2 rounded-full", stage.dot)} />{stage.name}
<span className="text-xs text-fg-subtle">{stage.deals.length}</span>
<span className="ml-auto text-xs tabular-nums text-fg-muted">{stage.total}</span>
</div>
{stage.deals.map((d) => (
<article key={d.company} className="grid cursor-grab gap-2 rounded border border-border bg-bg p-3 shadow-sm transition hover:border-border-strong">
<div>
<h3 className="text-[13px] font-medium">{d.company}</h3>
<p className="text-xs text-fg-subtle">{d.project}</p>
</div>
{d.tag && <span className={cn("w-fit rounded-full px-2 py-0.5 text-[11px] font-medium", tagTone[d.tag.tone])}>{d.tag.label}</span>}
<div className="flex items-center gap-1.5 text-xs text-fg-muted">
<span className="font-medium tabular-nums text-fg">{d.value}</span><span>·</span><span>{d.due}</span>
<span className="ml-auto grid size-6 place-items-center rounded-full bg-primary-soft text-[10px] font-semibold text-primary-soft-fg">{d.owner}</span>
</div>
</article>
))}
<button type="button" className="flex h-8 items-center gap-1.5 rounded px-2 text-[13px] text-fg-subtle hover:bg-surface-2 hover:text-fg">
<Plus className="size-4" aria-hidden /> Add
</button>
</section>
))}
</div>
</main>
</div>
</div>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.