Sobre el Proyecto
Sporting ASIX es un catálogo web de productos deportivos creado como proyecto de aprendizaje para trabajar JSON de forma práctica dentro de una aplicación web dinámica. Aunque la temática simula una tienda online, el objetivo real era comprender cómo estructurar datos, validarlos correctamente y utilizarlos desde JavaScript para generar una interfaz viva sin depender de frameworks externos.
El proyecto se desarrolló con HTML5 semántico, CSS moderno y JavaScript vanilla, de modo que todo el peso recae en tecnologías base del navegador. Esta decisión permitió reforzar conceptos fundamentales del curso y entender con claridad cómo se conectan la capa de datos, la presentación visual y la lógica de interacción.
Estructura y arquitectura
La aplicación se organiza alrededor de un fichero principal de datos (botiga.json) y un esquema de validación (botiga.schema.json). A partir de ellos, JavaScript carga la información, la valida y genera dinámicamente las distintas partes de la interfaz: categorías, tarjetas de producto, modal de detalle y elementos auxiliares como precios, stock o reseñas.
Fuente de datos
La estructura general del JSON se divide en tres bloques: tienda, categorias y productos. Esta separación fue una decisión importante porque evita duplicar información, hace más clara la organización del catálogo y facilita tanto el filtrado por categorías como el mantenimiento del contenido.
{
"tienda": { ... },
"categorias": [ ... ],
"productos": [ ... ]
}Organización del contenido
Dentro de tienda se agrupan los datos institucionales del proyecto, como nombre, eslogan, año de fundación, contacto y redes sociales. En categorias se definen los grupos del catálogo, mientras que productos contiene toda la información comercial y visual que la página necesita para representar cada artículo.
Renderizado desde datos
La idea clave es que la interfaz no nace de HTML estático repetido a mano, sino de una estructura de datos reutilizable que la aplicación interpreta para construir la experiencia completa.
Diseño del modelo de datos
Uno de los aspectos más importantes del proyecto fue diseñar un JSON que no solo almacenara información, sino que resultara cómodo de procesar desde JavaScript. Por eso, cada producto incluye campos muy definidos como sku, nombre, descripcion, marca, categoriaId, precio, stock, imagen, etiquetas, variantes y resenas.
{
"sku": "RUN-001",
"nombre": "Zapatillas Running Nike Air Zoom Pegasus",
"marca": "Nike",
"categoriaId": "CAT-RUN",
"precio": 119.99,
"precioDescuento": 99.99,
"stock": 45,
"disponible": true,
"imagen": "https://...",
"etiquetas": ["running", "zapatillas", "amortiguación"],
"variantes": [ ... ],
"resenas": [ ... ]
}Decisiones de modelado
Se optó por usar camelCase en todos los nombres de propiedad para mantener coherencia con JavaScript y permitir un acceso directo a los datos sin transformaciones extra. También fue importante mantener propiedades como variantes o precioDescuento incluso cuando su valor es null, ya que eso hace que la estructura del documento sea estable y predecible.
Las variantes se modelaron como un array anidado dentro del producto porque representan combinaciones concretas de talla y color con stock propio. De este modo, el detalle del producto puede reaccionar a la selección del usuario y mostrar información específica de cada combinación disponible.
{
"skuVariante": "RUN-001-42-NG",
"talla": "42",
"color": "Negro",
"stock": 7
}Las reseñas también se integraron dentro de cada producto en lugar de separarse en otro bloque. Esto simplifica mucho el renderizado del modal, ya que la aplicación puede leer directamente producto.resenas y construir la ficha sin búsquedas adicionales.
Validación con JSON Schema
Para asegurar que el catálogo tuviera una estructura fiable, se creó un esquema en JSON Schema. Este archivo funciona como un contrato de datos: define qué campos son obligatorios, qué tipo de dato debe tener cada propiedad y qué restricciones deben cumplirse antes de que la web procese el contenido.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["tienda", "categorias", "productos"],
"properties": {
"tienda": { "type": "object" },
"categorias": { "type": "array" },
"productos": { "type": "array" }
}
}Reglas que aporta el esquema
El esquema incluye reglas especialmente útiles, como patrones para IDs y SKUs, validación de correos y URLs, límites mínimos para precio y stock, y valores cerrados mediante enum en campos como la moneda o el color. También se emplean $defs y $ref para reutilizar subesquemas de categorías, productos, variantes y reseñas, lo que mejora la legibilidad y evita repetir definiciones.
Gracias a esta validación previa, la aplicación no depende de “suponer” que los datos están bien escritos. Antes de renderizar nada, JavaScript puede comprobar que el JSON cumple las reglas y detener la ejecución si detecta errores estructurales.
Lógica de la página y comportamiento dinámico
La parte dinámica del proyecto se desarrolla en app.js, que actúa como nexo entre los datos y la interfaz. El flujo general consiste en cargar el JSON y el esquema, validarlos, guardar la información en un estado global y después pintar el contenido en pantalla.
Carga y validación
Promise.all([
fetch('botiga.json').then(r => r.json()),
fetch('botiga.schema.json').then(r => r.json())
]).then(([datos, schema]) => {
const validate = ajv.compile(schema);
if (!validate(datos)) {
console.error(validate.errors);
return;
}
estado.tienda = datos.tienda;
estado.categorias = datos.categorias;
estado.productos = datos.productos;
renderizarPagina();
});Hidratación del estado
Este fragmento resume una de las ideas más importantes del proyecto: la interfaz no está escrita a mano producto por producto, sino que se construye a partir de datos. En otras palabras, la web deja de ser un conjunto estático de tarjetas HTML y pasa a comportarse como una aplicación capaz de interpretar información y representarla automáticamente.
Renderizado reactivo
Además, el uso de un estado centralizado permite aplicar filtros, cambiar de categoría o abrir el detalle de un producto sin recargar la página. El catálogo responde a las acciones del usuario reutilizando la información ya cargada en memoria.
Interfaz, CSS y experiencia de usuario
En la parte visual se evitó el uso de librerías como Bootstrap o Tailwind para trabajar directamente con CSS nativo. El diseño utiliza variables, flexbox, grid, clamp() y CSS Nesting, lo que hace que la hoja de estilos sea más moderna, flexible y fácil de mantener.
La interfaz está planteada para ser responsive desde el principio. La cuadrícula de productos se adapta al tamaño de pantalla, los espacios y tipografías escalan de forma fluida y el modal de detalle mantiene una lectura clara tanto en escritorio como en móvil.
Transición entre tarjeta y modal
Un punto especialmente interesante fue la experimentación con la View Transitions API, usada para suavizar el paso entre la tarjeta de producto y la vista ampliada del modal. En lugar de un cambio brusco, la imagen del producto puede “viajar” visualmente de una vista a otra.
function abrirModalProducto(productoId) {
const productCard = document.getElementById(`producto-${productoId}`);
const productImg = productCard.querySelector('img');
productImg.style.viewTransitionName = 'product-image-expand';
if (!document.startViewTransition) {
mostrarModal(productoId);
return;
}
document.startViewTransition(() => {
productImg.style.viewTransitionName = 'none';
mostrarModal(productoId);
const modalImg = document.querySelector('.modal-product-img');
modalImg.style.viewTransitionName = 'product-image-expand';
});
}Esta implementación demuestra que el proyecto no se limita a cargar datos correctamente, sino que también busca mejorar la experiencia de usuario con transiciones visuales más suaves y actuales. Además, el uso de un fallback garantiza que la funcionalidad siga operativa aunque el navegador no soporte esta API.
Aprendizajes y valor del proyecto
El valor principal de Sporting ASIX está en haber convertido un ejercicio de JSON en una aplicación web completa, donde los datos no son un complemento, sino el núcleo de todo el sistema. A través de este proyecto se trabajó la estructuración de información, la validación formal con JSON Schema, el renderizado dinámico con JavaScript y el diseño de una interfaz moderna y accesible.
Más que una tienda ficticia, el proyecto funciona como una demostración práctica de cómo diseñar bien los datos permite construir mejores interfaces. Esa relación entre estructura, validación y presentación es precisamente el aprendizaje más importante que deja este trabajo.



