Ir al contenido

Banner de Garantía

Banner de garantía de producto: título, descripción, una imagen o video y un botón opcional, más un sello circular con el texto de garantía. El comerciante lo arma una vez y lo ubica en la home, en todas las categorías o productos, o en una página de producto puntual.

En el paneltipo en el JSONToken de la clave
Banner de GarantíaWARRANTY_BANNERwarranty_banner

Este tipo usa el sobre genérico de los tipos generados: los campos editables viajan dentro de campos, no en propiedades con nombre propio.

{
tipo: 'WARRANTY_BANNER'; // identificador del tipo en el bundle
titulo: string | null; // columna compartida; hoy puede venir null
nombre_personalizado?: string; // nombre interno del panel (opcional)
items: []; // siempre vacío: el contenido vive a nivel sección
campos: {
productTitle: string | null;
productDescription: string | null;
productImageUrl: string | null; // imagen o video; null si no hay archivo o no está READY
productImageMimeType: string | null; // "image/webp", "video/mp4", …; null sin archivo
productImageDurationSeconds?: number; // solo videos READY con duración registrada; si no, la clave no viene
warrantyButtonUrl: string | null;
warrantyButtonLabel: string | null;
warrantySealText: string | null;
};
estado: { lifecycle: string; storefrontVisible: boolean };
orden: number;
indice?: number; // solo cuando hay más de una sección del mismo tipo
}

items viene como array vacío, por consistencia con el resto de las secciones. Este tipo no lo usa: no lo recorras.

{
"sections": {
"warranty_banner-product-344443275-cmu7axqfa0001uhc8b8hdznmy": {
"tipo": "WARRANTY_BANNER",
"titulo": null,
"items": [],
"campos": {
"productTitle": "Botas de presoterapia PRO 3",
"productDescription": "Botas de presoterapia con 5 años de garantía oficial.",
"productImageUrl": "https://cdn.example.com/botas-pro-3.jpg",
"productImageMimeType": "image/jpeg",
"warrantyButtonUrl": "https://mitienda.com/productos/botas-pro-3/",
"warrantyButtonLabel": "Ver producto",
"warrantySealText": "5 años de garantía"
},
"estado": { "lifecycle": "active", "storefrontVisible": true },
"orden": 0
}
}
}

Todos los campos pueden ser null, así que cada parte es condicional:

const res = await fetch(
`https://sectionfy.codefy-apps.com/api/public/content/${TOKEN}/product/${PRODUCT_ID}`,
);
const { sections } = await res.json();
const garantias = Object.entries(sections)
.filter(([, s]) => s.tipo === 'WARRANTY_BANNER')
.filter(([, s]) => s.estado.lifecycle === 'active' && s.estado.storefrontVisible)
.sort(([, a], [, b]) => a.orden - b.orden);
for (const [key, seccion] of garantias) {
const { campos } = seccion;
contenedor.insertAdjacentHTML(
'beforeend',
`<section class="sectionfy-garantia" data-block="${key}">
${
!campos.productImageUrl
? ''
: campos.productImageMimeType?.startsWith('video/')
? `<video src="${campos.productImageUrl}" muted loop playsinline autoplay></video>`
: `<img src="${campos.productImageUrl}"
alt="${escapar(campos.productTitle ?? '')}" loading="lazy">`
}
<div class="sectionfy-garantia__cuerpo">
${campos.productTitle ? `<h2>${escapar(campos.productTitle)}</h2>` : ''}
${campos.productDescription ? `<p>${escapar(campos.productDescription)}</p>` : ''}
${
campos.warrantyButtonUrl
? `<a class="sectionfy-garantia__boton" href="${campos.warrantyButtonUrl}">
${escapar(campos.warrantyButtonLabel ?? 'Ver producto')}
</a>`
: ''
}
</div>
${
campos.warrantySealText
? `<div class="sectionfy-garantia__sello">${escapar(campos.warrantySealText)}</div>`
: ''
}
</section>`,
);
}
  • El sello es siempre circular. El comerciante solo carga el texto (warrantySealText); el círculo, el borde y la tipografía son decisión de tu tema.
  • La imagen puede ser un video. Decidí <img> o <video> por productImageMimeType (video/…), no por la extensión de la URL. productImageDurationSeconds es aditivo: solo llega para videos y nunca para imágenes.
  • El botón necesita warrantyButtonUrl. warrantyButtonLabel puede ser null aunque haya URL: usá un texto de respaldo, como en el ejemplo.
  • productImageUrl es null mientras el asset no esté READY. Renderizá el banner sin imagen en ese caso, no lo descartes.
  • Placements home, category y product. Llega por el bundle de contenido de la página correspondiente; no tiene endpoint propio.