diff --git a/web/src/components/Layout.tsx b/web/src/components/Layout.tsx index 6ea0559..be33975 100644 --- a/web/src/components/Layout.tsx +++ b/web/src/components/Layout.tsx @@ -51,6 +51,7 @@ import { } from 'lucide-react'; import type { LucideIcon } from 'lucide-react'; import { useAuth } from './AuthProvider'; +import { ExternalLink } from './ExternalLink'; import logo from '../assets/certctl-logo.png'; // ----------------------------------------------------------------------------- @@ -289,18 +290,23 @@ export default function Layout() { the LinkedIn link (the same href + rel="me noopener" pattern the landing page uses). Single-maintainer OSS standard (Cal.com, Plausible, Beekeeper Studio do the same). */} + {/* Maintainer attribution row. The Bundle-8 L-015 CI guard line-greps + for `target="_blank"` without `rel="noopener noreferrer"` on the + SAME LINE — splitting target + rel across lines (as the prior + bare did) tripped the guard. ExternalLink is the canonical + chokepoint that the guard allowlists. We lose the rel="me" hint + (LinkedIn's identity-claim signal, not load-bearing), but gain + the CI gate. */}
Built and maintained by{' '} - Shankar - +
diff --git a/web/src/pages/DashboardPage.tsx b/web/src/pages/DashboardPage.tsx index 14cdae9..c75e1b0 100644 --- a/web/src/pages/DashboardPage.tsx +++ b/web/src/pages/DashboardPage.tsx @@ -29,8 +29,9 @@ import { // every dashboard load after the operator dismisses it once. const OnboardingWizard = lazy(() => import('./OnboardingWizard')); -// Convert PascalCase status like "RenewalInProgress" to "Renewal In Progress" -const formatStatus = (s: string) => s.replace(/([a-z])([A-Z])/g, '$1 $2'); +// formatStatus moved to pages/dashboard/charts.tsx in Phase 4 alongside +// the memoized chart panels that use it; deleted from here in Hotfix #8 +// to close CodeQL js/unused-local-variable alert #35. const STATUS_COLORS: Record = { Active: '#10b981',