forked from Goutam/lynkeduppro-crm
be50d53c50
Shared RealtimeProvider opens ONE dashboard-wide IIOS message socket reused by the messenger tab and the new NotificationCenter. CrmMessagingAdapter gains setFocus (drives presence/push suppression) and subscribeActivity (joins all of the caller's threads, fans out incoming messages). NotificationCenter shows a clickable toast on new messages when you're not on the messenger tab and deep-links to the conversation. Pulls @insignia/iios-messaging-ui@0.1.7. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
69 lines
2.6 KiB
TypeScript
69 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
// The CRM messenger, now rendered by the shared @insignia/iios-messaging-ui SDK instead of a
|
|
// bespoke in-CRM implementation. The CRM only supplies an adapter (transport) + theming; all the
|
|
// UI + messaging logic lives in the SDK. Live path = the be-crm data door (CrmMessagingAdapter);
|
|
// demo path = the SDK's own MockAdapter.
|
|
|
|
import { useMemo } from "react";
|
|
import { useAppShell, useAuth } from "@abe-kap/appshell-sdk/react";
|
|
import { MessagingProvider, Messenger as SdkMessenger, type MessagingAdapter } from "@insignia/iios-messaging-ui";
|
|
import { MockAdapter } from "@insignia/iios-messaging-ui/adapters/mock";
|
|
import "@insignia/iios-messaging-ui/styles.css";
|
|
import { isShellConfigured } from "@/lib/appshell";
|
|
import { useRealtime } from "@/lib/realtime";
|
|
import { CrmMessagingAdapter, type DataDoor } from "@/lib/crm-messaging-adapter";
|
|
|
|
const SHELL = isShellConfigured();
|
|
|
|
export function MessengerSdk({ focusThreadId }: { focusThreadId?: string | null } = {}) {
|
|
return (
|
|
<div className="view">
|
|
{!SHELL && (
|
|
<div
|
|
style={{
|
|
margin: "0 0 14px",
|
|
padding: "8px 14px",
|
|
borderRadius: 10,
|
|
background: "var(--panel-2)",
|
|
color: "var(--muted)",
|
|
fontSize: 13,
|
|
border: "1px solid var(--border)",
|
|
}}
|
|
>
|
|
Demo mode — running on the SDK's mock adapter.
|
|
</div>
|
|
)}
|
|
<div className="miu-host">{SHELL ? <LiveHost focusThreadId={focusThreadId} /> : <DemoHost focusThreadId={focusThreadId} />}</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// SHELL is a build-time constant, so exactly one of these mounts for the life of the app
|
|
// (Rules-of-Hooks safe — the other branch never renders).
|
|
function DemoHost({ focusThreadId }: { focusThreadId?: string | null }) {
|
|
const adapter = useMemo<MessagingAdapter>(() => new MockAdapter(), []);
|
|
return (
|
|
<MessagingProvider adapter={adapter}>
|
|
<SdkMessenger focusThreadId={focusThreadId} />
|
|
</MessagingProvider>
|
|
);
|
|
}
|
|
|
|
function LiveHost({ focusThreadId }: { focusThreadId?: string | null }) {
|
|
const { sdk } = useAppShell();
|
|
const { user } = useAuth();
|
|
const socket = useRealtime();
|
|
// Rebuilds once the socket connects: the first adapter (no socket) polls; the second runs live.
|
|
const adapter = useMemo<MessagingAdapter | null>(
|
|
() => (user?.id ? new CrmMessagingAdapter(sdk as unknown as DataDoor, user.id, socket ?? undefined) : null),
|
|
[sdk, user?.id, socket],
|
|
);
|
|
if (!adapter) return <div className="miu-empty">Loading…</div>;
|
|
return (
|
|
<MessagingProvider adapter={adapter}>
|
|
<SdkMessenger focusThreadId={focusThreadId} />
|
|
</MessagingProvider>
|
|
);
|
|
}
|