Sidebar redesign, dropdown fixes, and soft-delete UI #57

Merged
uz1mani merged 50 commits from staging into main 2026-03-19 00:08:16 +00:00
14 changed files with 1491 additions and 312 deletions
Showing only changes of commit 7ae5facd0c - Show all commits

View File

@@ -112,65 +112,66 @@ function LayoutInner({ children }: { children: React.ReactNode }) {
return <LoadingOverlay logoSrc="/pulse_icon_no_margins.png" title="Pulse" portal={false} />
}
const headerElement = (
<Header
auth={auth}
LinkComponent={Link}
logoSrc="/pulse_icon_no_margins.png"
appName="Pulse"
variant={isAuthenticated ? 'static' : 'floating'}
orgs={orgs}
activeOrgId={auth.user?.org_id}
onSwitchOrganization={handleSwitchOrganization}
onCreateOrganization={handleCreateOrganization}
allowPersonalOrganization={false}
showFaq={false}
showSecurity={false}
showPricing={true}
topOffset={!isAuthenticated && showOfflineBar ? '2.5rem' : undefined}
rightSideActions={auth.user ? <NotificationCenter /> : null}
apps={CIPHERA_APPS}
currentAppId="pulse"
onOpenSettings={openSettings}
leftActions={isAuthenticated ? <MobileSidebarToggle /> : undefined}
customNavItems={
<>
{!auth.user && (
<Link
href="/features"
className="px-4 py-2 text-sm font-medium text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white rounded-lg hover:bg-neutral-100/50 dark:hover:bg-neutral-800/50 transition-all duration-200"
>
Features
</Link>
)}
</>
}
/>
)
if (isAuthenticated) {
// Dashboard layout: header pinned, sidebar + content fill remaining viewport
return (
<div className="flex flex-col h-screen overflow-hidden">
{auth.user && <OfflineBanner isOnline={isOnline} />}
<div className="shrink-0">{headerElement}</div>
{children}
<SettingsModalWrapper />
</div>
)
}
// Public/marketing layout: floating header, scrollable page, footer
return (
<div className="flex flex-col min-h-screen">
{auth.user && <OfflineBanner isOnline={isOnline} />}
<Header
auth={auth}
{headerElement}
<main className="flex-1 pb-8 pt-24">
{children}
</main>
<Footer
LinkComponent={Link}
logoSrc="/pulse_icon_no_margins.png"
appName="Pulse"
variant={isAuthenticated ? 'static' : 'floating'}
orgs={orgs}
activeOrgId={auth.user?.org_id}
onSwitchOrganization={handleSwitchOrganization}
onCreateOrganization={handleCreateOrganization}
allowPersonalOrganization={false}
showFaq={false}
showSecurity={false}
showPricing={true}
topOffset={!isAuthenticated && showOfflineBar ? '2.5rem' : undefined}
rightSideActions={auth.user ? <NotificationCenter /> : null}
apps={CIPHERA_APPS}
currentAppId="pulse"
onOpenSettings={openSettings}
leftActions={isAuthenticated ? <MobileSidebarToggle /> : undefined}
customNavItems={
<>
{!auth.user && (
<Link
href="/features"
className="px-4 py-2 text-sm font-medium text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white rounded-lg hover:bg-neutral-100/50 dark:hover:bg-neutral-800/50 transition-all duration-200"
>
Features
</Link>
)}
</>
}
isAuthenticated={false}
/>
{isAuthenticated ? (
// Authenticated: sidebar layout — children include DashboardShell
<>{children}</>
) : (
// Public: standard content with footer
<>
<main className="flex-1 pb-8 pt-24">
{children}
</main>
<Footer
LinkComponent={Link}
appName="Pulse"
isAuthenticated={false}
/>
</>
)}
{isAuthenticated && (
<Footer
LinkComponent={Link}
appName="Pulse"
isAuthenticated={true}
/>
)}
<SettingsModalWrapper />
</div>
)

View File

@@ -13,9 +13,9 @@ export default function DashboardShell({
const { mobileOpen, closeMobile } = useSidebar()
return (
<div className="flex flex-1">
<div className="flex flex-1 overflow-hidden">
<Sidebar siteId={siteId} mobileOpen={mobileOpen} onMobileClose={closeMobile} />
<main className="flex-1 min-w-0 pb-8">
<main className="flex-1 min-w-0 overflow-y-auto">
{children}
</main>
</div>

View File

@@ -319,7 +319,7 @@ export default function Sidebar({
{/* Desktop sidebar */}
<aside
className={`hidden lg:flex flex-col shrink-0 sticky top-0 h-screen border-r border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900 transition-[width] duration-200 overflow-hidden ${
className={`hidden lg:flex flex-col shrink-0 border-r border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900 transition-[width] duration-200 overflow-hidden ${
collapsed ? 'w-[68px]' : 'w-60'
}`}
>