import React, { useState, useEffect } from 'react' import GeneratorForm from './components/GeneratorForm' import SplatViewer from './components/SplatViewer' import { Layers } from 'lucide-react' function App() { const [jobId, setJobId] = useState(null) const [status, setStatus] = useState('IDLE') // IDLE, PENDING, GENERATING, READY, FAILED const [splatUrl, setSplatUrl] = useState(null) const [eta, setEta] = useState(120) // Default 2 minutes ETA useEffect(() => { let timer; if (status === 'GENERATING') { setEta(120); timer = setInterval(() => { setEta((prev) => (prev > 0 ? prev - 1 : 0)); }, 1000); } return () => clearInterval(timer); }, [status]); return (
{/* Background decoration */}
{/* Header */}

Marble Clone

Powered by Gemini & 3DGS
{/* Main Content area */}
{/* Left column: Controls */}
{/* Right column: 3D Viewer */}
{status === 'IDLE' && (

Enter a prompt to generate a 3D environment

)} {(status === 'PENDING' || status === 'GENERATING') && (

{status === 'PENDING' ? 'Analyzing with Gemini...' : 'GPU Rasterizing Gaussians...'}

{status === 'GENERATING' && (
ETA: ~{Math.floor(eta / 60)}:{(eta % 60).toString().padStart(2, '0')} {eta === 0 && ' (Finalizing payload...)'}
)}
)} {status === 'FAILED' && (
!

Generation Failed

Please ensure you uploaded a valid image and the API is reachable.

)} {status === 'READY' && splatUrl && ( )}
) } export default App