70 lines
3.0 KiB
TypeScript
70 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
// ============================================================
|
|
// The actual @photo-gallery/sdk mount. Split out of smart-gallery.tsx so it can be
|
|
// loaded with next/dynamic({ ssr: false }) — the SDK is browser-only (matchMedia,
|
|
// IndexedDB, Leaflet, canvas) and pulls in heavy optional ML models on demand, so it
|
|
// must stay out of the dashboard's initial bundle and out of the server render.
|
|
// ============================================================
|
|
|
|
import { useMemo } from "react";
|
|
import { PhotoGallery, type ViewId } from "@photo-gallery/sdk";
|
|
import { createCrmAIProvider } from "@/lib/gallery-ai";
|
|
import {
|
|
GALLERY_THEME_TOKENS,
|
|
useGalleryFeatures,
|
|
useGalleryLockProvider,
|
|
useGalleryStorage,
|
|
useGalleryUser,
|
|
} from "@/lib/gallery-api";
|
|
|
|
import "@photo-gallery/sdk/styles.css";
|
|
import "leaflet/dist/leaflet.css";
|
|
|
|
export interface SmartGalleryMountProps {
|
|
/** The dashboard's current appearance — the gallery must never diverge from the host. */
|
|
theme: "dark" | "light";
|
|
}
|
|
|
|
export default function SmartGalleryMount({ theme }: SmartGalleryMountProps) {
|
|
const { adapter } = useGalleryStorage();
|
|
const currentUser = useGalleryUser();
|
|
// Server-backed Recently Deleted lock when the Shell is wired; `undefined` in demo mode, which
|
|
// leaves the SDK on its own device-local lock (see useGalleryLockProvider).
|
|
const lockProvider = useGalleryLockProvider();
|
|
// Feature toggles resolved from the caller's CRM permissions (Media group). Superadmins/owners and
|
|
// the demo see everything; see useGalleryFeatures for the safe permissive fallback.
|
|
const { features } = useGalleryFeatures();
|
|
|
|
// Sidebar rows + Collections sections the CRM never wants to surface. The SDK hides both the row and
|
|
// the matching Collections section for each id. Screenshots + Documents aren't part of a roofing CRM.
|
|
const hiddenViews: ViewId[] = ["screenshots", "sys:documents"];
|
|
|
|
// One provider per mount. Every model is dynamically imported inside it, so constructing
|
|
// it is cheap; the weight only arrives when a photo is actually analyzed.
|
|
const ai = useMemo(() => createCrmAIProvider(), []);
|
|
|
|
return (
|
|
<PhotoGallery
|
|
embedded
|
|
adapter={adapter}
|
|
ai={ai}
|
|
// The CRM owns light/dark, so the in-gallery Appearance switcher is suppressed and the
|
|
// theme is driven straight off the dashboard's own toggle.
|
|
theme={theme}
|
|
chrome={{ titlebar: false, themeSwitcher: false }}
|
|
themeTokens={GALLERY_THEME_TOKENS}
|
|
borderRadius={12}
|
|
currentUser={currentUser}
|
|
lockProvider={lockProvider}
|
|
title="Smart Gallery"
|
|
// The SDK's floating Info panel defaults to 64px from the top — the height of its
|
|
// OWN toolbar. Inside the dashboard it has to clear the 84px CRM topbar instead.
|
|
// `style` is applied after the token vars, so this wins over the SDK's inline default.
|
|
style={{ ["--apg-overlay-top" as string]: "96px" }}
|
|
hiddenViews={hiddenViews}
|
|
features={features}
|
|
/>
|
|
);
|
|
}
|