import React, { useState, useEffect } from 'react'; import ReactDOM from 'react-dom/client'; import { LogtoProvider, UserScope, useLogto } from '@logto/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { BrowserRouter } from 'react-router'; import { ThemeProvider, ToastProvider, BreadcrumbProvider, GlobalFilterProvider, CommandPaletteProvider, Spinner } from '@cameleer/design-system'; import '@cameleer/design-system/style.css'; import { AppRouter } from './router'; import { fetchConfig } from './config'; import { setTokenProvider } from './api/client'; import { useOrgStore } from './auth/useOrganization'; const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 1, staleTime: 10_000, }, }, }); function TokenSync({ resource }: { resource: string }) { const { getAccessToken, isAuthenticated, fetchUserInfo } = useLogto(); const { currentOrgId, setCurrentOrg, setOrganizations } = useOrgStore(); // After auth, resolve user's organizations from Logto useEffect(() => { if (!isAuthenticated) { setOrganizations([]); setCurrentOrg(null); return; } fetchUserInfo().then((info) => { const orgData = (info as Record)?.organization_data as Array<{ id: string; name: string }> | undefined; const orgs = orgData ?? []; setOrganizations(orgs.map((o) => ({ id: o.id, name: o.name }))); // Auto-select if user has exactly one org if (orgs.length === 1 && !currentOrgId) { setCurrentOrg(orgs[0].id); } }).catch(() => { // fetchUserInfo may fail if token is being refreshed }); }, [isAuthenticated]); // Set token provider — org-scoped if org selected, plain otherwise useEffect(() => { if (isAuthenticated && resource) { if (currentOrgId) { setTokenProvider(() => getAccessToken(resource, currentOrgId)); } else { setTokenProvider(() => getAccessToken(resource)); } } else { setTokenProvider(null); } }, [isAuthenticated, getAccessToken, resource, currentOrgId]); return null; } function App() { const [config, setConfig] = useState<{ logtoEndpoint: string; logtoClientId: string; logtoResource: string; } | null>(null); useEffect(() => { fetchConfig().then(setConfig); }, []); if (!config?.logtoClientId) { return (
); } return ( ); } ReactDOM.createRoot(document.getElementById('root')!).render( , );