Kairo-Jinkendo/frontend/src/pages/modes/PlanProfilePage.jsx

106 lines
3.6 KiB
React
Raw Normal View History

import { useState } from 'react'
import { RequireInitiativeScope } from '../../components/RequireInitiativeScope.jsx'
import { ScopedInitiativeProvider } from '../../layout/ScopedInitiativeProvider.jsx'
import { StatusBadge } from '../../components/StatusBadge.jsx'
import { LoadingState } from '../../components/LoadingState.jsx'
import { Modal } from '../../components/Modal.jsx'
import { InitiativeForm } from '../../components/InitiativeForm.jsx'
import { useInitiativeOperations } from '../../context/InitiativeOperationsContext.jsx'
import { useProgramScope } from '../../context/ProgramScopeContext.jsx'
import { initiativeArchetypeLabel } from '../../constants/initiativeArchetypes.js'
function PlanProfileInner() {
const ops = useInitiativeOperations()
const { refreshInitiativeMeta } = useProgramScope()
const { initiative, loading, error, capabilities, formBusy } = ops
const [editing, setEditing] = useState(false)
const canManage = capabilities.has('kairo.initiative.manage')
if (loading) {
return <LoadingState message="Lade Profil …" />
}
if (!initiative) {
return <p className="muted">Vorhaben nicht gefunden.</p>
}
async function handleSave(payload) {
const ok = await ops.handleUpdateInitiative(payload)
if (ok) {
refreshInitiativeMeta()
setEditing(false)
}
}
return (
<>
<section className="card plan-profile">
<header className="plan-profile__header">
<h2 className="card-title">{initiative.title}</h2>
<div className="plan-profile__header-actions">
<StatusBadge kind="initiative" status={initiative.status} />
{canManage && (
<button
type="button"
className="btn btn-secondary btn-sm"
onClick={() => setEditing(true)}
disabled={formBusy}
>
Bearbeiten
</button>
)}
</div>
</header>
{error && <p className="error">{error}</p>}
<div className="plan-profile__field">
<h3 className="plan-profile__label">Archetyp</h3>
<p>{initiativeArchetypeLabel(initiative.archetype_key)}</p>
</div>
{initiative.goal ? (
<div className="plan-profile__field">
<h3 className="plan-profile__label">Kurzbeschreibung (Ziel)</h3>
<p>{initiative.goal}</p>
</div>
) : (
<p className="muted">Noch keine Kurzbeschreibung hinterlegt.</p>
)}
{initiative.vision && (
<div className="plan-profile__field">
<h3 className="plan-profile__label">Vision</h3>
<p>{initiative.vision}</p>
</div>
)}
{initiative.target_state_summary && (
<div className="plan-profile__field">
<h3 className="plan-profile__label">Zielzustand</h3>
<p>{initiative.target_state_summary}</p>
</div>
)}
<p className="muted plan-profile__note">
Dynamische Zusatzfelder (EFS) folgen in AP1.10c.
</p>
</section>
<Modal open={editing} title="Vorhaben bearbeiten" onClose={() => setEditing(false)} size="lg">
<InitiativeForm
initial={initiative}
onSubmit={handleSave}
onCancel={() => setEditing(false)}
busy={formBusy}
/>
</Modal>
</>
)
}
export function PlanProfilePage() {
return (
<RequireInitiativeScope lead="Das Vorhabens-Profil gehört zu einem gewählten Scope.">
<ScopedInitiativeProvider>
<PlanProfileInner />
</ScopedInitiativeProvider>
</RequireInitiativeScope>
)
}