Etiquetas de producto para el storefront¶
Lo que la tienda necesita saber para dibujar las etiquetas que se administran desde este CMS. Escrito para quien implementa el lado del storefront, que es otra persona.
Requisito completo: RF-008. Historia #298, tarea #322.
Estado. El CMS expone la colección; el render todavía no existe. Hoy las etiquetas están escritas a mano en
src/modules/common/components/product-card/index.tsxy este trabajo las reemplaza.
La consulta¶
Lectura pública, sin autenticar. Una sola llamada, cacheable, que se hace una vez por página y no una vez por producto.
GET /api/product-badges?limit=0&depth=0&where[enabled][equals]=true&sort=priority
Son unidades o decenas de documentos, nunca miles. depth=0 alcanza: la colección no tiene
relaciones.
Cómo se asocia una etiqueta a un producto¶
Por el tag que el producto ya trae en el índice de Algolia, en product_tags. La etiqueta guarda
un slug y el storefront compara contra él.
La regla de normalización es una sola y tiene que ser la misma de los dos lados. El CMS genera
el slug con slugSinAcentos: minúsculas, sin tildes, la eñe pasa a n, todo lo que no sea
a-z0-9 se reemplaza por guion y se recortan los de las puntas. El storefront aplica esa misma
transformación a cada tag del producto antes de comparar.
"Solo Online" → "solo-online"
"SOLO_ONLINE" → "solo-online"
"Liquidación" → "liquidacion"
"⭐ Oferta" → "oferta"
Esto no es un detalle de estilo: hoy la tarjeta compara solo-hoy de forma literal en una línea y
normalizada en otra, y por eso un producto con ese tag muestra la etiqueta y además el chip gris
duplicado. Es la tarea #323.
Los pasos, en orden¶
- Filtrar por vigencia.
publishFromypublishUntilson opcionales. Vacío es sin límite. El filtro lo aplica el storefront, no la consulta, para que la respuesta siga siendo cacheable. - Filtrar por contexto.
contextses una lista:cardpara la tarjeta,productpara la ficha. Se queda con las que incluyen el contexto en el que se está dibujando. - Cruzar. Normalizar cada tag del producto y quedarse con las etiquetas cuyo
slugcoincida. - Ordenar por
priority, de menor a mayor. - Aplicar
exclusive. Si una etiqueta conexclusiveen verdadero cae en una zona, es la única que se dibuja en esa zona. - Agrupar por
sloty cortar según el tope que definas.
Dónde va cada una¶
slot dice la zona:
| Valor | Dónde |
|---|---|
over-image |
Encima de la imagen |
before-title |
Entre la imagen y el título |
after-title |
Debajo del título |
near-price |
Junto al precio |
card-footer |
Al pie de la tarjeta |
verticalPosition (top / bottom) solo llega con valor útil cuando slot es over-image.
No hay posición central a propósito: la tarjeta mide entre 119 y 202 píxeles de ancho y el centro es
donde está el producto.
align (left / center / right) aplica a todas las zonas.
El tope de etiquetas por zona lo decidís vos. El CMS entrega la lista ordenada y no sabe cuánto ancho hay. La referencia que se miró no pasa de dos por zona.
Cómo se ve¶
name es el texto a dibujar, tal cual llega, con emoji si lo tiene. No hay campo de imagen ni de
ícono en esta versión.
style trae uno de cinco nombres —oferta, promo, neutro, alerta, exito— que mapean a
los tokens que ya existen en el sistema de diseño, del estilo de bg-oferta y bg-solo-online.
El CMS guarda un nombre, no un color: qué color le corresponde a cada nombre lo decide la tienda.
Cuando style es custom, llegan bgColor, textColor y borderColor en hexadecimal.
Se aplican como estilo en línea. Una clase de Tailwind armada con un valor que viene de la base
se purga en compilación y la etiqueta sale sin color.
hasBorder dice si lleva borde y shape la forma: square, rounded o pill.
Un documento de ejemplo¶
{
"id": 3,
"name": "Solo Online",
"slug": "solo-online",
"enabled": true,
"publishFrom": null,
"publishUntil": null,
"contexts": ["card", "product"],
"style": "promo",
"hasBorder": false,
"shape": "rounded",
"slot": "before-title",
"align": "left",
"priority": 100,
"exclusive": false
}
Campos que llegan y no sirven¶
generateSlug es una casilla del panel: dice si el slug se sigue generando solo a partir del
texto. Es asunto del CMS, no de la tienda. Ignoralo.
Invalidación¶
La respuesta se cachea. Apagar o publicar una etiqueta se ve al vencer esa caché, no al instante, salvo que se agregue revalidación por gancho como hacen las páginas. Elegir un tiempo corto es razonable: la colección es chica y la consulta es barata.
Lo que hay hoy y se reemplaza¶
En product-card/index.tsx están escritas a mano: descuento, "Solo Hoy", "Solo Online", "Agotado",
"Nuevo", "¡Últimas N!" y hasta dos tags sueltos como chip gris.
De esas, solo "Solo Hoy" y "Solo Online" salen de un tag y son las que esta versión reemplaza.
Las otras se calculan de price_type, special_price, total_stock e is_new, y por ahora se
quedan como están: el CMS todavía no sabe expresar esa condición (decisión E9 del requisito).
Queda por decidir qué pasa con un tag que no tiene etiqueta definida en el CMS (decisión E7). Lo recomendado es que no se dibuje.