Skip to content
Framework: Vite + React + TypeScriptDifficulty: intermediate

CRM pipeline

Contacts table plus a five-stage deal pipeline board with inline stage changes, all persisted locally.

A small CRM with two views over the same data: a searchable contacts table with stage selects and delete, and a kanban-style pipeline (Lead → Qualified → Proposal → Won/Lost) where deals move between columns with keyboard-accessible buttons. State lives in localStorage via a typed hook so the app works offline; swap src/store.ts for API calls when you add a backend.

  • react
  • crm
  • pipeline
  • kanban
  • tailwind

This preview is the template's actual file tree and source code — exactly what is copied into a new project. Codexa does not publish screenshots or mock-ups of templates; run the project to see it rendered.

Files14 files

src/App.tsx61 lines
import { useState } from "react";
import { useContacts } from "./store";
import { ContactsTable } from "./ContactsTable";
import { Pipeline } from "./Pipeline";
import { ContactForm } from "./ContactForm";

export default function App() {
  const store = useContacts();
  const [tab, setTab] = useState<"contacts" | "pipeline">("pipeline");
  const [adding, setAdding] = useState(false);
  const open = store.contacts.filter((c) => c.stage !== "Won" && c.stage !== "Lost");
  const pipelineValue = open.reduce((s, c) => s + c.value, 0);

  return (
    <div className="min-h-screen bg-slate-50 text-slate-900">
      <header className="border-b border-slate-200 bg-white">
        <div className="mx-auto flex max-w-6xl flex-wrap items-center justify-between gap-3 px-4 py-3 sm:px-6">
          <h1 className="font-semibold tracking-tight">Pipeline CRM</h1>
          <div className="flex items-center gap-2">
            <div className="flex rounded-md border border-slate-300 p-0.5 text-sm" role="tablist" aria-label="View">
              {(["pipeline", "contacts"] as const).map((t) => (
                <button key={t} type="button" role="tab" aria-selected={tab === t} onClick={() => setTab(t)} className={"rounded px-3 py-1 capitalize " + (tab === t ? "bg-slate-900 text-white" : "hover:bg-slate-100")}>
                  {t}
                </button>
              ))}
            </div>
            <button type="button" onClick={() => setAdding(true)} className="rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700">
              New contact
            </button>
          </div>
        </div>
      </header>
      <main className="mx-auto max-w-6xl px-4 py-6 sm:px-6">
        <div className="grid gap-4 sm:grid-cols-3">
          <Stat label="Contacts" value={String(store.contacts.length)} />
          <Stat label="Open deals" value={String(open.length)} />
          <Stat label="Pipeline value" value={"$" + pipelineValue.toLocaleString()} />
        </div>
        <div className="mt-6">{tab === "pipeline" ? <Pipeline store={store} /> : <ContactsTable store={store} />}</div>
        {adding ? (
          <ContactForm
            onCancel={() => setAdding(false)}
            onSave={(c) => {
              store.add(c);
              setAdding(false);
            }}
          />
        ) : null}
      </main>
    </div>
  );
}

function Stat({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded-xl border border-slate-200 bg-white p-4">
      <p className="text-xs uppercase tracking-wide text-slate-500">{label}</p>
      <p className="mt-1 text-2xl font-semibold">{value}</p>
    </div>
  );
}

Dependencies

Documented from the template's package.json. The runtime has a prebuilt dependency set for Vite + React + TypeScript, so installs are fast.

PackageVersion
react^19.1.0
react-dom^19.1.0
vite^6.3.0
@vitejs/plugin-react^4.4.0
tailwindcss^4.1.0
@tailwindcss/vite^4.1.0
typescript^5.8.0

How it runs

Framework
Vite + React + TypeScript
Dev command
npm run dev
Build command
npm run build
Output directory
dist
Port
5173
Opens at
/
Difficulty
intermediate

Projects run in an isolated sandbox with a live preview. Read the projects documentation for details on settings, snapshots and deployment.

Need the raw data? GET /api/v1/templates/vite-react-crm returns this template with its files.

Build on CRM pipeline

Create a free account, start from this template, and ask the AI agent to turn it into your app.