Fix pagination of tutor

feat/ai-tutor-redesign
Kamran Ahmed 1 week ago
parent b28eb5fecf
commit 1970e0c92e
  1. 62
      src/components/AITutor/AIFeaturedCoursesListing.tsx
  2. 3
      src/components/GenerateCourse/AICourse.tsx
  3. 54
      src/components/GenerateCourse/UserCoursesList.tsx

@ -8,18 +8,18 @@ import { useEffect, useState } from 'react';
import { getUrlParams, setUrlParams, deleteUrlParam } from '../../lib/browser'; import { getUrlParams, setUrlParams, deleteUrlParam } from '../../lib/browser';
import { AICourseCard } from '../GenerateCourse/AICourseCard'; import { AICourseCard } from '../GenerateCourse/AICourseCard';
import { Pagination } from '../Pagination/Pagination'; import { Pagination } from '../Pagination/Pagination';
import { AILoadingState } from './AILoadingState';
import { AITutorTallMessage } from './AITutorTallMessage';
import { BookOpen } from 'lucide-react';
import { AITutorHeader } from './AITutorHeader'; import { AITutorHeader } from './AITutorHeader';
import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal'; import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal';
import { AITutorTallMessage } from './AITutorTallMessage';
import { BookOpen } from 'lucide-react';
import { AILoadingState } from './AILoadingState';
export function AIFeaturedCoursesListing() { export function AIFeaturedCoursesListing() {
const [isInitialLoading, setIsInitialLoading] = useState(true); const [isInitialLoading, setIsInitialLoading] = useState(true);
const [showUpgradePopup, setShowUpgradePopup] = useState(false); const [showUpgradePopup, setShowUpgradePopup] = useState(false);
const [pageState, setPageState] = useState<ListUserAiCoursesQuery>({ const [pageState, setPageState] = useState<ListUserAiCoursesQuery>({
perPage: '20', perPage: '21',
currPage: '1', currPage: '1',
}); });
@ -51,31 +51,8 @@ export function AIFeaturedCoursesListing() {
} }
}, [pageState]); }, [pageState]);
if (isInitialLoading || isFeaturedAiCoursesLoading) {
return ( return (
<AILoadingState <>
title="Loading featured courses"
subtitle="This may take a moment..."
/>
);
}
if (courses.length === 0) {
return (
<AITutorTallMessage
title="No featured courses"
subtitle="There are no featured courses available at the moment."
icon={BookOpen}
buttonText="Browse all courses"
onButtonClick={() => {
window.location.href = '/ai';
}}
/>
);
}
return (
<div className="w-full">
{showUpgradePopup && ( {showUpgradePopup && (
<UpgradeAccountModal onClose={() => setShowUpgradePopup(false)} /> <UpgradeAccountModal onClose={() => setShowUpgradePopup(false)} />
)} )}
@ -85,7 +62,16 @@ export function AIFeaturedCoursesListing() {
onUpgradeClick={() => setShowUpgradePopup(true)} onUpgradeClick={() => setShowUpgradePopup(true)}
/> />
{!isFeaturedAiCoursesLoading && courses && courses.length > 0 && ( {(isFeaturedAiCoursesLoading || isInitialLoading) && (
<AILoadingState
title="Loading featured courses"
subtitle="This may take a moment..."
/>
)}
{!isFeaturedAiCoursesLoading &&
!isInitialLoading &&
courses.length > 0 && (
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2 lg:grid-cols-3"> <div className="grid grid-cols-1 gap-2 md:grid-cols-2 lg:grid-cols-3">
{courses.map((course) => ( {courses.map((course) => (
@ -112,14 +98,18 @@ export function AIFeaturedCoursesListing() {
)} )}
{!isFeaturedAiCoursesLoading && {!isFeaturedAiCoursesLoading &&
(featuredAiCourses?.data?.length || 0 > 0) && !isInitialLoading &&
courses.length === 0 && ( courses.length === 0 && (
<div className="flex min-h-[114px] items-center justify-center rounded-lg border border-gray-200 bg-white py-4"> <AITutorTallMessage
<p className="text-sm text-gray-600"> title="No featured courses"
No courses match your search. subtitle="There are no featured courses available at the moment."
</p> icon={BookOpen}
</div> buttonText="Browse all courses"
onButtonClick={() => {
window.location.href = '/ai';
}}
/>
)} )}
</div> </>
); );
} }

@ -92,6 +92,7 @@ export function AICourse(props: AICourseProps) {
id="keyword" id="keyword"
type="text" type="text"
value={keyword} value={keyword}
autoFocus={true}
onChange={(e) => setKeyword(e.target.value)} onChange={(e) => setKeyword(e.target.value)}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
placeholder="e.g. JavaScript Promises, React Hooks, Go Routines etc" placeholder="e.g. JavaScript Promises, React Hooks, Go Routines etc"
@ -126,7 +127,7 @@ export function AICourse(props: AICourseProps) {
type="submit" type="submit"
disabled={!keyword.trim()} disabled={!keyword.trim()}
className={cn( className={cn(
'flex items-center justify-center rounded-full px-4 py-1 text-white transition-colors text-sm', 'flex items-center justify-center rounded-full px-4 py-1 text-sm text-white transition-colors',
!keyword.trim() !keyword.trim()
? 'cursor-not-allowed bg-gray-400' ? 'cursor-not-allowed bg-gray-400'
: 'bg-black hover:bg-gray-800', : 'bg-black hover:bg-gray-800',

@ -9,13 +9,13 @@ import {
type ListUserAiCoursesQuery, type ListUserAiCoursesQuery,
} from '../../queries/ai-course'; } from '../../queries/ai-course';
import { queryClient } from '../../stores/query-client'; import { queryClient } from '../../stores/query-client';
import { AILoadingState } from '../AITutor/AILoadingState';
import { AITutorHeader } from '../AITutor/AITutorHeader'; import { AITutorHeader } from '../AITutor/AITutorHeader';
import { AITutorTallMessage } from '../AITutor/AITutorTallMessage'; import { AITutorTallMessage } from '../AITutor/AITutorTallMessage';
import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal'; import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal';
import { Pagination } from '../Pagination/Pagination'; import { Pagination } from '../Pagination/Pagination';
import { AICourseCard } from './AICourseCard'; import { AICourseCard } from './AICourseCard';
import { AICourseSearch } from './AICourseSearch'; import { AICourseSearch } from './AICourseSearch';
import { AILoadingState } from '../AITutor/AILoadingState';
export function UserCoursesList() { export function UserCoursesList() {
const [isInitialLoading, setIsInitialLoading] = useState(true); const [isInitialLoading, setIsInitialLoading] = useState(true);
@ -60,16 +60,7 @@ export function UserCoursesList() {
} }
}, [pageState]); }, [pageState]);
if (isInitialLoading || isUserAiCoursesLoading) { if (!isInitialLoading && !isLoggedIn()) {
return (
<AILoadingState
title="Loading your courses"
subtitle="This may take a moment..."
/>
);
}
if (!isLoggedIn()) {
return ( return (
<AITutorTallMessage <AITutorTallMessage
title="Sign up or login" title="Sign up or login"
@ -83,20 +74,6 @@ export function UserCoursesList() {
); );
} }
if (courses.length === 0) {
return (
<AITutorTallMessage
title="No courses found"
subtitle="You haven't generated any courses yet."
icon={BookOpen}
buttonText="Create your first course"
onButtonClick={() => {
window.location.href = '/ai';
}}
/>
);
}
return ( return (
<> <>
{showUpgradePopup && ( {showUpgradePopup && (
@ -119,7 +96,14 @@ export function UserCoursesList() {
/> />
</AITutorHeader> </AITutorHeader>
{!isUserAiCoursesLoading && courses && courses.length > 0 && ( {(isUserAiCoursesLoading || isInitialLoading) && (
<AILoadingState
title="Loading your courses"
subtitle="This may take a moment..."
/>
)}
{!isUserAiCoursesLoading && !isInitialLoading && courses.length > 0 && (
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<div className="grid grid-cols-3 gap-2"> <div className="grid grid-cols-3 gap-2">
{courses.map((course) => ( {courses.map((course) => (
@ -140,14 +124,16 @@ export function UserCoursesList() {
</div> </div>
)} )}
{!isUserAiCoursesLoading && {!isUserAiCoursesLoading && !isInitialLoading && courses.length === 0 && (
(userAiCourses?.data?.length || 0 > 0) && <AITutorTallMessage
courses.length === 0 && ( title="No courses found"
<div className="flex min-h-[114px] items-center justify-center rounded-lg border border-gray-200 bg-white py-4"> subtitle="You haven't generated any courses yet."
<p className="text-sm text-gray-600"> icon={BookOpen}
No courses match your search. buttonText="Create your first course"
</p> onButtonClick={() => {
</div> window.location.href = '/ai';
}}
/>
)} )}
</> </>
); );

Loading…
Cancel
Save