diff options
| author | soryu <soryu@soryu.co> | 2026-02-16 15:09:25 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-16 15:09:25 +0000 |
| commit | b6a29bb563499b2fd6280c742bd2106d66393112 (patch) | |
| tree | 6f8d13fe989613b687b12e37277b661ff4d607c8 /makima/frontend | |
| parent | 0676468e3e69ff36f1e509d775f191dd41f6080b (diff) | |
| download | soryu-b6a29bb563499b2fd6280c742bd2106d66393112.tar.gz soryu-b6a29bb563499b2fd6280c742bd2106d66393112.zip | |
Add pick-up-orders feature for directives (#64)
* WIP: heartbeat checkpoint
* WIP: heartbeat checkpoint
* feat: soryu-co/soryu - makima: Add frontend pick-up-orders button and API integration
* feat: soryu-co/soryu - makima: Add pick-up-orders backend endpoint and repository functions
Diffstat (limited to 'makima/frontend')
| -rw-r--r-- | makima/frontend/src/components/directives/DirectiveDetail.tsx | 35 | ||||
| -rw-r--r-- | makima/frontend/src/hooks/useDirectives.ts | 9 | ||||
| -rw-r--r-- | makima/frontend/src/lib/api.ts | 14 | ||||
| -rw-r--r-- | makima/frontend/src/routes/directives.tsx | 3 |
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"> |
