Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProyectoFerretek/FerreMarket/llms.txt

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

The FerreMarket Dashboard is the central control panel for your hardware store. It aggregates live data from Supabase across four key dimensions — sales revenue, inventory valuation, product stock counts, and registered customers — and presents them in a responsive grid of KPI cards, a 7-day bar chart, a category breakdown panel, and two activity panels showing featured products and recent transactions. The Dashboard is the first screen you see after logging in and refreshes automatically every time the component mounts.

KPI Cards

Four EstadisticaCard widgets appear at the top of the Dashboard in a responsive 1 → 2 → 4 column grid. Each card displays a title, a formatted value, and an orange circular icon.

Ventas Totales

The cumulative total of all sales records in the database, formatted as Chilean pesos (CLP). Also shows a day-over-day percentage change badge (green for positive, red for negative) comparing today’s revenue against yesterday’s.

Valor del Inventario

The total monetary value of current stock, calculated as the sum of precio × stock for every product row in the productos table.

Total de Productos

The aggregate unit count across all products — i.e., the sum of every product’s stock field, not the number of distinct SKUs.

Clientes Registrados

The total number of client records in the clientes table, counting both individual and business clients.
The day-over-day increment displayed on Ventas Totales is computed by comparing the last two days in the 30-day sales array:
const incremento = Math.round((ultimoDia - penultimoDia) / penultimoDia * 100);
// If penultimoDia === 0 but ultimoDia > 0, increment is set to 100.
// If both are 0, increment is 0.

Sales Chart

The GraficoVentas component renders a bar chart of the last 7 days of sales using Recharts. It receives the full 30-day ventasPorDia array from the Dashboard and internally slices it to the most recent 7 entries.
PropertyDescription
datosArray of { fecha: string; ventas: number } — one entry per calendar day
isLoadingBoolean; while true the chart shows an animated orange spinner
How the chart data is built:
  1. The Dashboard generates an array of the last 30 calendar dates using Date.setDate.
  2. Every date is initialised with 0 in a Map<string, number>.
  3. Each Venta record is iterated; if its fecha.split('T')[0] key exists in the map, its total is added to that bucket.
  4. The map is converted to a sorted array and stored in ventasPorDia state.
The chart header also displays a 7-day total and a daily average, both formatted as CLP currency.
While the Dashboard data is loading, every KPI card displays the string "Cargando..." in place of a numeric value, and the sales chart shows a spinning loader. This loading state is driven by the isLoading boolean, which is set to true before Promise.all is called and false in the finally block — so it clears even if one of the parallel requests fails.

Product Categories

The CategoriasProductos panel sits to the right of the chart in a 2/3 + 1/3 desktop grid. It displays the six product categories defined in mockData.ts:
Category IDNameIcon
1Herramientastool
2Pinturaspaintbrush
3Electricidadzap
4Plomeríadroplets
5Materialesbox
6Jardínflower
Each category row links to the Products page with a ?categoria=<id> query parameter so that the product list is pre-filtered on arrival.

Recent Activity

Below the chart row, the Dashboard renders two equal-width panels in a 1 → 2 column grid:

ProductosDestacados

Fetches products via obtenerProductosDestacados(limit), which queries the ventas_productos join table ordered by cantidad descending. The component then filters to only those where destacado === true and sorts by ascending stock level. Product images, names, categories, prices, and stock indicators are shown.

VentasRecientes

Shows the most recent transactions ordered by fecha descending, including sale ID, client name, total amount formatted in CLP, and status badge (Completada / Pendiente / Cancelada).

Data Loading

All four primary metrics are fetched in parallel using Promise.all to minimise total load time:
const [valor, totalProductos, clientesRegistrados, ventas] = await Promise.all([
  calcularValorInventario(),   // SUM(precio * stock) from 'productos'
  calcularStockTotal(),        // SUM(stock) from 'productos'
  obtenerClientesRegistrados(), // COUNT(*) from 'clientes'
  obtenerVentas()              // SELECT * from 'ventas' + 'ventas_productos'
]);
Each function is defined in src/data/mockData.ts and communicates directly with the Supabase client. After the Promise.all resolves, the Dashboard also computes the 30-day ventasPorDia array and the day-over-day increment before setting isLoading to false.

Build docs developers (and LLMs) love