'use client' import { Editor, type SceneGraph, type SidebarTab, ViewerToolbarLeft, ViewerToolbarRight, } from '@pascal-app/editor' import Link from 'next/link' import { useRouter } from 'next/navigation' import { useCallback, useRef, useState } from 'react' export interface SceneMeta { id: string name: string projectId: string | null thumbnailUrl: string | null version: number createdAt: string updatedAt: string ownerId: string | null sizeBytes: number nodeCount: number } const SIDEBAR_TABS: (SidebarTab & { component: React.ComponentType })[] = [ { id: 'site', label: 'Scene', component: () => null, // Built-in SitePanel handles this }, ] interface SceneLoaderProps { initialScene: SceneGraph meta: SceneMeta } export function SceneLoader({ initialScene, meta }: SceneLoaderProps) { const router = useRouter() const versionRef = useRef(meta.version) const [conflict, setConflict] = useState(false) const [saveError, setSaveError] = useState(null) const handleLoad = useCallback(async () => initialScene, [initialScene]) const handleSave = useCallback( async (graph: SceneGraph) => { try { const response = await fetch(`/api/scenes/${meta.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'If-Match': String(versionRef.current), }, body: JSON.stringify({ name: meta.name, graph }), }) if (response.status === 409) { setConflict(true) return } if (!response.ok) { setSaveError(`Save failed (${response.status})`) return } const next = (await response.json()) as SceneMeta versionRef.current = next.version setSaveError(null) } catch (error) { setSaveError(error instanceof Error ? error.message : 'Save failed') } }, [meta.id, meta.name], ) const handleThumb = useCallback( async (_blob: Blob) => { // TODO(phase7): upload thumbnail via POST /api/scenes/[id]/thumbnail. // Stub endpoint is not yet implemented in v0.1 — skip upload for now. await fetch(`/api/scenes/${meta.id}/thumbnail`, { method: 'POST', // Intentionally no body — endpoint is a stub. }).catch(() => { // Swallow errors silently; thumbnail upload is best-effort. }) }, [meta.id], ) return (
{conflict && (

Another session saved first — refresh?

Your changes haven't been saved. Reload to pick up the latest version.

)} {saveError && !conflict && (

{saveError}

)}
All scenes
} viewerToolbarRight={} />
) }