import React, { useEffect, useState } from 'react'; import Typography from 'antd/es/typography'; const { Text } = Typography; interface BuildInfo { commit: string; builtAt: string | null; } /** * Which build this environment is running (#233). * * There was previously no way to tell from the screen, and a stack that had * been redeployed could still be serving the previous image. Shown in the admin * header rather than tucked into a settings tab, because its whole value is * being visible without going to look for it. * * Served from the gated /api/admin/version rather than the public /api/config, * so a commit hash is never handed to a storefront visitor. */ export default function BuildStamp() { const [info, setInfo] = useState(null); useEffect(() => { let cancelled = false; void fetch('/api/admin/version') .then((res) => (res.ok ? res.json() : null)) .then((data: BuildInfo | null) => { if (!cancelled) setInfo(data); }) // Renders nothing on failure. A version stamp is a convenience, and it // should not put an error in front of someone doing something else. .catch(() => undefined); return () => { cancelled = true; }; }, []); if (!info) return null; // Local time and no seconds: this is read by a person comparing it against // when they pressed redeploy, not by anything that needs precision. const built = info.builtAt ? new Date(info.builtAt).toLocaleString(undefined, { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' }) : null; return ( {info.commit} {built ? ` ยท built ${built}` : ''} ); }