Unified settings modal + dashboard shell redesign #69
@@ -38,16 +38,7 @@ function GlassTopBar({ siteId }: { siteId: string }) {
|
|||||||
}, [realtime])
|
}, [realtime])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hidden md:flex items-center justify-between h-10 shrink-0 pr-3">
|
<div className="hidden md:flex items-center justify-end h-10 shrink-0 px-3">
|
||||||
{/* Collapse toggle — negative margin to align with sidebar icons */}
|
|
||||||
<button
|
|
||||||
onClick={toggle}
|
|
||||||
className="flex items-center justify-center w-10 h-10 -ml-[52px] text-neutral-400 hover:text-white rounded-lg hover:bg-white/[0.06] transition-colors"
|
|
||||||
aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
|
|
||||||
>
|
|
||||||
<SidebarSimple className="w-[18px] h-[18px]" weight={collapsed ? 'regular' : 'fill'} />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Realtime indicator */}
|
{/* Realtime indicator */}
|
||||||
{lastUpdatedRef.current != null && (
|
{lastUpdatedRef.current != null && (
|
||||||
<div className="flex items-center gap-1.5 text-xs text-neutral-500">
|
<div className="flex items-center gap-1.5 text-xs text-neutral-500">
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { listSites, type Site } from '@/lib/api/sites'
|
|||||||
import { useAuth } from '@/lib/auth/context'
|
import { useAuth } from '@/lib/auth/context'
|
||||||
import { useSettingsModal } from '@/lib/settings-modal-context'
|
import { useSettingsModal } from '@/lib/settings-modal-context'
|
||||||
import { useSidebar } from '@/lib/sidebar-context'
|
import { useSidebar } from '@/lib/sidebar-context'
|
||||||
|
import { SidebarSimple } from '@phosphor-icons/react'
|
||||||
// `,` shortcut handled globally by UnifiedSettingsModal
|
// `,` shortcut handled globally by UnifiedSettingsModal
|
||||||
import { getUserOrganizations, switchContext, type OrganizationMember } from '@/lib/api/organization'
|
import { getUserOrganizations, switchContext, type OrganizationMember } from '@/lib/api/organization'
|
||||||
import { setSessionAction } from '@/app/actions/auth'
|
import { setSessionAction } from '@/app/actions/auth'
|
||||||
@@ -340,6 +341,7 @@ interface SidebarContentProps {
|
|||||||
onMobileClose: () => void
|
onMobileClose: () => void
|
||||||
onExpand: () => void
|
onExpand: () => void
|
||||||
onCollapse: () => void
|
onCollapse: () => void
|
||||||
|
onToggle: () => void
|
||||||
wasCollapsed: React.MutableRefObject<boolean>
|
wasCollapsed: React.MutableRefObject<boolean>
|
||||||
pickerOpenCallbackRef: React.MutableRefObject<(() => void) | null>
|
pickerOpenCallbackRef: React.MutableRefObject<(() => void) | null>
|
||||||
auth: ReturnType<typeof useAuth>
|
auth: ReturnType<typeof useAuth>
|
||||||
@@ -350,7 +352,7 @@ interface SidebarContentProps {
|
|||||||
|
|
||||||
function SidebarContent({
|
function SidebarContent({
|
||||||
isMobile, collapsed, siteId, sites, canEdit, pendingHref,
|
isMobile, collapsed, siteId, sites, canEdit, pendingHref,
|
||||||
onNavigate, onMobileClose, onExpand, onCollapse,
|
onNavigate, onMobileClose, onExpand, onCollapse, onToggle,
|
||||||
wasCollapsed, pickerOpenCallbackRef, auth, orgs, onSwitchOrganization, openSettings,
|
wasCollapsed, pickerOpenCallbackRef, auth, orgs, onSwitchOrganization, openSettings,
|
||||||
}: SidebarContentProps) {
|
}: SidebarContentProps) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -359,7 +361,20 @@ function SidebarContent({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full overflow-hidden">
|
<div className="flex flex-col h-full overflow-hidden">
|
||||||
{/* App Switcher — top of sidebar (scope-level switch) */}
|
{/* Collapse toggle — first item, aligned with all other sidebar icons */}
|
||||||
|
{!isMobile && (
|
||||||
|
<div className="flex items-center gap-2.5 px-[14px] pt-3 pb-0 shrink-0 overflow-hidden">
|
||||||
|
<button
|
||||||
|
onClick={onToggle}
|
||||||
|
className="w-9 h-9 flex items-center justify-center shrink-0 text-neutral-400 hover:text-white rounded-lg hover:bg-white/[0.06] transition-colors"
|
||||||
|
aria-label={c ? 'Expand sidebar' : 'Collapse sidebar'}
|
||||||
|
>
|
||||||
|
<SidebarSimple className="w-[18px] h-[18px]" weight={c ? 'regular' : 'fill'} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* App Switcher — scope-level switch */}
|
||||||
<div className="flex items-center gap-2.5 px-[14px] pt-3 pb-1 shrink-0 overflow-hidden">
|
<div className="flex items-center gap-2.5 px-[14px] pt-3 pb-1 shrink-0 overflow-hidden">
|
||||||
<span className="w-9 h-9 flex items-center justify-center shrink-0">
|
<span className="w-9 h-9 flex items-center justify-center shrink-0">
|
||||||
<AppLauncher apps={CIPHERA_APPS} currentAppId="pulse" anchor="right" />
|
<AppLauncher apps={CIPHERA_APPS} currentAppId="pulse" anchor="right" />
|
||||||
@@ -525,7 +540,7 @@ export default function Sidebar({
|
|||||||
onMobileClose={onMobileClose}
|
onMobileClose={onMobileClose}
|
||||||
onExpand={expand}
|
onExpand={expand}
|
||||||
onCollapse={collapse}
|
onCollapse={collapse}
|
||||||
|
onToggle={toggle}
|
||||||
wasCollapsed={wasCollapsedRef}
|
wasCollapsed={wasCollapsedRef}
|
||||||
pickerOpenCallbackRef={pickerOpenCallbackRef}
|
pickerOpenCallbackRef={pickerOpenCallbackRef}
|
||||||
auth={auth}
|
auth={auth}
|
||||||
@@ -568,7 +583,7 @@ export default function Sidebar({
|
|||||||
onMobileClose={handleMobileClose}
|
onMobileClose={handleMobileClose}
|
||||||
onExpand={expand}
|
onExpand={expand}
|
||||||
onCollapse={collapse}
|
onCollapse={collapse}
|
||||||
|
onToggle={toggle}
|
||||||
wasCollapsed={wasCollapsedRef}
|
wasCollapsed={wasCollapsedRef}
|
||||||
pickerOpenCallbackRef={pickerOpenCallbackRef}
|
pickerOpenCallbackRef={pickerOpenCallbackRef}
|
||||||
auth={auth}
|
auth={auth}
|
||||||
|
|||||||
Reference in New Issue
Block a user