diff --git a/src/alerts/enrollment-alert/hooks.js b/src/alerts/enrollment-alert/hooks.js index b7e83ff3..d0b5b510 100644 --- a/src/alerts/enrollment-alert/hooks.js +++ b/src/alerts/enrollment-alert/hooks.js @@ -8,7 +8,7 @@ import { postCourseEnrollment } from './data/api'; export function useEnrollmentAlert(courseId) { - const course = useModel('courseHomeMetadata', courseId); + const course = useModel('courses', courseId); const code = course.isStaff ? 'clientStaffEnrollmentAlert' : 'clientEnrollmentAlert'; const isVisible = course && course.isEnrolled !== undefined && !course.isEnrolled; diff --git a/src/course-header/CourseTabsNavigation.jsx b/src/course-header/CourseTabsNavigation.jsx index 3efdb39f..a24c30e5 100644 --- a/src/course-header/CourseTabsNavigation.jsx +++ b/src/course-header/CourseTabsNavigation.jsx @@ -36,6 +36,7 @@ CourseTabsNavigation.propTypes = { className: PropTypes.string, tabs: PropTypes.arrayOf(PropTypes.shape({ title: PropTypes.string.isRequired, + priority: PropTypes.number.isRequired, slug: PropTypes.string.isRequired, url: PropTypes.string.isRequired, })).isRequired, diff --git a/src/course-home/outline-tab/OutlineTab.jsx b/src/course-home/outline-tab/OutlineTab.jsx index 1e3d9fae..2be2a3d6 100644 --- a/src/course-home/outline-tab/OutlineTab.jsx +++ b/src/course-home/outline-tab/OutlineTab.jsx @@ -29,7 +29,7 @@ export default function OutlineTab() { enrollmentEnd, enrollmentMode, isEnrolled, - } = useModel('courseHomeMetadata', courseId); + } = useModel('courses', courseId); const { courseBlocks: { diff --git a/src/data/api.js b/src/data/api.js index 38ad54f6..1fda3d98 100644 --- a/src/data/api.js +++ b/src/data/api.js @@ -40,30 +40,12 @@ function normalizeMetadata(metadata) { }; } -function normalizeCourseHomeCourseMetadata(metadata) { - const data = camelCaseObject(metadata); - return { - ...data, - tabs: data.tabs.map(tab => ({ - slug: tab.tabId, - title: tab.title, - url: tab.url, - })), - }; -} - export async function getCourseMetadata(courseId) { const url = `${getConfig().LMS_BASE_URL}/api/courseware/course/${courseId}`; const { data } = await getAuthenticatedHttpClient().get(url); return normalizeMetadata(data); } -export async function getCourseHomeCourseMetadata(courseId) { - const url = `${getConfig().LMS_BASE_URL}/api/course_home/v1/course_metadata/${courseId}`; - const { data } = await getAuthenticatedHttpClient().get(url); - return normalizeCourseHomeCourseMetadata(data); -} - export async function getDatesTabData(courseId, version) { const url = `${getConfig().LMS_BASE_URL}/api/course_home/${version}/dates/${courseId}`; try { @@ -226,8 +208,3 @@ export async function getResumeBlock(courseId) { const { data } = await getAuthenticatedHttpClient().get(url.href, {}); return camelCaseObject(data); } - -export async function updateCourseDeadlines(courseId) { - const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_experience/v1/reset_course_deadlines`); - await getAuthenticatedHttpClient().post(url.href, { course_key: courseId }); -} diff --git a/src/data/thunks.js b/src/data/thunks.js index 98f23534..51396474 100644 --- a/src/data/thunks.js +++ b/src/data/thunks.js @@ -5,8 +5,6 @@ import { getSequenceMetadata, getDatesTabData, getOutlineTabData, - getCourseHomeCourseMetadata, - updateCourseDeadlines, } from './api'; import { addModelsMap, updateModel, updateModels, updateModelsMap, addModel, @@ -97,27 +95,24 @@ export function fetchTab(courseId, tab, version, getTabData) { return async (dispatch) => { dispatch(fetchTabRequest({ courseId })); Promise.allSettled([ - getCourseHomeCourseMetadata(courseId), + getCourseMetadata(courseId), getTabData(courseId, version), - ]).then(([courseHomeCourseMetadataResult, tabDataResult]) => { - const fetchedCourseHomeMetaData = courseHomeCourseMetadataResult.status === 'fulfilled'; + ]).then(([courseMetadataResult, tabDataResult]) => { + const fetchedMetadata = courseMetadataResult.status === 'fulfilled'; const fetchedTabData = tabDataResult.status === 'fulfilled'; - if (fetchedCourseHomeMetaData) { + if (fetchedMetadata) { /* * NOTE: The "courses" models created by this thunk do not include an array of sectionIds. * If that data is required for some use case, then fetchTab will need to call * getCourseBlocks as well. See fetchCourse above. */ dispatch(addModel({ - modelType: 'courseHomeMetadata', - model: { - id: courseId, - ...courseHomeCourseMetadataResult.value, - }, + modelType: 'courses', + model: courseMetadataResult.value, })); } else { - logError(courseHomeCourseMetadataResult.reason); + logError(courseMetadataResult.reason); } if (fetchedTabData) { @@ -132,7 +127,7 @@ export function fetchTab(courseId, tab, version, getTabData) { logError(tabDataResult.reason); } - if (fetchedCourseHomeMetaData && fetchedTabData) { + if (fetchedMetadata && fetchedTabData) { dispatch(fetchTabSuccess({ courseId })); } else { dispatch(fetchTabFailure({ courseId })); @@ -169,13 +164,3 @@ export function fetchSequence(sequenceId) { } }; } - -export function resetDeadlines(courseId, tab, getTabData) { - return async (dispatch) => { - updateCourseDeadlines(courseId).then(() => { - if (tab === 'dates') { - dispatch(getTabData(courseId)); - } - }); - }; -} diff --git a/src/dates-banner/DatesBanner.jsx b/src/dates-banner/DatesBanner.jsx deleted file mode 100644 index 6c8d4a0d..00000000 --- a/src/dates-banner/DatesBanner.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; - -import messages from './messages'; - -function DatesBanner(props) { - const { - intl, - name, - bannerClickHandler, - } = props; - - return ( -
-
-
- - {intl.formatMessage(messages[`datesBanner.${name}.header`])} - - {intl.formatMessage(messages[`datesBanner.${name}.body`])} -
- {bannerClickHandler && ( - - )} -
-
- ); -} - -DatesBanner.propTypes = { - intl: intlShape.isRequired, - name: PropTypes.string.isRequired, - bannerClickHandler: PropTypes.func, -}; - -DatesBanner.defaultProps = { - bannerClickHandler: null, -}; - -export default injectIntl(DatesBanner); diff --git a/src/dates-banner/DatesBannerContainer.jsx b/src/dates-banner/DatesBannerContainer.jsx deleted file mode 100644 index 982c625f..00000000 --- a/src/dates-banner/DatesBannerContainer.jsx +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { useDispatch, useSelector } from 'react-redux'; - -import { useModel } from '../model-store'; - -import DatesBanner from './DatesBanner'; -import { fetchDatesTab, resetDeadlines } from '../data/thunks'; - -function DatesBannerContainer(props) { - const { - model, - } = props; - - const { - courseId, - } = useSelector(state => state.courseware); - - const { - datesBannerInfo, - } = useModel(model, courseId); - - const { - contentTypeGatingEnabled, - missedDeadlines, - missedGatedContent, - verifiedUpgradeLink, - } = datesBannerInfo; - - const { - isSelfPaced, - } = useModel('courseHomeMetadata', courseId); - - const dispatch = useDispatch(); - const upgradeToCompleteGraded = model === 'dates' && contentTypeGatingEnabled && !missedDeadlines; - const upgradeToReset = !upgradeToCompleteGraded && missedDeadlines && missedGatedContent; - const resetDates = !upgradeToCompleteGraded && missedDeadlines && !missedGatedContent; - const datesBanners = [ - { name: 'datesTabInfoBanner', shouldDisplay: model === 'dates' && !missedDeadlines && isSelfPaced }, - { - name: 'upgradeToCompleteGradedBanner', - shouldDisplay: upgradeToCompleteGraded, - clickHandler: () => window.location.replace(verifiedUpgradeLink), - }, - { - name: 'upgradeToResetBanner', - shouldDisplay: upgradeToReset, - clickHandler: () => window.location.replace(verifiedUpgradeLink), - }, - { - name: 'resetDatesBanner', - shouldDisplay: resetDates, - clickHandler: () => dispatch(resetDeadlines(courseId, model, fetchDatesTab)), - }, - ]; - - return ( - <> - {datesBanners.map((banner) => banner.shouldDisplay && ( - - ))} - - ); -} - -DatesBannerContainer.propTypes = { - model: PropTypes.string.isRequired, -}; - -export default DatesBannerContainer; diff --git a/src/dates-banner/messages.js b/src/dates-banner/messages.js deleted file mode 100644 index cae3f829..00000000 --- a/src/dates-banner/messages.js +++ /dev/null @@ -1,66 +0,0 @@ -import { defineMessages } from '@edx/frontend-platform/i18n'; - -const messages = defineMessages({ - 'datesBanner.datesTabInfoBanner.header': { - id: 'datesBanner.datesTabInfoBanner.header', - defaultMessage: "We've built a suggested schedule to help you stay on track. ", - description: 'Strong text in Dates Tab Info Banner', - }, - 'datesBanner.datesTabInfoBanner.body': { - id: 'datesBanner.datesTabInfoBanner.body', - defaultMessage: `But don't worry—it's flexible so you can learn at your own pace. If you happen to fall behind on - our suggested dates, you'll be able to adjust them to keep yourself on track.`, - description: 'Body in Dates Tab Info Banner', - }, - 'datesBanner.upgradeToCompleteGradedBanner.header': { - id: 'datesBanner.upgradeToCompleteGradedBanner.header', - defaultMessage: 'You are auditing this course, ', - description: 'Strong text in Upgrade To Complete Graded Banner', - }, - 'datesBanner.upgradeToCompleteGradedBanner.body': { - id: 'datesBanner.upgradeToCompleteGradedBanner.body', - defaultMessage: `which means that you are unable to participate in graded assignments. To complete graded - assignments as part of this course, you can upgrade today.`, - description: 'Body in Upgrade To Complete Graded Banner', - }, - 'datesBanner.upgradeToCompleteGradedBanner.button': { - id: 'datesBanner.upgradeToCompleteGradedBanner.button', - defaultMessage: 'Upgrade now', - description: 'Button in Upgrade To Complete Graded Banner', - }, - 'datesBanner.upgradeToResetBanner.header': { - id: 'datesBanner.upgradeToResetBanner.header', - defaultMessage: 'You are auditing this course, ', - description: 'Strong text in Upgrade To Reset Banner', - }, - 'datesBanner.upgradeToResetBanner.body': { - id: 'datesBanner.upgradeToResetBanner.body', - defaultMessage: `which means that you are unable to participate in graded assignments. It looks like you missed - some important deadlines based on our suggested schedule. To complete graded assignments as part of this course - and shift the past due assignments into the future, you can upgrade today.`, - description: 'Body in Upgrade To Reset Banner', - }, - 'datesBanner.upgradeToResetBanner.button': { - id: 'datesBanner.upgradeToResetBanner.button', - defaultMessage: 'Upgrade to shift due dates', - description: 'Button in Upgrade To Reset Banner', - }, - 'datesBanner.resetDatesBanner.header': { - id: 'datesBanner.resetDatesBanner.header', - defaultMessage: 'It looks like you missed some important deadlines based on our suggested schedule. ', - description: 'Strong text in Reset Dates Banner', - }, - 'datesBanner.resetDatesBanner.body': { - id: 'datesBanner.resetDatesBanner.body', - defaultMessage: `To keep yourself on track, you can update this schedule and shift the past due assignments into - the future. Don’t worry—you won’t lose any of the progress you’ve made when you shift your due dates.`, - description: 'Body in Reset Dates Banner', - }, - 'datesBanner.resetDatesBanner.button': { - id: 'datesBanner.resetDatesBanner.button', - defaultMessage: 'Reset my deadlines', - description: 'Button in Reset Dates Banner', - }, -}); - -export default messages; diff --git a/src/dates-tab/DatesTab.jsx b/src/dates-tab/DatesTab.jsx index 54403e9f..088d2685 100644 --- a/src/dates-tab/DatesTab.jsx +++ b/src/dates-tab/DatesTab.jsx @@ -3,12 +3,10 @@ import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import messages from './messages'; import Timeline from './Timeline'; -import DatesBannerContainer from '../dates-banner/DatesBannerContainer'; function DatesTab({ intl }) { return ( <> -

{intl.formatMessage(messages.title)}

diff --git a/src/tab-page/LoadedTabPage.jsx b/src/tab-page/LoadedTabPage.jsx index 89788416..8e538b44 100644 --- a/src/tab-page/LoadedTabPage.jsx +++ b/src/tab-page/LoadedTabPage.jsx @@ -20,7 +20,7 @@ function LoadedTabPage({ org, tabs, title, - } = useModel('courseHomeMetadata', courseId); + } = useModel('courses', courseId); return ( <>