From 5c91cbc522a7d2372d1770dc1f6e204d8c9a9f8b Mon Sep 17 00:00:00 2001 From: M1 Date: Tue, 17 Mar 2026 09:54:44 +0400 Subject: [PATCH] refactor: convert all static HTML to EJS with cssHash cache-busting, remove stale html files --- apps/web/src/dashboard/detail.html | 291 ------------------ apps/web/src/dashboard/home.html | 112 ------- apps/web/src/dashboard/new.html | 106 ------- apps/web/src/dashboard/settings.html | 234 -------------- apps/web/src/index.ts | 1 - apps/web/src/routes/dashboard.ts | 10 +- .../{dashboard/docs.html => views/docs.ejs} | 4 +- .../landing.html => views/landing.ejs} | 4 +- .../{dashboard/index.html => views/login.ejs} | 6 +- .../privacy.html => views/privacy.ejs} | 4 +- 10 files changed, 15 insertions(+), 757 deletions(-) delete mode 100644 apps/web/src/dashboard/detail.html delete mode 100644 apps/web/src/dashboard/home.html delete mode 100644 apps/web/src/dashboard/new.html delete mode 100644 apps/web/src/dashboard/settings.html rename apps/web/src/{dashboard/docs.html => views/docs.ejs} (99%) rename apps/web/src/{dashboard/landing.html => views/landing.ejs} (99%) rename apps/web/src/{dashboard/index.html => views/login.ejs} (97%) rename apps/web/src/{dashboard/privacy.html => views/privacy.ejs} (99%) diff --git a/apps/web/src/dashboard/detail.html b/apps/web/src/dashboard/detail.html deleted file mode 100644 index a6a4aba..0000000 --- a/apps/web/src/dashboard/detail.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - PingQL — Monitor Detail - - - - - - - - - - -
-
- ← Back -
- -
Loading...
- -
- - - - diff --git a/apps/web/src/dashboard/home.html b/apps/web/src/dashboard/home.html deleted file mode 100644 index e2d969c..0000000 --- a/apps/web/src/dashboard/home.html +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - PingQL — Dashboard - - - - - - - - - - -
-
-

Monitors

-
-
- + New -
-
- -
-
Loading...
-
- - -
- - - - diff --git a/apps/web/src/dashboard/new.html b/apps/web/src/dashboard/new.html deleted file mode 100644 index 959eb63..0000000 --- a/apps/web/src/dashboard/new.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - PingQL — New Monitor - - - - - - - - - - -
-
- ← Back to monitors -

Create Monitor

-
- -
-
- - -
- -
- - -
- -
- - -
- -
- -

Define when this monitor should be considered "up". Defaults to status < 400.

-
-
- - - - -
-
- - - - diff --git a/apps/web/src/dashboard/settings.html b/apps/web/src/dashboard/settings.html deleted file mode 100644 index fa63e3b..0000000 --- a/apps/web/src/dashboard/settings.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - - PingQL — Settings - - - - - - - -
- -

Settings

- - -
-

Account

-
-
- -
- - -
-
-
- -

-
-
-
- - -
-

Recovery Email

-

Used for account recovery only. Stored as a one-way hash — we can't read it.

-
- - - -
- -
- - -
-

Rotate Primary Key

-

Generates a new primary key. Your old key will stop working immediately. Sub-keys are not affected.

- -
- - -
-
-
-

API Keys

-

Create separate keys for different apps, scripts, or teammates.

-
- -
- - - - - - - - -
-

No API keys yet.

-
-
- -
- - - - - diff --git a/apps/web/src/index.ts b/apps/web/src/index.ts index d35c535..405f133 100644 --- a/apps/web/src/index.ts +++ b/apps/web/src/index.ts @@ -14,7 +14,6 @@ const app = new Elysia() origin: process.env.CORS_ORIGINS?.split(",") ?? ["https://pingql.com", "https://api.pingql.com"], credentials: true, })) - .get("/", ({ set }) => { set.headers["content-type"] = "text/html"; return Bun.file(`${import.meta.dir}/dashboard/landing.html`); }) .use(dashboard) .use(account) .use(monitors) diff --git a/apps/web/src/routes/dashboard.ts b/apps/web/src/routes/dashboard.ts index 1863630..e6296ae 100644 --- a/apps/web/src/routes/dashboard.ts +++ b/apps/web/src/routes/dashboard.ts @@ -60,7 +60,7 @@ function escapeHtmlSSR(str: string): string { return str.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } -function html(template: string, data: Record = {}) { +export function html(template: string, data: Record = {}) { return new Response(eta.render(template, { ...data, timeAgoSSR, sparklineSSR, latencyChartSSR, escapeHtmlSSR, cssHash }), { headers: { "content-type": "text/html; charset=utf-8" }, }); @@ -82,6 +82,8 @@ async function getAccountId(cookie: any, headers: any): Promise { const dashDir = resolve(import.meta.dir, "../dashboard"); export const dashboard = new Elysia() + .get("/", () => html("landing", {})) + .get("/dashboard/app.js", () => new Response(Bun.file(`${dashDir}/app.js`), { headers: { "cache-control": "public, max-age=31536000, immutable" } })) .get("/dashboard/app.css", () => new Response(Bun.file(`${dashDir}/app.css`), { headers: { "cache-control": "public, max-age=31536000, immutable" } })) .get("/dashboard/tailwind.css", () => new Response(Bun.file(`${dashDir}/tailwind.css`), { headers: { "cache-control": "public, max-age=31536000, immutable" } })) @@ -96,7 +98,7 @@ export const dashboard = new Elysia() // Invalid/stale key — clear it and show login cookie.pingql_key?.remove(); } - return Bun.file(`${dashDir}/index.html`); + return html("login", {}); }) // Logout @@ -235,5 +237,5 @@ export const dashboard = new Elysia() }) // Docs - .get("/docs", () => Bun.file(`${dashDir}/docs.html`)) - .get("/privacy", () => Bun.file(`${dashDir}/privacy.html`)); + .get("/docs", () => html("docs", {})) + .get("/privacy", () => html("privacy", {})); diff --git a/apps/web/src/dashboard/docs.html b/apps/web/src/views/docs.ejs similarity index 99% rename from apps/web/src/dashboard/docs.html rename to apps/web/src/views/docs.ejs index e0319ff..c582691 100644 --- a/apps/web/src/dashboard/docs.html +++ b/apps/web/src/views/docs.ejs @@ -4,7 +4,7 @@ PingQL — Documentation - +