improve pages
This commit is contained in:
parent
b1ad8f513b
commit
9339c67ba7
|
|
@ -680,7 +680,7 @@ export const dashboard = new Elysia()
|
|||
})
|
||||
|
||||
// ── Status pages ──────────────────────────────────────────────────
|
||||
.get("/dashboard/status-pages", async ({ cookie, headers }) => {
|
||||
.get("/dashboard/pages", async ({ cookie, headers }) => {
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
if (!resolved?.accountId) return redirect("/dashboard");
|
||||
const pages = await sql`
|
||||
|
|
@ -688,25 +688,25 @@ export const dashboard = new Elysia()
|
|||
FROM status_pages WHERE account_id = ${resolved.accountId}
|
||||
ORDER BY created_at DESC
|
||||
`;
|
||||
return html("status-pages", { nav: "status-pages", pages });
|
||||
return html("status-pages", { nav: "pages", pages });
|
||||
})
|
||||
|
||||
.get("/dashboard/status-pages/new", async ({ cookie, headers }) => {
|
||||
.get("/dashboard/pages/new", async ({ cookie, headers }) => {
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
if (!resolved?.accountId) return redirect("/dashboard");
|
||||
const allMonitors = await sql`
|
||||
SELECT id, name FROM monitors WHERE account_id = ${resolved.accountId} ORDER BY created_at DESC
|
||||
`;
|
||||
return html("status-page-edit", { nav: "status-pages", isNew: true, page: null, allMonitors });
|
||||
return html("status-page-edit", { nav: "pages", isNew: true, page: null, allMonitors });
|
||||
})
|
||||
|
||||
.get("/dashboard/status-pages/:id", async ({ cookie, headers, params }) => {
|
||||
.get("/dashboard/pages/:id", async ({ cookie, headers, params }) => {
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
if (!resolved?.accountId) return redirect("/dashboard");
|
||||
const [page] = await sql`
|
||||
SELECT * FROM status_pages WHERE id = ${params.id} AND account_id = ${resolved.accountId}
|
||||
`;
|
||||
if (!page) return redirect("/dashboard/status-pages");
|
||||
if (!page) return redirect("/dashboard/pages");
|
||||
const [monitors, groups, allMonitors] = await Promise.all([
|
||||
sql`SELECT monitor_id, display_name, group_id FROM status_page_monitors WHERE status_page_id = ${params.id} ORDER BY position ASC`,
|
||||
sql`SELECT id, name, position FROM status_page_groups WHERE status_page_id = ${params.id} ORDER BY position ASC`,
|
||||
|
|
@ -714,10 +714,10 @@ export const dashboard = new Elysia()
|
|||
]);
|
||||
page.monitors = monitors;
|
||||
page.groups = groups;
|
||||
return html("status-page-edit", { nav: "status-pages", isNew: false, page, allMonitors });
|
||||
return html("status-page-edit", { nav: "pages", isNew: false, page, allMonitors });
|
||||
})
|
||||
|
||||
.post("/dashboard/status-pages/new", async ({ cookie, headers, body }) => {
|
||||
.post("/dashboard/pages/new", async ({ cookie, headers, body }) => {
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
if (!resolved?.accountId) return redirect("/dashboard");
|
||||
const b = body as any;
|
||||
|
|
@ -752,10 +752,10 @@ export const dashboard = new Elysia()
|
|||
}),
|
||||
});
|
||||
} catch {}
|
||||
return redirect("/dashboard/status-pages");
|
||||
return redirect("/dashboard/pages");
|
||||
})
|
||||
|
||||
.post("/dashboard/status-pages/:id/edit", async ({ cookie, headers, params, body }) => {
|
||||
.post("/dashboard/pages/:id/edit", async ({ cookie, headers, params, body }) => {
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
if (!resolved?.accountId) return redirect("/dashboard");
|
||||
const b = body as any;
|
||||
|
|
@ -796,10 +796,10 @@ export const dashboard = new Elysia()
|
|||
body: JSON.stringify(payload),
|
||||
});
|
||||
} catch {}
|
||||
return redirect("/dashboard/status-pages");
|
||||
return redirect("/dashboard/pages");
|
||||
})
|
||||
|
||||
.post("/dashboard/status-pages/:id/delete", async ({ cookie, headers, params }) => {
|
||||
.post("/dashboard/pages/:id/delete", async ({ cookie, headers, params }) => {
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
if (!resolved?.accountId) return redirect("/dashboard");
|
||||
try {
|
||||
|
|
@ -810,7 +810,7 @@ export const dashboard = new Elysia()
|
|||
headers: { "Authorization": `Bearer ${key}` },
|
||||
});
|
||||
} catch {}
|
||||
return redirect("/dashboard/status-pages");
|
||||
return redirect("/dashboard/pages");
|
||||
})
|
||||
|
||||
// ── Incidents ─────────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<div>
|
||||
<label class="block text-sm text-gray-400 mb-1.5">Show on status pages</label>
|
||||
<% if (allPages.length === 0) { %>
|
||||
<p class="text-xs text-gray-600">No status pages yet. <a href="/dashboard/status-pages/new" class="text-blue-400 hover:text-blue-300">Create one</a>.</p>
|
||||
<p class="text-xs text-gray-600">No status pages yet. <a href="/dashboard/pages/new" class="text-blue-400 hover:text-blue-300">Create one</a>.</p>
|
||||
<% } else { %>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<% allPages.forEach(function(p) { %>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<a href="/dashboard/home" class="text-xl font-bold tracking-tight group">Ping<span class="text-blue-400 transition-all group-hover:drop-shadow-[0_0_8px_rgba(59,130,246,0.4)]">QL</span></a>
|
||||
<div class="flex items-center gap-5 text-sm text-gray-500">
|
||||
<a href="/dashboard/home" class="<%= it.nav === 'monitors' ? 'text-gray-200 relative after:absolute after:bottom-[-18px] after:left-0 after:right-0 after:h-[2px] after:bg-blue-500 after:rounded-full' : 'hover:text-gray-300' %> transition-colors">Monitors</a>
|
||||
<a href="/dashboard/status-pages" class="<%= it.nav === 'status-pages' ? 'text-gray-200 relative after:absolute after:bottom-[-18px] after:left-0 after:right-0 after:h-[2px] after:bg-blue-500 after:rounded-full' : 'hover:text-gray-300' %> transition-colors">Pages</a>
|
||||
<a href="/dashboard/pages" class="<%= it.nav === 'pages' ? 'text-gray-200 relative after:absolute after:bottom-[-18px] after:left-0 after:right-0 after:h-[2px] after:bg-blue-500 after:rounded-full' : 'hover:text-gray-300' %> transition-colors">Pages</a>
|
||||
<a href="/dashboard/incidents" class="<%= it.nav === 'incidents' ? 'text-gray-200 relative after:absolute after:bottom-[-18px] after:left-0 after:right-0 after:h-[2px] after:bg-blue-500 after:rounded-full' : 'hover:text-gray-300' %> transition-colors">Incidents</a>
|
||||
<a href="/dashboard/notifications" class="<%= it.nav === 'notifications' ? 'text-gray-200 relative after:absolute after:bottom-[-18px] after:left-0 after:right-0 after:h-[2px] after:bg-blue-500 after:rounded-full' : 'hover:text-gray-300' %> transition-colors">Notifications</a>
|
||||
<a href="/dashboard/settings" class="<%= it.nav === 'settings' ? 'text-gray-200 relative after:absolute after:bottom-[-18px] after:left-0 after:right-0 after:h-[2px] after:bg-blue-500 after:rounded-full' : 'hover:text-gray-300' %> transition-colors">Settings</a>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<%~ include('./partials/head', { title: it.isNew ? 'New status page' : 'Edit status page' }) %>
|
||||
<%~ include('./partials/nav', { nav: 'status-pages' }) %>
|
||||
<%~ include('./partials/nav', { nav: 'pages' }) %>
|
||||
|
||||
<%
|
||||
const p = it.page || {};
|
||||
|
|
@ -31,17 +31,24 @@
|
|||
<main class="max-w-3xl mx-auto px-8 py-10">
|
||||
|
||||
<div class="mb-6">
|
||||
<a href="/dashboard/status-pages" class="text-sm text-gray-500 hover:text-gray-300 transition-colors">← Back to status pages</a>
|
||||
<a href="/dashboard/pages" class="text-sm text-gray-500 hover:text-gray-300 transition-colors">← Back to status pages</a>
|
||||
<h1 class="text-xl font-semibold text-white mt-2"><%= it.isNew ? 'New status page' : 'Edit status page' %></h1>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="<%= it.isNew ? '/dashboard/status-pages/new' : '/dashboard/status-pages/' + p.id + '/edit' %>" class="space-y-6">
|
||||
<form method="POST" action="<%= it.isNew ? '/dashboard/pages/new' : '/dashboard/pages/' + p.id + '/edit' %>" class="space-y-6">
|
||||
|
||||
<div>
|
||||
<label class="block text-sm text-gray-400 mb-1.5">Slug</label>
|
||||
<input name="slug" type="text" required value="<%= p.slug || '' %>" placeholder="my-app" pattern="^[a-z0-9][a-z0-9-]*$"
|
||||
<input id="slug-input" name="slug" type="text" required value="<%= p.slug || '' %>" placeholder="my-app" pattern="^[a-z0-9][a-z0-9-]*$"
|
||||
class="w-full bg-surface-solid border border-border-subtle rounded-lg px-4 py-2.5 text-gray-100 placeholder-gray-600 focus:outline-none focus:border-blue-500 font-mono text-sm">
|
||||
<p class="text-xs text-gray-600 mt-1">Public URL: <span class="text-blue-400 font-mono">pages.pingql.com/<your-slug></span></p>
|
||||
<p class="text-xs text-gray-600 mt-1">Public URL: <a id="slug-url" href="https://pages.pingql.com/<%= p.slug || '' %>" target="_blank" class="text-blue-400 hover:text-blue-300 font-mono">pages.pingql.com/<span id="slug-preview"><%= p.slug || '' %></span></a></p>
|
||||
<script>
|
||||
document.getElementById('slug-input').addEventListener('input', function() {
|
||||
var v = this.value.trim();
|
||||
document.getElementById('slug-preview').textContent = v || '';
|
||||
document.getElementById('slug-url').href = 'https://pages.pingql.com/' + encodeURIComponent(v);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<%~ include('./partials/head', { title: 'Status pages' }) %>
|
||||
<%~ include('./partials/nav', { nav: 'status-pages' }) %>
|
||||
<%~ include('./partials/nav', { nav: 'pages' }) %>
|
||||
|
||||
<main class="max-w-3xl mx-auto px-8 py-10 space-y-8">
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-xl font-semibold text-white">Status pages</h1>
|
||||
<a href="/dashboard/status-pages/new" class="btn-primary inline-flex items-center gap-2 px-4 py-2 text-sm">+ New page</a>
|
||||
<a href="/dashboard/pages/new" class="btn-primary inline-flex items-center gap-2 px-4 py-2 text-sm">+ New page</a>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-gray-500 leading-relaxed">
|
||||
|
|
@ -33,8 +33,8 @@
|
|||
<% if (p.description) { %><p class="text-xs text-gray-500 mt-1"><%= p.description %></p><% } %>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 shrink-0">
|
||||
<a href="/dashboard/status-pages/<%= p.id %>" class="px-3 py-1.5 rounded-lg border border-border-subtle text-gray-400 hover:text-gray-200 text-xs transition-colors">Edit</a>
|
||||
<form action="/dashboard/status-pages/<%= p.id %>/delete" method="POST" class="inline" onsubmit="return confirm('Delete status page \'<%= p.title %>\'? This cannot be undone.')">
|
||||
<a href="/dashboard/pages/<%= p.id %>" class="px-3 py-1.5 rounded-lg border border-border-subtle text-gray-400 hover:text-gray-200 text-xs transition-colors">Edit</a>
|
||||
<form action="/dashboard/pages/<%= p.id %>/delete" method="POST" class="inline" onsubmit="return confirm('Delete status page \'<%= p.title %>\'? This cannot be undone.')">
|
||||
<button type="submit" class="px-3 py-1.5 rounded-lg border border-red-900/30 text-red-400 hover:bg-red-900/20 hover:border-red-800/40 text-xs transition-colors">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue