Footer: match new SSW.Rules deployment line (text + tooltip + live time)#4720
Conversation
…, commit hash) Mirrors the change shipped in SSW.Rules (SSWConsulting/SSW.Rules#2646) so ssw.com.au stays consistent with rules.ssw.com.au. - Text: "This website is under continuous deployment. Last updated X ago. Last commit YYY" (lowercase, drop CONSTANT, drop Build #). - New <RelativeTime> Client Component (components/layout/footer/ relative-time.tsx): * Ticks every 60s so the relative time doesn't freeze in cached HTML. * Custom CSS tooltip (group-hover / group-focus-visible) showing the exact UTC datetime — replaces the easy-to-miss native title-only tooltip. * a11y: tabIndex=0 when a tooltip exists, aria-describedby linking to the tooltip span, native title fallback for older AT, conditional cursor-help. * Native Date formatting (no moment) — small bundle. - Replace the Build # run-number link with a commit-hash link to the GitHub commit, using NEXT_PUBLIC_GITHUB_SHA from the build env. - template-build.yml: plumb NEXT_PUBLIC_GITHUB_SHA=${{ github.sha }} into the Docker build args alongside the existing NEXT_PUBLIC_GITHUB_* family. - Delete components/layout/deploymentLink.tsx — no longer imported. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Coverage report
Test suite run success13 tests passing in 1 suite. Report generated by 🧪jest coverage report action from 63213bd |
- Restore Rules' { buildTimestamp, buildDate } props signature; derive
buildTimestamp from NEXT_PUBLIC_GITHUB_RUN_DATE in deployment-info
with the same Date.now() - 30min fallback Rules uses.
- Drop the Website-only "XXX" fallback; let RelativeTime render
"1 min ago" with the fallback timestamp like Rules does.
- transition-colors -> transition-all on both the inline links and the
RelativeTime wrapper, matching Rules' existing pattern.
No scope creep: relative-time.tsx is now byte-identical to the merged
SSW.Rules version; deployment-info.tsx is the Rules text adapted to
SSW.Website's existing markup (CustomLink + text-center sm:text-left).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Updates the website footer deployment line to match the refreshed wording/behavior used on ssw.com.au/rules, including a live-updating relative time display and a link to the latest GitHub commit.
Changes:
- Replaces the previous “CONSTANT CONTINUOUS DEPLOYMENT / Last deployed / Build #…” line with “continuous deployment / Last updated / Last commit ”.
- Adds a new client component (
RelativeTime) that re-ticks every 60s and shows an accessible custom tooltip with the exact UTC timestamp. - Passes
NEXT_PUBLIC_GITHUB_SHAinto the Docker build and removes the now-unuseddeploymentLinkcomponent.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| components/layout/footer/relative-time.tsx | New client component for ticking relative time + custom tooltip. |
| components/layout/footer/deployment-info.tsx | Updates footer text and links; integrates RelativeTime and commit link. |
| components/layout/deploymentLink.tsx | Removes the old deployment/build-number link component. |
| .github/workflows/template-build.yml | Adds NEXT_PUBLIC_GITHUB_SHA to Docker build args for footer commit link. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Deployed changes to https://app-sswwebsite-9eb3-pr-4720.azurewebsites.net |
The workflow change in the previous commit passed the new env as a docker build-arg, but Docker only forwards args that are declared ARG in the Dockerfile. Without the matching ARG/ENV pair the var silently never reaches the Next.js build -> footer commit hash would never render in prod. - Dockerfile: declare ARG/ENV NEXT_PUBLIC_GITHUB_SHA next to the existing NEXT_PUBLIC_GITHUB_* family. - .env.example: add the new key so local devs see it documented alongside NEXT_PUBLIC_GITHUB_RUN_DATE. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the same pattern raised in SSWConsulting/SSW.Rules#2651: - commitHash now holds the full SHA from NEXT_PUBLIC_GITHUB_SHA (was sliced at module level). - URL keeps using ${commitHash} -> always resolves unambiguously. - Display label uses {commitHash.slice(0, 7)} -> same visible 7-char text, no real-world ambiguity for users. Address Copilot's review comment (#4720) about short-SHA ambiguity, and keeps the 3 SSW footers consistent on the same approach. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ture-timestamp regression) Copilot flagged that my earlier Math.abs-based formatRelative would render "X ago" for future buildDate (client clock skew). The original Website code used dayjs.utc().fromNow() which correctly outputs "in X" for that case — the screenshot of current prod confirms the existing "3 days ago" / "in N" semantics. Swap relative-time.tsx's native-Date implementation back to dayjs while keeping every other piece of the Rules-parity work intact: * custom CSS tooltip on hover/focus * tabIndex + aria-describedby + native title fallback * cursor-help on the wrapper * 60s tick so the relative time doesn't freeze in cached HTML * full SHA in URL, slice-7 for display (mirroring Rules#2651) dayjs is already extended globally in app/layout.tsx with relativeTime and utc plugins, so this is zero-cost — no new imports beyond `dayjs`. Hydration: `now` state is seeded with the build's timestamp so server and client render the same initial "a few seconds ago" markup; the useEffect then advances `now` to the wall clock. Same SSR-safe pattern as the previous version, swapped helper, no Math.abs regression. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per @0xharkirat: most of the footer is already there - just need to correct words, add commit hash + tooltip, and add hover feedback. Don't introduce regressions or much code change. - Drop components/layout/footer/relative-time.tsx (separate client component was overkill; the original Website footer was a plain Server Component using dayjs.utc().fromNow() inline). - deployment-info.tsx stays a Server Component. dayjs.utc().fromNow() computed at request time (matches existing behaviour, no regression on future timestamps). Adds: * "continuous deployment" lowercase link (instead of CAPS) * "Last updated X ago" wording * "Last commit YYY" linked to GitHub commit (full SHA in URL, slice-7 for display) * Custom CSS tooltip on the time span (group-hover, pure CSS, no JS) showing the exact UTC datetime + native title fallback for AT support * hover:text-ssw-red transition on all three hoverables for clear UI feedback - Fixes lint: tailwindcss class order + drops text-[11px] arbitrary value (-> text-xs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The footer's global CSS underlines every <a>, so the continuous-
deployment link and the commit-hash link rendered underlined while the
"X ago" tooltip span did not. Visually inconsistent and louder than
the new design needs.
Override with inline `style={{ textDecoration: "none" }}` on the two
CustomLinks - inline style wins the specificity battle against the
parent CSS rule; the Tailwind `no-underline` class doesn't (same
specificity, parent rule was declared later). Hover affordance remains
hover:text-ssw-red so users still see they're interactive.
Out of scope: the FEEDBACK/TERMS/SITEMAP links elsewhere in the footer
keep their existing underline - this PR only touches the deployment
line.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The continuous-deployment link, the "X ago" tooltip trigger, and the
commit-hash link were inheriting the surrounding footer prose color
(text-gray-300), so they didn't visually pop as interactive elements.
Add text-white on each so they're brighter than the prose around them
("This website is under...", "Last updated", "Last commit"), matching
the same pattern used in the merged SSW.Rules footer.
Hover still flips them to text-ssw-red via transition-colors; the
inline-style underline override stays in place.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Deployed changes to https://app-sswwebsite-9eb3-pr-4720.azurewebsites.net |
Footer change — before / after / SSW.Rules referenceBEFORE — current production ssw.com.au
AFTER — this PR's preview slotPreview: https://app-sswwebsite-9eb3-pr-4720.azurewebsites.net
Hover on "X ago" reveals the exact UTC datetimeReference — current ssw.com.au/rules (merged SSWConsulting/SSW.Rules#2646)This PR mirrors what's already live on Rules. Screenshots hosted on branch |




Summary
Mirrors the footer deployment-line refresh shipped in SSWConsulting/SSW.Rules#2646 so
ssw.com.au(homepage + most pages) stays consistent withssw.com.au/rules.Tiago's review on the Rules PR called out:
This is the ssw.com.au half of that. SSW.People follow-up PR is next.
Before:
After:
Changes
<RelativeTime>Client Component (newcomponents/layout/footer/relative-time.tsx):group-hover+group-focus-visible) showing the exact UTC datetime — replaces the easy-to-miss nativetitle-only tooltip.tabIndex=0when a tooltip exists,aria-describedbylinking to the tooltip span, plus a nativetitlefallback for older AT / non-AT browsers, conditionalcursor: help.Dateformatting — nomomentshipped to the browser for one tooltip.template-build.ymlplumbsNEXT_PUBLIC_GITHUB_SHA=${{ github.sha }}into the Docker build args alongside the existingNEXT_PUBLIC_GITHUB_*family. The footer then derives the 7-char short hash for display + the commit URL viaNEXT_PUBLIC_GITHUB_REPOSITORY.components/layout/deploymentLink.tsx— no longer imported now that the deployment line is inline indeployment-info.tsx.Test plan
pnpm dev+ mock build env (NEXT_PUBLIC_GITHUB_RUN_DATE,NEXT_PUBLIC_GITHUB_SHA,NEXT_PUBLIC_GITHUB_REPOSITORY)continuous deploymentlink → SSW Rulehttps://github.com/SSWConsulting/SSW.Website/commit/<sha>NEXT_PUBLIC_GITHUB_SHAmissing (dev), commit segment hides cleanly; ifNEXT_PUBLIC_GITHUB_RUN_DATEmissing, RelativeTime falls back to "XXX" (matches existing behaviour)Follow-up
ssw.com.au/people.🤖 Generated with Claude Code