parent
4123e6ee90
commit
6964925b15
3 changed files with 121 additions and 171 deletions
@ -1,129 +0,0 @@ |
||||
import { Loader2Icon, SearchIcon, WandIcon } from 'lucide-react'; |
||||
import { difficultyLevels } from './AICourse'; |
||||
import { cn } from '../../lib/classname'; |
||||
|
||||
type AICourseGenerateFormProps = { |
||||
keyword: string; |
||||
setKeyword: (keyword: string) => void; |
||||
difficulty: string; |
||||
setDifficulty: (difficulty: string) => void; |
||||
|
||||
onSubmit: () => void; |
||||
isGenerating: boolean; |
||||
}; |
||||
|
||||
export function AICourseGenerateForm(props: AICourseGenerateFormProps) { |
||||
const { |
||||
keyword, |
||||
setKeyword, |
||||
difficulty, |
||||
setDifficulty, |
||||
onSubmit, |
||||
isGenerating, |
||||
} = props; |
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => { |
||||
if (e.key === 'Enter' && keyword.trim()) { |
||||
onSubmit(); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<section className="flex flex-grow flex-col bg-gray-100"> |
||||
<div className="container mx-auto flex max-w-3xl flex-col py-12"> |
||||
<h1 className="mb-2 text-3xl font-bold">AI Course Generator</h1> |
||||
<p className="mb-6 text-gray-600"> |
||||
Create personalized learning paths with AI |
||||
</p> |
||||
|
||||
<div className="rounded-md border border-gray-200 bg-white p-6"> |
||||
<p className="mb-6 text-gray-600"> |
||||
Enter a keyword or topic, and our AI will create a personalized |
||||
learning course for you. |
||||
</p> |
||||
|
||||
<form |
||||
className="flex flex-col gap-4" |
||||
onSubmit={(e) => { |
||||
e.preventDefault(); |
||||
onSubmit(); |
||||
}} |
||||
> |
||||
<div className="flex flex-col"> |
||||
<label |
||||
htmlFor="keyword" |
||||
className="mb-2 text-sm font-medium text-gray-700" |
||||
> |
||||
Course Topic |
||||
</label> |
||||
<div className="relative"> |
||||
<div className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"> |
||||
<SearchIcon size={18} /> |
||||
</div> |
||||
<input |
||||
id="keyword" |
||||
type="text" |
||||
value={keyword} |
||||
onChange={(e) => setKeyword(e.target.value)} |
||||
onKeyDown={handleKeyDown} |
||||
placeholder="e.g., Machine Learning, JavaScript, Photography" |
||||
className="w-full rounded-md border border-gray-300 bg-white p-3 pl-10 text-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-500" |
||||
maxLength={50} |
||||
/> |
||||
<span className="absolute bottom-3 right-3 text-xs text-gray-400"> |
||||
{keyword.length}/50 |
||||
</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<div className="flex flex-col"> |
||||
<label className="mb-2 text-sm font-medium text-gray-700"> |
||||
Difficulty Level |
||||
</label> |
||||
<div className="flex gap-2"> |
||||
{difficultyLevels.map((level) => ( |
||||
<button |
||||
key={level} |
||||
type="button" |
||||
onClick={() => setDifficulty(level)} |
||||
className={cn( |
||||
'rounded-md border px-4 py-2 capitalize', |
||||
difficulty === level |
||||
? 'border-gray-800 bg-gray-800 text-white' |
||||
: 'border-gray-200 bg-gray-100 text-gray-700 hover:bg-gray-200', |
||||
)} |
||||
> |
||||
{level} |
||||
</button> |
||||
))} |
||||
</div> |
||||
</div> |
||||
|
||||
<button |
||||
type="submit" |
||||
disabled={!keyword.trim()} |
||||
className={cn( |
||||
'mt-2 flex items-center justify-center rounded-md px-4 py-2 font-medium text-white transition-colors', |
||||
!keyword.trim() |
||||
? 'cursor-not-allowed bg-gray-400' |
||||
: 'bg-black hover:bg-gray-800', |
||||
)} |
||||
> |
||||
{isGenerating ? ( |
||||
<> |
||||
<Loader2Icon size={18} className="mr-2 animate-spin" /> |
||||
Generating... |
||||
</> |
||||
) : ( |
||||
<> |
||||
<WandIcon size={18} className="mr-2" /> |
||||
Generate Course |
||||
</> |
||||
)} |
||||
</button> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
); |
||||
} |
Loading…
Reference in new issue