([])
const [isSwitchingOrg, setIsSwitchingOrg] = useState(() => {
if (typeof window === 'undefined') return false
return sessionStorage.getItem(ORG_SWITCH_KEY) === 'true'
})
// * Clear the switching flag once the page has settled after reload
useEffect(() => {
if (isSwitchingOrg) {
sessionStorage.removeItem(ORG_SWITCH_KEY)
const timer = setTimeout(() => setIsSwitchingOrg(false), 600)
return () => clearTimeout(timer)
}
}, [isSwitchingOrg])
// * Fetch organizations for the header organization switcher
useEffect(() => {
if (auth.user) {
getUserOrganizations()
.then((organizations) => setOrgs(Array.isArray(organizations) ? organizations : []))
.catch(err => logger.error('Failed to fetch orgs for header', err))
}
}, [auth.user])
const handleSwitchOrganization = async (orgId: string | null) => {
if (!orgId) return // Pulse doesn't support personal organization context
try {
const { access_token } = await switchContext(orgId)
await setSessionAction(access_token)
sessionStorage.setItem(ORG_SWITCH_KEY, 'true')
window.location.reload()
} catch (err) {
logger.error('Failed to switch organization', err)
}
}
const handleCreateOrganization = () => {
router.push('/onboarding')
}
const isAuthenticated = !!auth.user
const showOfflineBar = Boolean(auth.user && !isOnline)
if (isSwitchingOrg) {
return
}
const headerElement = (
: null}
apps={CIPHERA_APPS}
currentAppId="pulse"
onOpenSettings={openSettings}
leftActions={isAuthenticated ? : undefined}
customNavItems={
<>
{!auth.user && (
Features
)}
>
}
/>
)
if (isAuthenticated) {
// Dashboard layout: header pinned, sidebar + content fill remaining viewport
return (
{auth.user &&
}
{headerElement}
{children}
)
}
// Public/marketing layout: floating header, scrollable page, footer
return (
{headerElement}
{children}
)
}
export default function LayoutContent({ children }: { children: React.ReactNode }) {
return (
{children}
)
}