feat: move status to footer and clean up home page
This commit is contained in:
@@ -7,7 +7,10 @@ describe("Web Router", () => {
|
|||||||
const res = await router(req);
|
const res = await router(req);
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
expect(res.headers.get("Content-Type")).toBe("text/html");
|
expect(res.headers.get("Content-Type")).toBe("text/html");
|
||||||
expect(await res.text()).toContain("Aurora Web");
|
const text = await res.text();
|
||||||
|
expect(text).toContain("Aurora Web");
|
||||||
|
expect(text).toContain("Uptime:");
|
||||||
|
expect(text).toContain('id="uptime-display"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return health check on /health", async () => {
|
it("should return health check on /health", async () => {
|
||||||
|
|||||||
@@ -1,20 +1,11 @@
|
|||||||
import { BaseLayout } from "../views/layout";
|
import { BaseLayout } from "../views/layout";
|
||||||
import { formatUptime } from "../utils/format";
|
|
||||||
|
|
||||||
export function homeRoute(): Response {
|
export function homeRoute(): Response {
|
||||||
const uptime = formatUptime(process.uptime());
|
|
||||||
const startTimestamp = Date.now() - (process.uptime() * 1000);
|
|
||||||
|
|
||||||
const content = `
|
const content = `
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Welcome</h2>
|
<h2>Welcome</h2>
|
||||||
<p>The Aurora web server is up and running!</p>
|
<p>The Aurora web server is up and running!</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
|
||||||
<h3>Status</h3>
|
|
||||||
<p>System operational.</p>
|
|
||||||
<p><strong>Uptime:</strong> <span id="uptime-display" data-start-timestamp="${Math.floor(startTimestamp)}">${uptime}</span></p>
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const html = BaseLayout({ title: "Home", content });
|
const html = BaseLayout({ title: "Home", content });
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { escapeHtml } from "../utils/html";
|
import { escapeHtml } from "../utils/html";
|
||||||
|
import { formatUptime } from "../utils/format";
|
||||||
|
|
||||||
interface LayoutProps {
|
interface LayoutProps {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -7,6 +8,12 @@ interface LayoutProps {
|
|||||||
|
|
||||||
export function BaseLayout({ title, content }: LayoutProps): string {
|
export function BaseLayout({ title, content }: LayoutProps): string {
|
||||||
const safeTitle = escapeHtml(title);
|
const safeTitle = escapeHtml(title);
|
||||||
|
|
||||||
|
// Calculate uptime for the footer
|
||||||
|
const uptimeSeconds = process.uptime();
|
||||||
|
const startTimestamp = Date.now() - (uptimeSeconds * 1000);
|
||||||
|
const initialUptimeString = formatUptime(uptimeSeconds);
|
||||||
|
|
||||||
return `<!DOCTYPE html>
|
return `<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@@ -30,7 +37,15 @@ export function BaseLayout({ title, content }: LayoutProps): string {
|
|||||||
${content}
|
${content}
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
|
<div class="footer-content">
|
||||||
<p>© ${new Date().getFullYear()} Aurora Bot</p>
|
<p>© ${new Date().getFullYear()} Aurora Bot</p>
|
||||||
|
<div class="footer-status">
|
||||||
|
<span class="status-indicator online">●</span>
|
||||||
|
<span>System Operational</span>
|
||||||
|
<span class="separator">|</span>
|
||||||
|
<span>Uptime: <span id="uptime-display" data-start-timestamp="${Math.floor(startTimestamp)}">${initialUptimeString}</span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="/script.js" defer></script>
|
<script src="/script.js" defer></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
38
tickets/2026-01-07-move-status-to-footer.md
Normal file
38
tickets/2026-01-07-move-status-to-footer.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# 2026-01-07-move-status-to-footer
|
||||||
|
|
||||||
|
**Status:** Done
|
||||||
|
**Created:** 2026-01-07
|
||||||
|
**Tags:** ui, layout, enhancement
|
||||||
|
|
||||||
|
## 1. Context & User Story
|
||||||
|
* **As a:** User of the Web Interface
|
||||||
|
* **I want to:** see the system status and uptime information in the footer of every page
|
||||||
|
* **So that:** the main content area is less cluttered and status information is globally available.
|
||||||
|
|
||||||
|
## 2. Technical Requirements
|
||||||
|
### Data Model Changes
|
||||||
|
- [ ] N/A
|
||||||
|
|
||||||
|
### API / Interface
|
||||||
|
- [x] **Home Page:** Remove the "Status" card from the main content.
|
||||||
|
- [x] **Layout:** Update `BaseLayout` (or `layout.ts`) to accept or calculate uptime/status information and render it in the `<footer>`.
|
||||||
|
|
||||||
|
## 3. Constraints & Validations (CRITICAL)
|
||||||
|
- **Visuals:** The footer should remain clean and not be overcrowded.
|
||||||
|
- **Functionality:** The existing client-side uptime counter (via `#uptime-display` in `script.js`) must continue to work. Ensure the ID or data attributes it relies on are preserved in the new location.
|
||||||
|
|
||||||
|
## 4. Acceptance Criteria
|
||||||
|
1. [x] The "Status" card is removed from the Home page content.
|
||||||
|
2. [x] The Footer displays "System Operational" and the running Uptime counter.
|
||||||
|
3. [x] navigation to other pages (if any) still shows the status in the footer.
|
||||||
|
|
||||||
|
## 5. Implementation Plan
|
||||||
|
- [x] Edit `src/web/routes/home.ts` to remove the Status card.
|
||||||
|
- [x] Edit `src/web/views/layout.ts` to add the Status HTML structure to the footer.
|
||||||
|
- [x] Verify `script.js` selector targets the new element correctly.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
- Moved Status/Uptime logic from `home.ts` to `layout.ts` (footer).
|
||||||
|
- Calculated server-side uptime for initial rendering to prevent flash.
|
||||||
|
- Preserved `id="uptime-display"` and `data-start-timestamp` for `script.js` compatibility.
|
||||||
|
- Updated tests to verify uptime presence in global layout.
|
||||||
Reference in New Issue
Block a user