forked from Goutam/lynkeduppro-crm
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useRef } from 'react';
|
|
|
|
import { useIsMobile } from '../hooks/useMediaQuery';
|
|
import { useKeyboardShortcuts } from '../hooks/useKeyboardShortcuts';
|
|
import { useGallery, useGalleryStoreApi } from '../store/context';
|
|
import { Sidebar } from './Sidebar';
|
|
import { SelectionBar } from './SelectionBar';
|
|
import { TopToolbar } from './TopToolbar';
|
|
import { ViewRouter } from './ViewRouter';
|
|
|
|
export function AppShell() {
|
|
const api = useGalleryStoreApi();
|
|
const sidebarOpen = useGallery((s) => s.sidebarOpen);
|
|
const showSidebar = useGallery((s) => s.config.chrome.sidebar);
|
|
const showToolbar = useGallery((s) => s.config.chrome.toolbar);
|
|
const shortcutsEnabled = useGallery((s) => s.config.keyboardShortcuts);
|
|
const view = useGallery((s) => s.view);
|
|
const hiddenViews = useGallery((s) => s.config.hiddenViews);
|
|
const isMobile = useIsMobile();
|
|
|
|
// If the active view becomes hidden (host toggled `hiddenViews`, or a deep link
|
|
// landed on one), fall back to the Library instead of rendering a dead view.
|
|
useEffect(() => {
|
|
if (hiddenViews && hiddenViews.includes(view) && view !== 'library') {
|
|
api.getState().setView('library');
|
|
}
|
|
}, [api, view, hiddenViews]);
|
|
// The hook is always called (stable hook order); it binds nothing when disabled.
|
|
useKeyboardShortcuts(shortcutsEnabled);
|
|
|
|
// Collapse the sidebar by default on phones; expand on larger screens.
|
|
const lastMobile = useRef<boolean | null>(null);
|
|
useEffect(() => {
|
|
if (lastMobile.current === isMobile) return;
|
|
lastMobile.current = isMobile;
|
|
api.getState().setSidebar(!isMobile);
|
|
}, [isMobile, api]);
|
|
|
|
return (
|
|
<>
|
|
{showSidebar ? <Sidebar /> : null}
|
|
{showSidebar ? (
|
|
<div
|
|
className={['apg-scrim', isMobile && sidebarOpen ? 'apg-scrim--show' : '']
|
|
.filter(Boolean)
|
|
.join(' ')}
|
|
onClick={() => api.getState().setSidebar(false)}
|
|
/>
|
|
) : null}
|
|
<div className="apg-main">
|
|
{showToolbar ? <TopToolbar /> : null}
|
|
<div className="apg-viewport">
|
|
<ViewRouter />
|
|
<SelectionBar />
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|