Diseño visual: tema NovaWoW (tokens Tailwind), hero en la home, cabecera pulida
- globals.css: tokens @theme (nw-bg/panel/border/gold/text/muted), fondo con degradado + brillo radial, y componentes reutilizables (.nw-btn, .nw-btn-ghost, .nw-card, .nw-heading con oro degradado). - Header: sticky con backdrop-blur y marca en oro degradado. - Home: sección hero (nombre del server + tagline + CTAs Crear cuenta / Foros) y estado del servidor + noticias en tarjetas (nw-card). Textos hero en catálogos. Verificado: build OK, home renderiza el hero/tarjetas, los tokens nw compilan en el CSS. Sistema visual base listo para aplicar al resto de páginas. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { getTranslations, setRequestLocale } from 'next-intl/server'
|
||||
import { Link } from '@/i18n/navigation'
|
||||
import { getNoticias, getServerStatus, type Noticia, type ServerStatus } from '@/lib/home'
|
||||
|
||||
// SSR por petición: los datos se leen DIRECTAMENTE de MySQL desde el servidor Next.
|
||||
@@ -19,54 +20,91 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s
|
||||
const { noticias, status } = await getData()
|
||||
|
||||
return (
|
||||
<main className="mx-auto max-w-3xl px-4 py-8">
|
||||
<h1 className="text-3xl font-bold text-amber-500">{t('brand')}</h1>
|
||||
|
||||
<section className="my-6 rounded-lg border border-amber-900/60 bg-[#241812] p-4">
|
||||
<h2 className="mb-3 text-lg font-semibold">{t('serverStatus')}</h2>
|
||||
{status ? (
|
||||
<ul className="space-y-1 text-sm">
|
||||
<li>
|
||||
{t('server')}: <span className="text-amber-400">{status.server_name ?? '—'}</span> ({status.expansion})
|
||||
</li>
|
||||
<li>
|
||||
{t('onlineCharacters')}: {status.online_characters}
|
||||
</li>
|
||||
<li>
|
||||
{t('login')}:{' '}
|
||||
<span className={status.status === 'Online' ? 'text-green-400' : 'text-red-400'}>{status.status}</span>
|
||||
</li>
|
||||
<li>
|
||||
{t('address')}: {status.address ?? '—'}
|
||||
</li>
|
||||
</ul>
|
||||
) : (
|
||||
<p>{t('notAvailable')}</p>
|
||||
)}
|
||||
<div>
|
||||
{/* Hero */}
|
||||
<section className="relative overflow-hidden border-b border-nw-border/50">
|
||||
<div className="mx-auto max-w-4xl px-4 py-16 text-center sm:py-24">
|
||||
<p className="mb-3 text-sm font-semibold uppercase tracking-[0.3em] text-nw-gold/80">
|
||||
WotLK Classic 3.4.3
|
||||
</p>
|
||||
<h1 className="nw-heading text-5xl sm:text-6xl">Nova WoW</h1>
|
||||
<p className="mx-auto mt-5 max-w-2xl text-nw-muted">{t('tagline')}</p>
|
||||
<div className="mt-8 flex flex-wrap justify-center gap-3">
|
||||
<Link href="/register" className="nw-btn">
|
||||
{t('ctaRegister')}
|
||||
</Link>
|
||||
<Link href="/forum" className="nw-btn-ghost">
|
||||
{t('ctaForum')}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="mb-3 text-lg font-semibold">{t('news')}</h2>
|
||||
{noticias.length === 0 ? (
|
||||
<p className="text-amber-200/70">{t('noNews')}</p>
|
||||
) : (
|
||||
noticias.map((n) => (
|
||||
<article key={n.id} className="mb-4 border-b border-amber-900/60 pb-4">
|
||||
<h3 className="text-xl font-semibold">{n.titulo}</h3>
|
||||
{n.fecha && <small className="text-amber-200/60">{new Date(n.fecha).toLocaleString(locale)}</small>}
|
||||
<div className="prose prose-invert mt-2 max-w-none" dangerouslySetInnerHTML={{ __html: n.contenido }} />
|
||||
{n.enlace && (
|
||||
<p className="mt-2">
|
||||
{t('link')}:{' '}
|
||||
<a className="text-sky-400 underline" href={n.enlace} target="_blank" rel="noopener noreferrer">
|
||||
{t('here')}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
</article>
|
||||
))
|
||||
)}
|
||||
</section>
|
||||
</main>
|
||||
<main className="mx-auto max-w-4xl px-4 py-10">
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
{/* Estado del servidor */}
|
||||
<aside className="nw-card md:col-span-1">
|
||||
<h2 className="mb-3 text-lg font-semibold text-nw-gold-light">{t('serverStatus')}</h2>
|
||||
{status ? (
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li className="flex justify-between">
|
||||
<span className="text-nw-muted">{t('server')}</span>
|
||||
<span>
|
||||
{status.server_name ?? '—'} <span className="text-nw-muted">({status.expansion})</span>
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex justify-between">
|
||||
<span className="text-nw-muted">{t('onlineCharacters')}</span>
|
||||
<span className="text-green-400">{status.online_characters}</span>
|
||||
</li>
|
||||
<li className="flex justify-between">
|
||||
<span className="text-nw-muted">{t('login')}</span>
|
||||
<span className={status.status === 'Online' ? 'text-green-400' : 'text-red-400'}>
|
||||
{status.status}
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex justify-between">
|
||||
<span className="text-nw-muted">{t('address')}</span>
|
||||
<span className="text-nw-gold-light">{status.address ?? '—'}</span>
|
||||
</li>
|
||||
</ul>
|
||||
) : (
|
||||
<p className="text-nw-muted">{t('notAvailable')}</p>
|
||||
)}
|
||||
</aside>
|
||||
|
||||
{/* Noticias */}
|
||||
<section className="md:col-span-2">
|
||||
<h2 className="mb-4 text-xl font-semibold text-nw-gold-light">{t('news')}</h2>
|
||||
{noticias.length === 0 ? (
|
||||
<p className="text-nw-muted">{t('noNews')}</p>
|
||||
) : (
|
||||
<div className="space-y-5">
|
||||
{noticias.map((n) => (
|
||||
<article key={n.id} className="nw-card">
|
||||
<h3 className="text-lg font-semibold">{n.titulo}</h3>
|
||||
{n.fecha && (
|
||||
<small className="text-nw-muted">{new Date(n.fecha).toLocaleString(locale)}</small>
|
||||
)}
|
||||
<div
|
||||
className="prose prose-invert mt-3 max-w-none text-sm"
|
||||
dangerouslySetInnerHTML={{ __html: n.contenido }}
|
||||
/>
|
||||
{n.enlace && (
|
||||
<p className="mt-3">
|
||||
{t('link')}:{' '}
|
||||
<a href={n.enlace} target="_blank" rel="noopener noreferrer" className="text-sky-400 underline">
|
||||
{t('here')}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user