From b15dea465b92f236fe261e1225ca211c423ad25e Mon Sep 17 00:00:00 2001 From: AI Bot Date: Sat, 12 Sep 2026 09:53:56 -0500 Subject: [PATCH] feat: format description aesthetics, remove horma nacional in favor of EUR, and fix duplicate notifications --- .../dripzone/app/manager/TemplateManager.kt | 2 +- .../src/app/admin/catalogo-whatsapp/page.tsx | 28 +- dripzone-app/src/app/admin/productos/page.tsx | 41 ++- .../src/app/api/webhook/whatsapp/route.ts | 72 ++++- dripzone-app/src/app/mis-pedidos/page.tsx | 6 +- .../admin/WhatsAppOrderLinkModal.tsx | 2 +- .../components/store/FormattedDescription.tsx | 258 ++++++++++++++++++ .../src/components/store/ProductModal.tsx | 17 +- dripzone-app/src/lib/evolution-api.ts | 35 ++- dripzone-app/src/lib/pricing-engine.ts | 2 +- dripzone-app/src/lib/templates-service.ts | 26 +- dripzone-app/src/lib/whatsapp-catalog.ts | 4 +- scripts/deploy_and_send_monitoring_fix.py | 116 ++++++++ 13 files changed, 564 insertions(+), 45 deletions(-) create mode 100644 dripzone-app/src/components/store/FormattedDescription.tsx create mode 100644 scripts/deploy_and_send_monitoring_fix.py diff --git a/dripzone-app/android/app/src/main/java/co/dripzone/app/manager/TemplateManager.kt b/dripzone-app/android/app/src/main/java/co/dripzone/app/manager/TemplateManager.kt index a6690f1..b09833d 100644 --- a/dripzone-app/android/app/src/main/java/co/dripzone/app/manager/TemplateManager.kt +++ b/dripzone-app/android/app/src/main/java/co/dripzone/app/manager/TemplateManager.kt @@ -49,7 +49,7 @@ object TemplateManager { "Hola {tienda_nombre}! 👋 Quiero pedir las zapatillas:\n" + "👟 *{zapatilla_nombre}*\n" + "🎨 Color: *{color_nombre}*\n" + - "📏 Talla: *{talla}* (Horma Nacional)\n" + + "📏 Talla: *{talla}* (EUR)\n" + "💎 Precio: *{precio} COP*\n" + "🚚 Entrega en: *{ciudad}* (Pago Contraentrega)\n" + "⚡ Deseo separar con $10.000 COP y cancelar el saldo en mi casa.\n\n" + diff --git a/dripzone-app/src/app/admin/catalogo-whatsapp/page.tsx b/dripzone-app/src/app/admin/catalogo-whatsapp/page.tsx index cfadd3b..6904f39 100644 --- a/dripzone-app/src/app/admin/catalogo-whatsapp/page.tsx +++ b/dripzone-app/src/app/admin/catalogo-whatsapp/page.tsx @@ -33,6 +33,7 @@ import { OFFICIAL_COLLECTION_NAMES, resolveProductCollection, } from '@/lib/whatsapp-catalog'; +import { FormattedDescription } from '@/components/store/FormattedDescription'; export default function AdminWhatsAppCatalogPage() { const [products, setProducts] = useState([]); @@ -49,6 +50,7 @@ export default function AdminWhatsAppCatalogPage() { // Modal para Generación de Enlaces de Pedido WhatsApp para Asesores const [selectedProductForLink, setSelectedProductForLink] = useState(null); const [isOrderLinkModalOpen, setIsOrderLinkModalOpen] = useState(false); + const [expandedDescId, setExpandedDescId] = useState(null); // Formulario de Meta API const [metaCatalogId, setMetaCatalogId] = useState(''); @@ -854,16 +856,34 @@ export default function AdminWhatsAppCatalogPage() {
📏 Tallas disponibles: - Horma Nacional + Tallas EUR
{sizesList}
- {/* Descripción de la publicación */} -
- {product.description || 'Producto de alta calidad con garantía y cambio asegurado.'} + {/* Descripción de la publicación con formato y vista previa estética */} +
+
+ Descripción / Copy WhatsApp: + +
+ {expandedDescId === product.id ? ( +
+ +
+ ) : ( +

+ {product.description || 'Producto de alta calidad con garantía y cambio asegurado.'} +

+ )}
{/* Botón para Asesor Comercial: Enlace Directo para WhatsApp */} diff --git a/dripzone-app/src/app/admin/productos/page.tsx b/dripzone-app/src/app/admin/productos/page.tsx index 2f56322..b0f27f5 100644 --- a/dripzone-app/src/app/admin/productos/page.tsx +++ b/dripzone-app/src/app/admin/productos/page.tsx @@ -15,6 +15,7 @@ import { cleanProductName, detectBrandFromText } from '@/lib/gemini-parser'; import { generateAttractiveProductCopy } from '@/lib/attractive-copy'; import { WhatsAppOrderLinkModal } from '@/components/admin/WhatsAppOrderLinkModal'; import { getProductPublicationDate, getProductAgeInDays, isProductOlderThanDays } from '@/lib/expiration-service'; +import { FormattedDescription } from '@/components/store/FormattedDescription'; export default function AdminProductsPage() { const [products, setProducts] = useState(INITIAL_PRODUCTS); @@ -95,6 +96,8 @@ export default function AdminProductsPage() { const [editSizesInput, setEditSizesInput] = useState(''); const [editImageUrl, setEditImageUrl] = useState(''); const [editCategory, setEditCategory] = useState(''); + const [editDescription, setEditDescription] = useState(''); + const [showDescPreview, setShowDescPreview] = useState(false); // 1-to-1 AI processor form const [rawText, setRawText] = useState(''); @@ -328,6 +331,8 @@ export default function AdminProductsPage() { setEditSizesInput(product.sizes.join(', ')); setEditImageUrl(product.images[0] || ''); setEditCategory(product.category || 'Sneakers / Urbano'); + setEditDescription(product.description || ''); + setShowDescPreview(false); }; const handleSaveEdit = async (e: React.FormEvent) => { @@ -337,7 +342,7 @@ export default function AdminProductsPage() { const sizes = editSizesInput.split(',').map((s) => s.trim()).filter(Boolean); const chosenSupplier = suppliers.find((s) => s.id === editSupplierId) || suppliers[0]; const cleanProdName = sanitizePublicationTitle(editName, [chosenSupplier.name], editBrand); - const cleanProdDesc = sanitizePublicationText(editingProduct.description || '', [chosenSupplier.name]); + const cleanProdDesc = sanitizePublicationText(editDescription || '', [chosenSupplier.name]); const updates = { name: cleanProdName, @@ -1970,6 +1975,40 @@ export default function AdminProductsPage() { />
+ {/* Descripción de la Publicación con vista previa organizada */} +
+
+ + +
+ + {!showDescPreview ? ( +