Armería: búsqueda insensible a mayúsculas, autocompletar y proxy del visor 3D

Tres arreglos:

1) Búsqueda insensible a mayúsculas/minúsculas. Las consultas usaban LIKE directo
   (sensible según la colación de la tabla), así que 'test' no encontraba 'Test'.
   Ahora comparan con LOWER(col) LIKE LOWER(?).

2) Autocompletar tipo wowhead. Nuevo /api/armory/suggest + ArmorySearchBox
   reescrito: al teclear (≥1 carácter, con debounce) muestra un desplegable con
   personajes, ítems y hermandades que coinciden; clic va directo a la ficha/wowhead.
   Enter o el botón siguen haciendo la búsqueda completa.

3) Visor 3D «no disponible». Causa: el contenido de wow.zamimg.com/modelviewer no
   envía cabeceras CORS (el propio README de wow-model-viewer pide un proxy). Se
   añade un rewrite en next.config (/modelviewer/* -> zamimg) para servirlo
   same-origin, y el visor usa esas rutas. Además, si falla la resolución de ítems
   se renderiza el personaje sin equipo, y los errores se registran en consola para
   diagnóstico.

Verificado: 'test' encuentra 'Test'; el autocompletar responde; el proxy
/modelviewer/live/viewer/viewer.min.js sirve 200 same-origin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-16 14:41:06 +00:00
parent 297257b753
commit 65f6776969
6 changed files with 221 additions and 30 deletions
+22 -1
View File
@@ -1,9 +1,30 @@
/* Estilos de la armería, en la línea del tema (oscuro + dorado #d79602). Reutiliza
main-wide, nice_button, forum-input y los colores de calidad qN de forum.css. */
.armory-search { display: flex; gap: 10px; align-items: center; margin: 10px 0 18px; flex-wrap: wrap; }
.armory-search { position: relative; margin: 10px 0 18px; }
.armory-search-form { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.armory-search .forum-input { flex: 1 1 260px; margin: 0; }
/* Desplegable de autocompletar (tipo wowhead) */
.armory-suggest {
position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 50; max-height: 420px; overflow-y: auto;
background: #14110d; border: 1px solid #2a2723; border-radius: 4px;
box-shadow: 0 8px 24px rgba(0, 0, 0, .6);
}
.armory-suggest-group { border-bottom: 1px solid #201d18; }
.armory-suggest-group:last-child { border-bottom: 0; }
.armory-suggest-head {
font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #6d6a5e; font-weight: bold;
padding: 6px 12px; background: rgba(255, 255, 255, .02);
}
.armory-suggest-item {
display: flex; justify-content: space-between; align-items: center; gap: 10px; width: 100%;
padding: 8px 12px; background: none; border: 0; cursor: pointer; text-align: left; text-decoration: none;
font-size: 13px; font-weight: bold; color: #d4cdbb; transition: background .1s;
}
.armory-suggest-item:hover { background: rgba(255, 255, 255, .05); }
.armory-suggest-sub { font-size: 11px; color: #6d6a5e; font-weight: normal; white-space: nowrap; }
.armory-tabs { display: flex; gap: 6px; border-bottom: 1px solid #2a2723; margin-bottom: 16px; flex-wrap: wrap; }
.armory-tab {
padding: 8px 16px; color: #8a8578; text-decoration: none; font-weight: bold; text-transform: uppercase;