{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "zona", "type": "registry:block", "title": "zona", "description": "Bloque Concorde zona — incluye sus 11 componentes.", "dependencies": [ "react" ], "registryDependencies": [], "files": [ { "path": "bloques/zona/desktop/dimensions.ts", "type": "registry:file", "target": "bloques/zona/desktop/dimensions.ts", "content": "/**\n * Dimensiones del bloque Zona — módulo PLANO (sin \"use client\") para que los\n * Server Components (catálogo /blocks, página del bloque) puedan importar estas\n * constantes sin que se evalúen a undefined → NaN en los cálculos de escala.\n *\n * Zona = Header (vault, 64) + área blanca (24px arriba/abajo · 16px a los lados)\n * con una columna de 766 y gap 16:\n * UserProfileCard (140) · 2 cards (221) · Secondary banner (100) ·\n * OfferShelf Recomendados (352) · OfferShelf Me interesa (352) ·\n * Centro de ayuda banner (100)\n */\n\nexport const ZONA_WIDTH = 798;\n// 64 (header) + 24 + [140+16+221+16+100+16+352+16+352+16+100] + 24\nexport const ZONA_HEIGHT = 1457;\n" }, { "path": "bloques/zona/desktop/Zona.tsx", "type": "registry:file", "target": "bloques/zona/desktop/Zona.tsx", "content": "/**\n * Zona — Bloque de Concorde (Voyager DS)\n *\n * Zona de usuario (Header logueado + contenido blanco):\n * · UserProfileCard — saludo, riesgo, puntos VMC, accesos\n * · 2 columnas: WalletBalanceCard (Billetera) · ActivityCard (Tu actividad)\n * · Secondary banner (placeholder)\n * · OfferShelf «Recomendados» · OfferShelf «Me interesa» (4 OfferCards c/u)\n * · Centro de ayuda banner (placeholder)\n *\n * Bloque = composición de componentes existentes (reusa el bloque Header).\n */\n\nimport type { CSSProperties, JSX } from \"react\";\nimport AppHeader from \"@/concorde/bloques/header/desktop/Header\";\nimport UserProfileCard from \"@/concorde/components/UserProfileCard\";\nimport WalletBalanceCard from \"@/concorde/components/WalletBalanceCard\";\nimport ActivityCard from \"@/concorde/components/ActivityCard\";\nimport OfferShelf from \"@/concorde/components/OfferShelf\";\nimport { ZONA_WIDTH, ZONA_HEIGHT } from \"./dimensions\";\n\nexport { ZONA_WIDTH, ZONA_HEIGHT } from \"./dimensions\";\n\nexport interface ZonaProps {\n /** Usuario logueado — alimenta el CTA del header y el saludo de la card. */\n username?: string;\n /** Renderiza el AppHeader interno. Ponlo en `false` cuando el visor dibuja el\n * header por separado (para escalarlo aparte del cuerpo). Por defecto `true`. */\n renderHeader?: boolean;\n className?: string;\n}\n\n// Banner placeholder gris 766×100 (igual que en Homepage) — secondary / centro de ayuda.\nconst BANNER_PLACEHOLDER: CSSProperties = {\n width: 766,\n height: 100,\n borderRadius: 8,\n background: \"#E9EAEC\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: 13,\n fontWeight: 600,\n letterSpacing: \"0.06em\",\n color: \"#9AA1AC\",\n};\n\nexport default function Zona({ username = \"ZAEX5G\", renderHeader = true, className = \"\" }: ZonaProps): JSX.Element {\n return (\n \n {renderHeader ? : null}\n\n {/* Área blanca: columna de 766 (16px a cada lado = 798), gap 16 entre secciones */}\n
\n
\n {/* Tarjeta de perfil */}\n \n\n {/* 2 columnas — Billetera (izq) · Tu actividad (der) */}\n
\n \n \n
\n\n {/* Secondary banner */}\n
\n SECONDARY BANNER\n
\n\n {/* Estantes de ofertas — Recomendados / Me interesa */}\n \n \n\n {/* Centro de ayuda banner */}\n
\n CENTRO DE AYUDA\n
\n
\n
\n \n );\n}\n" }, { "path": "bloques/zona/mobile/dimensions.ts", "type": "registry:file", "target": "bloques/zona/mobile/dimensions.ts", "content": "/**\n * Dimensiones del bloque ZonaMobile — módulo plano sin \"use client\".\n */\n\nexport const ZONA_MOBILE_WIDTH = 420;\nexport const ZONA_MOBILE_HEIGHT = 2059;\n" }, { "path": "bloques/zona/mobile/ZonaMobile.tsx", "type": "registry:file", "target": "bloques/zona/mobile/ZonaMobile.tsx", "content": "\"use client\";\n\n/**\n * ZonaMobile — Bloque de Concorde (Voyager DS)\n *\n * Zona de usuario · mobile (420 de ancho):\n * · Header 420×64 logueado → «Bienvenido, ZAEX5G»\n * · UserProfileCard mobile 388×132 (2 filas: saludo + stats)\n * · WalletBalanceCard mobile 388×206 (botón CTA morado)\n * · ActivityCard mobile 388×221 (grid 2×2 de pills)\n * · Banner secundario 388×120\n */\n\nimport type { JSX } from \"react\";\nimport { useState } from \"react\";\nimport AppHeader from \"../../header/desktop/Header\";\nimport AvatarZone from \"../../../components/AvatarZone\";\nimport StarIcon from \"../../../components/StarIcon\";\nimport InfoIcon from \"../../../components/InfoIcon\";\nimport ProfileButton from \"../../../components/ProfileButton\";\nimport WalletBalanceCard from \"../../../components/WalletBalanceCard\";\nimport ActivityCard from \"../../../components/ActivityCard\";\nimport CardTitle from \"../../../components/CardTitle\";\nimport OfferCard from \"../../../components/OfferCard\";\nimport BadgeStatus from \"../../../components/BadgeStatus\";\nimport SidebarMobile, { SidebarMenuButton } from \"../../sidebar/mobile/SidebarMobile\";\n\nimport { ZONA_MOBILE_WIDTH, ZONA_MOBILE_HEIGHT } from \"./dimensions\";\nexport { ZONA_MOBILE_WIDTH, ZONA_MOBILE_HEIGHT } from \"./dimensions\";\n\nconst ZM_STYLES = `\n/* WalletBalanceCard — override mobile (388×206, botón morado) */\n.zm-wallet.wbc { width: 388px; height: 206px; border-radius: 8px; }\n/* ActivityCard — override mobile (388×221) */\n.zm-activity.actcard { width: 388px; border-radius: 8px; }\n.zm-wallet .wbc__acquire {\n background-image:\n linear-gradient(159deg, #8460E5 0%, #3B1782 100%),\n linear-gradient(135deg, #CFBAFF 0%, #FFFFFF 35%, #AE8EFF 65%, #CFBAFF 100%);\n box-shadow: rgba(255,255,255,0.22) 0 1px 0 2px inset, rgba(132,96,229,0.3) 0 2px 8px;\n}\n.zm-wallet .wbc__acquire:hover {\n box-shadow: rgba(255,255,255,0.2) 0 1px 0 2px inset, rgba(132,96,229,0.4) 0 8px 24px, rgba(132,96,229,0.25) 0 4px 10px;\n}\n/* Texto degradado \"¡Hola, {username}!\" */\n.zm-greeting {\n background: linear-gradient(90deg, #ED8936 0%, #ED8936 40%, #8460E5 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n font-size: 16px;\n font-weight: 700;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.zm-stat-label {\n font-size: 10px;\n font-weight: 500;\n color: #9AA1AC;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n.zm-stat-value {\n font-size: 13px;\n font-weight: 700;\n color: #ED8936;\n margin-top: 2px;\n}\n.zm-pts {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 13px;\n font-weight: 700;\n color: #3B1782;\n margin-top: 2px;\n}\n/* Mobile OfferShelf — 388px wide, grid 2×2 de OfferCards 170×232 */\n.zm-shelf {\n width: 388px;\n box-sizing: border-box;\n background: #ffffff;\n border-radius: 8px;\n box-shadow: 0 0 8px 4px rgba(0,0,0,0.08);\n padding: 20px 16px 16px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n.zm-shelf__grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n}\n`;\n\nexport interface ZonaMobileProps {\n username?: string;\n className?: string;\n /** Alto del marco para previsualizaciones (px). En producción se omite. Ver `SidebarMobile`. */\n frameHeight?: number;\n}\n\nexport default function ZonaMobile({ username = \"ZAEX5G\", className = \"\", frameHeight }: ZonaMobileProps): JSX.Element {\n const [menuOpen, setMenuOpen] = useState(false);\n\n const page = (\n \n