Initial GeoIntel V1 foundation
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-06-16 23:36:32 +02:00
commit 6ea3586a3e
605 changed files with 45284 additions and 0 deletions
@@ -0,0 +1,66 @@
import type { FormEvent } from 'react'
import type { AreaRead, ProjectRead } from '../../types'
interface AreaFormState {
name: string
geometry: string
crs: string
}
interface AreaPanelProps {
areas: AreaRead[]
selectedProject: ProjectRead | null
selectedProjectId: string | null
loadingAreas: boolean
areaForm: AreaFormState
onCreateArea: (event: FormEvent<HTMLFormElement>) => void
onUpdateAreaForm: (areaForm: AreaFormState) => void
}
export function AreaPanel({
areas,
selectedProject,
selectedProjectId,
loadingAreas,
areaForm,
onCreateArea,
onUpdateAreaForm,
}: AreaPanelProps): JSX.Element {
return (
<section>
<h2>Area manager</h2>
<p>{selectedProject ? `Selected project: ${selectedProject.name}` : 'Select a project first'}</p>
<form onSubmit={onCreateArea}>
<input
value={areaForm.name}
onChange={(event) => onUpdateAreaForm({ ...areaForm, name: event.target.value })}
placeholder="AOI name"
/>
<input
value={areaForm.crs}
onChange={(event) => onUpdateAreaForm({ ...areaForm, crs: event.target.value })}
placeholder="EPSG:4326"
/>
<textarea
value={areaForm.geometry}
onChange={(event) => onUpdateAreaForm({ ...areaForm, geometry: event.target.value })}
rows={4}
/>
<button type="submit" disabled={!selectedProjectId}>
Create area
</button>
</form>
{loadingAreas ? <p>Loading areas...</p> : null}
{areas.length === 0 ? <p>No areas yet</p> : null}
<ul>
{areas.map((area) => (
<li key={area.id}>
{area.name} · {area.area_m2 ? `${area.area_m2.toFixed(2)} m²` : 'n/a'}
</li>
))}
</ul>
</section>
)
}
@@ -0,0 +1,76 @@
import type { FormEvent } from 'react'
import type { ProjectCreate, ProjectRead } from '../../types'
interface ProjectPanelProps {
projects: ProjectRead[]
selectedProjectId: string | null
loadingProjects: boolean
projectForm: ProjectCreate
loadingDemoWorkflow: boolean
demoWorkflowMessage: string | null
onCreateProject: (event: FormEvent<HTMLFormElement>) => void
onUpdateProjectForm: (projectForm: ProjectCreate) => void
onSelectProject: (projectId: string) => void
onLoadDemoWorkflow: () => void
}
export function ProjectPanel({
projects,
selectedProjectId,
loadingProjects,
projectForm,
loadingDemoWorkflow,
demoWorkflowMessage,
onCreateProject,
onUpdateProjectForm,
onSelectProject,
onLoadDemoWorkflow,
}: ProjectPanelProps): JSX.Element {
return (
<section>
<h2>Projects</h2>
{loadingProjects ? <p>Loading projects...</p> : null}
<form onSubmit={onCreateProject}>
<input
value={projectForm.name}
onChange={(event) => onUpdateProjectForm({ ...projectForm, name: event.target.value })}
placeholder="Project name"
/>
<input
value={projectForm.description ?? ''}
onChange={(event) => onUpdateProjectForm({ ...projectForm, description: event.target.value })}
placeholder="Description"
/>
<input
value={projectForm.region ?? 'Kempen'}
onChange={(event) => onUpdateProjectForm({ ...projectForm, region: event.target.value })}
placeholder="Region"
/>
<button type="submit">Create project</button>
</form>
<div className="demo-actions">
<button type="button" onClick={onLoadDemoWorkflow} disabled={loadingDemoWorkflow}>
{loadingDemoWorkflow ? 'Loading demo...' : 'Load demo workflow'}
</button>
{demoWorkflowMessage ? <p>{demoWorkflowMessage}</p> : null}
</div>
<ul>
{projects.map((project) => (
<li key={project.id}>
<button
type="button"
onClick={() => onSelectProject(project.id)}
aria-pressed={project.id === selectedProjectId}
>
{project.name}
</button>
</li>
))}
{projects.length === 0 ? <li>No projects yet</li> : null}
</ul>
</section>
)
}