import { useEffect, useMemo } from 'react' import { getRouteApi } from '@tanstack/react-router' import { Alert } from '@/components/ui/Alert' import { GardenCanvas } from '@/editor/GardenCanvas' import { useEditorStore } from '@/editor/store' import type { EditorGarden } from '@/editor/types' import { toEditorObject } from '@/lib/objects' import { toEditorPlanting } from '@/lib/plantings' import { usePublicGarden } from '@/lib/publicGarden' import { usePageTitle } from '@/lib/usePageTitle' const routeApi = getRouteApi('/g/$token') /** * The public, read-only garden view behind a share token. Rendered on the * unauthenticated `/g/$token` route (no auth guard), so a logged-out visitor * never hits /login or OIDC. Reuses GardenCanvas with canEdit=false — pan/zoom * to explore, but no editing chrome. */ export function PublicGardenPage() { const { token } = routeApi.useParams() const full = usePublicGarden(token) usePageTitle(full.data?.garden.name ?? 'Shared garden') // Start from a clean canvas: if a logged-in user reaches here from their own // editor, stale focus/selection state would otherwise dim or highlight things. useEffect(() => { useEditorStore.getState().resetTransient() }, [token]) const objects = useMemo(() => full.data?.objects.map(toEditorObject) ?? [], [full.data?.objects]) const plantings = useMemo(() => full.data?.plantings.map(toEditorPlanting) ?? [], [full.data?.plantings]) const plants = useMemo(() => full.data?.plants ?? [], [full.data?.plants]) const plantsById = useMemo(() => new Map(plants.map((p) => [p.id, p])), [plants]) if (full.isPending) return
Loading garden…
if (full.isError) return (