Files
apes/ui/colony/src/components/ComposeBox.tsx
limiteinductive 4a9807ccd8 fix: TS build errors — remove asChild, simplify type selector
- SheetTrigger: remove asChild (base-ui doesn't support it)
- ComposeBox: use plain buttons with cn() instead of ToggleGroup (API mismatch)
- Remove unused Button import from App

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:01:22 +02:00

108 lines
3.0 KiB
TypeScript

import { useState } from "react";
import type { MessageType } from "@/types/MessageType";
import { postMessage } from "@/api";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
interface Props {
channelId: string;
replyTo: string | null;
onClearReply: () => void;
onMessageSent: () => void;
}
const MSG_TYPES: { value: MessageType; label: string }[] = [
{ value: "text", label: "T" },
{ value: "code", label: "C" },
{ value: "result", label: "R" },
{ value: "error", label: "E" },
{ value: "plan", label: "P" },
];
export function ComposeBox({
channelId,
replyTo,
onClearReply,
onMessageSent,
}: Props) {
const [content, setContent] = useState("");
const [msgType, setMsgType] = useState<MessageType>("text");
const [sending, setSending] = useState(false);
async function handleSend() {
if (!content.trim() || sending) return;
setSending(true);
try {
await postMessage(channelId, {
content: content.trim(),
type: msgType,
reply_to: replyTo ?? undefined,
});
setContent("");
setMsgType("text");
onClearReply();
onMessageSent();
} finally {
setSending(false);
}
}
return (
<div className="border-t border-border bg-card px-3 py-2 md:px-4 md:py-3 pb-[env(safe-area-inset-bottom,8px)]">
{replyTo && (
<div className="flex items-center gap-2 mb-1.5 text-xs text-muted-foreground">
<span>^ #{replyTo.slice(0, 8)}</span>
<Button variant="ghost" size="sm" onClick={onClearReply} className="h-6 px-1 text-xs">
[x]
</Button>
</div>
)}
<div className="flex items-center gap-1.5 md:gap-2">
{/* Type selector */}
<div className="flex gap-0.5 rounded-md border border-border p-0.5">
{MSG_TYPES.map((t) => (
<button
type="button"
key={t.value}
onClick={() => setMsgType(t.value)}
className={cn(
"h-7 w-7 md:h-6 md:w-6 rounded-sm text-xs font-bold transition-colors",
msgType === t.value
? "bg-primary text-primary-foreground"
: "text-muted-foreground hover:text-foreground"
)}
>
{t.label}
</button>
))}
</div>
<Input
value={content}
onChange={(e) => setContent(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSend();
}
}}
placeholder="message..."
disabled={sending}
className="flex-1 h-9 md:h-8 text-sm"
/>
<Button
onClick={handleSend}
disabled={sending || !content.trim()}
size="sm"
className="h-9 md:h-8 px-3 text-xs font-bold"
>
{sending ? "..." : "SEND"}
</Button>
</div>
</div>
);
}