Initial version of Course Home page (#20)
* refactor: Moving PageLoading up to the top This way it can be used on both the courseware and outline pages. * Adding index.js files to data directories, and PropTypes data shapes - The course-blocks and course-meta data directories now have index files so their exports can be imported from that, rather than reaching into specific files in the directories. - Also added “shapes” for use in React Components that use PropTypes for the course blocks data structure, and the course metadata data structure. * Simplifying/refactoring CourseContainer rendering a bit. * Adding course outline page. This page is not complete. - It contains the ‘outline’ itself with links to the Sequences in the course. - It contains a very basic stab at displaying dates - they’re not even formatted. - It shows logistration and enrollment alerts for anonymous and unenrolled users. It does not include any other content in the right-hand sidebar. It also doesn’t include a welcome message, or perhaps any number of other features on the page. This is effectively an initial implementation for discovering how much data we’re missing from our APIs. It should not be used as-is by any means.
This commit is contained in:
20
src/data/course-blocks/index.js
Normal file
20
src/data/course-blocks/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
export {
|
||||
getCourseBlocks,
|
||||
getSequenceMetadata,
|
||||
updateSequencePosition,
|
||||
getBlockCompletion,
|
||||
createBookmark,
|
||||
deleteBookmark,
|
||||
} from './api';
|
||||
export {
|
||||
reducer,
|
||||
courseBlocksShape,
|
||||
} from './slice';
|
||||
export {
|
||||
fetchCourseBlocks,
|
||||
fetchSequenceMetadata,
|
||||
checkBlockCompletion,
|
||||
saveSequencePosition,
|
||||
addBookmark,
|
||||
removeBookmark,
|
||||
} from './thunks';
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const blocksSlice = createSlice({
|
||||
name: 'blocks',
|
||||
@@ -132,3 +133,10 @@ export const {
|
||||
} = blocksSlice.actions;
|
||||
|
||||
export const { reducer } = blocksSlice;
|
||||
|
||||
export const courseBlocksShape = PropTypes.objectOf(PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
displayName: PropTypes.string.isRequired,
|
||||
children: PropTypes.arrayOf(PropTypes.string),
|
||||
parentId: PropTypes.string,
|
||||
}));
|
||||
|
||||
6
src/data/course-meta/index.js
Normal file
6
src/data/course-meta/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export { getCourseMetadata } from './api';
|
||||
export {
|
||||
reducer,
|
||||
courseMetadataShape,
|
||||
} from './slice';
|
||||
export { fetchCourseMetadata } from './thunks';
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const courseMetaSlice = createSlice({
|
||||
name: 'course-meta',
|
||||
@@ -12,13 +13,33 @@ const courseMetaSlice = createSlice({
|
||||
},
|
||||
fetchCourseMetadataSuccess: (draftState, { payload }) => ({
|
||||
fetchState: 'loaded',
|
||||
|
||||
/*
|
||||
* NOTE: If you change the data saved here,
|
||||
* update the courseMetadataShape below!
|
||||
*/
|
||||
|
||||
// Course identifiers
|
||||
name: payload.name,
|
||||
number: payload.number,
|
||||
org: payload.org,
|
||||
tabs: payload.tabs,
|
||||
userHasAccess: payload.userHasAccess,
|
||||
|
||||
// Enrollment dates
|
||||
enrollmentStart: payload.enrollmentStart,
|
||||
enrollmentEnd: payload.enrollmentEnd,
|
||||
|
||||
// Course dates
|
||||
end: payload.end,
|
||||
start: payload.start,
|
||||
|
||||
// User access/enrollment status
|
||||
enrollmentMode: payload.enrollment.mode,
|
||||
isEnrolled: payload.enrollment.isActive,
|
||||
userHasAccess: payload.userHasAccess,
|
||||
verifiedMode: payload.verifiedMode,
|
||||
|
||||
// Misc
|
||||
tabs: payload.tabs,
|
||||
}),
|
||||
fetchCourseMetadataFailure: (draftState) => {
|
||||
draftState.fetchState = 'failed';
|
||||
@@ -33,3 +54,40 @@ export const {
|
||||
} = courseMetaSlice.actions;
|
||||
|
||||
export const { reducer } = courseMetaSlice;
|
||||
|
||||
export const courseMetadataShape = PropTypes.shape({
|
||||
fetchState: PropTypes.string,
|
||||
// Course identifiers
|
||||
name: PropTypes.string,
|
||||
number: PropTypes.string,
|
||||
org: PropTypes.string,
|
||||
|
||||
// Enrollment dates
|
||||
enrollmentStart: PropTypes.string,
|
||||
enrollmentEnd: PropTypes.string,
|
||||
|
||||
// User access/enrollment status
|
||||
enrollmentMode: PropTypes.string,
|
||||
isEnrolled: PropTypes.bool,
|
||||
userHasAccess: PropTypes.bool,
|
||||
verifiedMode: PropTypes.shape({
|
||||
price: PropTypes.number.isRequired,
|
||||
currency: PropTypes.string.isRequired,
|
||||
currencySymbol: PropTypes.string.isRequired,
|
||||
sku: PropTypes.string.isRequired,
|
||||
upgradeUrl: PropTypes.string.isRequired,
|
||||
}),
|
||||
|
||||
// Course dates
|
||||
start: PropTypes.string,
|
||||
end: PropTypes.string,
|
||||
|
||||
// Misc
|
||||
tabs: PropTypes.arrayOf(PropTypes.shape({
|
||||
priority: PropTypes.number,
|
||||
slug: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
})),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user