You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
// frontend/components/dashboard/CommandInput.tsx
|
|
"use client";
|
|
import { useRouter } from "next/navigation";
|
|
import { useState } from "react";
|
|
import { Icon } from "@/components/Icon";
|
|
import { captureCommand } from "@/lib/dashboard/api";
|
|
|
|
export function CommandInput() {
|
|
const [value, setValue] = useState("");
|
|
const [busy, setBusy] = useState(false);
|
|
const router = useRouter();
|
|
|
|
async function submit() {
|
|
const raw = value.trim();
|
|
if (!raw || busy) return;
|
|
setBusy(true);
|
|
try {
|
|
await captureCommand(raw); // POST /api/inbox/capture
|
|
window.dispatchEvent(
|
|
new CustomEvent("ari:toast", {
|
|
detail: { text: "인박스에 적어뒀어요 — 아리가 분류할게요" },
|
|
}),
|
|
);
|
|
router.push("/inbox");
|
|
} catch {
|
|
window.dispatchEvent(
|
|
new CustomEvent("ari:toast", {
|
|
detail: { text: "지금은 적어두지 못했어요. 잠시 후 다시 시도해 주세요.", tone: "coral" },
|
|
}),
|
|
);
|
|
} finally {
|
|
setBusy(false);
|
|
setValue("");
|
|
}
|
|
}
|
|
|
|
return (
|
|
<form
|
|
className="cmd"
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
submit();
|
|
}}
|
|
>
|
|
<Icon name="spark" />
|
|
<input
|
|
value={value}
|
|
onChange={(e) => setValue(e.target.value)}
|
|
placeholder="오늘 하루, 무엇이든 맡겨보세요…"
|
|
aria-label="아리에게 명령 입력"
|
|
disabled={busy}
|
|
/>
|
|
<button className="send" type="submit" aria-label="보내기" disabled={busy || !value.trim()}>
|
|
<Icon name="send" />
|
|
</button>
|
|
</form>
|
|
);
|
|
}
|