Intelligence
Artifacts
Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.
Repository
assignment-dispatch-button.tsxassignment-status-badge.tsxassignments-panel.tsxcreate-mission-form.tsxgovernance-panels.tsxmission-dispatch.tsxmission-edit.tsxmission-state-actions.tsxmission-status-badge.tsxobjective-edit.tsxobjective-status-badge.tsxobjective-status-select.tsxobjectives-panel.tsxreport-list.tsxwork-orders-panel.tsx
README.md
CONSTITUTION_COMPLIANCE_AUDIT_V1.mdREADME.md
repositories/aaf-holdings/hq01/components/missions/objective-status-select.tsx
1.5 KB
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import type { ObjectiveStatus } from "@/lib/missions/types";
const STATUSES: ObjectiveStatus[] = [
"Draft",
"Planned",
"Active",
"Blocked",
"Completed",
"Cancelled",
"Archived",
];
/**
* Inline status control for an objective. Changing it records a state_changed
* event server-side and refreshes the view (which recomputes mission progress).
*/
export function ObjectiveStatusSelect({
missionId,
oid,
status,
}: {
missionId: string;
oid: string;
status: ObjectiveStatus;
}) {
const router = useRouter();
const [busy, setBusy] = useState(false);
async function change(to: ObjectiveStatus) {
if (to === status) return;
setBusy(true);
try {
await fetch(`/api/missions/${missionId}/objectives/${oid}/status`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: to }),
});
router.refresh();
} finally {
setBusy(false);
}
}
return (
<select
value={status}
disabled={busy}
onChange={(e) => change(e.target.value as ObjectiveStatus)}
className="h-7 rounded-md border border-input bg-background px-2 text-[12px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50"
title="Change status"
>
{STATUSES.map((s) => (
<option key={s} value={s}>
{s}
</option>
))}
</select>
);
}
root · /srv/aaf