25ced0c2f6
SiteHeader enlazaba /content-creators y esa página no existía en Next: el menú VIDEOS llevaba a un 404. Réplica del partial Django `partials/videos.html`, con sus clases del tema (cc-box, cc-avatar, cc-name...). Lee el primer registro de home_contentcreator, igual que la vista de Django. La descripción es HTML de CKEditor (lo edita un admin), así que se sanea con `cleanPostHtml`, la misma allowlist que los mensajes del foro. Comprobado metiendo un <script>alert(1)</script> a propósito: no aparece en el HTML servido. Dos arreglos sobre el diseño de Django, que copiaba tal cual: - El título va SIEMPRE. Django lo metía dentro del `if content_creator`, así que sin datos la página quedaba con un <p> suelto, sin cabecera ni caja. Ahora sin creador sale el título de la sección y el aviso centrado en su box-content. - Los enlaces de YouTube/Facebook se salían por abajo de la caja. El tema le da a `.cc-box` una altura FIJA de 172px contando con el content-box del navegador, y el border-box de Tailwind le restaba el padding y el borde: 24px menos de alto útil. Es el mismo caso que .item-box en la tienda. Medido: la caja pasa de 172 a 196px de alto y los enlaces dejan de desbordar. Verificado con un creador de prueba (borrado después): /es/ y /en/ dan 200, el título, el avatar, el iframe y los enlaces caen dentro de la caja, y con la tabla vacía sale el mismo texto que Django. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
46 lines
1.5 KiB
TypeScript
46 lines
1.5 KiB
TypeScript
import type { RowDataPacket } from 'mysql2'
|
|
import { db, DB } from './db'
|
|
|
|
/**
|
|
* Creador de contenido destacado (`home_contentcreator`, el menú VIDEOS).
|
|
*
|
|
* Como en Django, se muestra SOLO el primero: la tabla se maneja desde el admin
|
|
* y ahora mismo está vacía, así que la página enseña el aviso de "no hay
|
|
* información" igual que hacía Django.
|
|
*/
|
|
export interface ContentCreator {
|
|
title: string
|
|
/** HTML de CKEditor. Se sanea antes de pintarlo (ver la página). */
|
|
description: string
|
|
contentType: string
|
|
subtitle: string
|
|
youtubeVideoUrl: string | null
|
|
avatarImageUrl: string | null
|
|
youtubeChannelUrl: string | null
|
|
facebookPageUrl: string | null
|
|
}
|
|
|
|
export async function getContentCreator(): Promise<ContentCreator | null> {
|
|
try {
|
|
const [rows] = await db(DB.default).query<RowDataPacket[]>(
|
|
`SELECT title, description, content_type, subtitle, youtube_video_url,
|
|
avatar_image_url, youtube_channel_url, facebook_page_url
|
|
FROM home_contentcreator ORDER BY id LIMIT 1`,
|
|
)
|
|
const r = rows[0]
|
|
if (!r) return null
|
|
return {
|
|
title: String(r.title),
|
|
description: String(r.description ?? ''),
|
|
contentType: String(r.content_type ?? ''),
|
|
subtitle: String(r.subtitle ?? ''),
|
|
youtubeVideoUrl: r.youtube_video_url ?? null,
|
|
avatarImageUrl: r.avatar_image_url ?? null,
|
|
youtubeChannelUrl: r.youtube_channel_url ?? null,
|
|
facebookPageUrl: r.facebook_page_url ?? null,
|
|
}
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|