diff --git a/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx b/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx index ed8a399f..76fd9dbe 100644 --- a/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx +++ b/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx @@ -1,13 +1,16 @@ 'use client' // ============================================================================= -// SIDEBAR ADDITIONAL MODULE LIST -// The "Zusatzmodule" and "Maschinenrecht / CE" sections rendered in the nav. +// SIDEBAR MODULE LIST +// Customer-facing module groups (always shown) + an internal/developer section +// (catalog/template management, corpus curation, engine internals, admin tooling) +// gated by useInternalUI() so customers never see it. See lib/sdk/useInternalUI. // ============================================================================= import React from 'react' import Link from 'next/link' import { usePathname } from 'next/navigation' import { AdditionalModuleItem, withProject } from './SidebarSubComponents' +import { useInternalUI } from '@/lib/sdk/useInternalUI' interface SidebarModuleListProps { collapsed: boolean @@ -15,210 +18,182 @@ interface SidebarModuleListProps { pendingCRCount: number } +const ic = (d: string) => ( + + + +) + +// Shared icon path data (de-duplicated from the previous inline SVGs). +const I = { + barChart: 'M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z', + shieldCheck: 'M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z', + iace: 'M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z', + clipboardCheck: 'M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4', + list: 'M4 6h16M4 10h16M4 14h16M4 18h16', + bolt: 'M13 10V3L4 14h7v7l9-11h-7z', + euReg: 'M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4', + optimizer: 'M13 7h8m0 0v8m0-8l-8 8-4-4-6 6', + chip: 'M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z', + grid: 'M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z', + eyeCircle: 'M15 12a3 3 0 11-6 0 3 3 0 016 0z', + consent: 'M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10', + users: 'M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z', + user: 'M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z', + clock: 'M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z', + envelope: 'M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z', + card: 'M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z', + rolesUsers: 'M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z', + book: 'M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253', + warning: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z', + catalog: 'M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4', + globe: 'M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9', + search: 'M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z', + checkCircle: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z', + architecture: 'M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01', + portfolio: 'M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10', + roadmap: 'M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2', + code: 'M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4', +} + +function SectionHeader({ label, collapsed, tone = 'gray' }: { label: string; collapsed: boolean; tone?: 'gray' | 'indigo' | 'purple' | 'slate' }) { + if (collapsed) return null + const cls = { + gray: 'text-gray-400 font-medium', + indigo: 'text-indigo-600 font-semibold', + purple: 'text-purple-600 font-semibold', + slate: 'text-slate-500 font-semibold', + }[tone] + return
{label}
+} + export function SidebarModuleList({ collapsed, projectId, pendingCRCount }: SidebarModuleListProps) { const pathname = usePathname() + const showInternal = useInternalUI() + const active = (href: string, prefix = false) => + prefix ? (pathname?.startsWith(href) ?? false) : pathname === href + const item = (href: string, d: string, label: string, prefix = false) => ( + + ) return ( <> - {/* CMP — Consent Management Platform */} -
- {!collapsed && ( -
- CMP -
- )} - } label="Dashboard" isActive={pathname === '/sdk/cmp'} collapsed={collapsed} projectId={projectId} /> - } label="Cookie-Banner" isActive={pathname?.startsWith('/sdk/cookie-banner') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Live-Vorschau" isActive={pathname === '/sdk/cookie-banner/preview'} collapsed={collapsed} projectId={projectId} /> - } label="Consent-Records" isActive={pathname?.startsWith('/sdk/einwilligungen') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Consent-Verwaltung" isActive={pathname === '/sdk/consent-management'} collapsed={collapsed} projectId={projectId} /> - } label="Vendor-Compliance" isActive={pathname?.startsWith('/sdk/vendor-compliance') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="DSR Portal" isActive={pathname?.startsWith('/sdk/dsr') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Loeschfristen" isActive={pathname === '/sdk/loeschfristen'} collapsed={collapsed} projectId={projectId} /> - } label="E-Mail-Templates" isActive={pathname === '/sdk/email-templates'} collapsed={collapsed} projectId={projectId} /> -
+ {/* === KUNDE === */} - {/* Maschinenrecht / CE */} -
- {!collapsed && ( -
- Maschinenrecht / CE -
- )} - - - - } - label="CE-Compliance (IACE)" - isActive={pathname?.startsWith('/sdk/iace') ?? false} - collapsed={collapsed} - projectId={projectId} - /> + {/* Produkt-Compliance (CE & Cyber) — die vier Kern-Module zusammen */} +
+ + {item('/sdk/gap-analysis', I.barChart, 'Gap-Analyse', true)} + {item('/sdk/iace', I.iace, 'Maschinensicherheit (CE)', true)} + {item('/sdk/cra', I.shieldCheck, 'Cyber Resilience (CRA)', true)}
{/* KI-Compliance */}
- {!collapsed && ( -
- KI-Compliance -
- )} - } label="Use Case Erfassung" isActive={pathname === '/sdk/advisory-board'} collapsed={collapsed} projectId={projectId} /> - } label="Use Cases" isActive={pathname?.startsWith('/sdk/use-cases') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="AI Act" isActive={pathname?.startsWith('/sdk/ai-act') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="EU Registrierung" isActive={pathname?.startsWith('/sdk/ai-registration') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Compliance Optimizer" isActive={pathname?.startsWith('/sdk/compliance-optimizer') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Compliance Agent" isActive={pathname?.startsWith('/sdk/agent') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Branchen-Benchmark" isActive={pathname?.startsWith('/sdk/benchmark') ?? false} collapsed={collapsed} projectId={projectId} /> + + {item('/sdk/advisory-board', I.clipboardCheck, 'Use Case Erfassung')} + {item('/sdk/use-cases', I.list, 'Use Cases', true)} + {item('/sdk/ai-act', I.bolt, 'AI Act', true)} + {item('/sdk/ai-registration', I.euReg, 'EU Registrierung', true)} + {item('/sdk/compliance-optimizer', I.optimizer, 'Compliance Optimizer', true)} + {item('/sdk/agent', I.chip, 'Compliance Agent', true)} + {item('/sdk/benchmark', I.barChart, 'Branchen-Benchmark', true)}
- {/* CRA Compliance */} -
- {!collapsed && ( -
- CRA Compliance -
- )} - - - - } - label="CRA Compliance" - isActive={pathname?.startsWith('/sdk/cra') ?? false} - collapsed={collapsed} - projectId={projectId} - /> + {/* Datenschutz (CMP) */} +
+ + {item('/sdk/cmp', I.grid, 'Dashboard')} + {item('/sdk/cookie-banner', I.shieldCheck, 'Cookie-Banner', true)} + {item('/sdk/cookie-banner/preview', I.eyeCircle, 'Live-Vorschau')} + {item('/sdk/einwilligungen', I.clipboardCheck, 'Consent-Records', true)} + {item('/sdk/consent-management', I.consent, 'Consent-Verwaltung')} + {item('/sdk/vendor-compliance', I.users, 'Vendor-Compliance', true)} + {item('/sdk/dsr', I.user, 'DSR Portal', true)} + {item('/sdk/loeschfristen', I.clock, 'Loeschfristen')} + {item('/sdk/email-templates', I.envelope, 'E-Mail-Templates')}
- {/* Regulatory Gap-Analyse */} -
- {!collapsed && ( -
- Gap-Analyse -
- )} - - - - } - label="Regulatory Gap-Analyse" - isActive={pathname?.startsWith('/sdk/gap-analysis') ?? false} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Vertragspruefung" - isActive={pathname?.startsWith('/sdk/vendor-assessment') ?? false} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Audit Timeline" - isActive={pathname?.startsWith('/sdk/audit-timeline') ?? false} - collapsed={collapsed} - projectId={projectId} - /> + {/* Verträge & Audit */} +
+ + {item('/sdk/vendor-assessment', I.clipboardCheck, 'Vertragspruefung', true)} + {item('/sdk/audit-timeline', I.clock, 'Audit Timeline', true)}
{/* Payment / Terminal */}
- {!collapsed && ( -
- Payment / Terminal -
- )} - } label="Payment Compliance" isActive={pathname?.startsWith('/sdk/payment-compliance') ?? false} collapsed={collapsed} projectId={projectId} /> + + {item('/sdk/payment-compliance', I.card, 'Payment Compliance', true)}
- {/* Additional Modules */} + {/* Betrieb & Nachweise */}
- {!collapsed && ( -
- Zusatzmodule -
- )} - } label="Rollenkonzept" isActive={pathname?.startsWith('/sdk/rollenkonzept') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Schulung (Admin)" isActive={pathname === '/sdk/training'} collapsed={collapsed} projectId={projectId} /> - } label="Schulung (Learner)" isActive={pathname === '/sdk/training/learner'} collapsed={collapsed} projectId={projectId} /> - } label="Legal RAG" isActive={pathname === '/sdk/rag'} collapsed={collapsed} projectId={projectId} /> - } label="AI Quality" isActive={pathname === '/sdk/quality'} collapsed={collapsed} projectId={projectId} /> - } label="Security Backlog" isActive={pathname === '/sdk/security-backlog'} collapsed={collapsed} projectId={projectId} /> - } label="Compliance Hub" isActive={pathname === '/sdk/compliance-hub'} collapsed={collapsed} projectId={projectId} /> - } label="Assertions" isActive={pathname === '/sdk/assertions'} collapsed={collapsed} projectId={projectId} /> - } label="DSMS" isActive={pathname === '/sdk/dsms'} collapsed={collapsed} projectId={projectId} /> - } label="SDK Flow" isActive={pathname === '/sdk/sdk-flow'} collapsed={collapsed} projectId={projectId} /> - } label="Architektur" isActive={pathname === '/sdk/architecture'} collapsed={collapsed} projectId={projectId} /> - } label="Agenten" isActive={pathname?.startsWith('/sdk/agents') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="Workshop" isActive={pathname === '/sdk/workshop'} collapsed={collapsed} projectId={projectId} /> - } label="Portfolio" isActive={pathname === '/sdk/portfolio'} collapsed={collapsed} projectId={projectId} /> - } label="Roadmap" isActive={pathname === '/sdk/roadmap'} collapsed={collapsed} projectId={projectId} /> - } label="Quellen-Verwaltung" isActive={pathname?.startsWith('/sdk/source-policy') ?? false} collapsed={collapsed} projectId={projectId} /> - } label="ISMS Readiness" isActive={pathname === '/sdk/isms'} collapsed={collapsed} projectId={projectId} /> - } label="LLM Audit" isActive={pathname === '/sdk/audit-llm'} collapsed={collapsed} projectId={projectId} /> - } label="RBAC Admin" isActive={pathname === '/sdk/rbac'} collapsed={collapsed} projectId={projectId} /> - } label="Kataloge" isActive={pathname === '/sdk/catalog-manager'} collapsed={collapsed} projectId={projectId} /> - } label="Compliance Wiki" isActive={pathname?.startsWith('/sdk/wiki')} collapsed={collapsed} projectId={projectId} /> - } label="API-Referenz" isActive={pathname === '/sdk/api-docs'} collapsed={collapsed} projectId={projectId} /> - - {/* Change Requests — needs badge so handled directly */} - - - - - {!collapsed && ( - - Änderungsanfragen - {pendingCRCount > 0 && ( - - {pendingCRCount} - - )} - - )} - {collapsed && pendingCRCount > 0 && ( - - )} - - - } label="Developer Portal" isActive={false} collapsed={collapsed} projectId={projectId} /> - } label="SDK Dokumentation" isActive={false} collapsed={collapsed} projectId={projectId} /> + + {item('/sdk/rollenkonzept', I.rolesUsers, 'Rollenkonzept', true)} + {item('/sdk/training', I.book, 'Schulung (Admin)')} + {item('/sdk/training/learner', I.user, 'Schulung (Learner)')} + {item('/sdk/security-backlog', I.warning, 'Security Backlog')} + {item('/sdk/compliance-hub', I.barChart, 'Compliance Hub')} + {item('/sdk/isms', I.shieldCheck, 'ISMS Readiness')} + {item('/sdk/wiki', I.book, 'Compliance Wiki', true)}
+ + {/* === INTERN · ENTWICKLUNG (nur intern sichtbar, nie für Kunden) === */} + {showInternal && ( +
+ + {item('/sdk/coverage', I.clipboardCheck, 'Abdeckung / Korpus', true)} + {item('/sdk/catalog-manager', I.catalog, 'Kataloge / Templates')} + {item('/sdk/source-policy', I.globe, 'Quellen-Verwaltung', true)} + {item('/sdk/rag', I.search, 'Legal RAG')} + {item('/sdk/quality', I.checkCircle, 'AI Quality')} + {item('/sdk/assertions', I.clipboardCheck, 'Assertions')} + {item('/sdk/dsms', I.shieldCheck, 'DSMS')} + {item('/sdk/sdk-flow', I.bolt, 'SDK Flow')} + {item('/sdk/architecture', I.architecture, 'Architektur')} + {item('/sdk/agents', I.chip, 'Agenten', true)} + {item('/sdk/workshop', I.users, 'Workshop')} + {item('/sdk/portfolio', I.portfolio, 'Portfolio')} + {item('/sdk/roadmap', I.roadmap, 'Roadmap')} + {item('/sdk/audit-llm', I.barChart, 'LLM Audit')} + {item('/sdk/rbac', I.shieldCheck, 'RBAC Admin')} + {item('/sdk/api-docs', I.code, 'API-Referenz')} + + {/* Change Requests — needs badge so handled directly */} + + + + + {!collapsed && ( + + Änderungsanfragen + {pendingCRCount > 0 && ( + + {pendingCRCount} + + )} + + )} + {collapsed && pendingCRCount > 0 && ( + + )} + + + + +
+ )} ) } diff --git a/admin-compliance/components/sdk/Sidebar/SidebarModuleNav.tsx b/admin-compliance/components/sdk/Sidebar/SidebarModuleNav.tsx deleted file mode 100644 index 5d19319f..00000000 --- a/admin-compliance/components/sdk/Sidebar/SidebarModuleNav.tsx +++ /dev/null @@ -1,383 +0,0 @@ -import React from 'react' -import Link from 'next/link' -import { AdditionalModuleItem } from './SidebarSubComponents' - -function withProject(url: string, projectId?: string): string { - if (!projectId) return url - const separator = url.includes('?') ? '&' : '?' - return `${url}${separator}project=${projectId}` -} - -interface SidebarModuleNavProps { - pathname: string | null - collapsed: boolean - projectId?: string - pendingCRCount: number -} - -export function SidebarModuleNav({ pathname, collapsed, projectId, pendingCRCount }: SidebarModuleNavProps) { - return ( - <> - {/* Master Controls */} - - - - } - label="Master Controls" - isActive={pathname?.startsWith('/sdk/master-controls') ?? false} - collapsed={collapsed} - projectId={projectId} - /> - - {/* Maschinenrecht / CE */} -
- {!collapsed && ( -
- Maschinenrecht / CE -
- )} - - - - } - label="CE-Compliance (IACE)" - isActive={pathname?.startsWith('/sdk/iace') ?? false} - collapsed={collapsed} - projectId={projectId} - /> -
- - {/* Additional Modules */} -
- {!collapsed && ( -
- Zusatzmodule -
- )} - - - - } - label="Schulung (Admin)" - isActive={pathname === '/sdk/training'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Schulung (Learner)" - isActive={pathname === '/sdk/training/learner'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Legal RAG" - isActive={pathname === '/sdk/rag'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="AI Quality" - isActive={pathname === '/sdk/quality'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Security Backlog" - isActive={pathname === '/sdk/security-backlog'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Compliance Hub" - isActive={pathname === '/sdk/compliance-hub'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Assertions" - isActive={pathname === '/sdk/assertions'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="DSMS" - isActive={pathname === '/sdk/dsms'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="SDK Flow" - isActive={pathname === '/sdk/sdk-flow'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Architektur" - isActive={pathname === '/sdk/architecture'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Agenten" - isActive={pathname?.startsWith('/sdk/agents') ?? false} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Workshop" - isActive={pathname === '/sdk/workshop'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Portfolio" - isActive={pathname === '/sdk/portfolio'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Roadmap" - isActive={pathname === '/sdk/roadmap'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="ISMS (ISO 27001)" - isActive={pathname === '/sdk/isms'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="LLM Audit" - isActive={pathname === '/sdk/audit-llm'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="RBAC Admin" - isActive={pathname === '/sdk/rbac'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Kataloge" - isActive={pathname === '/sdk/catalog-manager'} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="Compliance Wiki" - isActive={!!pathname?.startsWith('/sdk/wiki')} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="API-Referenz" - isActive={pathname === '/sdk/api-docs'} - collapsed={collapsed} - projectId={projectId} - /> - - - - - {!collapsed && ( - - Änderungsanfragen - {pendingCRCount > 0 && ( - - {pendingCRCount} - - )} - - )} - {collapsed && pendingCRCount > 0 && ( - - )} - - - - - } - label="Developer Portal" - isActive={false} - collapsed={collapsed} - projectId={projectId} - /> - - - - } - label="SDK Dokumentation" - isActive={false} - collapsed={collapsed} - projectId={projectId} - /> -
- - ) -} diff --git a/admin-compliance/lib/sdk/useInternalUI.ts b/admin-compliance/lib/sdk/useInternalUI.ts new file mode 100644 index 00000000..925f40c8 --- /dev/null +++ b/admin-compliance/lib/sdk/useInternalUI.ts @@ -0,0 +1,27 @@ +'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 +}