landscapeforge / frontend /src /pages /LandscapeExplorer.jsx
mnawfal29's picture
Upload folder using huggingface_hub
b89c27d verified
import { useState, useEffect } from 'react'
import Plot from 'react-plotly.js'
import { getLandscape } from '../lib/api.js'
const TEMPLATES = [
'quadratic', 'rosenbrock', 'styblinski_tang', 'huber',
'gaussian_mix', 'himmelblau', 'plateau', 'cliff',
]
export function LandscapeExplorer() {
const [template, setTemplate] = useState('rosenbrock')
const [dim, setDim] = useState(2)
const [seed, setSeed] = useState(0)
const [data, setData] = useState(null)
const [loading, setLoading] = useState(false)
async function build() {
setLoading(true)
try {
const d = await getLandscape({ template, dim, seed })
setData(d)
} finally { setLoading(false) }
}
useEffect(() => { build() /* initial load */ // eslint-disable-next-line
}, [])
return (
<div className="grid grid-cols-[320px_1fr] gap-5">
<aside className="card space-y-4 h-fit">
<div>
<h3 className="mb-1">Landscape explorer</h3>
<p className="text-xs text-muted">
Pick a template and see what the agent sees at reset.
</p>
</div>
<div>
<label className="label">Template</label>
<select className="input" value={template}
onChange={e => setTemplate(e.target.value)}>
{TEMPLATES.map(t => <option key={t}>{t}</option>)}
</select>
</div>
<div>
<label className="label">Dim: {dim}</label>
<input type="range" min={2} max={10} step={1} value={dim}
onChange={e => setDim(Number(e.target.value))}
className="w-full accent-accent" />
</div>
<div>
<label className="label">Seed: {seed}</label>
<input type="range" min={0} max={100} step={1} value={seed}
onChange={e => setSeed(Number(e.target.value))}
className="w-full accent-accent" />
</div>
<button className="btn-primary w-full"
onClick={build} disabled={loading}>
{loading ? 'Building…' : 'Build landscape'}
</button>
</aside>
<div className="space-y-4">
{data?.contour && (
<div className="card">
<Plot data={data.contour.data} layout={data.contour.layout}
config={{ displayModeBar: false, responsive: true }}
style={{ width: '100%' }} useResizeHandler />
</div>
)}
{data?.hints && (
<div className="card">
<h3 className="mb-2">Structural hints</h3>
<table className="w-full text-sm">
<tbody>
{data.hints.map(([k, v], i) => (
<tr key={i} className="border-b border-border-soft">
<td className="py-2 pr-3 text-muted font-mono text-xs">{k}</td>
<td className="py-2 text-ink font-mono text-xs">{v}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
</div>
)
}