Refactor containers to share more code (#61)
Specifically, make sure that the header, footer, and tabs are all shared code so that they look the same and don't need to be redefined as we add more tab pages.
This commit is contained in:
@@ -4,6 +4,7 @@ import { useSelector, useDispatch } from 'react-redux';
|
||||
import { history } from '@edx/frontend-platform';
|
||||
import { getLocale } from '@edx/frontend-platform/i18n';
|
||||
import { useRouteMatch, Redirect } from 'react-router';
|
||||
|
||||
import {
|
||||
fetchCourse,
|
||||
fetchSequence,
|
||||
@@ -14,9 +15,9 @@ import {
|
||||
saveSequencePosition,
|
||||
} from './data/thunks';
|
||||
import { useModel } from '../model-store';
|
||||
import { TabPage } from '../tab-page';
|
||||
|
||||
import Course from './course';
|
||||
|
||||
import { sequenceIdsSelector, firstSequenceIdSelector } from './data/selectors';
|
||||
|
||||
function useUnitNavigationHandler(courseId, sequenceId, unitId) {
|
||||
@@ -200,7 +201,10 @@ export default function CoursewareContainer() {
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="flex-grow-1 d-flex flex-column">
|
||||
<TabPage
|
||||
activeTabSlug="courseware"
|
||||
courseId={courseId}
|
||||
>
|
||||
<Course
|
||||
courseId={courseId}
|
||||
sequenceId={sequenceId}
|
||||
@@ -209,7 +213,7 @@ export default function CoursewareContainer() {
|
||||
previousSequenceHandler={previousSequenceHandler}
|
||||
unitNavigationHandler={unitNavigationHandler}
|
||||
/>
|
||||
</main>
|
||||
</TabPage>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AlertList } from '../../user-messages';
|
||||
import { useAccessExpirationAlert } from '../../access-expiration-alert';
|
||||
import { useLogistrationAlert } from '../../logistration-alert';
|
||||
import { useEnrollmentAlert } from '../../enrollment-alert';
|
||||
import { useOfferAlert } from '../../offer-alert';
|
||||
import PageLoading from '../../PageLoading';
|
||||
|
||||
import InstructorToolbar from './InstructorToolbar';
|
||||
import Sequence from './sequence';
|
||||
|
||||
import CourseBreadcrumbs from './CourseBreadcrumbs';
|
||||
import { Header, CourseTabsNavigation } from '../../course-header';
|
||||
import CourseSock from './course-sock';
|
||||
import ContentTools from './tools/ContentTools';
|
||||
import messages from './messages';
|
||||
import { useModel } from '../../model-store';
|
||||
|
||||
// Note that we import from the component files themselves in the enrollment-alert package.
|
||||
@@ -37,90 +29,53 @@ function Course({
|
||||
nextSequenceHandler,
|
||||
previousSequenceHandler,
|
||||
unitNavigationHandler,
|
||||
intl,
|
||||
}) {
|
||||
const course = useModel('courses', courseId);
|
||||
const sequence = useModel('sequences', sequenceId);
|
||||
const section = useModel('sections', sequence ? sequence.sectionId : null);
|
||||
|
||||
useOfferAlert(courseId);
|
||||
useLogistrationAlert();
|
||||
useEnrollmentAlert(courseId);
|
||||
useAccessExpirationAlert(courseId);
|
||||
|
||||
const courseStatus = useSelector(state => state.courseware.courseStatus);
|
||||
const {
|
||||
canShowUpgradeSock,
|
||||
verifiedMode,
|
||||
} = course;
|
||||
|
||||
if (courseStatus === 'loading') {
|
||||
return (
|
||||
<PageLoading
|
||||
srMessage={intl.formatMessage(messages['learn.loading.learning.sequence'])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (courseStatus === 'loaded') {
|
||||
const {
|
||||
canShowUpgradeSock,
|
||||
org, number, title, isStaff, tabs, verifiedMode,
|
||||
} = course;
|
||||
return (
|
||||
<>
|
||||
<Header
|
||||
courseOrg={org}
|
||||
courseNumber={number}
|
||||
courseTitle={title}
|
||||
/>
|
||||
{isStaff && (
|
||||
<InstructorToolbar
|
||||
courseId={courseId}
|
||||
unitId={unitId}
|
||||
/>
|
||||
)}
|
||||
<CourseTabsNavigation tabs={tabs} activeTabSlug="courseware" />
|
||||
<div className="container-fluid">
|
||||
<AlertList
|
||||
className="my-3"
|
||||
topic="course"
|
||||
customAlerts={{
|
||||
clientEnrollmentAlert: EnrollmentAlert,
|
||||
clientStaffEnrollmentAlert: StaffEnrollmentAlert,
|
||||
clientLogistrationAlert: LogistrationAlert,
|
||||
clientAccessExpirationAlert: AccessExpirationAlert,
|
||||
clientOfferAlert: OfferAlert,
|
||||
}}
|
||||
// courseId is provided because EnrollmentAlert and StaffEnrollmentAlert require it.
|
||||
customProps={{
|
||||
courseId,
|
||||
}}
|
||||
/>
|
||||
<CourseBreadcrumbs
|
||||
courseId={courseId}
|
||||
sectionId={section ? section.id : null}
|
||||
sequenceId={sequenceId}
|
||||
/>
|
||||
<AlertList topic="sequence" />
|
||||
</div>
|
||||
<div className="flex-grow-1 d-flex flex-column">
|
||||
<Sequence
|
||||
unitId={unitId}
|
||||
sequenceId={sequenceId}
|
||||
courseId={courseId}
|
||||
unitNavigationHandler={unitNavigationHandler}
|
||||
nextSequenceHandler={nextSequenceHandler}
|
||||
previousSequenceHandler={previousSequenceHandler}
|
||||
/>
|
||||
{canShowUpgradeSock && verifiedMode && <CourseSock verifiedMode={verifiedMode} />}
|
||||
<ContentTools course={course} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// courseStatus 'failed' and any other unexpected course status.
|
||||
return (
|
||||
<p className="text-center py-5 mx-auto" style={{ maxWidth: '30em' }}>
|
||||
{intl.formatMessage(messages['learn.course.load.failure'])}
|
||||
</p>
|
||||
<>
|
||||
<AlertList
|
||||
className="my-3"
|
||||
topic="course"
|
||||
customAlerts={{
|
||||
clientEnrollmentAlert: EnrollmentAlert,
|
||||
clientStaffEnrollmentAlert: StaffEnrollmentAlert,
|
||||
clientLogistrationAlert: LogistrationAlert,
|
||||
clientAccessExpirationAlert: AccessExpirationAlert,
|
||||
clientOfferAlert: OfferAlert,
|
||||
}}
|
||||
// courseId is provided because EnrollmentAlert and StaffEnrollmentAlert require it.
|
||||
customProps={{
|
||||
courseId,
|
||||
}}
|
||||
/>
|
||||
<CourseBreadcrumbs
|
||||
courseId={courseId}
|
||||
sectionId={section ? section.id : null}
|
||||
sequenceId={sequenceId}
|
||||
/>
|
||||
<AlertList topic="sequence" />
|
||||
<Sequence
|
||||
unitId={unitId}
|
||||
sequenceId={sequenceId}
|
||||
courseId={courseId}
|
||||
unitNavigationHandler={unitNavigationHandler}
|
||||
nextSequenceHandler={nextSequenceHandler}
|
||||
previousSequenceHandler={previousSequenceHandler}
|
||||
/>
|
||||
{canShowUpgradeSock && verifiedMode && <CourseSock verifiedMode={verifiedMode} />}
|
||||
<ContentTools course={course} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -131,7 +86,6 @@ Course.propTypes = {
|
||||
nextSequenceHandler: PropTypes.func.isRequired,
|
||||
previousSequenceHandler: PropTypes.func.isRequired,
|
||||
unitNavigationHandler: PropTypes.func.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
Course.defaultProps = {
|
||||
@@ -140,4 +94,4 @@ Course.defaultProps = {
|
||||
unitId: null,
|
||||
};
|
||||
|
||||
export default injectIntl(Course);
|
||||
export default Course;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
'learn.loading.learning.sequence': {
|
||||
id: 'learn.loading.learning.sequence',
|
||||
defaultMessage: 'Loading learning sequence...',
|
||||
description: 'Message when learning sequence is being loaded',
|
||||
},
|
||||
'learn.course.load.failure': {
|
||||
id: 'learn.course.load.failure',
|
||||
defaultMessage: 'There was an error loading this course.',
|
||||
description: 'Message when a course fails to load',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
Reference in New Issue
Block a user