Skip to content

Commit 1638f0a

Browse files
refactor: use Nav for course tabs
1 parent 0a7347e commit 1638f0a

2 files changed

Lines changed: 34 additions & 52 deletions

File tree

shell/header/course-navigation-bar/CourseTabsNavigation.tsx

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
import { useNavigate, useLocation } from 'react-router-dom';
1+
import { useState } from 'react';
2+
import { useLocation } from 'react-router-dom';
23
import { useQuery } from '@tanstack/react-query';
3-
import { Tab, Tabs } from '@openedx/paragon';
4-
import { Slot, useIntl } from '../../../runtime';
4+
import { Slot } from '../../../runtime';
55
import { getCourseHomeCourseMetadata } from './data/service';
6-
import messages from './messages';
76
import './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

189
const extractCourseId = (pathname: string): string => {
1910
const courseRegex = /\/courses?\/([^/]+)/;
@@ -23,58 +14,49 @@ const extractCourseId = (pathname: string): string => {
2314

2415
const 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

shell/header/course-navigation-bar/data/service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getSiteConfig, getAuthenticatedHttpClient, camelCaseObject } from '../../../../runtime';
22

3-
export const getCourseMetadataApiUrl = (courseId) => `${getSiteConfig().lmsBaseUrl}/api/course_home/course_metadata/${courseId}`;
3+
export const getCourseMetadataApiUrl = (courseId: string) => `${getSiteConfig().lmsBaseUrl}/api/course_home/course_metadata/${courseId}`;
44

55
function normalizeCourseHomeCourseMetadata(metadata) {
66
const data = camelCaseObject(metadata);
@@ -15,7 +15,7 @@ function normalizeCourseHomeCourseMetadata(metadata) {
1515
};
1616
}
1717

18-
export async function getCourseHomeCourseMetadata(courseId) {
18+
export async function getCourseHomeCourseMetadata(courseId: string) {
1919
const url = getCourseMetadataApiUrl(courseId);
2020
const { data } = await getAuthenticatedHttpClient().get(url);
2121

0 commit comments

Comments
 (0)