'use client'; import * as React from 'react'; import { loadRemote, registerRemotes } from './federation'; interface RemoteComponentModule

{ default: React.ComponentType

; } interface RemoteSelection { name: string; entry: string; } const STORAGE_KEY = 'remoteComponentSelections'; const HIGHLIGHT_EVENT = 'apna:customise-highlight'; export function setCustomiseHighlight(enabled: boolean): void { if (typeof window === 'undefined') return; (window as unknown as { __APNA_CUSTOMISE_HIGHLIGHT__?: boolean }).__APNA_CUSTOMISE_HIGHLIGHT__ = enabled; window.dispatchEvent( new CustomEvent(HIGHLIGHT_EVENT, { detail: { enabled }, }) ); } export function withDynamicComponent

( remoteModuleName: string, DefaultComponent: React.ComponentType

): any { function DynamicComponent(props: P) { const [isHighlighted, setIsHighlighted] = React.useState(false); const [isPickerOpen, setIsPickerOpen] = React.useState(false); const [remoteName, setRemoteName] = React.useState(''); const [remoteEntry, setRemoteEntry] = React.useState(''); const [RemoteComponent, setRemoteComponent] = React.useState | null>(null); const [error, setError] = React.useState(null); React.useEffect(() => { if (typeof window === 'undefined') return; const w = window as unknown as { __APNA_CUSTOMISE_HIGHLIGHT__?: boolean }; setIsHighlighted(Boolean(w.__APNA_CUSTOMISE_HIGHLIGHT__)); const onHighlight = (event: Event) => { setIsHighlighted(Boolean((event as CustomEvent).detail?.enabled)); }; window.addEventListener(HIGHLIGHT_EVENT, onHighlight); return () => window.removeEventListener(HIGHLIGHT_EVENT, onHighlight); }, []); React.useEffect(() => { const selection = readSelection(remoteModuleName); if (selection) { void loadComponent(selection, false); } }, []); async function loadComponent( selection: RemoteSelection, updateStorage = true ) { try { setError(null); registerRemotes( [ { name: selection.name, entry: selection.entry, }, ], { force: true } ); const remoteModule = await loadRemote>( `${selection.name}/${remoteModuleName}` ); if (!remoteModule?.default) { throw new Error('Remote module does not contain a default export'); } setRemoteComponent(() => remoteModule.default); setIsPickerOpen(false); if (updateStorage) writeSelection(remoteModuleName, selection); } catch (err) { setError( err instanceof Error ? err.message : 'Failed to load remote component' ); } } const SelectedComponent = RemoteComponent || DefaultComponent; return ( <>

{ event.stopPropagation(); setIsPickerOpen(true); } : undefined } style={ isHighlighted ? { outline: '4px solid #368564', borderRadius: 6 } : undefined } >
{isPickerOpen && (
Select Remote Component {error &&

{error}

} setRemoteName(event.target.value)} placeholder="Remote name" /> setRemoteEntry(event.target.value)} placeholder="Remote entry URL" />
)} ); } DynamicComponent.displayName = `withDynamicComponent(${remoteModuleName})`; return DynamicComponent; } function readSelection(remoteModuleName: string): RemoteSelection | null { if (typeof window === 'undefined') return null; const raw = window.localStorage.getItem(STORAGE_KEY); if (!raw) return null; const selections = JSON.parse(raw) as Record; return selections[remoteModuleName] ?? null; } function writeSelection( remoteModuleName: string, selection: RemoteSelection ): void { if (typeof window === 'undefined') return; const raw = window.localStorage.getItem(STORAGE_KEY); const selections = raw ? JSON.parse(raw) : {}; selections[remoteModuleName] = selection; window.localStorage.setItem(STORAGE_KEY, JSON.stringify(selections)); } function clearSelection(remoteModuleName: string): void { if (typeof window === 'undefined') return; const raw = window.localStorage.getItem(STORAGE_KEY); if (!raw) return; const selections = JSON.parse(raw); delete selections[remoteModuleName]; window.localStorage.setItem(STORAGE_KEY, JSON.stringify(selections)); }