refactor: change to useIntl

This commit is contained in:
KristinAoki
2025-03-11 16:18:34 -04:00
committed by Braden MacDonald
parent 14c662dc53
commit 903fe28ff6
71 changed files with 746 additions and 877 deletions

View File

@@ -1,14 +1,13 @@
import PropTypes from 'prop-types';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import {
FormattedMessage, FormattedDate, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { FormattedMessage, FormattedDate, useIntl } from '@edx/frontend-platform/i18n';
import { Alert, Hyperlink } from '@openedx/paragon';
import { Info } from '@openedx/paragon/icons';
import messages from './messages';
const AccessExpirationAlert = ({ intl, payload }) => {
const AccessExpirationAlert = ({ payload }) => {
const intl = useIntl();
const {
accessExpiration,
courseId,
@@ -119,7 +118,6 @@ const AccessExpirationAlert = ({ intl, payload }) => {
};
AccessExpirationAlert.propTypes = {
intl: intlShape.isRequired,
payload: PropTypes.shape({
accessExpiration: PropTypes.shape({
expirationDate: PropTypes.string.isRequired,
@@ -134,4 +132,4 @@ AccessExpirationAlert.propTypes = {
}).isRequired,
};
export default injectIntl(AccessExpirationAlert);
export default AccessExpirationAlert;

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import { Alert, Hyperlink } from '@openedx/paragon';
import { WarningFilled } from '@openedx/paragon/icons';
@@ -7,7 +7,8 @@ import { WarningFilled } from '@openedx/paragon/icons';
import { getConfig } from '@edx/frontend-platform';
import genericMessages from './messages';
const ActiveEnterpriseAlert = ({ intl, payload }) => {
const ActiveEnterpriseAlert = ({ payload }) => {
const intl = useIntl();
const { text, courseId } = payload;
const changeActiveEnterprise = (
<Hyperlink
@@ -38,11 +39,10 @@ const ActiveEnterpriseAlert = ({ intl, payload }) => {
};
ActiveEnterpriseAlert.propTypes = {
intl: intlShape.isRequired,
payload: PropTypes.shape({
text: PropTypes.string,
courseId: PropTypes.string,
}).isRequired,
};
export default injectIntl(ActiveEnterpriseAlert);
export default ActiveEnterpriseAlert;

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import { Alert, Button } from '@openedx/paragon';
import { Info, WarningFilled } from '@openedx/paragon/icons';
@@ -11,7 +11,8 @@ import { useModel } from '../../generic/model-store';
import messages from './messages';
import useEnrollClickHandler from './clickHook';
const EnrollmentAlert = ({ intl, payload }) => {
const EnrollmentAlert = ({ payload }) => {
const intl = useIntl();
const {
canEnroll,
courseId,
@@ -58,7 +59,6 @@ const EnrollmentAlert = ({ intl, payload }) => {
};
EnrollmentAlert.propTypes = {
intl: intlShape.isRequired,
payload: PropTypes.shape({
canEnroll: PropTypes.bool,
courseId: PropTypes.string,
@@ -67,4 +67,4 @@ EnrollmentAlert.propTypes = {
}).isRequired,
};
export default injectIntl(EnrollmentAlert);
export default EnrollmentAlert;

View File

@@ -9,13 +9,12 @@ import {
Icon,
} from '@openedx/paragon';
import { Check, ArrowForward } from '@openedx/paragon/icons';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { sendActivationEmail } from '../../courseware/data';
import messages from './messages';
const AccountActivationAlert = ({
intl,
}) => {
const AccountActivationAlert = () => {
const intl = useIntl();
const [showModal, setShowModal] = useState(false);
const [showSpinner, setShowSpinner] = useState(false);
const [showCheck, setShowCheck] = useState(false);
@@ -125,8 +124,4 @@ const AccountActivationAlert = ({
);
};
AccountActivationAlert.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(AccountActivationAlert);
export default AccountActivationAlert;

View File

@@ -1,13 +1,14 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
import { getLoginRedirectUrl } from '@edx/frontend-platform/auth';
import { Alert, Hyperlink } from '@openedx/paragon';
import { WarningFilled } from '@openedx/paragon/icons';
import genericMessages from '../../generic/messages';
const LogistrationAlert = ({ intl }) => {
const LogistrationAlert = () => {
const intl = useIntl();
const signIn = (
<Hyperlink
style={{ textDecoration: 'underline' }}
@@ -43,8 +44,4 @@ const LogistrationAlert = ({ intl }) => {
);
};
LogistrationAlert.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(LogistrationAlert);
export default LogistrationAlert;

View File

@@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Tabs, Tab } from '@openedx/paragon';
import { useParams } from 'react-router';
@@ -13,7 +13,8 @@ const filterTypes = ['text', 'video', 'sequence'];
const filterOther = 'other';
const validFilters = [filterAll, ...filterTypes, filterOther];
export const CoursewareSearchResultsFilter = ({ intl }) => {
export const CoursewareSearchResultsFilter = () => {
const intl = useIntl();
const { courseId } = useParams();
const lastSearch = useModel('contentSearchResults', courseId);
const { filter: filterKeyword, setFilter } = useCoursewareSearchParams();
@@ -73,8 +74,4 @@ export const CoursewareSearchResultsFilter = ({ intl }) => {
);
};
CoursewareSearchResultsFilter.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CoursewareSearchResultsFilter);
export default CoursewareSearchResultsFilter;

View File

@@ -1,15 +1,14 @@
import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
const CoursewareSearchEmpty = ({ intl }) => (
<div className="courseware-search-results">
<p className="courseware-search-results__empty" data-testid="no-results">{intl.formatMessage(messages.searchResultsNone)}</p>
</div>
);
CoursewareSearchEmpty.propTypes = {
intl: intlShape.isRequired,
const CoursewareSearchEmpty = () => {
const intl = useIntl();
return (
<div className="courseware-search-results">
<p className="courseware-search-results__empty" data-testid="no-results">{intl.formatMessage(messages.searchResultsNone)}</p>
</div>
);
};
export default injectIntl(CoursewareSearchEmpty);
export default CoursewareSearchEmpty;

View File

@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button } from '@openedx/paragon';
import { ManageSearch } from '@openedx/paragon/icons';
import { useDispatch } from 'react-redux';
@@ -7,9 +7,8 @@ import messages from './messages';
import { useCoursewareSearchFeatureFlag, useCoursewareSearchParams } from './hooks';
import { setShowSearch } from '../data/slice';
const CoursewareSearchToggle = ({
intl,
}) => {
const CoursewareSearchToggle = () => {
const intl = useIntl();
const dispatch = useDispatch();
const enabled = useCoursewareSearchFeatureFlag();
const { query } = useCoursewareSearchParams();
@@ -41,8 +40,4 @@ const CoursewareSearchToggle = ({
);
};
CoursewareSearchToggle.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CoursewareSearchToggle);
export default CoursewareSearchToggle;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
import Timeline from './timeline/Timeline';
@@ -14,7 +14,8 @@ import ShiftDatesAlert from '../suggested-schedule-messaging/ShiftDatesAlert';
import UpgradeToCompleteAlert from '../suggested-schedule-messaging/UpgradeToCompleteAlert';
import UpgradeToShiftDatesAlert from '../suggested-schedule-messaging/UpgradeToShiftDatesAlert';
const DatesTab = ({ intl }) => {
const DatesTab = () => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -59,8 +60,4 @@ const DatesTab = ({ intl }) => {
);
};
DatesTab.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(DatesTab);
export default DatesTab;

View File

@@ -5,8 +5,7 @@ import { useSelector } from 'react-redux';
import {
FormattedDate,
FormattedTime,
injectIntl,
intlShape,
useIntl,
} from '@edx/frontend-platform/i18n';
import { Tooltip, OverlayTrigger } from '@openedx/paragon';
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
@@ -20,10 +19,10 @@ import { isLearnerAssignment } from '../utils';
const Day = ({
date,
first,
intl,
items,
last,
}) => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -108,7 +107,6 @@ const Day = ({
Day.propTypes = {
date: PropTypes.objectOf(Date).isRequired,
first: PropTypes.bool,
intl: intlShape.isRequired,
items: PropTypes.arrayOf(PropTypes.shape({
date: PropTypes.string,
dateType: PropTypes.string,
@@ -126,4 +124,4 @@ Day.defaultProps = {
last: false,
};
export default injectIntl(Day);
export default Day;

View File

@@ -1,5 +1,4 @@
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { useParams, generatePath, useNavigate } from 'react-router-dom';
@@ -30,6 +29,4 @@ const DiscussionTab = () => {
);
};
DiscussionTab.propTypes = {};
export default injectIntl(DiscussionTab);
export default DiscussionTab;

View File

@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import HeaderSlot from '../../plugin-slots/HeaderSlot';
import PageLoading from '../../generic/PageLoading';
@@ -10,7 +10,8 @@ import { unsubscribeFromCourseGoal } from '../data/api';
import messages from './messages';
import ResultPage from './ResultPage';
const GoalUnsubscribe = ({ intl }) => {
const GoalUnsubscribe = () => {
const intl = useIntl();
const { token } = useParams();
const [error, setError] = useState(false);
const [isLoading, setIsLoading] = useState(true);
@@ -51,8 +52,4 @@ const GoalUnsubscribe = ({ intl }) => {
);
};
GoalUnsubscribe.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(GoalUnsubscribe);
export default GoalUnsubscribe;

View File

@@ -1,28 +1,26 @@
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Hyperlink } from '@openedx/paragon';
import messages from './messages';
import { ReactComponent as UnsubscribeIcon } from './unsubscribe.svg';
const ResultPage = ({ courseTitle, error, intl }) => {
const errorDescription = (
<FormattedMessage
id="learning.goals.unsubscribe.errorDescription"
defaultMessage="We were unable to unsubscribe you from goal reminder emails. Please try again later or {contactSupport} for help."
values={{
contactSupport: (
<Hyperlink
className="text-reset"
style={{ textDecoration: 'underline' }}
destination={`${getConfig().CONTACT_URL}`}
>
{intl.formatMessage(messages.contactSupport)}
</Hyperlink>
),
}}
/>
const ResultPage = ({ courseTitle, error }) => {
const intl = useIntl();
const errorDescription = intl.formatMessage(
messages.errorDescription,
{
contactSupport: (
<Hyperlink
className="text-reset"
style={{ textDecoration: 'underline' }}
destination={`${getConfig().CONTACT_URL}`}
>
{intl.formatMessage(messages.contactSupport)}
</Hyperlink>
),
},
);
const header = error
@@ -54,7 +52,6 @@ ResultPage.defaultProps = {
ResultPage.propTypes = {
courseTitle: PropTypes.string,
error: PropTypes.bool,
intl: intlShape.isRequired,
};
export default injectIntl(ResultPage);
export default ResultPage;

View File

@@ -16,6 +16,11 @@ const messages = defineMessages({
defaultMessage: 'Something went wrong',
description: 'It indicate that the unsubscribing request has failed',
},
errorDescription: {
id: 'learning.goals.unsubscribe.errorDescription',
defaultMessage: 'We were unable to unsubscribe you from goal reminder emails. Please try again later or {contactSupport} for help.',
description: 'Message that notifies user that unsubscribing failed and to try again',
},
goToDashboard: {
id: 'learning.goals.unsubscribe.goToDashboard',
defaultMessage: 'Go to dashboard',

View File

@@ -3,8 +3,7 @@ import PropTypes from 'prop-types';
import {
FormattedDate,
FormattedMessage,
injectIntl,
intlShape,
useIntl,
} from '@edx/frontend-platform/i18n';
import { Alert, Button } from '@openedx/paragon';
import { useDispatch } from 'react-redux';
@@ -25,7 +24,8 @@ export const CERT_STATUS_TYPE = {
UNVERIFIED: 'unverified',
};
const CertificateStatusAlert = ({ intl, payload }) => {
const CertificateStatusAlert = ({ payload }) => {
const intl = useIntl();
const dispatch = useDispatch();
const {
certificateAvailableDate,
@@ -192,7 +192,6 @@ const CertificateStatusAlert = ({ intl, payload }) => {
};
CertificateStatusAlert.propTypes = {
intl: intlShape.isRequired,
payload: PropTypes.shape({
certificateAvailableDate: PropTypes.string,
certStatus: PropTypes.string,
@@ -210,4 +209,4 @@ CertificateStatusAlert.propTypes = {
}).isRequired,
};
export default injectIntl(CertificateStatusAlert);
export default CertificateStatusAlert;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
import { getLoginRedirectUrl } from '@edx/frontend-platform/auth';
import { Alert, Button, Hyperlink } from '@openedx/paragon';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -14,7 +14,8 @@ import outlineMessages from '../../messages';
import useEnrollClickHandler from '../../../../alerts/enrollment-alert/clickHook';
import { useModel } from '../../../../generic/model-store';
const PrivateCourseAlert = ({ intl, payload }) => {
const PrivateCourseAlert = ({ payload }) => {
const intl = useIntl();
const {
anonymousUser,
canEnroll,
@@ -103,7 +104,6 @@ const PrivateCourseAlert = ({ intl, payload }) => {
};
PrivateCourseAlert.propTypes = {
intl: intlShape.isRequired,
payload: PropTypes.shape({
anonymousUser: PropTypes.bool,
canEnroll: PropTypes.bool,
@@ -111,4 +111,4 @@ PrivateCourseAlert.propTypes = {
}).isRequired,
};
export default injectIntl(PrivateCourseAlert);
export default PrivateCourseAlert;

View File

@@ -1,15 +1,14 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import DateSummary from '../DateSummary';
import messages from '../messages';
import { useModel } from '../../../generic/model-store';
const CourseDates = ({
intl,
}) => {
const CourseDates = () => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -48,8 +47,4 @@ const CourseDates = ({
);
};
CourseDates.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseDates);
export default CourseDates;

View File

@@ -1,13 +1,14 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import LmsHtmlFragment from '../LmsHtmlFragment';
import messages from '../messages';
import { useModel } from '../../../generic/model-store';
const CourseHandouts = ({ intl }) => {
const CourseHandouts = () => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -31,8 +32,4 @@ const CourseHandouts = ({ intl }) => {
);
};
CourseHandouts.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseHandouts);
export default CourseHandouts;

View File

@@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';
import { sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faBookmark, faCertificate, faInfo, faCalendar, faStar,
@@ -14,7 +14,8 @@ import messages from '../messages';
import { useModel } from '../../../generic/model-store';
import LaunchCourseHomeTourButton from '../../../product-tours/newUserCourseHomeTour/LaunchCourseHomeTourButton';
const CourseTools = ({ intl }) => {
const CourseTools = () => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -81,8 +82,4 @@ const CourseTools = ({ intl }) => {
);
};
CourseTools.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseTools);
export default CourseTools;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
// These flag svgs are derivatives of the Flag icon from paragon
import { ReactComponent as FlagIntenseIcon } from './flag_black.svg';
import { ReactComponent as FlagCasualIcon } from './flag_outline.svg';
@@ -13,8 +13,8 @@ const LearningGoalButton = ({
level,
isSelected,
handleSelect,
intl,
}) => {
const intl = useIntl();
const buttonDetails = {
casual: {
daysPerWeek: 1,
@@ -53,7 +53,6 @@ LearningGoalButton.propTypes = {
level: PropTypes.string.isRequired,
isSelected: PropTypes.bool.isRequired,
handleSelect: PropTypes.func.isRequired,
intl: intlShape.isRequired,
};
export default injectIntl(LearningGoalButton);
export default LearningGoalButton;

View File

@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import camelCase from 'lodash.camelcase';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button } from '@openedx/paragon';
import messages from '../messages';
@@ -10,7 +10,8 @@ import { getProctoringInfoData } from '../../data/api';
import { fetchProctoringInfoResolved } from '../../data/slice';
import { useModel } from '../../../generic/model-store';
const ProctoringInfoPanel = ({ intl }) => {
const ProctoringInfoPanel = () => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -216,8 +217,4 @@ const ProctoringInfoPanel = ({ intl }) => {
);
};
ProctoringInfoPanel.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(ProctoringInfoPanel);
export default ProctoringInfoPanel;

View File

@@ -1,13 +1,14 @@
import React from 'react';
import { Button, Card } from '@openedx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { useSelector } from 'react-redux';
import { sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
import messages from '../messages';
import { useModel } from '../../../generic/model-store';
const StartOrResumeCourseCard = ({ intl }) => {
const StartOrResumeCourseCard = () => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -62,8 +63,4 @@ const StartOrResumeCourseCard = ({ intl }) => {
);
};
StartOrResumeCourseCard.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(StartOrResumeCourseCard);
export default StartOrResumeCourseCard;

View File

@@ -6,7 +6,7 @@ import { Form, Card, Icon } from '@openedx/paragon';
import { history } from '@edx/frontend-platform';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Email } from '@openedx/paragon/icons';
import { useSelector } from 'react-redux';
import messages from '../messages';
@@ -18,8 +18,8 @@ import './FlagButton.scss';
const WeeklyLearningGoalCard = ({
daysPerWeek,
subscribedToReminders,
intl,
}) => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -152,11 +152,10 @@ const WeeklyLearningGoalCard = ({
WeeklyLearningGoalCard.propTypes = {
daysPerWeek: PropTypes.number,
subscribedToReminders: PropTypes.bool,
intl: intlShape.isRequired,
};
WeeklyLearningGoalCard.defaultProps = {
daysPerWeek: null,
subscribedToReminders: false,
};
export default injectIntl(WeeklyLearningGoalCard);
export default WeeklyLearningGoalCard;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Alert,
Button,
@@ -14,7 +14,8 @@ import { resetDeadlines } from '../data';
import { useModel } from '../../generic/model-store';
import messages from './messages';
const ShiftDatesAlert = ({ fetch, intl, model }) => {
const ShiftDatesAlert = ({ fetch, model }) => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -59,8 +60,7 @@ const ShiftDatesAlert = ({ fetch, intl, model }) => {
ShiftDatesAlert.propTypes = {
fetch: PropTypes.func.isRequired,
intl: intlShape.isRequired,
model: PropTypes.string.isRequired,
};
export default injectIntl(ShiftDatesAlert);
export default ShiftDatesAlert;

View File

@@ -1,16 +1,15 @@
import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
const SuggestedScheduleHeader = ({ intl }) => (
<p className="large">
{intl.formatMessage(messages.suggestedSchedule)}
</p>
);
SuggestedScheduleHeader.propTypes = {
intl: intlShape.isRequired,
const SuggestedScheduleHeader = () => {
const intl = useIntl();
return (
<p className="large">
{intl.formatMessage(messages.suggestedSchedule)}
</p>
);
};
export default injectIntl(SuggestedScheduleHeader);
export default SuggestedScheduleHeader;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Alert,
Button,
@@ -12,7 +12,8 @@ import {
import { useModel } from '../../generic/model-store';
import messages from './messages';
const UpgradeToCompleteAlert = ({ intl, logUpgradeLinkClick }) => {
const UpgradeToCompleteAlert = ({ logUpgradeLinkClick }) => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -58,7 +59,6 @@ const UpgradeToCompleteAlert = ({ intl, logUpgradeLinkClick }) => {
};
UpgradeToCompleteAlert.propTypes = {
intl: intlShape.isRequired,
logUpgradeLinkClick: PropTypes.func,
};
@@ -66,4 +66,4 @@ UpgradeToCompleteAlert.defaultProps = {
logUpgradeLinkClick: () => {},
};
export default injectIntl(UpgradeToCompleteAlert);
export default UpgradeToCompleteAlert;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Alert,
Button,
@@ -13,7 +13,8 @@ import {
import { useModel } from '../../generic/model-store';
import messages from './messages';
const UpgradeToShiftDatesAlert = ({ intl, logUpgradeLinkClick, model }) => {
const UpgradeToShiftDatesAlert = ({ logUpgradeLinkClick, model }) => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -60,7 +61,6 @@ const UpgradeToShiftDatesAlert = ({ intl, logUpgradeLinkClick, model }) => {
};
UpgradeToShiftDatesAlert.propTypes = {
intl: intlShape.isRequired,
logUpgradeLinkClick: PropTypes.func,
model: PropTypes.string.isRequired,
};
@@ -69,4 +69,4 @@ UpgradeToShiftDatesAlert.defaultProps = {
logUpgradeLinkClick: () => {},
};
export default injectIntl(UpgradeToShiftDatesAlert);
export default UpgradeToShiftDatesAlert;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import classNames from 'classnames';
import messages from './messages';
@@ -9,8 +9,9 @@ import { CoursewareSearch, CoursewareSearchToggle } from '../course-home/coursew
import { useCoursewareSearchState } from '../course-home/courseware-search/hooks';
const CourseTabsNavigation = ({
activeTabSlug, className, tabs, intl,
activeTabSlug, className, tabs,
}) => {
const intl = useIntl();
const { show } = useCoursewareSearchState();
return (
@@ -51,7 +52,6 @@ CourseTabsNavigation.propTypes = {
slug: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
})).isRequired,
intl: intlShape.isRequired,
};
CourseTabsNavigation.defaultProps = {
@@ -59,4 +59,4 @@ CourseTabsNavigation.defaultProps = {
className: null,
};
export default injectIntl(CourseTabsNavigation);
export default CourseTabsNavigation;

View File

@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
ActionRow,
breakpoints,
@@ -18,8 +18,9 @@ import { recordFirstSectionCelebration } from './utils';
import { useModel } from '../../../generic/model-store';
const CelebrationModal = ({
courseId, intl, isOpen, onClose, ...rest
courseId, isOpen, onClose, ...rest
}) => {
const intl = useIntl();
const { org, celebrations } = useModel('courseHomeMeta', courseId);
const dispatch = useDispatch();
const wideScreen = useWindowSize().width >= breakpoints.small.minWidth;
@@ -66,9 +67,8 @@ const CelebrationModal = ({
CelebrationModal.propTypes = {
courseId: PropTypes.string.isRequired,
intl: intlShape.isRequired,
isOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
};
export default injectIntl(CelebrationModal);
export default CelebrationModal;

View File

@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import {
ActionRow, Button, Icon, StandardModal,
} from '@openedx/paragon';
@@ -12,8 +12,9 @@ import { recordWeeklyGoalCelebration } from './utils';
import { useModel } from '../../../generic/model-store';
const WeeklyGoalCelebrationModal = ({
courseId, daysPerWeek, intl, isOpen, onClose, ...rest
courseId, daysPerWeek, isOpen, onClose, ...rest
}) => {
const intl = useIntl();
const { org } = useModel('courseHomeMeta', courseId);
useEffect(() => {
@@ -77,9 +78,8 @@ const WeeklyGoalCelebrationModal = ({
WeeklyGoalCelebrationModal.propTypes = {
courseId: PropTypes.string.isRequired,
daysPerWeek: PropTypes.number.isRequired,
intl: intlShape.isRequired,
isOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
};
export default injectIntl(WeeklyGoalCelebrationModal);
export default WeeklyGoalCelebrationModal;

View File

@@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
import { Xpert } from '@edx/frontend-lib-learning-assistant';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { ALLOW_UPSELL_MODES, VERIFIED_MODES } from '@src/constants';
import { useModel } from '../../../generic/model-store';
@@ -80,4 +79,4 @@ Chat.defaultProps = {
enrollmentMode: null,
};
export default injectIntl(Chat);
export default Chat;

View File

@@ -1,402 +1,389 @@
import React, { Component } from 'react';
import React, { useState } from 'react';
import { Collapsible } from '@openedx/paragon';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import {
FormattedMessage, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faCalculator, faQuestionCircle, faTimesCircle, faEquals,
} from '@fortawesome/free-solid-svg-icons';
import messages from './messages';
class Calculator extends Component {
constructor(props) {
super(props);
this.state = {
equation: '',
result: '',
};
this.handleSubmit = this.handleSubmit.bind(this);
}
const Calculator = () => {
const intl = useIntl();
const [equation, setEquation] = useState('');
const [result, setResult] = useState('');
async handleSubmit(event) {
const handleSubmit = async (event) => {
event.preventDefault();
event.stopPropagation();
const urlEncoded = new URLSearchParams();
urlEncoded.append('equation', this.state.equation);
urlEncoded.append('equation', equation);
const response = await getAuthenticatedHttpClient().get(
`${getConfig().LMS_BASE_URL}/calculate?${urlEncoded.toString()}`,
);
this.setState(() => ({ result: response.data.result }));
}
setResult(response.data.result);
};
changeEquation(value) {
this.setState(() => ({ equation: value }));
}
const changeEquation = (value) => {
setEquation(value);
};
render() {
return (
<Collapsible.Advanced className="calculator">
<div className="text-right">
<Collapsible.Trigger tag="a" className="trigger btn">
<Collapsible.Visible whenOpen>
<FontAwesomeIcon icon={faTimesCircle} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
<Collapsible.Visible whenClosed>
<FontAwesomeIcon icon={faCalculator} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
{this.props.intl.formatMessage(messages['calculator.button.label'])}
</Collapsible.Trigger>
</div>
<Collapsible.Body className="calculator-content pt-4">
<form onSubmit={this.handleSubmit} className="container-xl form-inline flex-nowrap">
<input
type="text"
placeholder={this.props.intl.formatMessage(messages['calculator.input.field.label'])}
aria-label={this.props.intl.formatMessage(messages['calculator.input.field.label'])}
className="form-control w-100"
onChange={(event) => this.changeEquation(event.target.value)}
/>
<button
className="btn btn-primary mx-3"
aria-label={this.props.intl.formatMessage(messages['calculator.submit.button.label'])}
type="submit"
>
<FontAwesomeIcon icon={faEquals} aria-hidden="true" />
</button>
<input
type="text"
tabIndex="-1"
readOnly
aria-live="polite"
placeholder={this.props.intl.formatMessage(messages['calculator.result.field.placeholder'])}
aria-label={this.props.intl.formatMessage(messages['calculator.result.field.label'])}
className="form-control w-50"
value={this.state.result}
/>
</form>
return (
<Collapsible.Advanced className="calculator">
<div className="text-right">
<Collapsible.Trigger tag="a" className="trigger btn">
<Collapsible.Visible whenOpen>
<FontAwesomeIcon icon={faTimesCircle} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
<Collapsible.Visible whenClosed>
<FontAwesomeIcon icon={faCalculator} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
{intl.formatMessage(messages['calculator.button.label'])}
</Collapsible.Trigger>
</div>
<Collapsible.Body className="calculator-content pt-4">
<form onSubmit={handleSubmit} className="container-xl form-inline flex-nowrap">
<input
type="text"
placeholder={intl.formatMessage(messages['calculator.input.field.label'])}
aria-label={intl.formatMessage(messages['calculator.input.field.label'])}
className="form-control w-100"
onChange={(event) => changeEquation(event.target.value)}
/>
<button
className="btn btn-primary mx-3"
aria-label={intl.formatMessage(messages['calculator.submit.button.label'])}
type="submit"
>
<FontAwesomeIcon icon={faEquals} aria-hidden="true" />
</button>
<input
type="text"
tabIndex="-1"
readOnly
aria-live="polite"
placeholder={intl.formatMessage(messages['calculator.result.field.placeholder'])}
aria-label={intl.formatMessage(messages['calculator.result.field.label'])}
className="form-control w-50"
value={result}
/>
</form>
<Collapsible.Advanced>
<div className="container-xl">
<Collapsible.Trigger className="btn btn-link btn-sm px-0 d-inline-flex align-items-center">
<Collapsible.Visible whenOpen>
<FontAwesomeIcon icon={faTimesCircle} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
<Collapsible.Visible whenClosed>
<FontAwesomeIcon icon={faQuestionCircle} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
<FormattedMessage
id="calculator.instructions.button.label"
defaultMessage="Calculator Instructions"
/>
</Collapsible.Trigger>
</div>
<Collapsible.Body className="container-xl pt-3" style={{ maxHeight: '50vh', overflow: 'auto' }}>
<Collapsible.Advanced>
<div className="container-xl">
<Collapsible.Trigger className="btn btn-link btn-sm px-0 d-inline-flex align-items-center">
<Collapsible.Visible whenOpen>
<FontAwesomeIcon icon={faTimesCircle} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
<Collapsible.Visible whenClosed>
<FontAwesomeIcon icon={faQuestionCircle} aria-hidden="true" className="mr-2" />
</Collapsible.Visible>
<FormattedMessage
tagName="h6"
id="calculator.instructions"
defaultMessage="For detailed information, see the {expressions_link}."
description="Text that precedes the link which redirects to help page calculator"
values={{
expressions_link: (
<a href={getConfig().SUPPORT_URL_CALCULATOR_MATH}>
<FormattedMessage
id="calculator.instructions.support.title"
defaultMessage="Help Center"
description="Anchor text for link which redirects to help page calculator"
/>
</a>
),
}}
id="calculator.instructions.button.label"
defaultMessage="Calculator Instructions"
/>
<p>
<strong>
<FormattedMessage
id="calculator.instructions.useful.tips"
defaultMessage="Useful tips:"
description="Headline for the (list of tips) about using the calculator"
/>
</strong>
</p>
<ul>
<li className="hint-item" id="hint-paren">
<FormattedMessage
id="calculator.hint1"
defaultMessage="Use parentheses () to make expressions clear. You can use parentheses inside other parentheses."
description="The text indicate that the calculator supports parentheses"
/>
</li>
<li className="hint-item" id="hint-spaces">
<FormattedMessage
id="calculator.hint2"
defaultMessage="Do not use spaces in expressions."
description="It indicate that using a space might cause un expected behavior"
/>
</li>
<li className="hint-item" id="hint-howto-constants">
<FormattedMessage
id="calculator.hint3"
defaultMessage="For constants, indicate multiplication explicitly (example: 5*c)."
description="It indicate the style of math notation"
/>
</li>
<li className="hint-item" id="hint-howto-maffixes">
<FormattedMessage
id="calculator.hint4"
defaultMessage="For affixes, type the number and affix without a space (example: 5c)."
/>
</li>
<li className="hint-item" id="hint-howto-functions">
<FormattedMessage
id="calculator.hint5"
defaultMessage="For functions, type the name of the function, then the expression in parentheses."
description="It indicate how to use a math function, e.g. exp(4)."
/>
</li>
</ul>
<table className="table small">
<thead>
<tr>
<th scope="col">
<FormattedMessage
id="calculator.instruction.table.to.use.heading"
defaultMessage="To Use"
description="Column header which indicate calculator functionality"
/>
</th>
<th scope="col">
<FormattedMessage
id="calculator.instruction.table.type.heading"
defaultMessage="Type"
description="Column header which indicate the supported type(s) of a the calculator functionality"
/>
</th>
<th scope="col">
<FormattedMessage
id="calculator.instruction.table.examples.heading"
defaultMessage="Examples"
description="Column header which list examples of calculator functionality"
/>
</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.numbers"
defaultMessage="Numbers"
description="A calculator functionality"
/>
</th>
<td>
<ul className="list-unstyled m-0">
<li>
<FormattedMessage
id="calculator.instruction.table.to.use.numbers.type1"
defaultMessage="Integers"
description="Type of numbers that is supported the calculator"
/>
</li>
<li>
<FormattedMessage
id="calculator.instruction.table.to.use.numbers.type2"
defaultMessage="Fractions"
description="Type of numbers that is supported by the calculator"
/>
</li>
<li>
<FormattedMessage
id="calculator.instruction.table.to.use.numbers.type3"
defaultMessage="Decimals"
description="Type of numbers that is supported by the calculator"
/>
</li>
</ul>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>2520</li>
<li>2/3</li>
<li>3.14, .98</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.operators"
defaultMessage="Operators"
description="A calculator functionality"
/>
</th>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>
{' + - * / '}
<FormattedMessage
id="calculator.instruction.table.to.use.operators.type1"
defaultMessage="(add, subtract, multiply, divide)"
description="Type of opprators that are supported by the calculator"
/>
</li>
<li>
{'^ '}
<FormattedMessage
id="calculator.instruction.table.to.use.operators.type2"
defaultMessage="(raise to a power)"
description="It indicate that symbol (^) is being used to raise power, e.g. 2^2 = 4"
/>
</li>
<li>
{'|| '}
<FormattedMessage
id="calculator.instruction.table.to.use.operators.type3"
defaultMessage="(parallel resistors)"
description="It indicate that the sympol (||) is being used to calculate (parallel resistor), it is a concept in electrical/electronic engineering"
/>
</li>
</ul>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>x+(2*y)/x-1</li>
<li>x^(n+1)</li>
<li>v_IN+v_OUT</li>
<li>1||2</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.constants"
defaultMessage="Constants"
description="It indicate that the calculator support constants, e.g. the speed of light"
/>
</th>
<td dir="auto">e, pi</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>20*e</li>
<li>418*pi</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.affixes"
defaultMessage="Affixes"
/>
</th>
<td dir="auto">
<FormattedMessage
id="calculator.instruction.table.to.use.affixes.type"
defaultMessage="Percent sign (%)"
/>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>20%</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.basic.functions"
defaultMessage="Basic functions"
description="It indicate that calculator supports mathematical function"
/>
</th>
<td dir="auto">abs, exp, fact, factorial, ln, log2, log10, sqrt</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>abs(x+y)</li>
<li>sqrt(x^2-y)</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.trig.functions"
defaultMessage="Trigonometric functions"
description="Type of mathematical function that is supported by the calculator"
/>
</th>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>sin, cos, tan, sec, csc, cot</li>
<li>arcsin, sinh, arcsinh</li>
</ul>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>sin(4x+y)</li>
<li>arccsch(4x+y)</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation"
defaultMessage="Scientific notation"
description="It indicate that calculator supports scientific notation"
/>
</th>
<td dir="auto">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation.type1"
defaultMessage="{exponentSyntax} and the exponent"
description="Type of scientific notation that is supported by the calculator"
values={{
exponentSyntax: '10^',
}}
/>
</td>
<td dir="auto">10^-9</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation.type2"
defaultMessage="{notationSyntax} notation"
description="It indicate that calculator supports (e) to be used in notation"
values={{
notationSyntax: 'e',
}}
/>
</th>
<td dir="auto">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation.type3"
defaultMessage="{notationSyntax} and the exponent"
description="An example for using (e) in notation"
values={{
notationSyntax: '1e',
}}
/>
</td>
<td dir="auto">1e-9</td>
</tr>
</tbody>
</table>
</Collapsible.Body>
</Collapsible.Advanced>
</Collapsible.Body>
</Collapsible.Advanced>
);
}
}
Calculator.propTypes = {
intl: intlShape.isRequired,
</Collapsible.Trigger>
</div>
<Collapsible.Body className="container-xl pt-3" style={{ maxHeight: '50vh', overflow: 'auto' }}>
<FormattedMessage
tagName="h6"
id="calculator.instructions"
defaultMessage="For detailed information, see the {expressions_link}."
description="Text that precedes the link which redirects to help page calculator"
values={{
expressions_link: (
<a href={getConfig().SUPPORT_URL_CALCULATOR_MATH}>
<FormattedMessage
id="calculator.instructions.support.title"
defaultMessage="Help Center"
description="Anchor text for link which redirects to help page calculator"
/>
</a>
),
}}
/>
<p>
<strong>
<FormattedMessage
id="calculator.instructions.useful.tips"
defaultMessage="Useful tips:"
description="Headline for the (list of tips) about using the calculator"
/>
</strong>
</p>
<ul>
<li className="hint-item" id="hint-paren">
<FormattedMessage
id="calculator.hint1"
defaultMessage="Use parentheses () to make expressions clear. You can use parentheses inside other parentheses."
description="The text indicate that the calculator supports parentheses"
/>
</li>
<li className="hint-item" id="hint-spaces">
<FormattedMessage
id="calculator.hint2"
defaultMessage="Do not use spaces in expressions."
description="It indicate that using a space might cause un expected behavior"
/>
</li>
<li className="hint-item" id="hint-howto-constants">
<FormattedMessage
id="calculator.hint3"
defaultMessage="For constants, indicate multiplication explicitly (example: 5*c)."
description="It indicate the style of math notation"
/>
</li>
<li className="hint-item" id="hint-howto-maffixes">
<FormattedMessage
id="calculator.hint4"
defaultMessage="For affixes, type the number and affix without a space (example: 5c)."
/>
</li>
<li className="hint-item" id="hint-howto-functions">
<FormattedMessage
id="calculator.hint5"
defaultMessage="For functions, type the name of the function, then the expression in parentheses."
description="It indicate how to use a math function, e.g. exp(4)."
/>
</li>
</ul>
<table className="table small">
<thead>
<tr>
<th scope="col">
<FormattedMessage
id="calculator.instruction.table.to.use.heading"
defaultMessage="To Use"
description="Column header which indicate calculator functionality"
/>
</th>
<th scope="col">
<FormattedMessage
id="calculator.instruction.table.type.heading"
defaultMessage="Type"
description="Column header which indicate the supported type(s) of a the calculator functionality"
/>
</th>
<th scope="col">
<FormattedMessage
id="calculator.instruction.table.examples.heading"
defaultMessage="Examples"
description="Column header which list examples of calculator functionality"
/>
</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.numbers"
defaultMessage="Numbers"
description="A calculator functionality"
/>
</th>
<td>
<ul className="list-unstyled m-0">
<li>
<FormattedMessage
id="calculator.instruction.table.to.use.numbers.type1"
defaultMessage="Integers"
description="Type of numbers that is supported the calculator"
/>
</li>
<li>
<FormattedMessage
id="calculator.instruction.table.to.use.numbers.type2"
defaultMessage="Fractions"
description="Type of numbers that is supported by the calculator"
/>
</li>
<li>
<FormattedMessage
id="calculator.instruction.table.to.use.numbers.type3"
defaultMessage="Decimals"
description="Type of numbers that is supported by the calculator"
/>
</li>
</ul>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>2520</li>
<li>2/3</li>
<li>3.14, .98</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.operators"
defaultMessage="Operators"
description="A calculator functionality"
/>
</th>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>
{' + - * / '}
<FormattedMessage
id="calculator.instruction.table.to.use.operators.type1"
defaultMessage="(add, subtract, multiply, divide)"
description="Type of opprators that are supported by the calculator"
/>
</li>
<li>
{'^ '}
<FormattedMessage
id="calculator.instruction.table.to.use.operators.type2"
defaultMessage="(raise to a power)"
description="It indicate that symbol (^) is being used to raise power, e.g. 2^2 = 4"
/>
</li>
<li>
{'|| '}
<FormattedMessage
id="calculator.instruction.table.to.use.operators.type3"
defaultMessage="(parallel resistors)"
description="It indicate that the sympol (||) is being used to calculate (parallel resistor), it is a concept in electrical/electronic engineering"
/>
</li>
</ul>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>x+(2*y)/x-1</li>
<li>x^(n+1)</li>
<li>v_IN+v_OUT</li>
<li>1||2</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.constants"
defaultMessage="Constants"
description="It indicate that the calculator support constants, e.g. the speed of light"
/>
</th>
<td dir="auto">e, pi</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>20*e</li>
<li>418*pi</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.affixes"
defaultMessage="Affixes"
/>
</th>
<td dir="auto">
<FormattedMessage
id="calculator.instruction.table.to.use.affixes.type"
defaultMessage="Percent sign (%)"
/>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>20%</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.basic.functions"
defaultMessage="Basic functions"
description="It indicate that calculator supports mathematical function"
/>
</th>
<td dir="auto">abs, exp, fact, factorial, ln, log2, log10, sqrt</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>abs(x+y)</li>
<li>sqrt(x^2-y)</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.trig.functions"
defaultMessage="Trigonometric functions"
description="Type of mathematical function that is supported by the calculator"
/>
</th>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>sin, cos, tan, sec, csc, cot</li>
<li>arcsin, sinh, arcsinh</li>
</ul>
</td>
<td dir="auto">
<ul className="list-unstyled m-0">
<li>sin(4x+y)</li>
<li>arccsch(4x+y)</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation"
defaultMessage="Scientific notation"
description="It indicate that calculator supports scientific notation"
/>
</th>
<td dir="auto">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation.type1"
defaultMessage="{exponentSyntax} and the exponent"
description="Type of scientific notation that is supported by the calculator"
values={{
exponentSyntax: '10^',
}}
/>
</td>
<td dir="auto">10^-9</td>
</tr>
<tr>
<th scope="row">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation.type2"
defaultMessage="{notationSyntax} notation"
description="It indicate that calculator supports (e) to be used in notation"
values={{
notationSyntax: 'e',
}}
/>
</th>
<td dir="auto">
<FormattedMessage
id="calculator.instruction.table.to.use.scientific.notation.type3"
defaultMessage="{notationSyntax} and the exponent"
description="An example for using (e) in notation"
values={{
notationSyntax: '1e',
}}
/>
</td>
<td dir="auto">1e-9</td>
</tr>
</tbody>
</table>
</Collapsible.Body>
</Collapsible.Advanced>
</Collapsible.Body>
</Collapsible.Advanced>
);
};
export default injectIntl(Calculator);
export default Calculator;

View File

@@ -1,11 +1,9 @@
import React, { Component } from 'react';
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import {
injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import messages from './messages';
@@ -15,47 +13,41 @@ function toggleNotes() {
iframe.contentWindow.postMessage('tools.toggleNotes', getConfig().LMS_BASE_URL);
}
class NotesVisibility extends Component {
constructor(props) {
super(props);
this.state = {
visible: props.course.notes.visible,
};
this.visibilityUrl = `${getConfig().LMS_BASE_URL}/courses/${props.course.id}/edxnotes/visibility/`;
}
const NotesVisibility = ({ course }) => {
const intl = useIntl();
const [visible, setVisible] = useState(course.notes.visible);
const visibilityUrl = `${getConfig().LMS_BASE_URL}/courses/${course.id}/edxnotes/visibility/`;
handleClick = () => {
const data = { visibility: !this.state.visible };
const handleClick = () => {
const data = { visibility: !visible };
getAuthenticatedHttpClient().put(
this.visibilityUrl,
visibilityUrl,
data,
).then(() => {
this.setState((state) => ({ visible: !state.visible }));
setVisible(!visible);
toggleNotes();
});
};
render() {
const message = this.state.visible ? 'notes.button.hide' : 'notes.button.show';
return (
<button
className={`trigger btn ${this.state.visible ? 'text-secondary' : 'text-success'} mx-2 `}
role="switch"
type="button"
onClick={this.handleClick}
onKeyDown={this.handleClick}
tabIndex="-1"
aria-checked={this.state.visible ? 'true' : 'false'}
>
<FontAwesomeIcon icon={faPencilAlt} aria-hidden="true" className="mr-2" />
{this.props.intl.formatMessage(messages[message])}
</button>
);
}
}
const message = visible ? 'notes.button.hide' : 'notes.button.show';
return (
<button
className={`trigger btn ${visible ? 'text-secondary' : 'text-success'} mx-2 `}
role="switch"
type="button"
onClick={handleClick}
onKeyDown={handleClick}
tabIndex="-1"
aria-checked={visible ? 'true' : 'false'}
>
<FontAwesomeIcon icon={faPencilAlt} aria-hidden="true" className="mr-2" />
{intl.formatMessage(messages[message])}
</button>
);
};
NotesVisibility.propTypes = {
intl: intlShape.isRequired,
course: PropTypes.shape({
id: PropTypes.string.isRequired,
notes: PropTypes.shape({
@@ -64,4 +56,4 @@ NotesVisibility.propTypes = {
}).isRequired,
};
export default injectIntl(NotesVisibility);
export default NotesVisibility;

View File

@@ -4,9 +4,7 @@ import { useSelector } from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import {
FormattedMessage, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink } from '@openedx/paragon';
import { faSearch } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -16,7 +14,8 @@ import { useModel } from '../../../generic/model-store';
import messages from './messages';
import { logClick } from './utils';
const CatalogSuggestion = ({ intl, variant }) => {
const CatalogSuggestion = ({ variant }) => {
const intl = useIntl();
const { courseId } = useSelector(state => state.courseware);
const { org } = useModel('courseHomeMeta', courseId);
const { administrator } = getAuthenticatedUser();
@@ -48,8 +47,7 @@ const CatalogSuggestion = ({ intl, variant }) => {
};
CatalogSuggestion.propTypes = {
intl: intlShape.isRequired,
variant: PropTypes.string.isRequired,
};
export default injectIntl(CatalogSuggestion);
export default CatalogSuggestion;

View File

@@ -2,9 +2,7 @@ import React, { useEffect } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faLinkedinIn } from '@fortawesome/free-brands-svg-icons';
import {
FormattedDate, FormattedMessage, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { FormattedDate, FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Helmet } from 'react-helmet';
import { useDispatch, useSelector } from 'react-redux';
import {
@@ -36,7 +34,8 @@ import CourseRecommendationsSlot from '../../../plugin-slots/CourseRecommendatio
const LINKEDIN_BLUE = '#2867B2';
const CourseCelebration = ({ intl }) => {
const CourseCelebration = () => {
const intl = useIntl();
const wideScreen = useWindowSize().width >= breakpoints.medium.minWidth;
const { courseId } = useSelector(state => state.courseware);
const dispatch = useDispatch();
@@ -364,8 +363,4 @@ const CourseCelebration = ({ intl }) => {
);
};
CourseCelebration.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseCelebration);
export default CourseCelebration;

View File

@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button } from '@openedx/paragon';
import { useSelector } from 'react-redux';
import { Navigate } from 'react-router-dom';
@@ -15,7 +15,8 @@ import { unsubscribeFromGoalReminders } from './data/thunks';
import { useModel } from '../../../generic/model-store';
const CourseExit = ({ intl }) => {
const CourseExit = () => {
const intl = useIntl();
const { courseId } = useSelector(state => state.courseware);
const {
certificateData,
@@ -76,8 +77,4 @@ const CourseExit = ({ intl }) => {
);
};
CourseExit.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseExit);
export default CourseExit;

View File

@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Helmet } from 'react-helmet';
import { useSelector } from 'react-redux';
import { Alert, Button } from '@openedx/paragon';
@@ -14,7 +14,8 @@ import DashboardFootnote from './DashboardFootnote';
import messages from './messages';
import { logClick, logVisit } from './utils';
const CourseInProgress = ({ intl }) => {
const CourseInProgress = () => {
const intl = useIntl();
const { courseId } = useSelector(state => state.courseware);
const {
org,
@@ -60,8 +61,4 @@ const CourseInProgress = ({ intl }) => {
);
};
CourseInProgress.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseInProgress);
export default CourseInProgress;

View File

@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Helmet } from 'react-helmet';
import { useSelector } from 'react-redux';
import { Alert, Button } from '@openedx/paragon';
@@ -14,7 +14,8 @@ import DashboardFootnote from './DashboardFootnote';
import messages from './messages';
import { logClick, logVisit } from './utils';
const CourseNonPassing = ({ intl }) => {
const CourseNonPassing = () => {
const intl = useIntl();
const { courseId } = useSelector(state => state.courseware);
const {
org,
@@ -60,8 +61,4 @@ const CourseNonPassing = ({ intl }) => {
);
};
CourseNonPassing.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseNonPassing);
export default CourseNonPassing;

View File

@@ -4,7 +4,7 @@ import { getConfig } from '@edx/frontend-platform';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import {
FormattedMessage, injectIntl, intlShape, defineMessages,
FormattedMessage, useIntl, defineMessages,
} from '@edx/frontend-platform/i18n';
import { useSelector, useDispatch } from 'react-redux';
import {
@@ -64,8 +64,8 @@ const CourseCard = ({
marketingUrl,
onClick,
},
intl,
}) => {
const intl = useIntl();
const formatList = (items, style) => (
items.join(intl.formatMessage(
messages.listJoin,
@@ -127,12 +127,12 @@ CourseCard.propTypes = {
})),
onClick: PropTypes.func,
}).isRequired,
intl: intlShape.isRequired,
};
const IntlCard = injectIntl(CourseCard);
const IntlCard = CourseCard;
const CourseRecommendations = ({ intl, variant }) => {
const CourseRecommendations = ({ variant }) => {
const intl = useIntl();
const { courseId, recommendationsStatus } = useSelector(state => ({ ...state.recommendations, ...state.courseware }));
const { recommendations } = useModel('coursewareMeta', courseId);
const { org, number } = useModel('courseHomeMeta', courseId);
@@ -205,8 +205,7 @@ const CourseRecommendations = ({ intl, variant }) => {
};
CourseRecommendations.propTypes = {
intl: intlShape.isRequired,
variant: PropTypes.string.isRequired,
};
export default injectIntl(CourseRecommendations);
export default CourseRecommendations;

View File

@@ -3,9 +3,7 @@ import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import {
FormattedMessage, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink } from '@openedx/paragon';
import { faCalendarAlt } from '@fortawesome/free-regular-svg-icons';
import { getConfig } from '@edx/frontend-platform';
@@ -16,7 +14,8 @@ import Footnote from './Footnote';
import messages from './messages';
import { logClick } from './utils';
const DashboardFootnote = ({ intl, variant }) => {
const DashboardFootnote = ({ variant }) => {
const intl = useIntl();
const { courseId } = useSelector(state => state.courseware);
const { org } = useModel('courseHomeMeta', courseId);
const { administrator } = getAuthenticatedUser();
@@ -48,8 +47,7 @@ const DashboardFootnote = ({ intl, variant }) => {
};
DashboardFootnote.propTypes = {
intl: intlShape.isRequired,
variant: PropTypes.string.isRequired,
};
export default injectIntl(DashboardFootnote);
export default DashboardFootnote;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert, Button, Hyperlink } from '@openedx/paragon';
import certImage from '../../../generic/assets/edX_certificate.png';
import messages from './messages';
@@ -20,12 +20,12 @@ import messages from './messages';
const programTypes = ['microbachelors', 'micromasters', 'professional-certificate', 'xseries'];
const ProgramCompletion = ({
intl,
progress,
title,
type,
url,
}) => {
const intl = useIntl();
if (!programTypes.includes(type) || progress.notStarted !== 0 || progress.inProgress !== 0) {
return null;
}
@@ -98,7 +98,6 @@ const ProgramCompletion = ({
};
ProgramCompletion.propTypes = {
intl: intlShape.isRequired,
progress: PropTypes.shape({
completed: PropTypes.number.isRequired,
inProgress: PropTypes.number.isRequired,
@@ -109,4 +108,4 @@ ProgramCompletion.propTypes = {
url: PropTypes.string.isRequired,
};
export default injectIntl(ProgramCompletion);
export default ProgramCompletion;

View File

@@ -3,9 +3,7 @@ import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import {
FormattedDate, FormattedMessage, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { FormattedDate, FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink } from '@openedx/paragon';
import { faCalendarAlt } from '@fortawesome/free-regular-svg-icons';
@@ -14,7 +12,8 @@ import { logClick } from './utils';
import messages from './messages';
import { useModel } from '../../../generic/model-store';
const UpgradeFootnote = ({ deadline, href, intl }) => {
const UpgradeFootnote = ({ deadline, href }) => {
const intl = useIntl();
const { courseId } = useSelector(state => state.courseware);
const { org } = useModel('courseHomeMeta', courseId);
const { administrator } = getAuthenticatedUser();
@@ -60,7 +59,6 @@ const UpgradeFootnote = ({ deadline, href, intl }) => {
UpgradeFootnote.propTypes = {
deadline: PropTypes.instanceOf(Date).isRequired,
href: PropTypes.string.isRequired,
intl: intlShape.isRequired,
};
export default injectIntl(UpgradeFootnote);
export default UpgradeFootnote;

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCopyright } from '@fortawesome/free-regular-svg-icons';
@@ -105,8 +105,8 @@ function parseLicense(license) {
const CourseLicense = ({
license,
intl,
}) => {
const intl = useIntl();
const renderAllRightsReservedLicense = () => (
<div className="text-gray-500">
<FontAwesomeIcon aria-hidden="true" className="mr-1" icon={faCopyright} />
@@ -155,11 +155,10 @@ const CourseLicense = ({
CourseLicense.propTypes = {
license: PropTypes.string,
intl: intlShape.isRequired,
};
CourseLicense.defaultProps = {
license: 'all-rights-reserved',
};
export default injectIntl(CourseLicense);
export default CourseLicense;

View File

@@ -3,14 +3,15 @@ import PropTypes from 'prop-types';
import { useNavigate } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faLock } from '@fortawesome/free-solid-svg-icons';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button } from '@openedx/paragon';
import messages from './messages';
const ContentLock = ({
intl, courseId, prereqSectionName, prereqId, sequenceTitle,
courseId, prereqSectionName, prereqId, sequenceTitle,
}) => {
const intl = useIntl();
const navigate = useNavigate();
const handleClick = useCallback(() => {
navigate(`/course/${courseId}/${prereqId}`);
@@ -36,10 +37,9 @@ const ContentLock = ({
);
};
ContentLock.propTypes = {
intl: intlShape.isRequired,
courseId: PropTypes.string.isRequired,
prereqSectionName: PropTypes.string.isRequired,
prereqId: PropTypes.string.isRequired,
sequenceTitle: PropTypes.string.isRequired,
};
export default injectIntl(ContentLock);
export default ContentLock;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert, Hyperlink } from '@openedx/paragon';
import { Info } from '@openedx/paragon/icons';
@@ -8,7 +8,8 @@ import { useModel } from '../../../../generic/model-store';
import messages from './messages';
const HiddenAfterDue = ({ courseId, intl }) => {
const HiddenAfterDue = ({ courseId }) => {
const intl = useIntl();
const { tabs } = useModel('courseHomeMeta', courseId);
const progressTab = tabs.find(tab => tab.slug === 'progress');
@@ -44,8 +45,7 @@ const HiddenAfterDue = ({ courseId, intl }) => {
};
HiddenAfterDue.propTypes = {
intl: intlShape.isRequired,
courseId: PropTypes.string.isRequired,
};
export default injectIntl(HiddenAfterDue);
export default HiddenAfterDue;

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { useDispatch } from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { ActionRow, Alert, Button } from '@openedx/paragon';
import { useNavigate } from 'react-router-dom';
@@ -11,7 +11,8 @@ import { useModel } from '../../../../generic/model-store';
import { saveIntegritySignature } from '../../../data';
import messages from './messages';
const HonorCode = ({ intl, courseId }) => {
const HonorCode = ({ courseId }) => {
const intl = useIntl();
const navigate = useNavigate();
const dispatch = useDispatch();
const {
@@ -68,8 +69,7 @@ const HonorCode = ({ intl, courseId }) => {
};
HonorCode.propTypes = {
intl: intlShape.isRequired,
courseId: PropTypes.string.isRequired,
};
export default injectIntl(HonorCode);
export default HonorCode;

View File

@@ -2,7 +2,7 @@ import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Alert, Hyperlink, breakpoints, useWindowSize,
} from '@openedx/paragon';
@@ -20,9 +20,9 @@ import {
} from '../../../../generic/upsell-bullets/UpsellBullets';
const LockPaywall = ({
intl,
courseId,
}) => {
const intl = useIntl();
const { notificationTrayVisible } = useContext(SidebarContext);
const course = useModel('coursewareMeta', courseId);
const {
@@ -143,7 +143,6 @@ const LockPaywall = ({
);
};
LockPaywall.propTypes = {
intl: intlShape.isRequired,
courseId: PropTypes.string.isRequired,
};
export default injectIntl(LockPaywall);
export default LockPaywall;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import EffortEstimate from '../../../../shared/effort-estimate';
import { sequenceIdsSelector } from '../../../data';
@@ -24,10 +24,10 @@ import messages from './messages';
const UnitNavigationEffortEstimate = ({
children,
intl,
sequenceId,
unitId,
}) => {
const intl = useIntl();
const sequenceIds = useSelector(sequenceIdsSelector);
const sequenceIndex = sequenceIds.indexOf(sequenceId);
const nextSequenceId = sequenceIndex < sequenceIds.length - 1 ? sequenceIds[sequenceIndex + 1] : null;
@@ -59,7 +59,6 @@ const UnitNavigationEffortEstimate = ({
UnitNavigationEffortEstimate.propTypes = {
children: PropTypes.node,
intl: intlShape.isRequired,
sequenceId: PropTypes.string.isRequired,
unitId: PropTypes.string,
};
@@ -69,4 +68,4 @@ UnitNavigationEffortEstimate.defaultProps = {
unitId: null,
};
export default injectIntl(UnitNavigationEffortEstimate);
export default UnitNavigationEffortEstimate;

View File

@@ -1,4 +1,4 @@
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Icon, IconButton } from '@openedx/paragon';
import { ArrowBackIos, Close } from '@openedx/paragon/icons';
import classNames from 'classnames';
@@ -9,7 +9,6 @@ import messages from '../../messages';
import SidebarContext from '../SidebarContext';
const SidebarBase = ({
intl,
title,
ariaLabel,
sidebarId,
@@ -18,6 +17,7 @@ const SidebarBase = ({
showTitleBar,
width,
}) => {
const intl = useIntl();
const {
toggleSidebar,
shouldDisplayFullScreen,
@@ -87,7 +87,6 @@ const SidebarBase = ({
};
SidebarBase.propTypes = {
intl: intlShape.isRequired,
title: PropTypes.string.isRequired,
ariaLabel: PropTypes.string.isRequired,
sidebarId: PropTypes.string.isRequired,
@@ -102,4 +101,4 @@ SidebarBase.defaultProps = {
showTitleBar: true,
};
export default injectIntl(SidebarBase);
export default SidebarBase;

View File

@@ -1,4 +1,3 @@
import { injectIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import React from 'react';
@@ -25,4 +24,4 @@ SidebarTriggerBase.propTypes = {
children: PropTypes.element.isRequired,
};
export default injectIntl(SidebarTriggerBase);
export default SidebarTriggerBase;

View File

@@ -1,7 +1,7 @@
import { useState } from 'react';
import classNames from 'classnames';
import { Button, useToggle, IconButton } from '@openedx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
MenuOpen as MenuOpenIcon,
ChevronLeft as ChevronLeftIcon,
@@ -16,7 +16,8 @@ import { ID } from './constants';
import { useCourseOutlineSidebar } from './hooks';
import messages from './messages';
const CourseOutlineTray = ({ intl }) => {
const CourseOutlineTray = () => {
const intl = useIntl();
const [selectedSection, setSelectedSection] = useState(null);
const [isDisplaySequenceLevel, setDisplaySequenceLevel, setDisplaySectionLevel] = useToggle(true);
@@ -131,10 +132,6 @@ const CourseOutlineTray = ({ intl }) => {
);
};
CourseOutlineTray.propTypes = {
intl: intlShape.isRequired,
};
CourseOutlineTray.ID = ID;
export default injectIntl(CourseOutlineTray);
export default CourseOutlineTray;

View File

@@ -1,6 +1,6 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { IconButton } from '@openedx/paragon';
import { MenuOpen as MenuOpenIcon } from '@openedx/paragon/icons';
@@ -8,7 +8,8 @@ import { useCourseOutlineSidebar } from './hooks';
import { ID } from './constants';
import messages from './messages';
const CourseOutlineTrigger = ({ intl, isMobileView }) => {
const CourseOutlineTrigger = ({ isMobileView }) => {
const intl = useIntl();
const {
currentSidebar,
shouldDisplayFullScreen,
@@ -45,8 +46,7 @@ CourseOutlineTrigger.defaultProps = {
};
CourseOutlineTrigger.propTypes = {
intl: intlShape.isRequired,
isMobileView: PropTypes.bool,
};
export default injectIntl(CourseOutlineTrigger);
export default CourseOutlineTrigger;

View File

@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Icon } from '@openedx/paragon';
import { ChevronRight as ChevronRightIcon } from '@openedx/paragon/icons';
@@ -8,7 +8,8 @@ import courseOutlineMessages from '@src/course-home/outline-tab/messages';
import CompletionIcon from './CompletionIcon';
import { useCourseOutlineSidebar } from '../hooks';
const SidebarSection = ({ intl, section, handleSelectSection }) => {
const SidebarSection = ({ section, handleSelectSection }) => {
const intl = useIntl();
const {
id,
complete,
@@ -54,7 +55,6 @@ const SidebarSection = ({ intl, section, handleSelectSection }) => {
};
SidebarSection.propTypes = {
intl: intlShape.isRequired,
section: PropTypes.shape({
complete: PropTypes.bool,
id: PropTypes.string,
@@ -68,4 +68,4 @@ SidebarSection.propTypes = {
handleSelectSection: PropTypes.func.isRequired,
};
export default injectIntl(SidebarSection);
export default SidebarSection;

View File

@@ -1,7 +1,7 @@
import { useState } from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Collapsible } from '@openedx/paragon';
import courseOutlineMessages from '@src/course-home/outline-tab/messages';
@@ -11,12 +11,12 @@ import SidebarUnit from './SidebarUnit';
import { UNIT_ICON_TYPES } from './UnitIcon';
const SidebarSequence = ({
intl,
courseId,
defaultOpen,
sequence,
activeUnitId,
}) => {
const intl = useIntl();
const {
id,
complete,
@@ -78,7 +78,6 @@ const SidebarSequence = ({
};
SidebarSequence.propTypes = {
intl: intlShape.isRequired,
courseId: PropTypes.string.isRequired,
defaultOpen: PropTypes.bool.isRequired,
sequence: PropTypes.shape({
@@ -96,4 +95,4 @@ SidebarSequence.propTypes = {
activeUnitId: PropTypes.string.isRequired,
};
export default injectIntl(SidebarSequence);
export default SidebarSequence;

View File

@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from '../messages';
import UnitIcon, { UNIT_ICON_TYPES } from './UnitIcon';
@@ -8,7 +8,6 @@ import UnitLinkWrapper from './UnitLinkWrapper';
const SidebarUnit = ({
id,
intl,
courseId,
sequenceId,
isFirst,
@@ -17,6 +16,7 @@ const SidebarUnit = ({
isLocked,
activeUnitId,
}) => {
const intl = useIntl();
const {
complete,
title,
@@ -52,7 +52,6 @@ const SidebarUnit = ({
};
SidebarUnit.propTypes = {
intl: intlShape.isRequired,
id: PropTypes.string.isRequired,
isFirst: PropTypes.bool.isRequired,
unit: PropTypes.shape({
@@ -69,4 +68,4 @@ SidebarUnit.propTypes = {
activeUnitId: PropTypes.string.isRequired,
};
export default injectIntl(SidebarUnit);
export default SidebarUnit;

View File

@@ -1,7 +1,7 @@
import { useContext } from 'react';
import classNames from 'classnames';
import { ensureConfig, getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { useModel } from '@src/generic/model-store';
import SidebarBase from '../../common/SidebarBase';
@@ -12,7 +12,8 @@ import messages from './messages';
ensureConfig(['DISCUSSIONS_MFE_BASE_URL']);
const DiscussionsSidebar = ({ intl }) => {
const DiscussionsSidebar = () => {
const intl = useIntl();
const {
unitId,
courseId,
@@ -47,11 +48,7 @@ const DiscussionsSidebar = ({ intl }) => {
);
};
DiscussionsSidebar.propTypes = {
intl: intlShape.isRequired,
};
DiscussionsSidebar.Trigger = DiscussionsSidebar;
DiscussionsSidebar.ID = ID;
export default injectIntl(DiscussionsSidebar);
export default DiscussionsSidebar;

View File

@@ -1,5 +1,5 @@
import { ensureConfig, getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Icon } from '@openedx/paragon';
import { QuestionAnswer } from '@openedx/paragon/icons';
import PropTypes from 'prop-types';
@@ -16,9 +16,9 @@ ensureConfig(['DISCUSSIONS_MFE_BASE_URL']);
export const ID = WIDGETS.DISCUSSIONS;
const DiscussionsTrigger = ({
intl,
onClick,
}) => {
const intl = useIntl();
const {
unitId,
courseId,
@@ -51,8 +51,7 @@ const DiscussionsTrigger = ({
};
DiscussionsTrigger.propTypes = {
intl: intlShape.isRequired,
onClick: PropTypes.func.isRequired,
};
export default injectIntl(DiscussionsTrigger);
export default DiscussionsTrigger;

View File

@@ -1,4 +1,4 @@
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Icon } from '@openedx/paragon';
import { WatchOutline } from '@openedx/paragon/icons';
import classNames from 'classnames';
@@ -8,35 +8,36 @@ import React from 'react';
import messages from '../../../messages';
const NotificationIcon = ({
intl,
status,
notificationColor,
}) => (
<>
<Icon src={WatchOutline} className="m-0 m-auto" alt={intl.formatMessage(messages.openNotificationTrigger)} />
{status === 'active'
? (
<span
className={classNames(notificationColor, 'rounded-circle p-1 position-absolute')}
data-testid="notification-dot"
style={{
top: '0.3rem',
right: '0.55rem',
}}
/>
)
: null}
</>
);
}) => {
const intl = useIntl();
return (
<>
<Icon src={WatchOutline} className="m-0 m-auto" alt={intl.formatMessage(messages.openNotificationTrigger)} />
{status === 'active'
? (
<span
className={classNames(notificationColor, 'rounded-circle p-1 position-absolute')}
data-testid="notification-dot"
style={{
top: '0.3rem',
right: '0.55rem',
}}
/>
)
: null}
</>
);
};
NotificationIcon.defaultProps = {
status: null,
};
NotificationIcon.propTypes = {
intl: intlShape.isRequired,
status: PropTypes.string,
notificationColor: PropTypes.string.isRequired,
};
export default injectIntl(NotificationIcon);
export default NotificationIcon;

View File

@@ -1,4 +1,4 @@
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import classNames from 'classnames';
import { useContext, useEffect, useMemo } from 'react';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
@@ -11,7 +11,8 @@ import SidebarBase from '../../common/SidebarBase';
import SidebarContext from '../../SidebarContext';
import NotificationTrigger, { ID } from './NotificationTrigger';
const NotificationTray = ({ intl }) => {
const NotificationTray = () => {
const intl = useIntl();
const {
courseId,
onNotificationSeen,
@@ -92,11 +93,7 @@ const NotificationTray = ({ intl }) => {
);
};
NotificationTray.propTypes = {
intl: intlShape.isRequired,
};
NotificationTray.Trigger = NotificationTrigger;
NotificationTray.ID = ID;
export default injectIntl(NotificationTray);
export default NotificationTray;

View File

@@ -1,5 +1,5 @@
import { useContext, useEffect } from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import { WIDGETS } from '@src/constants';
@@ -12,9 +12,9 @@ import NotificationIcon from './NotificationIcon';
export const ID = WIDGETS.NOTIFICATIONS;
const NotificationTrigger = ({
intl,
onClick,
}) => {
const intl = useIntl();
const {
courseId,
notificationStatus,
@@ -55,8 +55,7 @@ const NotificationTrigger = ({
};
NotificationTrigger.propTypes = {
intl: intlShape.isRequired,
onClick: PropTypes.func.isRequired,
};
export default injectIntl(NotificationTrigger);
export default NotificationTrigger;

View File

@@ -14,7 +14,7 @@ import {
import { getConfig } from '@edx/frontend-platform';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
import { useModel } from '../../generic/model-store';
@@ -26,9 +26,9 @@ const SocialIcons = ({
emailBody,
emailSubject,
hashtags,
intl,
socialMessage,
}) => {
const intl = useIntl();
const { marketingUrl } = useModel('coursewareMeta', courseId);
const {
@@ -122,8 +122,7 @@ SocialIcons.propTypes = {
emailBody: PropTypes.shape({}),
emailSubject: PropTypes.shape({}),
hashtags: PropTypes.arrayOf(PropTypes.string),
intl: intlShape.isRequired,
socialMessage: PropTypes.shape({}),
};
export default injectIntl(SocialIcons);
export default SocialIcons;

View File

@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { useParams, Navigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import FooterSlot from '@openedx/frontend-slot-footer';
import { LOADED, LOADING } from '@src/constants';
import HeaderSlot from '../plugin-slots/HeaderSlot';
@@ -11,7 +11,8 @@ import { fetchDiscussionTab } from '../course-home/data/thunks';
import PageLoading from './PageLoading';
import messages from '../tab-page/messages';
const CourseAccessErrorPage = ({ intl }) => {
const CourseAccessErrorPage = () => {
const intl = useIntl();
const { courseId } = useParams();
const dispatch = useDispatch();
@@ -56,8 +57,4 @@ const CourseAccessErrorPage = ({ intl }) => {
);
};
CourseAccessErrorPage.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(CourseAccessErrorPage);
export default CourseAccessErrorPage;

View File

@@ -1,13 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
const FormattedPricing = (props) => {
const intl = useIntl();
const {
inline,
intl,
offer,
verifiedMode,
} = props;
@@ -67,7 +67,6 @@ FormattedPricing.defaultProps = {
FormattedPricing.propTypes = {
inline: PropTypes.bool,
intl: intlShape.isRequired,
offer: PropTypes.shape({
discountedPrice: PropTypes.string.isRequired,
originalPrice: PropTypes.string.isRequired,
@@ -80,4 +79,4 @@ FormattedPricing.propTypes = {
}),
};
export default injectIntl(FormattedPricing);
export default FormattedPricing;

View File

@@ -1,13 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { Button } from '@openedx/paragon';
import FormattedPricing from './FormattedPricing';
const UpgradeButton = (props) => {
const {
intl,
offer,
variant,
onClick,
@@ -50,7 +49,6 @@ UpgradeButton.defaultProps = {
};
UpgradeButton.propTypes = {
intl: intlShape.isRequired,
offer: PropTypes.shape({
upgradeUrl: PropTypes.string.isRequired,
}),
@@ -61,4 +59,4 @@ UpgradeButton.propTypes = {
variant: PropTypes.string,
};
export default injectIntl(UpgradeButton);
export default UpgradeButton;

View File

@@ -1,13 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { Button } from '@openedx/paragon';
import FormattedPricing from './FormattedPricing';
const UpgradeNowButton = (props) => {
const {
intl,
offer,
variant,
onClick,
@@ -48,7 +47,6 @@ UpgradeNowButton.defaultProps = {
};
UpgradeNowButton.propTypes = {
intl: intlShape.isRequired,
offer: PropTypes.shape({
upgradeUrl: PropTypes.string.isRequired,
}),
@@ -59,4 +57,4 @@ UpgradeNowButton.propTypes = {
variant: PropTypes.string,
};
export default injectIntl(UpgradeNowButton);
export default UpgradeNowButton;

View File

@@ -4,7 +4,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Icon } from '@openedx/paragon';
import { Compass } from '@openedx/paragon/icons';
@@ -12,7 +12,8 @@ import { useModel } from '../../generic/model-store';
import { launchCourseHomeTour } from '../data/slice';
import messages from '../messages';
const LaunchCourseHomeTourButton = ({ intl, srOnly }) => {
const LaunchCourseHomeTourButton = ({ srOnly }) => {
const intl = useIntl();
const {
courseId,
} = useSelector(state => state.courseHome);
@@ -63,8 +64,7 @@ LaunchCourseHomeTourButton.defaultProps = {
};
LaunchCourseHomeTourButton.propTypes = {
intl: intlShape.isRequired,
srOnly: PropTypes.bool,
};
export default injectIntl(LaunchCourseHomeTourButton);
export default LaunchCourseHomeTourButton;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import {
ActionRow, Button, MarketingModal, ModalDialog,
} from '@openedx/paragon';
@@ -10,63 +10,65 @@ import heroImage from './course_home_tour_modal_hero.png';
import messages from '../messages';
const NewUserCourseHomeTourModal = ({
intl,
isOpen,
onDismiss,
onStartTour,
}) => (
<MarketingModal
isOpen={isOpen}
title="New user course home prompt"
className="new-user-tour-dialog"
heroIsDark
hasCloseButton={false}
heroNode={(
<ModalDialog.Hero>
<ModalDialog.Hero.Background
backgroundSrc={heroImage}
/>
<ModalDialog.Hero.Content style={{ maxWidth: '20rem' }}>
<ModalDialog.Title as="h2">
<FormattedMessage
id="tours.newUserModal.title"
defaultMessage="{welcome} {siteName} course!"
values={{
siteName: getConfig().SITE_NAME,
welcome: <span className="text-accent-b">{intl.formatMessage(messages.newUserModalTitleWelcome)}</span>,
}}
/>
</ModalDialog.Title>
</ModalDialog.Hero.Content>
</ModalDialog.Hero>
)}
footerNode={(
<ActionRow>
<Button
variant="tertiary"
onClick={onDismiss}
>
{intl.formatMessage(messages.skipForNow)}
</Button>
<Button
variant="brand"
onClick={onStartTour}
>
{intl.formatMessage(messages.beginTour)}
</Button>
</ActionRow>
)}
onClose={onDismiss}
>
<p className="text-dark-900">{intl.formatMessage(messages.newUserModalBody, { siteName: getConfig().SITE_NAME })}</p>
</MarketingModal>
);
}) => {
const intl = useIntl();
return (
<MarketingModal
isOpen={isOpen}
title="New user course home prompt"
className="new-user-tour-dialog"
heroIsDark
hasCloseButton={false}
heroNode={(
<ModalDialog.Hero>
<ModalDialog.Hero.Background
backgroundSrc={heroImage}
/>
<ModalDialog.Hero.Content style={{ maxWidth: '20rem' }}>
<ModalDialog.Title as="h2">
<FormattedMessage
id="tours.newUserModal.title"
defaultMessage="{welcome} {siteName} course!"
values={{
siteName: getConfig().SITE_NAME,
welcome: <span className="text-accent-b">{intl.formatMessage(messages.newUserModalTitleWelcome)}</span>,
}}
/>
</ModalDialog.Title>
</ModalDialog.Hero.Content>
</ModalDialog.Hero>
)}
footerNode={(
<ActionRow>
<Button
variant="tertiary"
onClick={onDismiss}
>
{intl.formatMessage(messages.skipForNow)}
</Button>
<Button
variant="brand"
onClick={onStartTour}
>
{intl.formatMessage(messages.beginTour)}
</Button>
</ActionRow>
)}
onClose={onDismiss}
>
<p className="text-dark-900">{intl.formatMessage(messages.newUserModalBody, { siteName: getConfig().SITE_NAME })}</p>
</MarketingModal>
);
};
NewUserCourseHomeTourModal.propTypes = {
intl: intlShape.isRequired,
isOpen: PropTypes.bool.isRequired,
onDismiss: PropTypes.func.isRequired,
onStartTour: PropTypes.func.isRequired,
};
export default injectIntl(NewUserCourseHomeTourModal);
export default NewUserCourseHomeTourModal;

View File

@@ -1,20 +1,20 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
// This component shows an effort estimate provided by the backend block data. Either time, activities, or both.
const EffortEstimate = (props) => {
const intl = useIntl();
const {
block: {
effortActivities,
effortTime,
},
className,
intl,
} = props;
const minuteCount = Math.ceil(effortTime / 60); // effortTime is in seconds
@@ -66,7 +66,6 @@ EffortEstimate.propTypes = {
effortTime: PropTypes.number,
}).isRequired,
className: PropTypes.string,
intl: intlShape.isRequired,
};
export default injectIntl(EffortEstimate);
export default EffortEstimate;

View File

@@ -1,26 +1,26 @@
import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { getConfig } from '@edx/frontend-platform';
import { Hyperlink } from '@openedx/paragon';
import messages from '../courseware/course/course-exit/messages';
const IntlDashboardLink = ({ intl }) => (
<Hyperlink
variant="muted"
isInline
destination={`${getConfig().LMS_BASE_URL}/dashboard`}
>
{intl.formatMessage(messages.dashboardLink)}
</Hyperlink>
);
IntlDashboardLink.propTypes = {
intl: intlShape.isRequired,
const DashboardLink = () => {
const intl = useIntl();
return (
<Hyperlink
variant="muted"
isInline
destination={`${getConfig().LMS_BASE_URL}/dashboard`}
>
{intl.formatMessage(messages.dashboardLink)}
</Hyperlink>
);
};
const IntlIdVerificationSupportLink = ({ intl }) => {
const IdVerificationSupportLink = () => {
const intl = useIntl();
if (!getConfig().SUPPORT_URL_ID_VERIFICATION) {
return null;
}
@@ -35,11 +35,8 @@ const IntlIdVerificationSupportLink = ({ intl }) => {
);
};
IntlIdVerificationSupportLink.propTypes = {
intl: intlShape.isRequired,
};
const IntlProfileLink = ({ intl }) => {
const ProfileLink = () => {
const intl = useIntl();
const { username } = getAuthenticatedUser();
return (
@@ -53,12 +50,4 @@ const IntlProfileLink = ({ intl }) => {
);
};
IntlProfileLink.propTypes = {
intl: intlShape.isRequired,
};
const DashboardLink = injectIntl(IntlDashboardLink);
const IdVerificationSupportLink = injectIntl(IntlIdVerificationSupportLink);
const ProfileLink = injectIntl(IntlProfileLink);
export { DashboardLink, IdVerificationSupportLink, ProfileLink };

View File

@@ -4,9 +4,7 @@ import PropTypes from 'prop-types';
import { camelCaseObject, getConfig } from '@edx/frontend-platform';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import {
FormattedMessage, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Lightbulb, MoneyFilled } from '@openedx/paragon/icons';
import {
Alert, breakpoints, Icon, ModalDialog, Spinner, useWindowSize,
@@ -59,9 +57,10 @@ const CloseText = ({ intl }) => (
);
const StreakModal = ({
courseId, metadataModel, streakLengthToCelebrate, intl, isStreakCelebrationOpen,
courseId, metadataModel, streakLengthToCelebrate, isStreakCelebrationOpen,
closeStreakCelebration, streakDiscountCouponEnabled, verifiedMode, ...rest
}) => {
const intl = useIntl();
const { org, celebrations, username } = useModel('courseHomeMeta', courseId);
const factoid = getRandomFactoid(intl, streakLengthToCelebrate);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -249,7 +248,6 @@ StreakModal.propTypes = {
courseId: PropTypes.string.isRequired,
metadataModel: PropTypes.string.isRequired,
streakLengthToCelebrate: PropTypes.number,
intl: intlShape.isRequired,
isStreakCelebrationOpen: PropTypes.bool,
closeStreakCelebration: PropTypes.func.isRequired,
streakDiscountCouponEnabled: PropTypes.bool,
@@ -261,4 +259,4 @@ StreakModal.propTypes = {
}),
};
export default injectIntl(StreakModal);
export default StreakModal;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { useDispatch, useSelector } from 'react-redux';
import { Navigate } from 'react-router-dom';
@@ -17,7 +17,8 @@ import LoadedTabPage from './LoadedTabPage';
import { setCallToActionToast } from '../course-home/data/slice';
import LaunchCourseHomeTourButton from '../product-tours/newUserCourseHomeTour/LaunchCourseHomeTourButton';
const TabPage = ({ intl, ...props }) => {
const TabPage = (props) => {
const intl = useIntl();
const {
activeTabSlug,
courseId,
@@ -92,11 +93,10 @@ TabPage.defaultProps = {
TabPage.propTypes = {
activeTabSlug: PropTypes.string.isRequired,
intl: intlShape.isRequired,
courseId: PropTypes.string,
courseStatus: PropTypes.string.isRequired,
metadataModel: PropTypes.string.isRequired,
unitId: PropTypes.string,
};
export default injectIntl(TabPage);
export default TabPage;