Versioning: package.json carries the app version (0.1.2 here; one bump per task with `npm run version:bump`, patch 0-9 rolling into the minor at 10), baked into the build via lib/version.ts, reported by /api/healthz and shown in Settings next to the running commit. AGENTS.md documents the rule; the native suite checks both the API and the Settings row. Fix: on desktop the app header is hidden, so every page owns its top padding — /create was the only one without `lg:pt-10`, which slammed the Study deck / Make my homework switch against the top of the window while /homework had a comfortable gap. Both now sit at 40px; the wizard suite asserts the clearance and that the two pages stay in step (90 checks). SW -> freezmo-v50.
37 lines
963 B
TypeScript
37 lines
963 B
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
export type RunningVersion = {
|
|
/** App version from package.json (bumped once per task). */
|
|
version?: string;
|
|
commit: string;
|
|
short: string;
|
|
builtAt: string | null;
|
|
release: string | null;
|
|
dev: boolean;
|
|
};
|
|
|
|
/** Which release is running (from /api/healthz), for the Settings details. */
|
|
export function useVersion(): RunningVersion | null {
|
|
const [version, setVersion] = useState<RunningVersion | null>(null);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
void (async () => {
|
|
try {
|
|
const response = await fetch("/api/healthz", { cache: "no-store" });
|
|
if (!response.ok) return;
|
|
const body = (await response.json()) as RunningVersion;
|
|
if (!cancelled) setVersion(body);
|
|
} catch {
|
|
/* offline or old server — the row stays hidden */
|
|
}
|
|
})();
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, []);
|
|
|
|
return version;
|
|
}
|