Files
NightSpire/web-next/app/forum.css
T
Inna af707ad98c Foro: reemplazar el foro anterior por el port del foro estilo FusionCMS
Se sustituye por completo el foro anterior de Next (que estaba vacío: 0 temas, 0
posts) por una adaptación del foro PHP de FusionCMS que tenía el usuario, con su
estructura, sus imágenes y su estética, llevadas a Next.

BASE DE DATOS (acore_web), esquema idéntico al original (sql/forum_fusion.sql):
  forum_categories(id, order, name)
  forum_forums(id, category, order, name, description, icon, colortitle, type)
  forum_topics(id, forum, name, sticky, locked, deleted, created)
  forum_posts(id, topic, poster, text, time, deleted)
Se hizo DROP de las tablas antiguas (forums, forum_categories, forum_topics,
forum_posts) y CREATE de estas, con el seed original (News/Reports/General,
foros con icono, clases con color, subforos por idioma con bandera). Única
diferencia con el dump: forum_topics.created, que faltaba y usan las vistas, y
el recorte del salto de línea final en los nombres de clase.

Los temas no guardan autor ni última actividad: se derivan del primer/último post,
como en el original. `poster` es el AccountID de acore_auth; el nombre se resuelve
al render (username sin el sufijo #N de Battle.net). El texto se guarda como HTML
saneado con nh3 (no BBCode) para encajar con el editor.

EDITOR: TinyMCE community self-hosted (licenseKey gpl), servido desde /tinymce
(scripts/copy-tinymce.mjs en postinstall; public/tinymce en .gitignore por ser
artefacto). El HTML se sanea SIEMPRE en el servidor.

PÁGINAS (app/[locale]/forum): índice con los 3 tipos de foro (fila normal, tarjeta
de clase tipo 1, tarjeta de idioma tipo 2), subforo, tema, crear y editar. La
lógica de forum.js (crear/responder/editar/moderar) se portó a fetch + los avisos
del sitio, sin jQuery/SweetAlert, y la moderación pasa por POST (no GET).

CSS: forum.css adaptado al tema (app/forum.css), rutas de imagen a /forum, dorado
alineado al acento del sitio (#d79602), y se aportan .nice_button/.main-wide/
.pagination que no estaban en theme.css.

ADMIN: lib/admin-forum.ts, sus rutas y AdminForumManager reescritos al esquema
nuevo (categoría, icono, color, tipo, orden; sin _en/visibility).

Se eliminan /forum/search y /forum/user (no existen en el foro nuevo) y los
componentes que quedaban huérfanos (ForumSearchBox, PostActions, TopicModBar,
NewTopicForm). i18n ES/EN completado (next-intl).

Verificado en producción: el índice renderiza en es/en con categorías, clases,
banderas e iconos; los assets y TinyMCE sirven 200; crear tema y responder guardan
las filas con el esquema correcto y las páginas las muestran (autor resuelto, HTML
saneado). Datos de prueba borrados: el foro arranca vacío.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 12:22:08 +00:00

243 lines
12 KiB
CSS

/*
* Estilos del foro (adaptado del forum.css original de FusionCMS).
* Cambios respecto al original:
* - rutas de imagen ../images/ -> /forum/ (assets en public/forum, ver copia)
* - el dorado del foro se alinea al acento del sitio (#d79602)
* - se aportan .nice_button, .main-wide y .pagination (no están en theme.css)
* theme.css se importa DESPUÉS y podría pisar reglas: por eso el foro cuelga de
* contenedores propios (.forum-container, .forum-padding, .topic_post…).
*/
:root {
--forum-gold: #d79602;
--forum-gold-soft: #c9a33c;
}
/* ===================== index ===================== */
.forum-container { margin: 0 40px; }
.category-title {
display: block;
color: #8a8272;
font-size: 15px;
font-weight: bold;
text-shadow: 0 0 8px #000, 0 1px 1px #000;
text-transform: uppercase;
text-align: left;
}
.forum-row {
width: 100%;
min-height: 75px;
display: flex;
align-items: center;
flex-wrap: wrap;
text-align: left;
border-radius: 3px;
overflow: hidden;
background: rgba(0, 0, 0, .18);
box-shadow: 0 0 11px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .03);
transition: all 200ms;
}
.forum-row:hover { box-shadow: 0 0 11px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .05); }
.forum-row .icon img { margin: 6px 0 0 6px; }
.forum-row .forum_title_desc { text-align: left; flex: 1 1 220px; }
.forum-row .forum_title_desc a { display: block; }
.forum-row .forum_title_desc a h1 {
font-size: 14px; color: var(--forum-gold); font-weight: bold; margin: 8px 0 0 20px; transition: all 200ms;
}
.forum-row .forum_title_desc a:hover h1 { color: #f0b53a; }
.forum-row .forum_title_desc a h2 { font-size: 12px; color: #6d6a5e; font-weight: bold; margin: 4px 0 8px 20px; }
.forum-row .post, .forum-row .topics { min-width: 78px; text-align: center; }
.forum-row .post p, .forum-row .topics p { font-size: 15px; color: #8a8578; font-weight: bold; margin: 24px 0; }
.forum-row .lastpost { flex: 1 1 200px; padding-left: 12px; }
.forum-row .lastpost p.topic_title a { font-size: 12px; color: #8d8370; font-weight: bold; }
.forum-row .lastpost p.topic_title a:hover { color: var(--forum-gold); }
.forum-row .lastpost p.by { margin: 0 0 0 15px; }
.forum-row .lastpost p.by a { font-size: 12px; font-weight: bold; color: var(--forum-gold-soft); }
.forum-row .lastpost p.postdate { font-size: 11px; color: #6d6a5e; margin: 0 0 0 15px; }
/* class tiles (type 1) & flag tiles (type 2) */
.class-row {
display: flex;
align-items: center;
width: 100%;
min-height: 53px;
overflow: hidden;
background: rgba(0, 0, 0, .18);
box-shadow: 0 0 11px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .03);
border-radius: 4px;
transition: all 200ms;
}
.class-row:hover { box-shadow: 0 0 11px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .05); }
.class-row .icon { width: 36px; height: 36px; margin: 8px; flex: 0 0 auto; }
.class-row .icon img.image_icon { width: 36px; height: 36px; border-radius: 3px; box-shadow: 0 0 6px rgba(0, 0, 0, .4); }
.class-row .icon div.image_icon {
width: 36px; height: 36px;
background-image: url(/forum/forum_icons/icons.jpg);
background-repeat: no-repeat;
border-radius: 3px;
box-shadow: 0 0 6px rgba(0, 0, 0, .4);
}
.deathknight .icon div.image_icon { background-position: 0 0; }
.druid .icon div.image_icon { background-position: -36px 0; }
.hunter .icon div.image_icon { background-position: -72px 0; }
.mage .icon div.image_icon { background-position: -108px 0; }
.paladin .icon div.image_icon { background-position: -144px 0; }
.priest .icon div.image_icon { background-position: -180px 0; }
.rogue .icon div.image_icon { background-position: -216px 0; }
.shaman .icon div.image_icon { background-position: -252px 0; }
.warlock .icon div.image_icon { background-position: -288px 0; }
.warrior .icon div.image_icon { background-position: -324px 0; }
.monk .icon div.image_icon { background-position: -360px 0; }
.demonhunter .icon div.image_icon { background-position: -396px 0; }
.evoker .icon div.image_icon { background-position: -432px 0; }
.class-row .info { margin: 0 0 0 4px; text-align: left; }
.class-row .info a { display: block; }
.class-row .info a h1 { font-size: 13px; color: var(--forum-gold); }
.class-row .info a h2 { font-size: 11px; color: #6d6a5e; }
.forum-path { margin-bottom: 10px; display: block; color: var(--forum-gold); font-weight: bold; }
.forum-path a { color: var(--forum-gold); opacity: .7; }
.forum-path a:hover { opacity: 1; }
.forum-path .sep { opacity: .4; margin: 0 6px; }
/* ===================== subforum ===================== */
.main-wide { max-width: 1100px; margin: 0 auto; padding: 0 15px; }
.forum-padding { margin: 0 30px; }
.forum_header, .topic_header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin: 20px 0;
padding-bottom: 12px;
box-shadow: 0 2px 0 rgba(0, 0, 0, .25);
}
.forum_title h1 { font-size: 24px; color: var(--forum-gold); }
.forum_title h3 { font-weight: bold; font-size: 13px; color: #6d6a5e; }
.forum_header h4, .topic_header h4 { font-size: 20px; color: #6d6a5e; font-weight: normal; }
.forum_header h4 b, .topic_header h4 b { color: var(--forum-gold-soft); }
.actions_c { display: flex; justify-content: space-between; align-items: center; margin: 0 0 24px; flex-wrap: wrap; gap: 10px; }
ul.pagination { display: flex; list-style: none; padding: 0; margin: 0; gap: 3px; flex-wrap: wrap; }
ul.pagination li a, ul.pagination li p {
display: block; min-width: 24px; height: 24px; line-height: 24px; padding: 0 6px;
background: rgba(241, 221, 196, .07); border-radius: 3px; text-align: center; color: #8a8578;
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .02), 0 1px 1px rgba(0, 0, 0, .4);
}
ul.pagination li.active p { color: var(--forum-gold); font-weight: bold; }
ul.pagination li a:hover { color: var(--forum-gold); }
ul.topic_row {
display: flex; flex-wrap: nowrap; align-items: center; width: 100%; list-style: none; margin: 0 0 6px; padding: 0;
background: rgba(0, 0, 0, .18);
box-shadow: 0 0 11px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .03);
border-radius: 3px;
}
ul.topic_row li { text-shadow: 0 0 6px rgba(0, 0, 0, .5), 0 1px 1px rgba(0, 0, 0, .6); }
ul.topic_row .icon { width: 60px; flex: 0 0 auto; }
ul.topic_row .icon img { margin: 8px 0 0 4px; }
ul.topic_row li.topic_title_by_date { flex: 1 1 auto; text-align: left; }
ul.topic_row li.topic_title_by_date h1 { margin: 11px 0 0 14px; }
ul.topic_row li.topic_title_by_date h1 a { font-size: 13px; font-weight: bold; color: var(--forum-gold); }
ul.topic_row li.topic_title_by_date h1 a:hover { color: #f0b53a; }
ul.topic_row li.topic_title_by_date p { margin: 3px 0 8px 14px; font-weight: bold; font-size: 11px; color: #6d6a5e; }
ul.topic_row li.topic_title_by_date p a.username { color: var(--forum-gold-soft); }
ul.topic_row .lastpost { flex: 0 0 220px; padding-left: 14px; color: #6d6a5e; text-align: left; }
ul.topic_row .lastpost h4 { margin: 13px 0 0 0; font-size: 11px; }
ul.topic_row .lastpost h4 a { color: var(--forum-gold-soft); }
ul.topic_row .lastpost h5 { margin: 2px 0 8px; font-size: 11px; color: #6d6a5e; }
.forum-empty { text-align: center; color: #6d6a5e; padding: 30px 0; }
/* ===================== posts ===================== */
.topic_title h1 { font-size: 22px; color: var(--forum-gold); margin: 0 0 5px; font-weight: bold; }
.topic_title h3 { font-weight: bold; font-size: 13px; color: #6d6a5e; }
.topic_post {
display: flex; flex-wrap: wrap; width: 100%;
background: rgba(0, 0, 0, .18);
box-shadow: 0 0 11px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .03);
border-radius: 3px; margin: 0 0 30px;
}
.topic_post.isStaff {
box-shadow: inset 0 0 1px rgba(96, 76, 65, .3), 0 0 0 1px #251d19, 0 2px 2px rgba(0, 0, 0, .3), inset 0 0 46px rgba(255, 68, 0, .12);
}
.topic_post .left_side {
flex: 0 0 200px; padding: 10px; background: rgba(0, 0, 0, .25);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .03);
}
.topic_post .right_side { flex: 1 1 320px; display: flex; flex-direction: column; }
.username_container { display: block; margin: 6px 0 0; text-align: center; }
.username_container a.username { font-size: 14px; color: var(--forum-gold-soft); font-weight: bold; }
.topic_post .left_side .user_avatar {
width: 86px; height: 86px; border-radius: 3px; margin: 16px auto; overflow: hidden;
background: rgba(69, 67, 62, .5);
box-shadow: inset 0 0 1px 1px rgba(255, 255, 255, .05), inset 0 0 28px rgba(0, 0, 0, .8), 0 0 16px rgba(0, 0, 0, .6);
}
.topic_post .left_side .user_avatar.isStaff { border: 1px solid #813c26; box-shadow: 0 0 21px rgba(240, 106, 59, .45); }
.topic_post .left_side .user_avatar span { display: block; width: 100%; height: 100%; }
.topic_post .left_side .user_info { text-align: center; }
h3.post_field {
border: 1px solid #212322; border-radius: 5px; margin: 8px 4px; display: flex; align-items: center; gap: .5rem; padding: 8px;
font-size: 12px; font-weight: bold; color: #8a8578;
}
h3.post_field dt { min-width: auto; }
h3.post_field dd { margin: 0; }
.badge_staff { color: #f06a3b; }
.topic_post .right_side .post_container {
padding: 14px; font-size: 13px; color: #b5b1a3; min-height: 120px;
text-shadow: 0 1px 1px rgba(0, 0, 0, .6);
}
.topic_post .right_side .post_container img { display: block; max-width: 100%; height: auto; }
.topic_post .right_side .post_container a { color: var(--forum-gold-soft); text-decoration: underline; }
.post_deleted { opacity: .5; }
ul.post_controls { display: flex; justify-content: flex-end; align-items: center; gap: 8px; list-style: none; padding: 15px; margin: auto 0 0; }
ul.post_controls li { height: 20px; }
ul.post_controls li a {
display: block; border-radius: 2px; padding: 4px 8px; background: rgba(255, 255, 255, .04); font-weight: bold; color: #8a8578;
box-shadow: 0 1px 1px rgba(0, 0, 0, .13), inset 0 1px 1px rgba(255, 255, 255, .04);
}
ul.post_controls li a:hover { background: rgba(255, 255, 255, .08); color: var(--forum-gold); }
ul.post_controls .post_date { color: #6d6a5e; font-weight: bold; font-size: 11px; margin-right: auto; }
/* quick reply / editor */
.quick_reply { padding: 0 20px 20px; background: rgba(0, 0, 0, .18); border-radius: 3px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .03); }
.quick_reply h2 { font-size: 14px; color: #8a8578; padding: 18px 0; text-transform: uppercase; text-align: left; }
.forum-form-actions { display: flex; align-items: center; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.forum-form-actions .right-0 { margin-left: auto; }
.forum-input {
width: 100%; padding: 12px; margin: 12px 0; border: none; border-radius: 3px; color: #d4cdbb; font-size: 14px;
background: rgba(0, 0, 0, .25); box-shadow: inset 1px 1px 2px rgba(0, 0, 0, .25), inset 0 0 10px rgba(0, 0, 0, .1);
}
.forum-input::placeholder { color: #6d6a5e; }
/* nice_button (no está en theme.css) */
.nice_button {
display: inline-block; padding: 9px 18px; border-radius: 5px; cursor: pointer; font-weight: bold; text-transform: uppercase;
color: #1c1305; border: 1px solid #b08f1d; background: linear-gradient(#e3ab2d, #b08f1d); transition: all 150ms;
}
.nice_button:hover { background: linear-gradient(#f0b53a, #c9a836); }
.nice_button:disabled { opacity: .5; cursor: default; }
/* ===================== responsive ===================== */
@media (max-width: 991px) {
.forum-container { margin: 0; }
.forum-padding { margin: 0; }
}
@media (max-width: 767px) {
.forum-row .post, .forum-row .topics { display: none; }
ul.topic_row .lastpost { display: none; }
.topic_post .left_side { flex-basis: 100%; }
.topic_post .left_side .user_avatar { width: 56px; height: 56px; }
}