diff --git a/src/components/AITutor/AILoadingState.tsx b/src/components/AITutor/AILoadingState.tsx new file mode 100644 index 000000000..66ed9de4e --- /dev/null +++ b/src/components/AITutor/AILoadingState.tsx @@ -0,0 +1,27 @@ +import { Loader2 } from 'lucide-react'; + +type AILoadingStateProps = { + title: string; + subtitle?: string; +}; + +export function AILoadingState(props: AILoadingStateProps) { + const { title, subtitle } = props; + + return ( +
+
+ +
+
+
+
+
+

{title}

+ {subtitle && ( +

{subtitle}

+ )} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/AITutor/AITutorLayout.tsx b/src/components/AITutor/AITutorLayout.tsx index 18b23649f..5cfe7f3ce 100644 --- a/src/components/AITutor/AITutorLayout.tsx +++ b/src/components/AITutor/AITutorLayout.tsx @@ -11,7 +11,9 @@ export function AITutorLayout(props: AITutorLayoutProps) { return (
-
{children}
+
+ {children} +
); } diff --git a/src/components/AITutor/AITutorTallMessage.tsx b/src/components/AITutor/AITutorTallMessage.tsx new file mode 100644 index 000000000..a0000a3ff --- /dev/null +++ b/src/components/AITutor/AITutorTallMessage.tsx @@ -0,0 +1,31 @@ +import { type LucideIcon } from 'lucide-react'; + +type AITutorTallMessageProps = { + title: string; + subtitle?: string; + icon: LucideIcon; + buttonText?: string; + onButtonClick?: () => void; +}; + +export function AITutorTallMessage(props: AITutorTallMessageProps) { + const { title, subtitle, icon: Icon, buttonText, onButtonClick } = props; + + return ( +
+ +
+

{title}

+ {subtitle &&

{subtitle}

} +
+ {buttonText && onButtonClick && ( + + )} +
+ ); +} diff --git a/src/components/GenerateCourse/AICourse.tsx b/src/components/GenerateCourse/AICourse.tsx index 5708a505c..428fb21fe 100644 --- a/src/components/GenerateCourse/AICourse.tsx +++ b/src/components/GenerateCourse/AICourse.tsx @@ -3,7 +3,6 @@ import { useEffect, useState } from 'react'; import { cn } from '../../lib/classname'; import { isLoggedIn } from '../../lib/jwt'; import { showLoginPopup } from '../../lib/popup'; -import { UserCoursesList } from './UserCoursesList'; import { FineTuneCourse } from './FineTuneCourse'; import { clearFineTuneData, @@ -72,97 +71,95 @@ export function AICourse(props: AICourseProps) { } return ( -
-
-

- Learn anything with AI -

-

- Enter a topic below to generate a personalized course for it -

- -
-
{ - e.preventDefault(); - onSubmit(); - }} - > -
- -
-
- -
- setKeyword(e.target.value)} - onKeyDown={handleKeyDown} - placeholder="e.g., Algebra, JavaScript, Photography" - className="w-full rounded-md border border-gray-300 bg-white p-3 pl-10 text-gray-900 focus:ring-1 focus:ring-gray-500 focus:outline-hidden max-sm:placeholder:text-base" - maxLength={50} - /> +
+

+ What can I help you learn? +

+

+ Enter a topic below to generate a personalized course for it +

+ +
+ { + e.preventDefault(); + onSubmit(); + }} + > +
+ +
+
+
+ setKeyword(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="e.g., Algebra, JavaScript, Photography" + className="w-full rounded-md border border-gray-300 bg-white p-3 pl-10 text-gray-900 focus:ring-1 focus:ring-gray-500 focus:outline-hidden max-sm:placeholder:text-base" + maxLength={50} + />
- -
- -
- {difficultyLevels.map((level) => ( - - ))} -
+
+ +
+ +
+ {difficultyLevels.map((level) => ( + + ))}
- - - - - -
+
+ + + + +
-
+ ); } diff --git a/src/components/GenerateCourse/AICourseCard.tsx b/src/components/GenerateCourse/AICourseCard.tsx index 0d758978b..9db197881 100644 --- a/src/components/GenerateCourse/AICourseCard.tsx +++ b/src/components/GenerateCourse/AICourseCard.tsx @@ -12,14 +12,6 @@ type AICourseCardProps = { export function AICourseCard(props: AICourseCardProps) { const { course, showActions = true, showProgress = true } = props; - // Format date if available - const formattedDate = course.createdAt - ? new Date(course.createdAt).toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - }) - : null; - // Map difficulty to color const difficultyColor = { @@ -35,10 +27,10 @@ export function AICourseCard(props: AICourseCardProps) { totalTopics > 0 ? Math.round((completedTopics / totalTopics) * 100) : 0; return ( -
+
+ ); + } + + if (!isLoggedIn()) { + return ( + { + showLoginPopup(); + }} + /> + ); + } + + if (courses.length === 0) { + return ( + { + window.location.href = '/ai'; + }} + /> + ); + } + return ( <> {showUpgradePopup && ( @@ -105,7 +144,7 @@ export function UserCoursesList(props: UserCoursesListProps) { onClick={() => { setShowUpgradePopup(true); }} - className="ml-1.5 flex items-center gap-1 rounded-full bg-yellow-600 py-0.5 pl-1.5 pr-2 text-xs text-white" + className="ml-1.5 flex items-center gap-1 rounded-full bg-yellow-600 py-0.5 pr-2 pl-1.5 text-xs text-white" > Upgrade @@ -127,46 +166,13 @@ export function UserCoursesList(props: UserCoursesListProps) {
- {!isInitialLoading && !isUserAiCoursesLoading && !isAuthenticated && ( -
- -

- {' '} - to generate and save courses. -

-
- )} - - {!isUserAiCoursesLoading && !isInitialLoading && courses.length === 0 && isAuthenticated && ( -
-

- You haven't generated any courses yet. -

-
- )} - - {(isUserAiCoursesLoading || isInitialLoading) && ( -
- -

Loading...

-
- )} - {!isUserAiCoursesLoading && courses && courses.length > 0 && (
- {courses.map((course) => ( - - ))} +
+ {courses.map((course) => ( + + ))} +
-
-
- -
-
+