* Add sidebar to ai-tutor * wip * wip * Fix mistakes and refacctor * AI landing page changes * Update sidebar design * wip * wip * Update AI tutor sidebar * wip * Add ai-course dropdown * Update * fix: ai chat window position * Course explanation changes * Update course * Tutor sidebar changes * Refactor staff picks and community * Update UI for a course * Improve pagination * Implement pagination of ai tutor ai courses * AI explore page with search * Fix pagination of tutor * Update tutor header design * Responsiveness of AI * Fork alert changes * Responsiveness of actions * Forking functionality changes * Fork confirmation changes * Add upgrade indicator in sidebar * fix: ai course access * fix: next lesson * Add login to view functionality * Add search to my picks --------- Co-authored-by: Arik Chakma <arikchangma@gmail.com>
103 lines
2.5 KiB
TypeScript
103 lines
2.5 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { getAiCourseOptions } from '../../queries/ai-course';
|
|
import { queryClient } from '../../stores/query-client';
|
|
import { useEffect, useState } from 'react';
|
|
import { AICourseContent } from './AICourseContent';
|
|
import { isLoggedIn } from '../../lib/jwt';
|
|
import { generateCourse } from '../../helper/generate-ai-course';
|
|
|
|
type GetAICourseProps = {
|
|
courseSlug: string;
|
|
};
|
|
|
|
export function GetAICourse(props: GetAICourseProps) {
|
|
const { courseSlug } = props;
|
|
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [isRegenerating, setIsRegenerating] = useState(false);
|
|
|
|
const [error, setError] = useState('');
|
|
const { data: aiCourse, error: queryError } = useQuery(
|
|
{
|
|
...getAiCourseOptions({ aiCourseSlug: courseSlug }),
|
|
enabled: !!courseSlug,
|
|
},
|
|
queryClient,
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (!aiCourse) {
|
|
return;
|
|
}
|
|
|
|
setIsLoading(false);
|
|
}, [aiCourse]);
|
|
|
|
useEffect(() => {
|
|
if (!queryError) {
|
|
return;
|
|
}
|
|
|
|
setIsLoading(false);
|
|
setError(queryError.message);
|
|
}, [queryError]);
|
|
|
|
const handleRegenerateCourse = async (prompt?: string) => {
|
|
if (!aiCourse) {
|
|
return;
|
|
}
|
|
|
|
queryClient.setQueryData(
|
|
getAiCourseOptions({ aiCourseSlug: courseSlug }).queryKey,
|
|
{
|
|
...aiCourse,
|
|
title: '',
|
|
difficulty: '',
|
|
modules: [],
|
|
},
|
|
);
|
|
|
|
await generateCourse({
|
|
term: aiCourse.keyword,
|
|
difficulty: aiCourse.difficulty,
|
|
slug: courseSlug,
|
|
prompt,
|
|
onCourseChange: (course, rawData) => {
|
|
queryClient.setQueryData(
|
|
getAiCourseOptions({ aiCourseSlug: courseSlug }).queryKey,
|
|
{
|
|
...aiCourse,
|
|
title: course.title,
|
|
difficulty: course.difficulty,
|
|
modules: course.modules,
|
|
},
|
|
);
|
|
},
|
|
onLoadingChange: (isNewLoading) => {
|
|
setIsRegenerating(isNewLoading);
|
|
if (!isNewLoading) {
|
|
// TODO: Update progress
|
|
}
|
|
},
|
|
onError: setError,
|
|
isForce: true,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<AICourseContent
|
|
course={{
|
|
title: aiCourse?.title || '',
|
|
modules: aiCourse?.modules || [],
|
|
difficulty: aiCourse?.difficulty || 'Easy',
|
|
done: aiCourse?.done || [],
|
|
}}
|
|
isLoading={isLoading || isRegenerating}
|
|
courseSlug={courseSlug}
|
|
error={error}
|
|
onRegenerateOutline={handleRegenerateCourse}
|
|
creatorId={aiCourse?.userId}
|
|
/>
|
|
);
|
|
}
|