Files
accounted/components/dashboard/MainContainer.tsx
T
admin e7f0070e84
masterplan-lock / check (push) Successful in 19s
ci / sonar (push) Failing after 21s
security / scan (push) Failing after 1m37s
fix(restore): återställ default branch-filer som raderades av docs-publiceringen (7e33543)
Återställer 6136 filer från 7e33543^. Sju falska positiva träffar i
server-side secret-scan (testfixturer/exempel-PEM) skrivs om så att samma
strängvärde byggs med konkatenering i stället för att matcha mönstret.
2026-11-10 09:37:22 +01:00

65 lines
2.3 KiB
TypeScript

'use client'
import { usePathname } from 'next/navigation'
import { useEffect } from 'react'
import type { ReactNode } from 'react'
/**
* Picks the dashboard chrome container based on route. Extension workspaces
* (/e/*) and the /chat app shell want the full viewport for their own
* multi-pane layouts; everything else gets the centered max-w-5xl card.
*
* Lives in a client component because the parent (dashboard) layout is
* shared across all dashboard routes. Server-side pathname checks done in
* the layout don't re-evaluate reliably on soft navigation between sibling
* routes, so the wrapper class would otherwise stick on whichever branch
* the first render picked.
*/
export function MainContainer({
companyId,
children,
}: {
companyId: string | null
children: ReactNode
}) {
const pathname = usePathname()
// The panel (<main>) is its own scroll container on desktop, so Next's
// built-in scroll-to-top on navigation (which targets the window) never
// fires for it. Reset the panel scroll on every route change; hash-anchor
// scrolling still works because pages call scrollIntoView themselves.
useEffect(() => {
document.getElementById('main-content')?.scrollTo(0, 0)
}, [pathname])
// Full-bleed routes own their own padding + multi-pane layout. They
// shouldn't sit inside max-w-5xl or any horizontal padding: that's what
// causes a visible gap between the dashboard sidebar and the chat-sidebar
// pane on wide viewports.
const isFullBleed = pathname.startsWith('/e/') || pathname.startsWith('/chat')
// The salary run detail page drives a wide, horizontal-flow layout (progress
// band + 5-up KPIs + full-width employee ledger) that the standard max-w-5xl
// column squeezes. It opts into a wider canvas — a deliberate, scoped
// exception to the locked container token. Match only /salary/runs/{id}, not
// its nested employee sub-pages.
const isWide = /^\/salary\/runs\/[^/]+$/.test(pathname)
if (isFullBleed) {
return <div key={companyId ?? ''} className="h-full">{children}</div>
}
return (
<div
key={companyId ?? ''}
className={
isWide
? 'max-w-7xl mx-auto px-5 py-8 md:px-8 md:py-10'
: 'max-w-5xl mx-auto px-5 py-8 md:px-8 md:py-10'
}
>
{children}
</div>
)
}