diff --git a/src/components/GenerateCourse/AICourse.tsx b/src/components/GenerateCourse/AICourse.tsx index 012df478c..2fb08a2a2 100644 --- a/src/components/GenerateCourse/AICourse.tsx +++ b/src/components/GenerateCourse/AICourse.tsx @@ -1,8 +1,6 @@ -import { Loader2, Search, Wand } from 'lucide-react'; +import { Loader2Icon, SearchIcon, WandIcon } from 'lucide-react'; import { useState } from 'react'; import { cn } from '../../lib/classname'; -import { AICourseGenerateForm } from './AICourseGenerateForm'; -import { AICourseContent } from './AICourseContent'; export const difficultyLevels = [ 'beginner', @@ -11,40 +9,112 @@ export const difficultyLevels = [ ] as const; export type DifficultyLevel = (typeof difficultyLevels)[number]; -type AICourseProps = { - courseId?: string; -}; +type AICourseProps = {}; export function AICourse(props: AICourseProps) { const [keyword, setKeyword] = useState(''); const [difficulty, setDifficulty] = useState('intermediate'); + const [isLoading, setIsLoading] = useState(false); - const [isGenerating, setIsGenerating] = useState(false); - const [isGeneratingError, setIsGeneratingError] = useState(false); + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && keyword.trim() && !isLoading) { + onSubmit(); + } + }; function onSubmit() { - setIsGenerating(true); - setIsGeneratingError(false); + if (typeof window !== 'undefined') { + window.location.href = `/ai-tutor/search?term=${encodeURIComponent(keyword)}&difficulty=${difficulty}`; + } } return ( - <> - {!isGenerating && ( - - setDifficulty(difficulty as DifficultyLevel) - } - onSubmit={onSubmit} - isGenerating={isGenerating} - /> - )} - - {isGenerating && ( - - )} - +
+
+

AI Course Generator

+

+ Create personalized learning paths with AI +

+ +
+

+ Enter a keyword or topic, and our AI will create a personalized + learning course for you. +

+ +
{ + e.preventDefault(); + onSubmit(); + }} + > +
+ +
+
+ +
+ 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} + /> + + {keyword.length}/50 + +
+
+ +
+ +
+ {difficultyLevels.map((level) => ( + + ))} +
+
+ + +
+
+
+
); } diff --git a/src/components/GenerateCourse/AICourseContent.tsx b/src/components/GenerateCourse/AICourseContent.tsx index ef1d84fb3..abdf09547 100644 --- a/src/components/GenerateCourse/AICourseContent.tsx +++ b/src/components/GenerateCourse/AICourseContent.tsx @@ -11,8 +11,8 @@ import { import { useEffect, useState } from 'react'; import { readAICourseStream } from '../../helper/read-stream'; import { cn } from '../../lib/classname'; +import { getUrlParams } from '../../lib/browser'; -// Define types for our course structure type Lesson = string; type Module = { @@ -26,17 +26,11 @@ type Course = { difficulty: string; }; -type AICourseContentProps = - | { - slug: string; - term?: string; - difficulty?: string; - } - | { - slug?: string; - term: string; - difficulty: string; - }; +type AICourseContentProps = { + slug?: string; + term?: string; + difficulty?: string; +}; export function AICourseContent(props: AICourseContentProps) { const { @@ -50,7 +44,7 @@ export function AICourseContent(props: AICourseContentProps) { const [courseSlug, setCourseSlug] = useState(defaultSlug || ''); const [courseId, setCourseId] = useState(''); - const [isLoading, setIsLoading] = useState(false); + const [isLoading, setIsLoading] = useState(true); const [courseContent, setCourseContent] = useState(''); const [streamedCourse, setStreamedCourse] = useState<{ @@ -106,6 +100,21 @@ export function AICourseContent(props: AICourseContentProps) { generateCourse({ slug: defaultSlug }); }, [defaultSlug]); + useEffect(() => { + if (term || courseSlug) { + return; + } + + const params = getUrlParams(); + const paramsTerm = params?.term; + const paramsDifficulty = params?.difficulty; + if (!paramsTerm || !paramsDifficulty) { + return; + } + + generateCourse({ term: paramsTerm, difficulty: paramsDifficulty }); + }, [term, difficulty, courseSlug]); + const generateCourse = async ({ term, difficulty, @@ -176,7 +185,7 @@ export function AICourseContent(props: AICourseContentProps) { console.log('extractedCourseSlug', extractedCourseSlug); if (extractedCourseSlug && !defaultSlug) { - window.history.pushState( + window.history.replaceState( { courseId, courseSlug: extractedCourseSlug, diff --git a/src/components/GenerateCourse/AICourseGenerateForm.tsx b/src/components/GenerateCourse/AICourseGenerateForm.tsx deleted file mode 100644 index 2259bf1d9..000000000 --- a/src/components/GenerateCourse/AICourseGenerateForm.tsx +++ /dev/null @@ -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 ( -
-
-

AI Course Generator

-

- Create personalized learning paths with AI -

- -
-

- Enter a keyword or topic, and our AI will create a personalized - learning course for you. -

- -
{ - e.preventDefault(); - onSubmit(); - }} - > -
- -
-
- -
- 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} - /> - - {keyword.length}/50 - -
-
- -
- -
- {difficultyLevels.map((level) => ( - - ))} -
-
- - -
-
-
-
- ); -}