1- import { useNavigate , useLocation } from 'react-router-dom' ;
1+ import { useState } from 'react' ;
2+ import { useLocation } from 'react-router-dom' ;
23import { useQuery } from '@tanstack/react-query' ;
3- import { Tab , Tabs } from '@openedx/paragon' ;
4- import { Slot , useIntl } from '../../../runtime' ;
4+ import { Slot } from '../../../runtime' ;
55import { getCourseHomeCourseMetadata } from './data/service' ;
6- import messages from './messages' ;
76import './course-tabs-navigation.scss' ;
8-
9- interface CourseMetaData {
10- tabs : {
11- title : string ,
12- slug : string ,
13- url : string ,
14- } [ ] ,
15- isMasquerading : boolean ,
16- }
7+ import { Nav , Navbar , Skeleton } from '@openedx/paragon' ;
178
189const extractCourseId = ( pathname : string ) : string => {
1910 const courseRegex = / \/ c o u r s e s ? \/ ( [ ^ / ] + ) / ;
@@ -23,58 +14,49 @@ const extractCourseId = (pathname: string): string => {
2314
2415const CourseTabsNavigation = ( ) => {
2516 const location = useLocation ( ) ;
26- const intl = useIntl ( ) ;
27- const navigate = useNavigate ( ) ;
17+ const [ currentTab , setCurrentTab ] = useState < string | null > ( null ) ;
2818
2919 const courseId = extractCourseId ( location . pathname ) ;
3020
31- const { data } = useQuery ( {
21+ const { data = { tabs : [ ] , isMasquerading : false } , isLoading } = useQuery ( {
3222 queryKey : [ 'org.openedx.frontend.app.header.course-meta' , courseId ] ,
3323 queryFn : ( ) => getCourseHomeCourseMetadata ( courseId ) ,
3424 retry : 2 ,
3525 enabled : ! ! courseId ,
3626 } ) ;
3727
38- if ( ! courseId ) {
39- return null ;
40- }
41-
42- const { tabs = [ ] } : CourseMetaData = data ?? { } ;
43-
44- const handleSelectedTab = ( eventKey : string | null ) => {
45- const selectedUrl = tabs . find ( tab => tab . slug === eventKey ) ?. url ?? '/' ;
28+ const { tabs } = data ;
4629
47- if ( selectedUrl . startsWith ( 'http://' ) || selectedUrl . startsWith ( 'https://' ) ) {
48- const url = new URL ( selectedUrl ) ;
49- if ( url . origin === window . location . origin ) {
50- navigate ( url . pathname + url . search + url . hash ) ;
51- } else {
52- window . location . href = selectedUrl ;
53- }
54- } else {
55- navigate ( selectedUrl ) ;
56- }
57- } ;
30+ if ( isLoading ) {
31+ return < Skeleton className = "lead" /> ;
32+ }
5833
59- if ( ! tabs || tabs . length === 0 ) {
34+ if ( ! courseId || ! tabs || tabs . length === 0 ) {
6035 return null ;
6136 }
6237
6338 return (
64- < div id = "courseTabsNavigation" className = "course-tabs-navigation" >
65- < div className = "container-xl" >
66- < div className = "nav-bar" >
67- < div className = "nav-menu" >
68- < Tabs className = "nav-underline-tabs" aria-label = { intl . formatMessage ( messages . courseMaterial ) } onSelect = { handleSelectedTab } >
69- { tabs . map ( ( { title, slug } ) => (
70- < Tab eventKey = { slug } title = { title } key = { slug } />
71- ) ) }
72- </ Tabs >
73- </ div >
74- < Slot id = "org.openedx.frontend.slot.header.courseNavigationBar.extraContent.v1" />
75- </ div >
76- </ div >
77- </ div >
39+ < Navbar className = "course-tabs-navigation pb-0" >
40+ < Nav
41+ variant = "tabs"
42+ activeKey = { currentTab }
43+ >
44+ {
45+ tabs . map ( ( tab : { tabId : string , url : string , title : string } ) => (
46+ < Nav . Item key = { tab . tabId } >
47+ < Nav . Link
48+ href = { tab . url }
49+ active = { tab . tabId === currentTab }
50+ onClick = { ( ) => setCurrentTab ( tab . tabId ) }
51+ >
52+ { tab . title }
53+ </ Nav . Link >
54+ </ Nav . Item >
55+ ) )
56+ }
57+ < Slot id = "org.openedx.frontend.slot.header.courseNavigationBar.extraContent.v1" />
58+ </ Nav >
59+ </ Navbar >
7860 ) ;
7961} ;
8062
0 commit comments