f8b45dd3d1
Die vier Kern-Module in eine Gruppe "Produkt-Compliance (CE & Cyber)" (Gap-Analyse, Maschinensicherheit/CE, Cyber Resilience/CRA) — iace+cra benachbart, KI-Compliance nicht mehr dazwischen gekeilt. Labels entschaerft (kein "IACE"-Codename, keine doppelten Header). Interne/Entwickler-Module (Kataloge/Templates, Korpus/coverage, Quellen, Engine-Internals, Admin) in eine per useInternalUI() gegatete Sektion "Intern · Entwicklung" — Kunden sehen sie nie (Default versteckt; intern = macmini/localhost o. Browser-Opt-in). coverage erstmals erreichbar (war verwaist). Toter SidebarModuleNav.tsx geloescht. Alle bestehenden Routen erhalten. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
28 lines
1.1 KiB
TypeScript
28 lines
1.1 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
// Gate for internal/developer-only navigation (template/catalog management, corpus
|
|
// curation, engine internals, admin tooling). Customers must NEVER see these.
|
|
//
|
|
// Until per-tenant RBAC lands, "internal" = our own environments (macmini /
|
|
// localhost) or an explicit per-browser opt-in. Public customer domains hide it
|
|
// by default (safe). Override per browser via localStorage `bp_internal_ui` =
|
|
// '1' (force show) / '0' (force hide, e.g. to preview the customer view).
|
|
// When real role-based auth arrives, swap only this hook's body.
|
|
export function useInternalUI(): boolean {
|
|
const [show, setShow] = useState(false)
|
|
useEffect(() => {
|
|
try {
|
|
const flag = localStorage.getItem('bp_internal_ui')
|
|
if (flag === '1') { setShow(true); return }
|
|
if (flag === '0') { setShow(false); return }
|
|
const h = window.location.hostname
|
|
setShow(h === 'macmini' || h === 'localhost' || h === '127.0.0.1' || h.endsWith('.local'))
|
|
} catch {
|
|
setShow(false)
|
|
}
|
|
}, [])
|
|
return show
|
|
}
|