From fdd360684a27f1bdc2b2b8f3fb113ceeb24ba720 Mon Sep 17 00:00:00 2001 From: adevopg Date: Mon, 13 Jul 2026 13:16:52 +0000 Subject: [PATCH] =?UTF-8?q?web-next:=20p=C3=A1gina=20/changelogs=20desde?= =?UTF-8?q?=20la=20API=20de=20Gitea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ruta que lista los últimos 50 commits del repo vía la API pública de Gitea (lib/changelog.ts getCommits → /api/v1/repos/Inna/NovaWoW/commits). Cada entrada: título (1ª línea), fecha, autor · sha (enlace al commit) y cuerpo del mensaje (sin trailers Co-Authored-By). Estilo del tema (como noticias). GITEA_URL/GITEA_REPO configurables por env (defaults al repo actual). revalidate 300s para no golpear Gitea en cada visita. Co-Authored-By: Claude Opus 4.8 (1M context) --- web-next/app/[locale]/changelogs/page.tsx | 67 +++++++++++++++++++++++ web-next/lib/changelog.ts | 55 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 web-next/app/[locale]/changelogs/page.tsx create mode 100644 web-next/lib/changelog.ts diff --git a/web-next/app/[locale]/changelogs/page.tsx b/web-next/app/[locale]/changelogs/page.tsx new file mode 100644 index 0000000..194cd7b --- /dev/null +++ b/web-next/app/[locale]/changelogs/page.tsx @@ -0,0 +1,67 @@ +import type { Metadata } from 'next' +import { setRequestLocale } from 'next-intl/server' +import { getCommits } from '@/lib/changelog' + +export const metadata: Metadata = { title: 'Changelogs' } + +function formatFecha(iso: string): string { + if (!iso) return '' + const d = new Date(iso) + if (isNaN(d.getTime())) return iso + return d.toLocaleString('es-ES', { + day: 'numeric', + month: 'long', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', + }) +} + +export default async function ChangelogsPage({ params }: { params: Promise<{ locale: string }> }) { + const { locale } = await params + setRequestLocale(locale) + const commits = await getCommits(50) + + return ( +
+
+
+
+

Changelogs

+
+
+
+ {commits.length === 0 ? ( +

No se pudieron cargar los cambios en este momento.

+ ) : ( + <> + {commits.map((c) => ( +
+

{c.title}

+ {formatFecha(c.date)} +

+ {c.author} + {' · '} + {c.shortSha} +

+ {c.body && ( +

{c.body}

+ )} +
+
+
+
+ ))} +

+ * Mostrando los últimos 50 cambios +

+
+ + )} +
+
+
+
+
+ ) +} diff --git a/web-next/lib/changelog.ts b/web-next/lib/changelog.ts new file mode 100644 index 0000000..68ba9e6 --- /dev/null +++ b/web-next/lib/changelog.ts @@ -0,0 +1,55 @@ +// Changelog desde la API de Gitea (commits del repo). +const GITEA = process.env.GITEA_URL || 'https://git.nightspire.gg' +const REPO = process.env.GITEA_REPO || 'Inna/NovaWoW' + +export interface Commit { + sha: string + shortSha: string + title: string + body: string + author: string + date: string + url: string +} + +interface GiteaCommit { + sha: string + html_url: string + created?: string + commit?: { message?: string; author?: { name?: string; date?: string } } + author?: { login?: string } | null +} + +export async function getCommits(limit = 50): Promise { + try { + const res = await fetch(`${GITEA}/api/v1/repos/${REPO}/commits?limit=${limit}`, { + headers: { Accept: 'application/json' }, + // Cache corto para no golpear Gitea en cada visita. + next: { revalidate: 300 }, + }) + if (!res.ok) return [] + const data = (await res.json()) as GiteaCommit[] + return data.map((c) => { + const msg = c.commit?.message ?? '' + const lines = msg.split('\n') + const title = lines[0].trim() + // Cuerpo sin la primera línea y sin los trailers (Co-Authored-By, etc.). + const body = lines + .slice(1) + .filter((l) => !/^Co-Authored-By:/i.test(l.trim()) && !/Generated with \[?Claude/i.test(l)) + .join('\n') + .trim() + return { + sha: c.sha, + shortSha: c.sha.slice(0, 7), + title, + body, + author: c.commit?.author?.name || c.author?.login || '', + date: c.commit?.author?.date || c.created || '', + url: c.html_url, + } + }) + } catch { + return [] + } +}