P PasteCode
Indicación

Prompt para crear un panel de administración en Next.js

Prompt para agente de IA para construir un panel de administración protegido en Next.js con tablas de datos, protecciones de autenticación del lado del servidor y un diseño de barra lateral usando Tailwind.

CursorClaude CodeCodexWindsurf Next.jsPostgreSQLTypeScriptTailwind
.md .json Dificultad: Difícil Actualizado 8 jun 2026

Da este prompt a tu agente para generar un área de administración con control de roles con una barra lateral persistente, tablas de datos ordenables y comprobaciones de autenticación del lado del servidor — sin que genere un proyecto completo de Next.js o instale un framework de administración inflado.

Prompt principal

Main Prompt
You are working in an existing Next.js App Router project with TypeScript, Tailwind CSS v4,
and PostgreSQL. Auth is already set up (assume a `getSession()` helper exists in `src/lib/get-session.ts`
that returns `{ user: { id, email, role } } | null`).
Task: add an admin dashboard at the `/admin` route group.
Requirements:
- Create a `src/app/(admin)/layout.tsx` that:
- Calls `getSession()` and redirects to `/login` if the session is null or `role !== 'admin'`.
- Renders a persistent sidebar with links: Dashboard, Users, Settings.
- Uses Tailwind for layout — a fixed-width sidebar and a scrollable main area.
- Create `src/app/(admin)/dashboard/page.tsx` with:
- Four KPI cards: Total Users, Active Today, Revenue (MRR), Churn Rate — all fetched from
PostgreSQL using parameterized queries via `postgres` npm package.
- A `<UsersTable>` server component that renders the 50 most recent users (id, email, role,
created_at) with sortable column headers (URL-based sort param).
- Create `src/components/admin/KpiCard.tsx` and `src/components/admin/UsersTable.tsx`.
- All DB queries must use parameterized placeholders — never string interpolation.
- Do not install Prisma, Drizzle, or any ORM. Use the `postgres` package directly.
- Do not use any pre-built admin UI library (Refine, AdminJS, etc.).
Stop and list all planned file changes before writing any code.

Notas de implementación

  • Los paréntesis del grupo de rutas (admin) mantienen /admin/dashboard fuera de la URL mientras comparten el diseño — el agente a veces olvida los paréntesis y crea un segmento literal /admin.
  • Las columnas ordenables deben usar parámetros de URL ?sort=email&dir=asc leídos en el Componente del Servidor mediante la prop searchParams — no se necesita estado del cliente.
  • Las consultas de KPI deben ejecutarse en paralelo con Promise.all para minimizar los viajes de ida y vuelta a la base de datos.

Cambios de archivos esperados

src/app/(admin)/layout.tsx (new)
src/app/(admin)/dashboard/page.tsx (new)
src/components/admin/KpiCard.tsx (new)
src/components/admin/UsersTable.tsx (new)
src/lib/queries/admin-stats.ts (new)

Criterios de aceptación

  • Visitar /dashboard como usuario no administrador redirige a /login.
  • Las tarjetas de KPI muestran valores reales de PostgreSQL.
  • La tabla de usuarios se ordena mediante los parámetros de URL sort + dir del lado del servidor.
  • bun run build sale con código 0 sin errores de tipo.

Comandos de prueba

Terminal window
bun run typecheck
bun run build
bun run dev
# log in as admin and visit /dashboard
# visit /dashboard without auth — confirm redirect to /login
# add ?sort=email&dir=asc to the URL and confirm table order

Errores comunes de la IA

  • Crear src/app/admin/layout.tsx en lugar de src/app/(admin)/layout.tsx.
  • Realizar la comprobación de autenticación del lado del cliente, lo cual es evitable.
  • Usar interpolación de cadenas en consultas SQL: `SELECT * FROM users WHERE role = '${role}'`.
  • Obtener estadísticas de KPI secuencialmente en lugar de usar Promise.all.

Prompt de corrección

Fix Prompt
The admin layout does not redirect unauthenticated users, or the route group folder name is wrong.
Fix in order:
1. Rename `src/app/admin/` to `src/app/(admin)/` — the parentheses are required for a route group.
2. In `layout.tsx`, add the auth check at the very top using `getSession()` and `redirect('/login')`.
3. Audit all SQL query strings and replace any interpolated variables with `$1`, `$2` placeholders.
Show the corrected diff only.