'use client'
import { useEffect, useState } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'
import { SDKProvider } from '@/lib/sdk'
import { SDKSidebar } from '@/components/sdk/Sidebar/SDKSidebar'
import { CommandBar } from '@/components/sdk/CommandBar'
import { SDKPipelineSidebar } from '@/components/sdk/SDKPipelineSidebar'
import { ComplianceAdvisorWidget } from '@/components/sdk/ComplianceAdvisorWidget'
import { useSDK } from '@/lib/sdk'
// =============================================================================
// SDK HEADER
// =============================================================================
function formatTimeAgo(date: Date | null): string {
if (!date) return 'Nie'
const now = Date.now()
const diff = now - date.getTime()
const seconds = Math.floor(diff / 1000)
if (seconds < 60) return 'Gerade eben'
const minutes = Math.floor(seconds / 60)
if (minutes < 60) return `vor ${minutes} Min`
const hours = Math.floor(minutes / 60)
if (hours < 24) return `vor ${hours} Std`
const days = Math.floor(hours / 24)
return `vor ${days} Tag${days > 1 ? 'en' : ''}`
}
const SYNC_STATUS_CONFIG = {
idle: { color: 'bg-green-400', label: 'Sync OK' },
syncing: { color: 'bg-yellow-400 animate-pulse', label: 'Synchronisiere...' },
error: { color: 'bg-red-400', label: 'Sync-Fehler' },
conflict: { color: 'bg-orange-400', label: 'Konflikt' },
offline: { color: 'bg-gray-400', label: 'Offline' },
} as const
function SDKHeader({ sidebarCollapsed }: { sidebarCollapsed: boolean }) {
const { state, currentStep, setCommandBarOpen, completionPercentage, syncState, projectId } = useSDK()
const syncConfig = SYNC_STATUS_CONFIG[syncState.status] || SYNC_STATUS_CONFIG.idle
return (
{/* Breadcrumb / Current Step */}
{/* Actions */}
{/* Command Bar Trigger */}
{/* Progress Indicator */}
{/* Help Button */}
{/* Session Info Bar */}
{/* Projekt-Name */}
{state.projectInfo?.name || state.companyProfile?.companyName || 'Kein Projekt'}
{/* Firmenname (falls abweichend vom Projektnamen) */}
{state.projectInfo && state.companyProfile?.companyName && state.companyProfile.companyName !== state.projectInfo.name && (
<>
|
{state.companyProfile.companyName}
>
)}
V{String(state.projectVersion || 1).padStart(3, '0')}
|
{/* Current step / last activity */}
Zuletzt: {currentStep?.name || 'Dashboard'}
|
{/* Last saved time */}
{formatTimeAgo(syncState.lastSyncedAt ? new Date(syncState.lastSyncedAt) : state.lastModified ? new Date(state.lastModified) : null)}
|
{/* Sync status dot */}
{syncConfig.label}
{/* User (only if not default) */}
{state.userId && state.userId !== 'default' && (
<>
|
Bearbeiter: {state.userId}
>
)}
)
}
// =============================================================================
// INNER LAYOUT (needs SDK context)
// =============================================================================
function SDKInnerLayout({ children }: { children: React.ReactNode }) {
const { isCommandBarOpen, setCommandBarOpen, projectId } = useSDK()
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
const pathname = usePathname()
// Extract current step from pathname (e.g., /sdk/vvt -> vvt)
const currentStep = pathname?.split('/').pop() || 'default'
// Load collapsed state from localStorage
useEffect(() => {
const stored = localStorage.getItem('sdk-sidebar-collapsed')
if (stored !== null) {
setSidebarCollapsed(stored === 'true')
}
}, [])
// Save collapsed state to localStorage
const handleCollapsedChange = (collapsed: boolean) => {
setSidebarCollapsed(collapsed)
localStorage.setItem('sdk-sidebar-collapsed', String(collapsed))
}
return (
{/* Sidebar — always visible */}
{/* Main Content - dynamic margin based on sidebar state */}
{/* Header — always visible */}
{/* Page Content */}
{children}
{/* Command Bar Modal */}
{isCommandBarOpen &&
setCommandBarOpen(false)} />}
{/* Pipeline Sidebar (FAB on mobile/tablet, fixed on desktop xl+) */}
{projectId && }
{/* Compliance Advisor Widget */}
{projectId && }
)
}
// =============================================================================
// SDK ROOT WITH SEARCH PARAMS (client component that reads ?project=)
// =============================================================================
import { Suspense } from 'react'
function SDKRootWithParams({ children }: { children: React.ReactNode }) {
const searchParams = useSearchParams()
const projectId = searchParams.get('project') || undefined
return (
{children}
)
}
// =============================================================================
// MAIN LAYOUT (wraps in Suspense for useSearchParams)
// =============================================================================
export default function SDKRootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
}>
{children}
)
}