summaryrefslogtreecommitdiff
path: root/makima/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'makima/frontend/src')
-rw-r--r--makima/frontend/src/components/directives/DirectiveDetail.tsx35
-rw-r--r--makima/frontend/src/hooks/useDirectives.ts9
-rw-r--r--makima/frontend/src/lib/api.ts14
-rw-r--r--makima/frontend/src/routes/directives.tsx3
4 files changed, 60 insertions, 1 deletions
diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx
index e278939..9305e20 100644
--- a/makima/frontend/src/components/directives/DirectiveDetail.tsx
+++ b/makima/frontend/src/components/directives/DirectiveDetail.tsx
@@ -26,6 +26,7 @@ interface DirectiveDetailProps {
onDelete: () => void;
onRefresh: () => void;
onCleanupTasks: () => void;
+ onPickUpOrders: () => Promise<{ message: string; orderCount: number; taskId: string | null } | null>;
}
export function DirectiveDetail({
@@ -41,10 +42,13 @@ export function DirectiveDetail({
onDelete,
onRefresh,
onCleanupTasks,
+ onPickUpOrders,
}: DirectiveDetailProps) {
const [editingGoal, setEditingGoal] = useState(false);
const [goalText, setGoalText] = useState(directive.goal);
const [visibleTaskIds, setVisibleTaskIds] = useState<Set<string> | null>(null);
+ const [pickingUpOrders, setPickingUpOrders] = useState(false);
+ const [pickUpResult, setPickUpResult] = useState<string | null>(null);
// Sync goalText and reset editing state when directive changes
useEffect(() => {
@@ -121,6 +125,23 @@ export function DirectiveDetail({
prevHadRunningRef.current = hasRunningTasks;
}, [hasRunningTasks]);
+ const handlePickUpOrders = async () => {
+ setPickingUpOrders(true);
+ setPickUpResult(null);
+ try {
+ const result = await onPickUpOrders();
+ if (result) {
+ setPickUpResult(result.message);
+ setTimeout(() => setPickUpResult(null), 5000);
+ }
+ } catch (e) {
+ setPickUpResult(e instanceof Error ? e.message : "Failed to pick up orders");
+ setTimeout(() => setPickUpResult(null), 5000);
+ } finally {
+ setPickingUpOrders(false);
+ }
+ };
+
const handleGoalSave = () => {
if (goalText.trim() && goalText !== directive.goal) {
onUpdateGoal(goalText.trim());
@@ -314,12 +335,26 @@ export function DirectiveDetail({
)}
<button
type="button"
+ onClick={handlePickUpOrders}
+ disabled={pickingUpOrders}
+ className="text-[10px] font-mono text-[#c084fc] hover:text-[#d8b4fe] border border-[rgba(192,132,252,0.3)] rounded px-2 py-1 disabled:opacity-50"
+ >
+ {pickingUpOrders ? "Picking up..." : "Pick Up Orders"}
+ </button>
+ <button
+ type="button"
onClick={onDelete}
className={`text-[10px] font-mono text-red-400 hover:text-red-300 border border-red-800 rounded px-2 py-1 ${hasTerminalTasks ? "" : "ml-auto"}`}
>
Delete
</button>
</div>
+
+ {pickUpResult && (
+ <div className="mt-2 px-2 py-1.5 bg-[#1a1030] border border-[rgba(192,132,252,0.2)] rounded">
+ <span className="text-[10px] font-mono text-[#c084fc]">{pickUpResult}</span>
+ </div>
+ )}
</div>
{/* Goal */}
diff --git a/makima/frontend/src/hooks/useDirectives.ts b/makima/frontend/src/hooks/useDirectives.ts
index 0453d14..7e26ec4 100644
--- a/makima/frontend/src/hooks/useDirectives.ts
+++ b/makima/frontend/src/hooks/useDirectives.ts
@@ -20,6 +20,7 @@ import {
skipDirectiveStep,
updateDirectiveGoal,
cleanupDirectiveTasks,
+ pickUpOrders as pickUpOrdersApi,
} from "../lib/api";
export function useDirectives() {
@@ -177,11 +178,19 @@ export function useDirective(id: string | undefined) {
await refresh();
}, [id, refresh]);
+ const pickUpOrdersFn = useCallback(async () => {
+ if (!id) return null;
+ const result = await pickUpOrdersApi(id);
+ await refresh();
+ return result;
+ }, [id, refresh]);
+
return {
directive, loading, error, refresh,
update, addStep, removeStep,
start, pause, advance,
completeStep, failStep, skipStep,
updateGoal, cleanupTasks,
+ pickUpOrders: pickUpOrdersFn,
};
}
diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts
index f88176b..467ee22 100644
--- a/makima/frontend/src/lib/api.ts
+++ b/makima/frontend/src/lib/api.ts
@@ -3256,6 +3256,20 @@ export async function cleanupDirectiveTasks(id: string): Promise<{ deleted: numb
return res.json();
}
+export interface PickUpOrdersResponse {
+ message: string;
+ orderCount: number;
+ taskId: string | null;
+}
+
+export async function pickUpOrders(directiveId: string): Promise<PickUpOrdersResponse> {
+ const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/pick-up-orders`, {
+ method: "POST",
+ });
+ if (!res.ok) throw new Error(`Failed to pick up orders: ${res.statusText}`);
+ return res.json();
+}
+
// =============================================================================
// Orders API
// =============================================================================
diff --git a/makima/frontend/src/routes/directives.tsx b/makima/frontend/src/routes/directives.tsx
index 643cfee..b4ed0cc 100644
--- a/makima/frontend/src/routes/directives.tsx
+++ b/makima/frontend/src/routes/directives.tsx
@@ -12,7 +12,7 @@ export default function DirectivesPage() {
const navigate = useNavigate();
const { id: selectedId } = useParams<{ id: string }>();
const { directives, loading: listLoading, create, remove } = useDirectives();
- const { directive, refresh: refreshDetail, update, start, pause, advance, completeStep, failStep, skipStep, updateGoal, cleanupTasks } = useDirective(selectedId);
+ const { directive, refresh: refreshDetail, update, start, pause, advance, completeStep, failStep, skipStep, updateGoal, cleanupTasks, pickUpOrders } = useDirective(selectedId);
const [showCreate, setShowCreate] = useState(false);
const [newTitle, setNewTitle] = useState("");
@@ -211,6 +211,7 @@ export default function DirectivesPage() {
onDelete={handleDelete}
onRefresh={refreshDetail}
onCleanupTasks={cleanupTasks}
+ onPickUpOrders={pickUpOrders}
/>
) : (
<div className="flex-1 flex items-center justify-center h-full">