Download src/components/study-chat/AnswerCorrectionForm.tsx from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 6.44 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/study-chat/AnswerCorrectionForm.tsx
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/study-chat/AnswerCorrectionForm.tsx
-
curl -L -o AnswerCorrectionForm.tsx https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/study-chat/AnswerCorrectionForm.tsx
6.44 kB
| "use client"; | |
| import { useState } from "react"; | |
| import { ClipboardCheck, LoaderCircle, Send } from "lucide-react"; | |
| import { generateBrainAnswerCorrection } from "@/lib/api/brain"; | |
| import type { BrainAnswerCorrectionOutput, BrainGenerationResponse } from "@/lib/api/types"; | |
| import type { ApiDocument } from "@/lib/api/types"; | |
| type AnswerCorrectionFormProps = { | |
| selectedDocuments: ApiDocument[]; | |
| onSubmit: (result: BrainGenerationResponse<BrainAnswerCorrectionOutput>, question: string, studentAnswer: string) => void; | |
| onCancel: () => void; | |
| }; | |
| export function AnswerCorrectionForm({ | |
| selectedDocuments, | |
| onSubmit, | |
| onCancel, | |
| }: AnswerCorrectionFormProps) { | |
| const [question, setQuestion] = useState(""); | |
| const [studentAnswer, setStudentAnswer] = useState(""); | |
| const [marks, setMarks] = useState<string>("not_sure"); | |
| const [subject, setSubject] = useState(selectedDocuments[0]?.subject ?? ""); | |
| const [isSubmitting, setIsSubmitting] = useState(false); | |
| const [error, setError] = useState<string | null>(null); | |
| const canSubmit = question.trim().length > 0 && studentAnswer.trim().length > 0 && !isSubmitting; | |
| async function handleSubmit() { | |
| if (!canSubmit) return; | |
| setIsSubmitting(true); | |
| setError(null); | |
| try { | |
| const sourceIds = selectedDocuments.filter((d) => d.status === "ready").map((d) => d.id); | |
| const result = await generateBrainAnswerCorrection({ | |
| topic: question, | |
| subject: subject || undefined, | |
| source_id: sourceIds[0] || undefined, | |
| source_ids: sourceIds.length > 0 ? sourceIds : undefined, | |
| language_preference: "English", | |
| options: { | |
| mode: "answer_correction", | |
| question, | |
| student_answer: studentAnswer, | |
| marks, | |
| subject: subject || undefined, | |
| }, | |
| }); | |
| onSubmit(result, question, studentAnswer); | |
| } catch (err) { | |
| setError(err instanceof Error ? err.message : "Correction failed. Please try again."); | |
| setIsSubmitting(false); | |
| } | |
| } | |
| return ( | |
| <div className="animate-msg-assistant w-full rounded-xl border border-white/[0.06] bg-[#080809] p-5"> | |
| <div className="mb-4 flex items-center gap-2.5"> | |
| <ClipboardCheck className="size-4 shrink-0 text-emerald-400/70" /> | |
| <div> | |
| <span className="text-[10px] font-medium uppercase tracking-[0.08em] text-white/22">Answer Correction</span> | |
| <p className="text-[14px] font-semibold text-white/90">Find marks lost and rewrite in board format</p> | |
| </div> | |
| </div> | |
| {selectedDocuments.length > 0 && ( | |
| <p className="mb-3 text-[11px] text-white/30"> | |
| Using: {selectedDocuments.map((d) => d.title).join(", ")} | |
| </p> | |
| )} | |
| <div className="grid gap-3"> | |
| <label className="grid gap-1.5"> | |
| <span className="text-[10px] font-bold uppercase tracking-[0.12em] text-white/30">Question</span> | |
| <textarea | |
| value={question} | |
| onChange={(e) => setQuestion(e.target.value)} | |
| rows={2} | |
| placeholder="Paste the exam question" | |
| className="min-h-16 resize-none rounded-xl border border-white/[0.07] bg-black/30 px-3 py-2.5 text-[13px] leading-5 text-white/80 outline-none placeholder:text-white/25 focus:border-emerald-400/30" | |
| /> | |
| </label> | |
| <label className="grid gap-1.5"> | |
| <span className="text-[10px] font-bold uppercase tracking-[0.12em] text-white/30">Your answer</span> | |
| <textarea | |
| value={studentAnswer} | |
| onChange={(e) => setStudentAnswer(e.target.value)} | |
| rows={4} | |
| placeholder="Paste what you wrote" | |
| className="min-h-24 resize-none rounded-xl border border-white/[0.07] bg-black/30 px-3 py-2.5 text-[13px] leading-5 text-white/80 outline-none placeholder:text-white/25 focus:border-emerald-400/30" | |
| /> | |
| </label> | |
| <div className="grid gap-2 sm:grid-cols-[minmax(0,1fr)_120px]"> | |
| <label className="grid gap-1.5"> | |
| <span className="text-[10px] font-bold uppercase tracking-[0.12em] text-white/30">Subject or chapter</span> | |
| <input | |
| value={subject} | |
| onChange={(e) => setSubject(e.target.value)} | |
| placeholder="Optional" | |
| className="h-10 rounded-xl border border-white/[0.07] bg-black/30 px-3 text-[13px] text-white/80 outline-none placeholder:text-white/25 focus:border-emerald-400/30" | |
| /> | |
| </label> | |
| <label className="grid gap-1.5"> | |
| <span className="text-[10px] font-bold uppercase tracking-[0.12em] text-white/30">Marks</span> | |
| <select | |
| value={marks} | |
| onChange={(e) => setMarks(e.target.value)} | |
| className="h-10 rounded-xl border border-white/[0.07] bg-black/30 px-3 text-[13px] text-white/80 outline-none focus:border-emerald-400/30" | |
| > | |
| <option value="not_sure">Not sure</option> | |
| <option value="1">1</option> | |
| <option value="2">2</option> | |
| <option value="3">3</option> | |
| <option value="4">4</option> | |
| <option value="5">5</option> | |
| <option value="6">6</option> | |
| </select> | |
| </label> | |
| </div> | |
| </div> | |
| {error && ( | |
| <p className="mt-2 text-[12px] text-red-400/80">{error}</p> | |
| )} | |
| <div className="mt-4 flex items-center gap-2"> | |
| <button | |
| type="button" | |
| onClick={handleSubmit} | |
| disabled={!canSubmit} | |
| className="inline-flex h-9 items-center justify-center gap-2 rounded-xl bg-emerald-600/90 px-4 text-[12px] font-bold text-white shadow-[0_0_16px_rgba(16,185,129,0.15)] transition hover:bg-emerald-500 active:scale-95 disabled:cursor-not-allowed disabled:opacity-40" | |
| > | |
| {isSubmitting ? ( | |
| <LoaderCircle className="size-3.5 animate-spin" /> | |
| ) : ( | |
| <Send className="size-3.5" /> | |
| )} | |
| {isSubmitting ? "Correcting..." : "Correct answer"} | |
| </button> | |
| <button | |
| type="button" | |
| onClick={onCancel} | |
| className="inline-flex h-9 items-center justify-center rounded-xl border border-white/[0.08] px-4 text-[12px] font-medium text-white/50 transition hover:border-white/20 hover:text-white/80" | |
| > | |
| Cancel | |
| </button> | |
| </div> | |
| </div> | |
| ); | |
| } | |