diff --git a/src/components/content/courses/CourseDetails.js b/src/components/content/courses/CourseDetails.js index 06ae2ec..bf8da54 100644 --- a/src/components/content/courses/CourseDetails.js +++ b/src/components/content/courses/CourseDetails.js @@ -30,6 +30,8 @@ export default function CourseDetails({ decryptionPerformed, handlePaymentSuccess, handlePaymentError, + isMobileView, + showCompletedTag = true, }) { const [zapAmount, setZapAmount] = useState(0); const [author, setAuthor] = useState(null); @@ -40,7 +42,8 @@ export default function CourseDetails({ const { data: session, status } = useSession(); const { showToast } = useToast(); const windowWidth = useWindowWidth(); - const isMobileView = windowWidth <= 768; + const localIsMobileView = windowWidth <= 768; // Use as fallback + const isPhone = isMobileView || localIsMobileView; const { ndk } = useNDKContext(); const menuRef = useRef(null); const toastRef = useRef(null); @@ -205,42 +208,81 @@ export default function CourseDetails({
{/* Header with course image, title and options */} -
- {/* Course image */} -
- course image -
- - {/* Title and options */} -
-
-
- {isCompleted && ( - - )} -

{processedEvent.name}

-
-
- - -
+ {!isPhone && ( +
+ {/* Course image */} +
+ course image
- {/* Topics/tags */} -
+ {/* Title and options */} +
+
+
+ {isCompleted && showCompletedTag && ( + + )} +

{processedEvent.name}

+
+
+ + +
+
+ + {/* Topics/tags */} +
+ {processedEvent.topics && + processedEvent.topics.length > 0 && + processedEvent.topics.map((topic, index) => ( + + ))} +
+ + {/* Author info */} + +
+
+ )} + + {/* Mobile-specific layout */} + {isPhone && ( +
+ {/* Completed tag is now moved to the parent component */} + + {/* Mobile topics/tags right below image (image is in parent component) */} +
{processedEvent.topics && processedEvent.topics.length > 0 && processedEvent.topics.map((topic, index) => ( @@ -248,41 +290,58 @@ export default function CourseDetails({ ))}
- {/* Author info */} -
- avatar image +

{processedEvent.name}

+ +
+ + {/* Author info and more options in bottom row */} +
-
+ )} {/* Course details */} -
+
{/* Left column: Description */} -
+

About This Course

{processedEvent.description && processedEvent.description .split('\n') - .map((line, index) =>

{line}

)} + .map((line, index) =>

{line}

)}
{/* Payment section */} @@ -292,8 +351,8 @@ export default function CourseDetails({
{/* Right column: Course details */} -
-

Course Information

+
+

Course Information

diff --git a/src/components/content/courses/CourseSidebar.js b/src/components/content/courses/CourseSidebar.js index f4728ea..4b16697 100644 --- a/src/components/content/courses/CourseSidebar.js +++ b/src/components/content/courses/CourseSidebar.js @@ -14,6 +14,7 @@ const CourseSidebar = ({ onClose, sidebarVisible: parentSidebarVisible, setSidebarVisible, + hideToggleButton = false, }) => { const { returnImageProxy } = useImageProxy(); const [visible, setVisible] = useState(true); @@ -85,7 +86,7 @@ const CourseSidebar = ({

Course Lessons

- {visible && ( + {visible && !hideToggleButton && !isMobileView && (
+ ); + }; + + // Mobile content tab + const MobileLessonsTab = () => ( +
+
+

Course Lessons

+
+
+
    + {lessons.map((lesson, index) => ( + + ))} +
+
); - // Desktop implementation with integrated toggle button - if (!isMobileView) { - return ( - <> - {/* Sidebar content */} -
+ return ( + <> + {/* Unified button approach for desktop - only if not hidden */} + {!hideToggleButton && } + + {/* Mobile view - direct content instead of sidebar */} + {isMobileView && visible && ( + + )} + + {/* Desktop sidebar */} + {!isMobileView && ( +
-
+
- - {/* Detached toggle button when sidebar is closed */} - {!visible && } - - ); - } - - // Mobile implementation with PrimeReact's Sidebar - return ( - <> - {/* Mobile toggle button - only shown when sidebar is closed */} - {!visible && ( -
-
)} - - {/* Mobile sidebar */} - -
-

Course Lessons

-
- -
-
    - {lessons.map((lesson, index) => ( - - ))} -
-
-
); }; diff --git a/src/components/menutab/MenuTab.js b/src/components/menutab/MenuTab.js index f05f1f9..707af67 100644 --- a/src/components/menutab/MenuTab.js +++ b/src/components/menutab/MenuTab.js @@ -1,9 +1,10 @@ import React from 'react'; import { TabMenu } from 'primereact/tabmenu'; +import { Button } from 'primereact/button'; -export default function MenuTab({ items, activeIndex, onTabChange }) { +export default function MenuTab({ items, activeIndex, onTabChange, sidebarVisible, onToggleSidebar, isMobileView = false }) { return ( -
+
+ + {/* Sidebar toggle button positioned at the far right - hidden on mobile */} + {!isMobileView && ( +
+
+ )}
); } diff --git a/src/pages/course/[slug]/index.js b/src/pages/course/[slug]/index.js index 74954e9..bfbbcbf 100644 --- a/src/pages/course/[slug]/index.js +++ b/src/pages/course/[slug]/index.js @@ -17,6 +17,7 @@ import ZapThreadsWrapper from '@/components/ZapThreadsWrapper'; import appConfig from '@/config/appConfig'; import useWindowWidth from '@/hooks/useWindowWidth'; import MenuTab from '@/components/menutab/MenuTab'; +import { Tag } from 'primereact/tag'; const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), { ssr: false, @@ -330,6 +331,10 @@ const Course = () => { } }; + const handleToggleSidebar = () => { + setSidebarVisible(!sidebarVisible); + }; + // Map active tab name back to index for MenuTab const getActiveTabIndex = () => { const tabMap = ['overview', 'content', 'qa']; @@ -344,11 +349,11 @@ const Course = () => { const getTabItems = () => { const items = [ { - label: 'Course Overview', + label: 'Overview', icon: 'pi pi-home', }, { - label: 'Lesson Content', + label: 'Content', icon: 'pi pi-book', } ]; @@ -356,7 +361,7 @@ const Course = () => { // Add lessons tab only on mobile if (isMobileView) { items.push({ - label: 'Course Lessons', + label: 'Lessons', icon: 'pi pi-list', }); } @@ -385,8 +390,32 @@ const Course = () => { // Render Course Overview section const renderOverviewSection = () => { + // Get isCompleted status for use in the component + const isCompleted = completedLessons.length > 0; + return ( -
+
+ {isMobileView && course && ( +
+ {/* Completed tag above image in mobile view */} + {isCompleted && ( +
+ +
+ )} + + {/* Course image */} + {course.image && ( +
+ {course.title} +
+ )} +
+ )} { decryptionPerformed={decryptionPerformed} handlePaymentSuccess={handlePaymentSuccess} handlePaymentError={handlePaymentError} + isMobileView={isMobileView} + showCompletedTag={!isMobileView} />
); @@ -461,16 +492,17 @@ const Course = () => { items={getTabItems()} activeIndex={getActiveTabIndex()} onTabChange={(index) => toggleTab(index)} + sidebarVisible={sidebarVisible} + onToggleSidebar={handleToggleSidebar} + isMobileView={isMobileView} />
-
- {/* Main content area - keep existing implementation */} -
+ {/* Revised layout structure to prevent content flexing */} +
+ {/* Main content area with fixed width */} +
{/* Overview tab content */}
{renderOverviewSection()} @@ -508,33 +540,60 @@ const Course = () => {
- {/* Course Sidebar Component - Always visible on desktop, hidden on mobile unless lessons tab is active */} -
+ +
+ ) : ( +
- { - handleLessonSelect(index); - if (isMobileView) { - toggleTab(getTabItems().findIndex(item => item.label === 'Lesson Content')); // On mobile, switch to content tab when a lesson is selected - } - }} - completedLessons={completedLessons} - isMobileView={isMobileView} - onClose={() => { - setSidebarVisible(false); - setActiveTab('content'); - }} - sidebarVisible={sidebarVisible || !isMobileView} // Always visible on desktop - setSidebarVisible={setSidebarVisible} - /> -
+ }`}> + { + handleLessonSelect(index); + if (isMobileView) { + toggleTab(getTabItems().findIndex(item => item.label === 'Lesson Content')); + } + }} + completedLessons={completedLessons} + isMobileView={isMobileView} + onClose={() => { + setSidebarVisible(false); + setActiveTab('content'); + }} + sidebarVisible={sidebarVisible} + setSidebarVisible={setSidebarVisible} + hideToggleButton={true} + /> +
+ )}