"use client"; import { useState } from "react"; import { ArrowUp, LoaderCircle, } from "lucide-react"; import type { ApiDocument } from "@/lib/api/types"; import { cn } from "@/lib/utils"; import { ComposerPlusMenu } from "./ComposerPlusMenu"; import { ComposerSourceDraft } from "./ComposerSourceDraft"; import { SourcePill } from "./SourceControls"; import type { SourceDraftMode } from "./types"; export function StudyComposer({ value, onChange, onSubmit, placeholder, disabled, selectedDocuments, onRemoveSource, onMaterialFile, onOpenMaterialPicker, onOpenPaperPicker, sourceDraftMode, onSourceDraftModeChange, draftTitle, onDraftTitleChange, draftText, onDraftTextChange, onSaveDraftSource, isSavingDraft, isUploading, uploadNotice, onRetryUpload, plusOpen, onPlusOpenChange, compact = false, variant = "default", }: { value: string; onChange: (value: string) => void; onSubmit: () => void; placeholder: string; disabled: boolean; selectedDocuments: ApiDocument[]; onRemoveSource: (id: string) => void; onMaterialFile: (file: File) => void; onOpenMaterialPicker: () => void; onOpenPaperPicker: () => void; sourceDraftMode: SourceDraftMode; onSourceDraftModeChange: (mode: SourceDraftMode) => void; draftTitle: string; onDraftTitleChange: (value: string) => void; draftText: string; onDraftTextChange: (value: string) => void; onSaveDraftSource: () => void; isSavingDraft: boolean; isUploading: boolean; uploadNotice: string | null; onRetryUpload?: () => void; plusOpen: boolean; onPlusOpenChange: (open: boolean) => void; compact?: boolean; variant?: "default" | "hero"; }) { const [dragging, setDragging] = useState(false); function handleDrop(event: React.DragEvent) { event.preventDefault(); setDragging(false); const file = event.dataTransfer.files?.[0]; if (file) onMaterialFile(file); } return (
{ event.preventDefault(); setDragging(true); }} onDragLeave={() => setDragging(false)} onDrop={handleDrop} className={cn( "kb-composer relative rounded-[1.35rem] border border-white/[0.095] bg-[#080808]/92 p-3 shadow-[0_18px_70px_rgba(0,0,0,0.38),inset_0_1px_0_rgba(255,255,255,0.04)] transition duration-200 focus-within:border-white/[0.22] focus-within:bg-[#0b0b0c] sm:p-4", variant === "hero" && !compact ? "kb-composer-hero border-white/[0.11] p-3.5 shadow-[0_22px_80px_rgba(0,0,0,0.45),inset_0_1px_0_rgba(255,255,255,0.05)] sm:p-5" : "", compact ? "rounded-[1.15rem] p-2.5 sm:p-3" : "", dragging ? "border-white/[0.28] bg-white/[0.07] shadow-[0_24px_90px_rgba(0,0,0,0.5)]" : "", )} > {dragging ? (
Drop your study source
) : null} {selectedDocuments.length > 0 ? (
grounded to {selectedDocuments.length} source(s) • multi-turn {selectedDocuments.map((document) => ( onRemoveSource(document.id)} onRemove={() => onRemoveSource(document.id)} /> ))}
) : null} {sourceDraftMode ? ( onSourceDraftModeChange(null)} isSavingDraft={isSavingDraft} /> ) : null}