From f4cf20d378d5294a4d89e7b8b2aaaf1334959c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 24 Jul 2026 13:53:37 +0000 Subject: [PATCH] header: per-route page titles + a centered, click-to-rename tab title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each dashboard route now sets its own document.title (route→title map in usePageTitleSync, mounted in DashboardLayout). The title also renders centered in the top header; clicking it edits inline and updates the browser tab live — per-tab only, reset on navigation/refresh (not persisted). Co-Authored-By: Claude Opus 4.8 --- .../Dashboard/Layout/DashboardLayout.tsx | 2 + .../Dashboard/Layout/Header/Header.tsx | 37 +++++++++++- src/apps/officer-web/state/usePageTitle.ts | 57 +++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/apps/officer-web/state/usePageTitle.ts diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx index 82f90fe3..fd631df7 100644 --- a/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx @@ -3,6 +3,7 @@ import { Background } from './Background'; import { Header } from './Header'; import { Dock, ALL_DOCK_ITEMS, DEFAULT_DOCK_PATHS } from './Dock'; import { useIsTouch } from './useIsTouch'; +import { usePageTitleSync } from '@/state/usePageTitle'; type DashboardLayoutProps = { children?: React.ReactNode; @@ -10,6 +11,7 @@ type DashboardLayoutProps = { export function DashboardLayout({ children }: DashboardLayoutProps) { const { items: visibleItems } = useDock(ALL_DOCK_ITEMS, DEFAULT_DOCK_PATHS); const isTouch = useIsTouch(); + usePageTitleSync(); return (
diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx index 5729ee40..68788ac3 100644 --- a/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx @@ -8,8 +8,39 @@ import { useIsTouch } from '../useIsTouch'; import { UserMenu } from './UserMenu'; import { JobsIndicator } from './JobsIndicator'; import { RescanButton } from '../Rescan/RescanButton'; +import { usePageTitle } from '@/state/usePageTitle'; // import { BugReportButton } from '../BugReport/BugReportButton'; +// Center title: click to rename this browser tab (per-tab, not persisted). +function EditablePageTitle() { + const [title, setTitle] = usePageTitle(); + const [editing, setEditing] = useState(false); + + if (editing) { + return ( + setTitle(ev.target.value)} + onBlur={() => setEditing(false)} + onKeyDown={(ev) => { + if (ev.key === 'Enter' || ev.key === 'Escape') setEditing(false); + }} + className="pointer-events-auto max-w-[50vw] border-b border-white/50 bg-transparent text-center text-sm font-semibold text-white outline-none md:text-base" + /> + ); + } + return ( + + ); +} + type HeaderProps = { dockItems?: DockItem[]; }; @@ -24,9 +55,13 @@ export function Header({ dockItems }: HeaderProps) { return (
+ {/* Centered, editable page title */} +
+ +
{isTouch && dockItems && (