fix(vcard-api): corregir tab Planes con campos reales de la API
- Corrección: p.activo → p.estado (activo no existe en la respuesta) - Corrección: tarifas usan t.monto, no t.precio/t.moneda/t.periodo - Mejora: precios únicos resumidos con helper uniqueMontos() (max 5) - Añade: img del plan, cantidad de vcards permitidas, conteo de tarifas por país - Añade: ID del plan al pie de cada card Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot
parent
5a1a8857a1
commit
15b38203f2
@@ -196,22 +196,35 @@
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4" x-show="items.length > 0">
|
||||
<template x-for="p in items" :key="p.id || p._id">
|
||||
<div class="border rounded-xl p-4 bg-white shadow-sm hover:shadow-md transition">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="font-semibold text-sm" x-text="p.nombre || '—'"></span>
|
||||
<span :class="p.activo ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'"
|
||||
class="text-xs px-2 py-0.5 rounded-full" x-text="p.activo ? 'Activo' : 'Inactivo'"></span>
|
||||
<!-- Header -->
|
||||
<div class="flex items-start justify-between mb-2 gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<img x-show="p.img" :src="'https://vcard.u-site.app/' + p.img"
|
||||
class="h-8 w-8 rounded object-cover border shrink-0" onerror="this.style.display='none'" />
|
||||
<span class="font-semibold text-sm" x-text="p.nombre || '—'"></span>
|
||||
</div>
|
||||
<span :class="p.estado ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'"
|
||||
class="text-xs px-2 py-0.5 rounded-full shrink-0" x-text="p.estado ? 'Activo' : 'Inactivo'"></span>
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 mb-2" x-text="p.descripcion || ''"></p>
|
||||
<div class="text-xs text-gray-600 space-y-1">
|
||||
<div x-show="p.tarifas && p.tarifas.length">
|
||||
<template x-for="t in (p.tarifas || [])" :key="t.id">
|
||||
<div class="flex justify-between">
|
||||
<span x-text="t.periodo || '—'"></span>
|
||||
<span class="font-mono" x-text="(t.moneda || '') + ' ' + (t.precio || '—')"></span>
|
||||
</div>
|
||||
<!-- Descripción -->
|
||||
<p class="text-xs text-gray-500 mb-2 line-clamp-2" x-text="p.descripcion || ''"></p>
|
||||
<!-- Cantidad vcards -->
|
||||
<div x-show="p.cantidad" class="text-xs text-gray-600 mb-2">
|
||||
<span class="font-medium">VCards permitidas:</span>
|
||||
<span x-text="p.cantidad"></span>
|
||||
</div>
|
||||
<!-- Precios únicos (resumidos) -->
|
||||
<div x-show="p.tarifas && p.tarifas.length" class="mt-2">
|
||||
<p class="text-xs font-medium text-gray-500 uppercase tracking-wide mb-1">Precios (muestra)</p>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<template x-for="t in uniqueMontos(p.tarifas || [])" :key="t">
|
||||
<span class="text-xs bg-gray-100 text-gray-700 px-2 py-0.5 rounded font-mono" x-text="t === '0' || t === 'Gratis' ? 'Gratis' : ('$' + t)"></span>
|
||||
</template>
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mt-1" x-text="(p.tarifas||[]).length + ' tarifas por país'"></p>
|
||||
</div>
|
||||
<!-- ID -->
|
||||
<p class="text-xs text-gray-300 font-mono mt-3 truncate" x-text="p._id || p.id"></p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -1460,6 +1473,11 @@ function vcardApiApp() {
|
||||
this.loadTab();
|
||||
},
|
||||
|
||||
uniqueMontos(tarifas) {
|
||||
const montos = [...new Set(tarifas.map(t => t.monto || '—'))];
|
||||
return montos.slice(0, 5); // max 5 precios únicos
|
||||
},
|
||||
|
||||
async loadPlanes() {
|
||||
try {
|
||||
const r = await fetch('/app/vcard-api/planes');
|
||||
|
||||
Reference in New Issue
Block a user