TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/davidmpizarro/QuipuEco-Hackaton/llms.txt
Use this file to discover all available pages before exploring further.
ImpactDashboard component gives users a personalised view of the environmental impact they have accumulated through every waste classification. All data is sourced from the useHistorial hook, which maintains a persistent record in localStorage under the key "quipueco_historial" — meaning the dashboard survives page refreshes, browser restarts, and even offline use. Three summary metrics are displayed at the top (CO₂ avoided, total weight, item count), followed by a gamified rank card showing the user’s current eco-tier and progress towards the next one. Below that, three tabs break the data down further: a per-category breakdown, a cumulative CO₂ area chart rendered with Recharts, and a scrollable log of the last ten classified items. This combination of real environmental data and game mechanics is designed to make recycling feel rewarding and measurable.
Accessing the Dashboard
Summary Metrics
The three top-level stat cards pull directly from thestats object returned by useHistorial:
| Metric | Source field | Description |
|---|---|---|
| kg CO₂ Evitado | stats.co2Total | Sum of co2_evitado_kg across all history entries |
| kg Peso Reciclado | stats.pesoTotal | Sum of peso_estimado_kg across all history entries |
| Items Clasificados | stats.totalItems | Total count of classification records |
Eco-Rank System
Classification activity earns Eco Points that unlock five rank tiers. The current rank and the progress bar towards the next tier are displayed in a gradient card at the top of the dashboard. Thresholds are defined in theNIVELES array in ImpactDashboard.jsx.
🌱 Semilla Eco
Threshold: 0 points
Starting rank for all users. Every classification, no matter how small, pushes you forward.
Starting rank for all users. Every classification, no matter how small, pushes you forward.
🌳 Árbol Joven
Threshold: 30 points
Reached after classifying roughly 3 recyclable items.
Reached after classifying roughly 3 recyclable items.
🌲 Bosque Verde
Threshold: 100 points
A dedicated recycler who has built a real habit.
A dedicated recycler who has built a real habit.
🦅 Guardián Eco
Threshold: 250 points
An active guardian of Lima’s environment.
An active guardian of Lima’s environment.
🏆 Héroe del Planeta
Threshold: 500 points
Maximum rank. The progress bar is replaced with a “¡Has alcanzado el rango máximo de Guardián Eco!” badge.
Maximum rank. The progress bar is replaced with a “¡Has alcanzado el rango máximo de Guardián Eco!” badge.
Points Calculation
Points are assigned per classification record by theuseHistorial hook. The logic rewards engagement with every item, including non-recyclable and hazardous waste — recognising that correctly identifying a hazardous material is itself an environmentally responsible action.
| Item type | Points |
|---|---|
| Any recyclable category (plastico, papel, vidrio, organico, metal, electronico) | +10 pts |
| Peligroso (hazardous waste) | +5 pts |
| No reciclable | +2 pts |
The useHistorial Hook
useHistorial is the single source of truth for all dashboard data. It is imported in App.jsx and its return values are passed down to both ImpactDashboard and used to seed new records via agregarRegistro.
API
agregarRegistro(resultado, imagen)
agregarRegistro(resultado, imagen)
Appends a new classification record to the history array and persists it to Called immediately after a successful
localStorage. The record merges all fields from the classification JSON with a generated id (timestamp), an ISO fecha, and the imagen data URL for the thumbnail./clasificar response in App.jsx, before the result view is rendered.limpiarHistorial()
limpiarHistorial()
Resets the history array to This is a destructive, irreversible action. There is no confirmation dialog — the button in the Historial tab triggers it directly.
[], which in turn clears localStorage via the useEffect sync. All stats drop to zero, the rank resets to Semilla Eco, and the empty-state screen is shown.stats object
stats object
A computed object derived from the full history array on every render:
| Field | Type | Description |
|---|---|---|
totalItems | number | Count of all records |
co2Total | number | Sum of CO₂ saved (kg) |
pesoTotal | number | Sum of estimated weights (kg) |
porTipo | Record<string, number> | Item count grouped by category key |
puntos | number | Total eco points |
localStorage persistence
localStorage persistence
The hook reads from and writes to Each record in the stored array includes the base64 image data URL in the
localStorage under the key quipueco_historial:imagen field. On devices with very limited localStorage quota, a large number of high-resolution images may cause a QuotaExceededError. For production use, consider storing images separately or as references to IndexedDB.Dashboard Tabs
Por tipo — category breakdown
Iterates over
stats.porTipo sorted descending by count. Each category renders a label badge (with emoji and colour from TIPO_CONFIG) and a relative-width progress bar showing that category’s share of total items.Tendencia — cumulative CO₂ area chart
Renders a Recharts The chart uses an emerald gradient fill (
AreaChart with cumulative CO₂ data. The history array is reversed (oldest first), then reduced to produce a running total:#10b981 at 40% opacity → 0%) and a 2 px stroke. The custom Tooltip is styled to match the dark app theme.Historial — last 10 entries
A scrollable
max-h-64 list showing the 10 most recent records (historial.slice(0, 10)). Each row displays:- Thumbnail image (
w-11 h-11rounded square, source from theimagendata URL) - Item name and category badge
- CO₂ saved in kg and classification date in
es-PElocale
onLimpiar (which maps to limpiarHistorial()).Empty State
Whenstats.totalItems === 0, the component renders an empty-state card instead of any metrics or tabs:
limpiarHistorial() is called.