Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/akibanks/tienda_musica_web/llms.txt

Use this file to discover all available pages before exploring further.

The admin panel (admin.html + admin.js) provides a dashboard for managing users and sales. Access is restricted to users with esAdmin === 'true' or esDemo === 'true' in localStorage. Demo users see all data but cannot make changes — all action controls are rendered in a disabled state and a read-only banner is inserted below the header.

Access Control

On page load, admin.js reads vv_token, esAdmin, and esDemo from localStorage. If the token is missing, or if neither esAdmin nor esDemo is true, an error toast reading “Acceso denegado.” is shown and the user is redirected to index.html after 1.5 seconds.
The admin panel enforces access on the frontend as a UX guard. The backend independently validates the JWT for every admin endpoint (GET /admin/usuarios, GET /admin/ventas, PUT, DELETE, etc.), so removing the client-side check would not grant actual access to data.
Users and sales data are both fetched in parallel on load via Promise.all([cargarUsuarios(), cargarVentas()]). Statistics are computed from those responses immediately after.

Statistics Dashboard

Four stat cards are displayed at the top of the panel. All values are derived from the same two requests made at initialization — no additional API calls are needed for the stats.

Total Users

Count of all entries returned by GET /admin/usuarios

Total Sales

Count of all entries returned by GET /admin/ventas

Revenue

Sum of total across all sales records

Pending Sales

Count of sales where estado === 'pendiente'
Stats are refreshed after any write operation (role change, user deletion, or status update) by calling cargarStats(), which re-fetches both endpoints and recomputes all four values.

User Management

The Usuarios tab shows a table of all registered accounts. Data is fetched once and filtered client-side. Table columns: ID · Name · Email · Role · Created At · Actions filtrarUsuarios(q) filters the in-memory _usuarios array by name or email (case-insensitive) and re-renders the table without a network request.

Role Management

async function cambiarRol(id, nuevoRol)
Calls PUT /admin/usuarios/{id}/rol with body { "rol": "nuevo_rol" }. The current admin cannot remove their own admin role — this is enforced by decoding the JWT payload (atob(token.split('.')[1])) to compare the current user’s ID with the target row’s ID. If they match and nuevoRol !== 'admin', the operation is blocked and the table is re-rendered to revert the select visually. Available roles:
RoleDescription
clienteStandard customer account
vendedorSeller account
adminFull admin panel access with write permissions

User Deletion

confirmarEliminarUsuario(id, nombre) replaces the action cell in the target table row with an inline confirmation prompt — “¿Eliminar a ""?” — and two buttons: Confirmar and Cancelar. Confirming calls eliminarUsuario(id, nombre), which sends DELETE /admin/usuarios/{id}. On success, the user is removed from the local _usuarios array, the table is re-rendered, and statistics are refreshed. Cancelling re-renders the table with the original action buttons.

Sales Management

The Ventas tab shows all orders placed through the store. Data is fetched in parallel with users on page load. Table columns: ID · User · Total · Status · Date · Actions

Search

filtrarVentas(q) filters the in-memory _ventas array by sale ID or customer name (case-insensitive) and re-renders the table client-side.

Status Updates

async function cambiarEstadoVenta(id, nuevoEstado)
Calls PUT /admin/ventas/{id}/estado with body { "estado": "nuevo_estado" }. On success, the local _ventas entry is updated and statistics are refreshed. Possible statuses:
StatusMeaning
pendienteOrder placed, not yet processed
pagadaPayment confirmed
enviadaOrder shipped
entregadaOrder delivered to customer
canceladaOrder cancelled

Sale Detail Modal

Clicking “Ver detalle” on any row calls verDetalleVenta(id), which fetches GET /admin/ventas/{id} for the full order record. The detail modal displays:
  • Order header — sale ID, customer name, and current status badge
  • Item list — each line shows the album title, quantity (×N), and line subtotal
  • Order total — highlighted in amber
  • Shipping address — recipient name, full address with interior number when present, and delivery references

Demo / Read-Only Mode

When esDemo === true and esAdmin === false, the panel enters read-only mode. The _esDemo flag is set to true at initialization and controls all disabled states throughout the page. A banner is inserted immediately below the admin header:
👁 Modo solo lectura — esta cuenta no puede realizar cambios
In this mode, every role <select> and action button across both the Users and Sales tables is rendered with the disabled attribute and reduced opacity (opacity: 0.4; cursor: not-allowed), preventing any write operations from being triggered.
Even if a demo user manually removes the disabled attribute via browser DevTools, the backend will reject any write requests because the JWT’s role claim does not carry admin privileges.

Build docs developers (and LLMs) love