Download src/components/mode-selection/ModeNaturalInput.tsx from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 2.91 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/mode-selection/ModeNaturalInput.tsx
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/mode-selection/ModeNaturalInput.tsx
-
curl -L -o ModeNaturalInput.tsx https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/mode-selection/ModeNaturalInput.tsx
2.91 kB
| "use client"; | |
| /** | |
| * Mode Natural Input Component | |
| * Natural language input for study queries with local mode detection | |
| */ | |
| import { useState } from "react"; | |
| import { detectModeFromQuery, EXAMPLE_QUERIES, type Mode } from "./modeSelectionTypes"; | |
| interface ModeNaturalInputProps { | |
| onSubmit: (query: string, detectedMode: Mode) => void; | |
| } | |
| export function ModeNaturalInput({ onSubmit }: ModeNaturalInputProps) { | |
| const [query, setQuery] = useState(""); | |
| const [isFocused, setIsFocused] = useState(false); | |
| const handleSubmit = (e: React.FormEvent) => { | |
| e.preventDefault(); | |
| if (query.trim()) { | |
| const detectedMode = detectModeFromQuery(query); | |
| if (detectedMode) { | |
| onSubmit(query.trim(), detectedMode); | |
| } | |
| } | |
| }; | |
| const handleExampleClick = (example: string) => { | |
| setQuery(example); | |
| const detectedMode = detectModeFromQuery(example); | |
| if (detectedMode) { | |
| onSubmit(example, detectedMode); | |
| } | |
| }; | |
| return ( | |
| <div className="w-full max-w-2xl mx-auto"> | |
| <form onSubmit={handleSubmit} className="mb-6"> | |
| <div className={`relative transition-all duration-200 ${isFocused ? 'ring-2 ring-white/20' : 'ring-1 ring-white/10'}`}> | |
| <input | |
| type="text" | |
| value={query} | |
| onChange={(e) => setQuery(e.target.value)} | |
| onFocus={() => setIsFocused(true)} | |
| onBlur={() => setIsFocused(false)} | |
| placeholder="Tell DocDoe your class, upload goal, skill, or topic..." | |
| aria-label="Search for a topic or exam to prepare for" | |
| className="w-full px-6 py-4 bg-white/5 border border-white/10 rounded-xl text-white placeholder-white/40 focus:outline-none focus:border-white/20 transition-colors" | |
| /> | |
| <button | |
| type="submit" | |
| disabled={!query.trim()} | |
| aria-label="Submit your study query" | |
| className="absolute right-3 top-1/2 -translate-y-1/2 px-4 py-2 bg-white/10 hover:bg-white/20 disabled:opacity-50 disabled:hover:bg-white/10 text-white text-sm font-medium rounded-lg transition-colors" | |
| > | |
| Go | |
| </button> | |
| </div> | |
| </form> | |
| {!isFocused && !query && ( | |
| <div className="space-y-2"> | |
| <p className="text-xs text-white/40 uppercase tracking-wider">Examples</p> | |
| <div className="flex flex-wrap gap-2"> | |
| {EXAMPLE_QUERIES.map((example, index) => ( | |
| <button | |
| key={index} | |
| type="button" | |
| onClick={() => handleExampleClick(example)} | |
| aria-label={`Try example: ${example}`} | |
| className="text-xs px-3 py-1.5 bg-white/5 hover:bg-white/10 text-white/60 hover:text-white/80 rounded-full transition-colors" | |
| > | |
| {example} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |