LoyaltyBlock.tsx
SubscriptionBlock.tsx
shopify.extension.toml
// customer-account.profile.block.render // Target: Perfil del cliente — Bloque de puntos de fidelidad // OrigenVerde · CULTIVA IA import "@shopify/ui-extensions/preact"; import { render } from "preact"; import { useApi, useCustomer, useMetafield, useState, } from "@shopify/ui-extensions-react/customer-account"; interface LoyaltyData { points: number; level: "basico" | "plus" | "premium"; } const LEVELS = { basico: { min: 0, max: 2499, label: "Verde Básico", icon: "🌱" }, plus: { min: 2500, max: 4999, label: "Verde Plus", icon: "🌿" }, premium: { min: 5000, max: Infinity, label: "Verde Premium", icon: "🍀" }, }; function getLevel(pts: number): keyof typeof LEVELS { if (pts >= 5000) return "premium"; if (pts >= 2500) return "plus"; return "basico"; } function LoyaltyBlock() { const [modalOpen, setModalOpen] = useState(false); // Leer puntos del metafield custom del cliente const pointsMeta = useMetafield({ namespace: "origenverde", key: "loyalty_points", }); const points = parseInt(pointsMeta?.value ?? "0", 10); const levelKey = getLevel(points); const level = LEVELS[levelKey]; const nextLevel= levelKey === "plus" ? LEVELS.premium : null; const progress = nextLevel ? Math.round(((points - level.min) / (nextLevel.min - level.min)) * 100) : 100; return ( <s-section heading="Mis Puntos Verdes"> {/* Nivel actual con avatar */} <s-stack direction="inline" gap="base" align-items="center"> <s-avatar initials="LG" size="large" alt="Laura García" /> <s-stack direction="block" gap="tight"> <s-text type="strong">{level.icon} {level.label}</s-text> <s-badge tone="success">Cliente Fiel</s-badge> </s-stack> </s-stack> {/* Puntos */} <s-box padding="base" background="subdued" border-radius="base"> <s-stack direction="inline" align-items="center" gap="loose"> <s-text tone="success">Puntos acumulados</s-text> <s-text type="strong" tone="success"> {points.toLocaleString("es-ES")} pts </s-text> </s-stack> </s-box> {/* Progreso hacia Premium */} {nextLevel && ( <s-stack direction="block" gap="tight"> <s-stack direction="inline" gap="loose"> <s-text>Hacia Verde Premium</s-text> <s-text>{progress}%</s-text> </s-stack> <s-progress value={progress} max={100} tone="auto" accessibility-label="Progreso hacia Verde Premium" /> </s-stack> )} {/* Botón canjear */} <s-button-group> <s-button variant="primary" command-for="redeem-modal"> Canjear puntos </s-button> <s-button variant="secondary">Ver historial</s-button> </s-button-group> {/* Modal de canje */} <s-modal id="redeem-modal" heading="Canjear Puntos Verdes"> <s-choice-list label="Selecciona tu descuento" name="redeem_option"> <s-choice value="500">500 pts → 5€ descuento</s-choice> <s-choice value="1000">1.000 pts → 12€ descuento</s-choice> <s-choice value="2000">2.000 pts → Envío gratis 3 pedidos</s-choice> </s-choice-list> <s-button variant="primary">Confirmar canje</s-button> </s-modal> </s-section> ); } render("customer-account.profile.block.render", () => <LoyaltyBlock />);
shopify.extension.toml
api_version = "2026-01" [[extensions]] type = "ui_extension" name = "origenverde-loyalty-block" handle = "origenverde-loyalty" [[extensions.targeting]] module = "./src/LoyaltyBlock.tsx" target = "customer-account.profile.block.render" [[extensions]] type = "ui_extension" name = "origenverde-subscription-block" handle = "origenverde-subscription" [[extensions.targeting]] module = "./src/SubscriptionBlock.tsx" target = "customer-account.order-index.block.render"
Mi Cuenta
¡Hola, Laura! Bienvenida de vuelta.
Extensión activa: customer-account.order-index.block.render
Mi Suscripción Eco
Activa
Plan
Caja Familiar
Precio
79,90 €/mes
Pedidos este año
7
Extensión activa: customer-account.profile.block.render
Mis Puntos Verdes
Verde Plus
Verde Plus
Nivel 2 de 3 · Desbloqueado con 2.500 pts
Puntos acumulados
3.240
pts
Con Verde Premium desbloqueas:
✓ Envío gratis siempre
✓ Acceso anticipado a productos nuevos
✓ 15% descuento en cada caja
Últimos pedidos
#OV-2847
5 jun 2026 · Caja Familiar Eco
79,90 €
Entregado
#OV-2791
3 may 2026 · Caja Familiar Eco + extras
112,40 €
Entregado
#OV-2734
1 abr 2026 · Caja Familiar Eco
79,90 €
Entregado