Download src/components/learn-anything/LearnAnythingQueryBox.tsx from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 9.63 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/learn-anything/LearnAnythingQueryBox.tsx
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/learn-anything/LearnAnythingQueryBox.tsx
-
curl -L -o LearnAnythingQueryBox.tsx https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/learn-anything/LearnAnythingQueryBox.tsx
9.63 kB
| "use client"; | |
| import { useId } from "react"; | |
| import type { LearningPathVariant, LearnAnythingFormData } from "./learnAnythingTypes"; | |
| const TUITION_EXAMPLE_CHIPS = [ | |
| "Teach me +2 Physics motion in a straight line", | |
| "Explain Kerala Plus Two Chemistry electrochemistry", | |
| "Teach Boolean logic from zero", | |
| "Revise Class 10 Maths quadratic equations", | |
| ]; | |
| const GENERAL_EXAMPLE_CHIPS = [ | |
| "Build a zero to advanced Python curriculum", | |
| "Teach me machine learning from scratch", | |
| "Create a business basics learning path", | |
| "Learn AI agents with projects", | |
| ]; | |
| const CLASS_OPTIONS = ["Class 8", "Class 9", "Class 10", "Plus One / Grade 11", "Plus Two / Grade 12"]; | |
| const SYLLABUS_OPTIONS = ["Kerala HSE", "CBSE", "ICSE", "State Board"]; | |
| const SUBJECT_OPTIONS = ["Physics", "Chemistry", "Mathematics", "Biology", "Computer Science", "Social Science"]; | |
| const DAILY_TIME_OPTIONS = ["30 minutes", "1 hour", "1.5 hours", "2 hours", "Exam-eve emergency mode"]; | |
| const TUITION_GOAL_OPTIONS = [ | |
| { value: "full-marks", label: "Full marks" }, | |
| { value: "a-plus", label: "A+" }, | |
| { value: "strong-basics", label: "Strong basics" }, | |
| { value: "pass", label: "Pass" }, | |
| { value: "revision", label: "Revision" }, | |
| { value: "exam-rescue", label: "Exam rescue" }, | |
| ]; | |
| const GENERAL_GOAL_OPTIONS = [ | |
| { value: "zero-to-advanced", label: "Zero to advanced" }, | |
| { value: "job-skill", label: "Practical job skill" }, | |
| { value: "project-based", label: "Project-based learning" }, | |
| { value: "exam-or-interview", label: "Exam or interview prep" }, | |
| { value: "quick-foundation", label: "Quick foundation" }, | |
| ]; | |
| const LEVEL_OPTIONS = [ | |
| { value: "beginner", label: "Beginner" }, | |
| { value: "basic", label: "Basic" }, | |
| { value: "average", label: "Average" }, | |
| { value: "intermediate", label: "Intermediate" }, | |
| { value: "advanced", label: "Advanced" }, | |
| ]; | |
| interface LearnAnythingQueryBoxProps { | |
| formData: LearnAnythingFormData; | |
| onChange: (data: LearnAnythingFormData) => void; | |
| variant?: LearningPathVariant; | |
| } | |
| export function LearnAnythingQueryBox({ formData, onChange, variant = "general" }: LearnAnythingQueryBoxProps) { | |
| const id = useId(); | |
| const isTuition = variant === "tuition"; | |
| const examples = isTuition ? TUITION_EXAMPLE_CHIPS : GENERAL_EXAMPLE_CHIPS; | |
| const goalOptions = isTuition ? TUITION_GOAL_OPTIONS : GENERAL_GOAL_OPTIONS; | |
| const updateField = (field: keyof LearnAnythingFormData, value: string) => { | |
| onChange({ ...formData, [field]: value }); | |
| }; | |
| return ( | |
| <div className="w-full space-y-4"> | |
| <div className="relative"> | |
| <label htmlFor={`${id}-query`} className="sr-only"> | |
| {isTuition ? "What school concept do you want to study?" : "What skill or topic do you want to learn?"} | |
| </label> | |
| <textarea | |
| id={`${id}-query`} | |
| value={formData.query} | |
| onChange={(e) => updateField("query", e.target.value)} | |
| placeholder={ | |
| isTuition | |
| ? "Tell DocDoe your class, syllabus, subject, chapter, or doubt..." | |
| : "Tell DocDoe the skill, topic, project, or outcome you want..." | |
| } | |
| className="w-full min-h-[120px] resize-none rounded-2xl border border-white/10 bg-white/[0.03] px-5 py-4 text-white placeholder:text-white/45 focus:outline-none focus:ring-2 focus:ring-white/20 focus:border-transparent transition-all scrollbar-thin scrollbar-thumb-white/20 scrollbar-track-transparent" | |
| aria-describedby={`${id}-description`} | |
| /> | |
| <p id={`${id}-description`} className="sr-only"> | |
| {isTuition | |
| ? "Enter a school topic, subject, chapter, doubt, or exam goal." | |
| : "Enter a skill, topic, project, or learning goal."} | |
| </p> | |
| </div> | |
| {formData.query.length === 0 && ( | |
| <div className="flex flex-wrap gap-2"> | |
| {examples.map((example) => ( | |
| <button | |
| key={example} | |
| type="button" | |
| onClick={() => updateField("query", example)} | |
| className="rounded-lg border border-white/15 bg-white/[0.04] px-3 py-1.5 text-sm text-white/70 hover:bg-white/[0.08] hover:border-white/25 transition-colors" | |
| > | |
| {example} | |
| </button> | |
| ))} | |
| </div> | |
| )} | |
| {isTuition ? ( | |
| <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"> | |
| <SelectField | |
| id={`${id}-class`} | |
| label="Class" | |
| value={formData.classLevel} | |
| placeholder="Class not set" | |
| options={CLASS_OPTIONS} | |
| onChange={(value) => updateField("classLevel", value)} | |
| /> | |
| <SelectField | |
| id={`${id}-syllabus`} | |
| label="Syllabus / Board" | |
| value={formData.syllabus} | |
| placeholder="Syllabus not set" | |
| options={SYLLABUS_OPTIONS} | |
| onChange={(value) => updateField("syllabus", value)} | |
| /> | |
| <SelectField | |
| id={`${id}-subject`} | |
| label="Subject" | |
| value={formData.subject} | |
| placeholder="Subject not set" | |
| options={SUBJECT_OPTIONS} | |
| onChange={(value) => updateField("subject", value)} | |
| /> | |
| <TextField | |
| id={`${id}-chapter`} | |
| label="Chapter / Topic" | |
| value={formData.chapter} | |
| placeholder="e.g. Ray Optics" | |
| onChange={(value) => updateField("chapter", value)} | |
| /> | |
| <TextField | |
| id={`${id}-exam-date`} | |
| label="Exam Date" | |
| value={formData.examDate} | |
| type="date" | |
| onChange={(value) => updateField("examDate", value)} | |
| /> | |
| <SelectField | |
| id={`${id}-daily-time`} | |
| label="Daily Study Time" | |
| value={formData.dailyStudyTime} | |
| placeholder="Time not set" | |
| options={DAILY_TIME_OPTIONS} | |
| onChange={(value) => updateField("dailyStudyTime", value)} | |
| /> | |
| <SelectField | |
| id={`${id}-current-level`} | |
| label="Current Level" | |
| value={formData.currentLevel} | |
| placeholder="Level not set" | |
| options={LEVEL_OPTIONS} | |
| onChange={(value) => updateField("currentLevel", value)} | |
| /> | |
| <TextField | |
| id={`${id}-weak-topics`} | |
| label="Weak Topics" | |
| value={formData.weakTopics} | |
| placeholder="e.g. derivations, units" | |
| onChange={(value) => updateField("weakTopics", value)} | |
| /> | |
| </div> | |
| ) : ( | |
| <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"> | |
| <TextField | |
| id={`${id}-subject`} | |
| label="Skill Area" | |
| value={formData.subject} | |
| placeholder="e.g. Python, ML, business" | |
| onChange={(value) => updateField("subject", value)} | |
| /> | |
| <SelectField | |
| id={`${id}-current-level`} | |
| label="Current Level" | |
| value={formData.currentLevel} | |
| placeholder="Level not set" | |
| options={LEVEL_OPTIONS} | |
| onChange={(value) => updateField("currentLevel", value)} | |
| /> | |
| <SelectField | |
| id={`${id}-daily-time`} | |
| label="Daily Study Time" | |
| value={formData.dailyStudyTime} | |
| placeholder="Time not set" | |
| options={DAILY_TIME_OPTIONS.filter((option) => option !== "Exam-eve emergency mode")} | |
| onChange={(value) => updateField("dailyStudyTime", value)} | |
| /> | |
| </div> | |
| )} | |
| <SelectField | |
| id={`${id}-goal`} | |
| label="Goal" | |
| value={formData.goal} | |
| placeholder="Goal not set" | |
| options={goalOptions} | |
| onChange={(value) => updateField("goal", value)} | |
| /> | |
| </div> | |
| ); | |
| } | |
| function fieldClassName() { | |
| return "w-full rounded-xl border border-white/10 bg-white/[0.03] px-4 py-2.5 text-white placeholder:text-white/45 focus:outline-none focus:ring-2 focus:ring-white/20 focus:border-transparent transition-all"; | |
| } | |
| function FieldLabel({ id, label }: { id: string; label: string }) { | |
| return ( | |
| <label htmlFor={id} className="block text-sm font-medium text-white/70 mb-1"> | |
| {label} | |
| </label> | |
| ); | |
| } | |
| function SelectField({ | |
| id, | |
| label, | |
| value, | |
| placeholder, | |
| options, | |
| onChange, | |
| }: { | |
| id: string; | |
| label: string; | |
| value: string; | |
| placeholder: string; | |
| options: Array<string | { value: string; label: string }>; | |
| onChange: (value: string) => void; | |
| }) { | |
| return ( | |
| <div> | |
| <FieldLabel id={id} label={label} /> | |
| <select id={id} value={value} onChange={(e) => onChange(e.target.value)} className={fieldClassName()}> | |
| <option value="">{placeholder}</option> | |
| {options.map((option) => { | |
| const value = typeof option === "string" ? option : option.value; | |
| const label = typeof option === "string" ? option : option.label; | |
| return ( | |
| <option key={value} value={value}> | |
| {label} | |
| </option> | |
| ); | |
| })} | |
| </select> | |
| </div> | |
| ); | |
| } | |
| function TextField({ | |
| id, | |
| label, | |
| value, | |
| placeholder, | |
| type = "text", | |
| onChange, | |
| }: { | |
| id: string; | |
| label: string; | |
| value: string; | |
| placeholder?: string; | |
| type?: "text" | "date"; | |
| onChange: (value: string) => void; | |
| }) { | |
| return ( | |
| <div> | |
| <FieldLabel id={id} label={label} /> | |
| <input | |
| id={id} | |
| value={value} | |
| type={type} | |
| placeholder={placeholder} | |
| onChange={(e) => onChange(e.target.value)} | |
| className={fieldClassName()} | |
| /> | |
| </div> | |
| ); | |
| } | |