feat: Añadir formato de fecha legible para las fechas de unión de servidores y pre-renderizar la barra de navegación

This commit is contained in:
Shni
2025-10-15 00:00:19 -05:00
parent 4358eb20de
commit 1ba74ce7f1
3 changed files with 71 additions and 10 deletions

View File

@@ -230,6 +230,21 @@ function validateDiscordId(id: unknown) {
return /^\d{17,20}$/.test(s); return /^\d{17,20}$/.test(s);
} }
function formatHumanDate(d: unknown): string | null {
if (!d) return null;
try {
const dt = new Date(d as any);
if (Number.isNaN(dt.getTime())) return null;
return dt.toLocaleDateString("es-ES", {
day: "numeric",
month: "short",
year: "numeric",
});
} catch {
return null;
}
}
async function safeUpsertGuild(g: any) { async function safeUpsertGuild(g: any) {
if (!g) return; if (!g) return;
if (!validateDiscordId(g.id)) { if (!validateDiscordId(g.id)) {
@@ -541,6 +556,23 @@ const renderTemplate = async (
dashboardNavHtml = null; dashboardNavHtml = null;
} }
// Pre-render the main navbar when layout expects it (and dashboard nav isn't used)
let navbarHtml: string | null = null;
try {
const shouldShowNavbar = !locals.hideNavbar && !locals.useDashboardNav;
if (shouldShowNavbar) {
const navPath = path.join(viewsDir, "partials", "navbar.ejs");
navbarHtml = await ejs.renderFile(
navPath,
{ appName: locals.appName ?? pkg.name ?? "Amayo Bot" },
{ async: true }
);
}
} catch (err) {
console.warn("Failed rendering navbar partial:", err);
navbarHtml = null;
}
const html = await ejs.renderFile( const html = await ejs.renderFile(
layoutFile, layoutFile,
{ {
@@ -565,6 +597,7 @@ const renderTemplate = async (
: false, : false,
// Pre-rendered partial HTML (if produced above) // Pre-rendered partial HTML (if produced above)
dashboardNav: dashboardNavHtml, dashboardNav: dashboardNavHtml,
navbar: navbarHtml,
...locals, ...locals,
title: locals.title ?? defaultTitle, title: locals.title ?? defaultTitle,
body: pageBody, body: pageBody,
@@ -848,6 +881,9 @@ export const server = createServer(
const safeGuilds = (adminGuilds || []).map((g: any) => ({ const safeGuilds = (adminGuilds || []).map((g: any) => ({
id: String(g.id), id: String(g.id),
name: sanitizeString(g.name ?? g.id, { max: 100 }), name: sanitizeString(g.name ?? g.id, { max: 100 }),
icon: sanitizeString(g.icon ?? "", { max: 100 }),
// Some sources may include a joinedAt/addedAt field; keep raw value for formatting later
addedAt: g.addedAt || g.joinedAt || null,
})); }));
// create session with tokens to allow refresh // create session with tokens to allow refresh
@@ -921,18 +957,37 @@ export const server = createServer(
touchSession(sid!); touchSession(sid!);
// Guild list: prefer session-stored guilds from OAuth (accurate), otherwise fallback to DB // Guild list: prefer session-stored guilds from OAuth (accurate), otherwise fallback to DB
const sessionGuilds: Array<{ id: string; name?: string }> = const sessionGuilds: Array<{
session?.guilds || []; id: string;
name?: string;
icon?: string;
addedAt?: string | null;
}> = session?.guilds || [];
let guilds: Array<{ id: string; name: string }> = []; let guilds: Array<{ id: string; name: string }> = [];
if (sessionGuilds && sessionGuilds.length) { if (sessionGuilds && sessionGuilds.length) {
guilds = sessionGuilds.map((g: any) => ({ guilds = sessionGuilds.map(
id: String(g.id), (g: any) =>
name: String(g.name || g.id), ({
})); id: String(g.id),
name: String(g.name || g.id),
icon: g.icon || null,
addedAt: g.addedAt || null,
addedAtHuman: formatHumanDate(g.addedAt || g.joinedAt || null),
} as any)
);
} else { } else {
try { try {
const rows = await prisma.guild.findMany({ take: 50 }); const rows = await prisma.guild.findMany({ take: 50 });
guilds = rows.map((r) => ({ id: r.id, name: r.name })); guilds = rows.map(
(r) =>
({
id: r.id,
name: r.name,
icon: null,
addedAt: null,
addedAtHuman: null,
} as any)
);
} catch { } catch {
guilds = []; guilds = [];
} }
@@ -945,6 +1000,7 @@ export const server = createServer(
user, user,
guilds, guilds,
hideNavbar: true, hideNavbar: true,
selectedGuildId: null,
}); });
return; return;
} }
@@ -975,6 +1031,7 @@ export const server = createServer(
user, user,
guilds, guilds,
selectedGuild: guildId, selectedGuild: guildId,
selectedGuildId: guildId,
selectedGuildName, selectedGuildName,
page, page,
hideNavbar: false, hideNavbar: false,

View File

@@ -29,7 +29,11 @@
<%- include('../partials/dashboard_nav') %> <%- include('../partials/dashboard_nav') %>
<% } %> <% } %>
<% } else if (!hideNavbar) { %> <% } else if (!hideNavbar) { %>
<%- include('../partials/navbar', { appName }) %> <% if (typeof navbar !== 'undefined' && navbar) { %>
<%- navbar %>
<% } else { %>
<%- include('../partials/navbar', { appName }) %>
<% } %>
<% } %> <% } %>
<div class="relative z-10"> <div class="relative z-10">

View File

@@ -35,8 +35,8 @@
<% } %> <% } %>
<div class="flex-1"> <div class="flex-1">
<div class="text-sm font-medium"><%= g.name %></div> <div class="text-sm font-medium"><%= g.name %></div>
<% if (g.addedAt || g.joinedAt) { %> <% if (g.addedAtHuman) { %>
<div class="text-xs text-slate-300"><%= (g.addedAt || g.joinedAt) %></div> <div class="text-xs text-slate-300"><%= g.addedAtHuman %></div>
<% } %> <% } %>
</div> </div>
</div> </div>