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

Analytics dashboard

A responsive dashboard layout with sidebar navigation, stat cards, and a data table.

A sidebar + content dashboard shell with three stat cards and a searchable customer table backed by an in-memory array. Swap the array for a fetch call to your API and the table keeps working. Uses CSS grid for the responsive layout, so it collapses to a single column on phones.

  • react
  • dashboard
  • tailwind
  • table

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.

Files9 files

src/App.tsx67 lines
import { useMemo, useState } from "react";

type Row = { id: number; customer: string; plan: "Free" | "Pro" | "Team"; mrr: number; status: "active" | "trialing" | "churned" };

const rows: Row[] = [
  { id: 1, customer: "Aarav Studio", plan: "Pro", mrr: 1499, status: "active" },
  { id: 2, customer: "Nimbus Labs", plan: "Team", mrr: 3999, status: "active" },
  { id: 3, customer: "Priya Designs", plan: "Free", mrr: 0, status: "trialing" },
  { id: 4, customer: "Orbit Retail", plan: "Pro", mrr: 1499, status: "churned" },
  { id: 5, customer: "Kavya Tech", plan: "Team", mrr: 3999, status: "active" },
];

export default function App() {
  const [query, setQuery] = useState("");
  const filtered = useMemo(() => rows.filter((r) => r.customer.toLowerCase().includes(query.toLowerCase())), [query]);
  const mrr = rows.filter((r) => r.status === "active").reduce((s, r) => s + r.mrr, 0);
  return (
    <div className="min-h-screen bg-slate-50 text-slate-900 md:grid md:grid-cols-[220px_1fr]">
      <aside className="border-b border-slate-200 bg-white p-4 md:border-b-0 md:border-r">
        <div className="text-sm font-semibold tracking-wide">ACME ANALYTICS</div>
        <nav className="mt-6 space-y-1 text-sm">
          {["Overview", "Customers", "Revenue", "Settings"].map((item, i) => (
            <a key={item} href="#" className={"block rounded-md px-3 py-2 " + (i === 0 ? "bg-slate-100 font-medium" : "text-slate-600 hover:bg-slate-50")}>
              {item}
            </a>
          ))}
        </nav>
      </aside>
      <main className="p-6">
        <h1 className="text-xl font-semibold">Overview</h1>
        <div className="mt-4 grid gap-4 sm:grid-cols-3">
          {[
            ["Active customers", String(rows.filter((r) => r.status === "active").length)],
            ["Monthly revenue", "₹" + mrr.toLocaleString("en-IN")],
            ["Trials", String(rows.filter((r) => r.status === "trialing").length)],
          ].map(([label, value]) => (
            <div key={label} className="rounded-xl border border-slate-200 bg-white p-4">
              <div className="text-xs uppercase tracking-wide text-slate-500">{label}</div>
              <div className="mt-1 text-2xl font-semibold">{value}</div>
            </div>
          ))}
        </div>
        <div className="mt-6 rounded-xl border border-slate-200 bg-white">
          <div className="flex items-center justify-between border-b border-slate-200 p-4">
            <h2 className="font-medium">Customers</h2>
            <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search" className="rounded-md border border-slate-300 px-3 py-1.5 text-sm" aria-label="Search customers" />
          </div>
          <table className="w-full text-sm">
            <thead className="text-left text-slate-500">
              <tr><th className="p-3">Customer</th><th className="p-3">Plan</th><th className="p-3">MRR</th><th className="p-3">Status</th></tr>
            </thead>
            <tbody>
              {filtered.map((r) => (
                <tr key={r.id} className="border-t border-slate-100">
                  <td className="p-3 font-medium">{r.customer}</td>
                  <td className="p-3">{r.plan}</td>
                  <td className="p-3">₹{r.mrr.toLocaleString("en-IN")}</td>
                  <td className="p-3 capitalize">{r.status}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </main>
    </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.

View all
  • Framework: Vite + React + TypeScriptDifficulty: intermediate

    Operations dashboard

    A dark service-health dashboard with SVG sparklines, status indicators, and a filterable incident table.

    • react
    • dashboard
    • monitoring
    • charts
    • dark-mode

    11 files

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

Build on Analytics dashboard

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