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

Admin panel

A CRUD members table with search, sortable columns, pagination, and validated create/edit forms.

An admin layout with a sidebar and a members resource: searchable, sortable, paginated table; create and edit dialogs with field-level validation and ARIA error wiring; activate/deactivate toggles and delete with confirmation. The data layer in src/api.ts mirrors the HTTP calls you would make (list, create, update, delete) so moving to a real API is a drop-in change.

  • react
  • admin
  • crud
  • table
  • forms
  • 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.

Files12 files

src/api.ts31 lines
import { useLocalStorage } from "./useLocalStorage";

export type Role = "admin" | "editor" | "viewer";
export type Member = { id: string; name: string; email: string; role: Role; active: boolean; createdAt: string };

const seed: Member[] = [
  { id: "m1", name: "Ananya Rao", email: "ananya@example.com", role: "admin", active: true, createdAt: "2026-01-12" },
  { id: "m2", name: "Ben Carter", email: "ben@example.com", role: "editor", active: true, createdAt: "2026-02-03" },
  { id: "m3", name: "Chloé Martin", email: "chloe@example.com", role: "viewer", active: false, createdAt: "2026-02-20" },
  { id: "m4", name: "Dev Patel", email: "dev@example.com", role: "editor", active: true, createdAt: "2026-03-08" },
  { id: "m5", name: "Elif Yilmaz", email: "elif@example.com", role: "viewer", active: true, createdAt: "2026-03-15" },
  { id: "m6", name: "Farid Haddad", email: "farid@example.com", role: "editor", active: true, createdAt: "2026-04-01" },
];

/** Local "API". Each function mirrors the HTTP call you would make: GET/POST/PATCH/DELETE /members. */
export function useMembers() {
  const [members, setMembers] = useLocalStorage<Member[]>("admin-members", seed);
  return {
    members,
    create: (m: Omit<Member, "id" | "createdAt">) => setMembers((p) => [...p, { ...m, id: "m" + Date.now().toString(36), createdAt: new Date().toISOString().slice(0, 10) }]),
    update: (id: string, patch: Partial<Member>) => setMembers((p) => p.map((m) => (m.id === id ? { ...m, ...patch } : m))),
    remove: (id: string) => setMembers((p) => p.filter((m) => m.id !== id)),
  };
}

export function validateMember(input: { name: string; email: string }) {
  const errors: Partial<Record<"name" | "email", string>> = {};
  if (input.name.trim().length < 2) errors.name = "Name must be at least 2 characters.";
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input.email)) errors.email = "Enter a valid email address.";
  return errors;
}

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-admin returns this template with its files.

Build on Admin panel

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