start/continue lesson button on course overview

This commit is contained in:
austinkelsay 2025-05-14 12:29:13 -05:00
parent d906625168
commit 724e7aa642
No known key found for this signature in database
GPG Key ID: 5A763922E5BA08EE
6 changed files with 148 additions and 23 deletions

View File

@ -31,6 +31,9 @@ export default function CourseDetails({
handlePaymentError,
isMobileView,
showCompletedTag = true,
completedLessons,
onLessonSelect,
toggleToContentTab
}) {
const [zapAmount, setZapAmount] = useState(0);
const [author, setAuthor] = useState(null);
@ -213,7 +216,10 @@ export default function CourseDetails({
returnImageProxy,
renderPaymentMessage,
isCompleted,
showCompletedTag
showCompletedTag,
completedLessons,
onLessonSelect,
toggleToContentTab
};
return (

View File

@ -4,6 +4,7 @@ import { Tag } from 'primereact/tag';
import ZapDisplay from '@/components/zaps/ZapDisplay';
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
import { Divider } from 'primereact/divider';
import GenericButton from '@/components/buttons/GenericButton';
export default function DesktopCourseDetails({
processedEvent,
@ -17,9 +18,46 @@ export default function DesktopCourseDetails({
returnImageProxy,
renderPaymentMessage,
isCompleted,
showCompletedTag
showCompletedTag,
completedLessons,
onLessonSelect,
toggleToContentTab
}) {
// Calculate next lesson to start/continue
const getNextLessonIndex = () => {
if (!lessons || lessons.length === 0) return 0;
// If no completed lessons, start with the first one
if (completedLessons.length === 0) return 0;
// Find the highest completed lesson index
const lessonIndices = lessons.map((lesson, index) => {
return { id: lesson.id, index };
});
// Get indices of completed lessons
const completedIndices = lessonIndices
.filter(item => completedLessons.includes(item.id))
.map(item => item.index);
// Get the max completed index
const maxCompletedIndex = Math.max(...completedIndices);
// Return the next lesson index (or the last one if all completed)
return Math.min(maxCompletedIndex + 1, lessons.length - 1);
};
const nextLessonIndex = getNextLessonIndex();
const buttonLabel = completedLessons.length === 0
? "Start Lesson 1"
: `Continue to Lesson ${nextLessonIndex + 1}`;
const handleContinueClick = () => {
onLessonSelect(nextLessonIndex);
toggleToContentTab();
};
return (
<>
{/* Header with course image, title and options */}
@ -141,6 +179,18 @@ export default function DesktopCourseDetails({
</div>
)}
</div>
{/* Continue/Start button */}
{lessons && lessons.length > 0 && !isCompleted && (
<div className="mt-4 flex justify-start">
<GenericButton
label={buttonLabel}
icon="pi pi-play"
onClick={handleContinueClick}
outlined={true}
disabled={paidCourse && !decryptionPerformed}
/>
</div>
)}
</div>
</div>
</>

View File

@ -4,6 +4,7 @@ import { Tag } from 'primereact/tag';
import ZapDisplay from '@/components/zaps/ZapDisplay';
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
import { Divider } from 'primereact/divider';
import GenericButton from '@/components/buttons/GenericButton';
export default function MobileCourseDetails({
processedEvent,
@ -17,8 +18,45 @@ export default function MobileCourseDetails({
returnImageProxy,
renderPaymentMessage,
isCompleted,
showCompletedTag
showCompletedTag,
completedLessons,
onLessonSelect,
toggleToContentTab
}) {
// Calculate next lesson to start/continue
const getNextLessonIndex = () => {
if (!lessons || lessons.length === 0) return 0;
// If no completed lessons, start with the first one
if (completedLessons.length === 0) return 0;
// Find the highest completed lesson index
const lessonIndices = lessons.map((lesson, index) => {
return { id: lesson.id, index };
});
// Get indices of completed lessons
const completedIndices = lessonIndices
.filter(item => completedLessons.includes(item.id))
.map(item => item.index);
// Get the max completed index
const maxCompletedIndex = Math.max(...completedIndices);
// Return the next lesson index (or the last one if all completed)
return Math.min(maxCompletedIndex + 1, lessons.length - 1);
};
const nextLessonIndex = getNextLessonIndex();
const buttonLabel = completedLessons.length === 0
? "Start Lesson 1"
: `Continue to Lesson ${nextLessonIndex + 1}`;
const handleContinueClick = () => {
onLessonSelect(nextLessonIndex);
toggleToContentTab();
};
return (
<>
{/* Mobile-specific layout */}
@ -128,6 +166,19 @@ export default function MobileCourseDetails({
</div>
)}
</div>
{/* Continue/Start button */}
{lessons && lessons.length > 0 && !isCompleted && (
<div className="mt-4 flex justify-start">
<GenericButton
label={buttonLabel}
icon="pi pi-play"
onClick={handleContinueClick}
outlined={true}
disabled={paidCourse && !decryptionPerformed}
/>
</div>
)}
</div>
</div>
</>

View File

@ -141,13 +141,15 @@ const DocumentLesson = ({ lesson, course, decryptionPerformed, isPaid, setComple
<div className="w-full">
<Toast ref={toastRef} />
<div className="relative w-[80%] h-[200px] mx-auto mb-24">
<div className="relative w-full h-full mt-2 rounded-lg">
<Image
alt="lesson background image"
src={returnImageProxy(lesson.image)}
fill
className="object-cover"
className="object-cover rounded-lg"
/>
<div className="absolute inset-0 bg-black bg-opacity-20"></div>
</div>
<div className="absolute inset-0 bg-gray-800 bg-opacity-20"></div>
</div>
<div className="w-full mx-auto px-4 py-8 -mt-32 relative z-10">
<div className="mb-8 bg-gray-800/70 rounded-lg p-4">

View File

@ -1,6 +1,7 @@
import React from 'react';
import { Tag } from 'primereact/tag';
import CourseDetails from '../details/CourseDetails';
import GenericButton from '@/components/buttons/GenericButton';
/**
* Component to display course overview with details
@ -13,12 +14,15 @@ const CourseOverview = ({
handlePaymentSuccess,
handlePaymentError,
isMobileView,
completedLessons
completedLessons,
onLessonSelect,
toggleToContentTab
}) => {
// Determine if course is completed
const isCompleted = lessons && lessons.length > 0 && completedLessons.length === lessons.length;
return (
<>
<div className={`bg-gray-800 rounded-lg border border-gray-800 shadow-md ${isMobileView ? 'p-4' : 'p-6'}`}>
{isMobileView && course && (
<div className="mb-2">
@ -50,8 +54,12 @@ const CourseOverview = ({
handlePaymentError={handlePaymentError}
isMobileView={isMobileView}
showCompletedTag={!isMobileView}
completedLessons={completedLessons}
onLessonSelect={onLessonSelect}
toggleToContentTab={toggleToContentTab}
/>
</div>
</>
);
};

View File

@ -242,6 +242,14 @@ const Course = () => {
handlePaymentError={handlePaymentError}
isMobileView={isMobileView}
completedLessons={completedLessons}
onLessonSelect={(index) => {
handleLessonSelect(index);
// Update URL with active parameter
const url = new URL(window.location.href);
url.searchParams.set('active', index);
router.push(url, undefined, { shallow: true });
}}
toggleToContentTab={() => toggleTab(1)} // Assuming content tab is at index 1
/>
</div>