fix: migrated functions to arrow functions to fix linting

This commit is contained in:
Abdullah Waheed
2022-10-24 15:53:58 +05:00
parent 9dd05761fd
commit dc26da9cc1
45 changed files with 312 additions and 324 deletions

View File

@@ -2,18 +2,16 @@ import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
function Alert(props) {
return (
<div className={classNames('alert d-flex align-items-start', props.className)}>
<div>
{props.icon}
</div>
<div>
{props.children}
</div>
const Alert = (props) => (
<div className={classNames('alert d-flex align-items-start', props.className)}>
<div>
{props.icon}
</div>
);
}
<div>
{props.children}
</div>
</div>
);
Alert.propTypes = {
className: PropTypes.string,

View File

@@ -10,7 +10,7 @@ import { YEAR_OF_BIRTH_OPTIONS } from './data/constants';
import { editableFieldSelector } from './data/selectors';
import { saveSettingsReset } from './data/actions';
function DOBModal(props) {
const DOBModal = (props) => {
const {
saveState,
error,
@@ -131,7 +131,7 @@ function DOBModal(props) {
</ModalDialog>
</>
);
}
};
DOBModal.propTypes = {
saveState: PropTypes.oneOf(['default', 'pending', 'complete', 'error']),

View File

@@ -20,7 +20,7 @@ import {
import { editableFieldSelector } from './data/selectors';
import CertificatePreference from './certificate-preference/CertificatePreference';
function EditableField(props) {
const EditableField = (props) => {
const {
name,
label,
@@ -179,7 +179,7 @@ function EditableField(props) {
}}
/>
);
}
};
EditableField.propTypes = {
name: PropTypes.string.isRequired,

View File

@@ -18,7 +18,7 @@ import {
} from './data/actions';
import { editableFieldSelector } from './data/selectors';
function EmailField(props) {
const EmailField = (props) => {
const {
name,
label,
@@ -169,7 +169,7 @@ function EmailField(props) {
}}
/>
);
}
};
EmailField.propTypes = {
name: PropTypes.string.isRequired,

View File

@@ -8,10 +8,10 @@ import { NavHashLink } from 'react-router-hash-link';
import Scrollspy from 'react-scrollspy';
import messages from './AccountSettingsPage.messages';
function JumpNav({
const JumpNav = ({
intl,
displayDemographicsLink,
}) {
}) => {
const stickToTop = useWindowSize().width > breakpoints.small.minWidth;
return (
<div className={classNames('jump-nav', { 'jump-nav-sm position-sticky pt-3': stickToTop })}>
@@ -69,7 +69,7 @@ function JumpNav({
</Scrollspy>
</div>
);
}
};
JumpNav.propTypes = {
intl: intlShape.isRequired,

View File

@@ -1,16 +1,16 @@
import React from 'react';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
export default function NotFoundPage() {
return (
<div className="container-fluid d-flex py-5 justify-content-center align-items-start text-center">
<p className="my-0 py-5 text-muted" style={{ maxWidth: '32em' }}>
<FormattedMessage
id="error.notfound.message"
defaultMessage="The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again."
description="Error message when a page does not exist"
/>
</p>
</div>
);
}
const NotFoundPage = () => (
<div className="container-fluid d-flex py-5 justify-content-center align-items-start text-center">
<p className="my-0 py-5 text-muted" style={{ maxWidth: '32em' }}>
<FormattedMessage
id="error.notfound.message"
defaultMessage="The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again."
description="Error message when a page does not exist"
/>
</p>
</div>
);
export default NotFoundPage;

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { Alert } from '@edx/paragon';
export default function OneTimeDismissibleAlert(props) {
const OneTimeDismissibleAlert = (props) => {
const [dismissed, setDismissed] = useState(localStorage.getItem(props.id) !== 'true');
const onClose = () => {
@@ -25,7 +25,7 @@ export default function OneTimeDismissibleAlert(props) {
</p>
</Alert>
);
}
};
OneTimeDismissibleAlert.propTypes = {
id: PropTypes.string.isRequired,
@@ -41,3 +41,5 @@ OneTimeDismissibleAlert.defaultProps = {
header: undefined,
body: undefined,
};
export default OneTimeDismissibleAlert;

View File

@@ -22,7 +22,7 @@ const onChildExit = (htmlNode) => {
}
};
function SwitchContent({ expression, cases, className }) {
const SwitchContent = ({ expression, cases, className }) => {
const getContent = (caseKey) => {
if (cases[caseKey]) {
if (typeof cases[caseKey] === 'string') {
@@ -48,7 +48,7 @@ function SwitchContent({ expression, cases, className }) {
{getContent(expression)}
</TransitionReplace>
);
}
};
SwitchContent.propTypes = {
expression: PropTypes.string,

View File

@@ -21,14 +21,14 @@ import { certPreferenceSelector } from '../data/selectors';
import commonMessages from '../AccountSettingsPage.messages';
import messages from './messages';
function CertificatePreference({
const CertificatePreference = ({
intl,
fieldName,
originalFullName,
originalVerifiedName,
saveState,
useVerifiedNameForCerts,
}) {
}) => {
const dispatch = useDispatch();
const [checked, setChecked] = useState(false);
const [modalIsOpen, setModalIsOpen] = useState(false);
@@ -152,7 +152,7 @@ function CertificatePreference({
</ModalDialog>
</>
) : null;
}
};
CertificatePreference.propTypes = {
intl: intlShape.isRequired,

View File

@@ -17,28 +17,24 @@ import LogoSVG from '../../logo.svg';
import { fetchSettings } from '../data/actions';
import { coachingConsentPageSelector } from '../data/selectors';
function Logo({ src, alt, ...attributes }) {
return <img src={src} alt={alt} {...attributes} />;
}
const Logo = ({ src, alt, ...attributes }) => <img src={src} alt={alt} {...attributes} />;
function SuccessMessage(props) {
return (
<div className="col-12 col-lg-6 shadow-lg mx-auto mt-4 p-5">
<FontAwesomeIcon className="text-success" icon={faCheck} size="5x" />
<div className="h3">{props.header}</div>
<div>{props.message}</div>
<Hyperlink destination={props.continueUrl} className="d-block p-2 my-3 text-center text-white bg-primary rounded">
{props.continue}
</Hyperlink>
</div>
);
}
const SuccessMessage = (props) => (
<div className="col-12 col-lg-6 shadow-lg mx-auto mt-4 p-5">
<FontAwesomeIcon className="text-success" icon={faCheck} size="5x" />
<div className="h3">{props.header}</div>
<div>{props.message}</div>
<Hyperlink destination={props.continueUrl} className="d-block p-2 my-3 text-center text-white bg-primary rounded">
{props.continue}
</Hyperlink>
</div>
);
function AutoRedirect(props) {
const AutoRedirect = (props) => {
window.location.href = props.redirectUrl;
// eslint-disable-next-line react/jsx-no-useless-fragment
return <></>;
}
};
const VIEWS = {
NOT_LOADED: 'NOT_LOADED',

View File

@@ -8,86 +8,80 @@ import PropTypes from 'prop-types';
import Alert from '../Alert';
import messages from './CoachingConsent.messages';
function ErrorMessage(props) {
return <div className="alert-warning mb-2">{props.message}</div>;
}
const ErrorMessage = (props) => <div className="alert-warning mb-2">{props.message}</div>;
function ManagedProfileAlert({ profileDataManager }) {
return (
<Alert className="alert alert-primary" role="alert">
<FormattedMessage
id="account.settings.coaching.managed.alert"
defaultMessage="Your name is managed by {managerTitle}. Contact your administrator for help."
description="Alert message informing the user their account data is managed by a third party"
values={{
managerTitle: <b>{profileDataManager}</b>,
}}
/>
</Alert>
);
}
function CoachingForm(props) {
return (
<div className="col-12 col-md-6 col-xl-5 mx-auto mt-4 p-5 shadow-lg">
<h2 className="h2">
{props.intl.formatMessage(messages['account.settings.coaching.consent.welcome.header'])}
</h2>
<p>{props.intl.formatMessage(messages['account.settings.coaching.consent.description'])}</p>
<div>
<form onSubmit={props.onSubmit}>
<div className="py-3">
{!!props.profileDataManager && (
<ManagedProfileAlert profileDataManager={props.profileDataManager} />
)}
<ErrorMessage message={props.formErrors.full_name} />
<label className="h6" htmlFor="fullName">
{props.intl.formatMessage(messages['account.settings.coaching.consent.label.name'])}
</label>
<Input
type="text"
name="full-name"
id="fullName"
disabled={!!props.profileDataManager}
defaultValue={props.formValues.name}
/>
</div>
<div className="py-3">
<ErrorMessage message={props.formErrors.phone_number} />
<label className="h6" htmlFor="phoneNumber">
{props.intl.formatMessage(messages['account.settings.coaching.consent.label.phone-number'])}
</label>
<Input
type="text"
name="phone_number"
id="phoneNumber"
defaultValue={props.formValues.phone_number}
/>
</div>
<div className=" py-3">
<p className="small font-italic">
{props.intl.formatMessage(messages['account.settings.coaching.consent.text-messaging.disclaimer'])}
</p>
</div>
<ErrorMessage message={props.formErrors.coaching} />
<div className="d-flex flex-column align-items-center">
<Button variant="outline-primary" className="w-100" type="submit">
{props.intl.formatMessage(messages['account.settings.coaching.consent.accept-coaching'])}
</Button>
</div>
<div className="mt-3">
<Hyperlink
className="mt-3 text-dark btn-link small"
destination={props.redirectUrl}
onClick={props.declineCoaching}
>
{props.intl.formatMessage(messages['account.settings.coaching.consent.decline-coaching'])}
</Hyperlink>
</div>
</form>
</div>
const ManagedProfileAlert = ({ profileDataManager }) => (
<Alert className="alert alert-primary" role="alert">
<FormattedMessage
id="account.settings.coaching.managed.alert"
defaultMessage="Your name is managed by {managerTitle}. Contact your administrator for help."
description="Alert message informing the user their account data is managed by a third party"
values={{
managerTitle: <b>{profileDataManager}</b>,
}}
/>
</Alert>
);
const CoachingForm = (props) => (
<div className="col-12 col-md-6 col-xl-5 mx-auto mt-4 p-5 shadow-lg">
<h2 className="h2">
{props.intl.formatMessage(messages['account.settings.coaching.consent.welcome.header'])}
</h2>
<p>{props.intl.formatMessage(messages['account.settings.coaching.consent.description'])}</p>
<div>
<form onSubmit={props.onSubmit}>
<div className="py-3">
{!!props.profileDataManager && (
<ManagedProfileAlert profileDataManager={props.profileDataManager} />
)}
<ErrorMessage message={props.formErrors.full_name} />
<label className="h6" htmlFor="fullName">
{props.intl.formatMessage(messages['account.settings.coaching.consent.label.name'])}
</label>
<Input
type="text"
name="full-name"
id="fullName"
disabled={!!props.profileDataManager}
defaultValue={props.formValues.name}
/>
</div>
<div className="py-3">
<ErrorMessage message={props.formErrors.phone_number} />
<label className="h6" htmlFor="phoneNumber">
{props.intl.formatMessage(messages['account.settings.coaching.consent.label.phone-number'])}
</label>
<Input
type="text"
name="phone_number"
id="phoneNumber"
defaultValue={props.formValues.phone_number}
/>
</div>
<div className=" py-3">
<p className="small font-italic">
{props.intl.formatMessage(messages['account.settings.coaching.consent.text-messaging.disclaimer'])}
</p>
</div>
<ErrorMessage message={props.formErrors.coaching} />
<div className="d-flex flex-column align-items-center">
<Button variant="outline-primary" className="w-100" type="submit">
{props.intl.formatMessage(messages['account.settings.coaching.consent.accept-coaching'])}
</Button>
</div>
<div className="mt-3">
<Hyperlink
className="mt-3 text-dark btn-link small"
destination={props.redirectUrl}
onClick={props.declineCoaching}
>
{props.intl.formatMessage(messages['account.settings.coaching.consent.decline-coaching'])}
</Hyperlink>
</div>
</form>
</div>
);
}
</div>
);
CoachingForm.defaultProps = {
formErrors: {

View File

@@ -8,69 +8,67 @@ import { editableFieldSelector } from '../data/selectors';
import { saveSettings, updateDraft, saveMultipleSettings } from '../data/actions';
import EditableField from '../EditableField';
function CoachingToggle(props) {
return (
<>
<EditableField
name="phone_number"
type="text"
value={props.phone_number}
label={props.intl.formatMessage(messages['account.settings.field.phone_number'])}
emptyLabel={props.intl.formatMessage(messages['account.settings.field.phone_number.empty'])}
onChange={props.updateDraft}
onSubmit={() => {
const { coaching } = props;
if (coaching.coaching_consent === true) {
return props.saveMultipleSettings([
{
formId: 'coaching',
commitValues: {
...coaching,
phone_number: props.phone_number,
},
const CoachingToggle = (props) => (
<>
<EditableField
name="phone_number"
type="text"
value={props.phone_number}
label={props.intl.formatMessage(messages['account.settings.field.phone_number'])}
emptyLabel={props.intl.formatMessage(messages['account.settings.field.phone_number.empty'])}
onChange={props.updateDraft}
onSubmit={() => {
const { coaching } = props;
if (coaching.coaching_consent === true) {
return props.saveMultipleSettings([
{
formId: 'coaching',
commitValues: {
...coaching,
phone_number: props.phone_number,
},
{
formId: 'phone_number',
commitValues: props.phone_number,
},
], 'phone_number');
}
return props.saveSettings('phone_number', props.phone_number);
},
{
formId: 'phone_number',
commitValues: props.phone_number,
},
], 'phone_number');
}
return props.saveSettings('phone_number', props.phone_number);
}}
/>
<ValidationFormGroup
for="coachingConsent"
helpText={props.intl.formatMessage(messages['account.settings.field.coaching_consent.tooltip'])}
invalid={!!props.error}
invalidMessage={props.intl.formatMessage(messages['account.settings.field.coaching_consent.error'])}
className="custom-control custom-switch"
>
<Input
name={props.name}
className="custom-control-input"
disabled={props.saveState === 'pending'}
type="checkbox"
id="coachingConsent"
checked={props.coaching.coaching_consent}
value={props.coaching.coaching_consent}
onChange={async (e) => {
const { name } = e.target;
// eslint-disable-next-line camelcase
const { user, eligible_for_coaching } = props.coaching;
const value = {
user,
// eslint-disable-next-line camelcase
eligible_for_coaching,
coaching_consent: e.target.checked,
};
props.saveSettings(name, value);
}}
/>
<ValidationFormGroup
for="coachingConsent"
helpText={props.intl.formatMessage(messages['account.settings.field.coaching_consent.tooltip'])}
invalid={!!props.error}
invalidMessage={props.intl.formatMessage(messages['account.settings.field.coaching_consent.error'])}
className="custom-control custom-switch"
>
<Input
name={props.name}
className="custom-control-input"
disabled={props.saveState === 'pending'}
type="checkbox"
id="coachingConsent"
checked={props.coaching.coaching_consent}
value={props.coaching.coaching_consent}
onChange={async (e) => {
const { name } = e.target;
// eslint-disable-next-line camelcase
const { user, eligible_for_coaching } = props.coaching;
const value = {
user,
// eslint-disable-next-line camelcase
eligible_for_coaching,
coaching_consent: e.target.checked,
};
props.saveSettings(name, value);
}}
/>
<label className="custom-control-label" htmlFor="coachingConsent">{props.intl.formatMessage(messages['account.settings.field.coaching_consent'])}</label>
</ValidationFormGroup>
</>
);
}
<label className="custom-control-label" htmlFor="coachingConsent">{props.intl.formatMessage(messages['account.settings.field.coaching_consent'])}</label>
</ValidationFormGroup>
</>
);
CoachingToggle.defaultProps = {
phone_number: '',

View File

@@ -12,7 +12,7 @@ import messages from './messages';
// Components
import Alert from '../Alert';
function BeforeProceedingBanner(props) {
const BeforeProceedingBanner = (props) => {
const { instructionMessageId, intl, supportArticleUrl } = props;
return (
@@ -35,7 +35,7 @@ function BeforeProceedingBanner(props) {
/>
</Alert>
);
}
};
BeforeProceedingBanner.propTypes = {
instructionMessageId: PropTypes.string.isRequired,

View File

@@ -5,7 +5,7 @@ import { Hyperlink } from '@edx/paragon';
import { getConfig } from '@edx/frontend-platform';
import messages from './messages';
function PrintingInstructions(props) {
const PrintingInstructions = (props) => {
const actionLink = (
<Hyperlink
// TODO: What would a generic version of this link look like? Should
@@ -38,7 +38,7 @@ function PrintingInstructions(props) {
values={{ actionLink }}
/>
);
}
};
PrintingInstructions.propTypes = {
intl: intlShape.isRequired,

View File

@@ -5,7 +5,7 @@ import { Modal } from '@edx/paragon';
import messages from './messages';
export function SuccessModal(props) {
export const SuccessModal = (props) => {
const { status, intl, onClose } = props;
return (
<Modal
@@ -23,7 +23,7 @@ export function SuccessModal(props) {
onClose={onClose}
/>
);
}
};
SuccessModal.propTypes = {
status: PropTypes.oneOf(['confirming', 'pending', 'deleted', 'failed']),

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { CheckBox } from '@edx/paragon';
import { DECLINED } from '../data/constants';
function Checkboxes(props) {
const Checkboxes = (props) => {
const {
id,
options,
@@ -59,7 +59,7 @@ function Checkboxes(props) {
{renderCheckboxes()}
</div>
);
}
};
Checkboxes.propTypes = {
id: PropTypes.string.isRequired,

View File

@@ -21,13 +21,13 @@ import { nameChangeSelector } from '../data/selectors';
import { requestNameChange, requestNameChangeFailure, requestNameChangeReset } from './data/actions';
import messages from './messages';
function NameChangeModal({
const NameChangeModal = ({
targetFormId,
errors,
formValues,
intl,
saveState,
}) {
}) => {
const dispatch = useDispatch();
const { push } = useHistory();
const { username } = getAuthenticatedUser();
@@ -183,7 +183,7 @@ function NameChangeModal({
</ModalDialog>
);
}
};
NameChangeModal.propTypes = {
targetFormId: PropTypes.string.isRequired,

View File

@@ -7,7 +7,7 @@ import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import Alert from '../Alert';
function ConfirmationAlert(props) {
const ConfirmationAlert = (props) => {
const { email } = props;
const technicalSupportLink = (
@@ -38,7 +38,7 @@ function ConfirmationAlert(props) {
/>
</Alert>
);
}
};
ConfirmationAlert.propTypes = {
email: PropTypes.string.isRequired,

View File

@@ -5,19 +5,17 @@ import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import Alert from '../Alert';
function RequestInProgressAlert() {
return (
<Alert
className="alert-warning mt-n2"
icon={<FontAwesomeIcon className="mr-2" icon={faExclamationTriangle} />}
>
<FormattedMessage
id="account.settings.editable.field.password.reset.button.forbidden"
defaultMessage="Your previous request is in progress, please try again in few moments."
description="A message displayed when a previous password reset request is still in progress."
/>
</Alert>
);
}
const RequestInProgressAlert = () => (
<Alert
className="alert-warning mt-n2"
icon={<FontAwesomeIcon className="mr-2" icon={faExclamationTriangle} />}
>
<FormattedMessage
id="account.settings.editable.field.password.reset.button.forbidden"
defaultMessage="Your previous request is in progress, please try again in few moments."
description="A message displayed when a previous password reset request is still in progress."
/>
</Alert>
);
export default RequestInProgressAlert;

View File

@@ -9,7 +9,7 @@ import messages from './messages';
import ConfirmationAlert from './ConfirmationAlert';
import RequestInProgressAlert from './RequestInProgressAlert';
function ResetPassword(props) {
const ResetPassword = (props) => {
const { email, intl, status } = props;
return (
<div className="form-group">
@@ -47,7 +47,7 @@ function ResetPassword(props) {
{status === 'forbidden' ? <RequestInProgressAlert /> : null}
</div>
);
}
};
ResetPassword.propTypes = {
email: PropTypes.string,

View File

@@ -5,16 +5,14 @@ import { getConfig } from '@edx/frontend-platform';
import messages from './messages';
function Head({ intl }) {
return (
<Helmet>
<title>
{intl.formatMessage(messages['account.page.title'], { siteName: getConfig().SITE_NAME })}
</title>
<link rel="shortcut icon" href={getConfig().FAVICON_URL} type="image/x-icon" />
</Helmet>
);
}
const Head = ({ intl }) => (
<Helmet>
<title>
{intl.formatMessage(messages['account.page.title'], { siteName: getConfig().SITE_NAME })}
</title>
<link rel="shortcut icon" href={getConfig().FAVICON_URL} type="image/x-icon" />
</Helmet>
);
Head.propTypes = {
intl: intlShape.isRequired,

View File

@@ -6,7 +6,7 @@ import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/
import messages from './IdVerification.messages';
import { ERROR_REASONS } from './IdVerificationContext';
function AccessBlocked({ error, intl }) {
const AccessBlocked = ({ error, intl }) => {
const handleMessage = () => {
if (error === ERROR_REASONS.COURSE_ENROLLMENT) {
return <p>{intl.formatMessage(messages['id.verification.access.blocked.enrollment'])}</p>;
@@ -39,7 +39,7 @@ function AccessBlocked({ error, intl }) {
</div>
</div>
);
}
};
AccessBlocked.propTypes = {
intl: intlShape.isRequired,

View File

@@ -6,35 +6,33 @@ import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { getConfig } from '@edx/frontend-platform';
import messages from './IdVerification.messages';
function CameraHelp(props) {
return (
<div>
<Collapsible
styling="card"
title={props.intl.formatMessage(messages['id.verification.camera.help.sight.question'])}
className="mb-4 shadow"
defaultOpen={props.isOpen}
>
<p>
{props.intl.formatMessage(messages[`id.verification.camera.help.sight.answer.${props.isPortrait ? 'portrait' : 'id'}`])}
</p>
</Collapsible>
<Collapsible
styling="card"
title={props.intl.formatMessage(messages[`id.verification.camera.help.difficulty.question.${props.isPortrait ? 'portrait' : 'id'}`])}
className="mb-4 shadow"
defaultOpen={props.isOpen}
>
<p>
{props.intl.formatMessage(
messages['id.verification.camera.help.difficulty.answer'],
{ siteName: getConfig().SITE_NAME },
)}
</p>
</Collapsible>
</div>
);
}
const CameraHelp = (props) => (
<div>
<Collapsible
styling="card"
title={props.intl.formatMessage(messages['id.verification.camera.help.sight.question'])}
className="mb-4 shadow"
defaultOpen={props.isOpen}
>
<p>
{props.intl.formatMessage(messages[`id.verification.camera.help.sight.answer.${props.isPortrait ? 'portrait' : 'id'}`])}
</p>
</Collapsible>
<Collapsible
styling="card"
title={props.intl.formatMessage(messages[`id.verification.camera.help.difficulty.question.${props.isPortrait ? 'portrait' : 'id'}`])}
className="mb-4 shadow"
defaultOpen={props.isOpen}
>
<p>
{props.intl.formatMessage(
messages['id.verification.camera.help.difficulty.answer'],
{ siteName: getConfig().SITE_NAME },
)}
</p>
</Collapsible>
</div>
);
CameraHelp.propTypes = {
intl: intlShape.isRequired,

View File

@@ -10,7 +10,7 @@ import IdVerificationContext from './IdVerificationContext';
import ImagePreview from './ImagePreview';
import SupportedMediaTypes from './SupportedMediaTypes';
function CameraHelpWithUpload(props) {
const CameraHelpWithUpload = (props) => {
const { setIdPhotoFile, idPhotoFile, userId } = useContext(IdVerificationContext);
const [hasUploadedImage, setHasUploadedImage] = useState(false);
@@ -41,7 +41,7 @@ function CameraHelpWithUpload(props) {
</Collapsible>
</div>
);
}
};
CameraHelpWithUpload.propTypes = {
intl: intlShape.isRequired,

View File

@@ -6,7 +6,7 @@ import { Button, Collapsible } from '@edx/paragon';
import IdVerificationContext from './IdVerificationContext';
import messages from './IdVerification.messages';
function CollapsibleImageHelp(props) {
const CollapsibleImageHelp = (props) => {
const {
userId, useCameraForId, setUseCameraForId,
} = useContext(IdVerificationContext);
@@ -47,7 +47,7 @@ function CollapsibleImageHelp(props) {
</Button>
</Collapsible>
);
}
};
CollapsibleImageHelp.propTypes = {
intl: intlShape.isRequired,

View File

@@ -15,7 +15,7 @@ import { hasGetUserMediaSupport } from './getUserMediaShim';
import IdVerificationContext, { MEDIA_ACCESS, ERROR_REASONS, VERIFIED_MODES } from './IdVerificationContext';
import { VerifiedNameContext } from './VerifiedNameContext';
export default function IdVerificationContextProvider({ children }) {
const IdVerificationContextProvider = ({ children }) => {
const { authenticatedUser } = useContext(AppContext);
const { verifiedNameHistoryCallStatus, verifiedName } = useContext(VerifiedNameContext);
@@ -129,8 +129,10 @@ export default function IdVerificationContextProvider({ children }) {
{children}
</IdVerificationContext.Provider>
);
}
};
IdVerificationContextProvider.propTypes = {
children: PropTypes.node.isRequired,
};
export default IdVerificationContextProvider;

View File

@@ -26,7 +26,7 @@ import SubmittedPanel from './panels/SubmittedPanel';
import messages from './IdVerification.messages';
// eslint-disable-next-line react/prefer-stateless-function
function IdVerificationPage(props) {
const IdVerificationPage = (props) => {
const { path } = useRouteMatch();
const { search } = useLocation();
@@ -106,7 +106,7 @@ function IdVerificationPage(props) {
</div>
</>
);
}
};
IdVerificationPage.propTypes = {
intl: intlShape.isRequired,

View File

@@ -5,7 +5,7 @@ import { Alert } from '@edx/paragon';
import messages from './IdVerification.messages';
import SupportedMediaTypes from './SupportedMediaTypes';
export default function ImageFileUpload({ onFileChange, intl }) {
const ImageFileUpload = ({ onFileChange, intl }) => {
const [error, setError] = useState(null);
const errorTypes = {
invalidFileType: 'invalidFileType',
@@ -54,9 +54,11 @@ export default function ImageFileUpload({ onFileChange, intl }) {
)}
</>
);
}
};
ImageFileUpload.propTypes = {
onFileChange: PropTypes.func.isRequired,
intl: intlShape.isRequired,
};
export default ImageFileUpload;

View File

@@ -1,15 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
export default function ImagePreview({ src, alt, id }) {
return (
<div id={id} className="image-preview">
const ImagePreview = ({ src, alt, id }) => (
<div id={id} className="image-preview">
<img data-hj-suppress style={{ objectFit: 'contain' }} src={src} alt={alt} />
<img data-hj-suppress style={{ objectFit: 'contain' }} src={src} alt={alt} />
</div>
);
}
</div>
);
ImagePreview.propTypes = {
src: PropTypes.string.isRequired,
@@ -20,3 +18,5 @@ ImagePreview.propTypes = {
ImagePreview.defaultProps = {
id: undefined,
};
export default ImagePreview;

View File

@@ -1,6 +1,6 @@
import React from 'react';
export default function SupportedMediaTypes() {
const SupportedMediaTypes = () => {
const SUPPORTED_TYPES = ['.png', '.jpeg', '.jpg', '.bmp', '.webp', '.tiff'];
const getSupportedTypes = () => SUPPORTED_TYPES.map((type, index) => {
@@ -11,4 +11,6 @@ export default function SupportedMediaTypes() {
});
return <span>{getSupportedTypes()}</span>;
}
};
export default SupportedMediaTypes;

View File

@@ -8,7 +8,7 @@ import { SUCCESS_STATUS } from '../constants';
export const VerifiedNameContext = createContext();
export function VerifiedNameContextProvider({ children }) {
export const VerifiedNameContextProvider = ({ children }) => {
const verifiedNameHistoryData = useAsyncCall(getVerifiedNameHistory);
let verifiedName = '';
@@ -24,7 +24,7 @@ export function VerifiedNameContextProvider({ children }) {
}), [status, verifiedName]);
return (<VerifiedNameContext.Provider value={value}>{children}</VerifiedNameContext.Provider>);
}
};
VerifiedNameContextProvider.propTypes = {
children: PropTypes.node.isRequired,

View File

@@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
import { Redirect } from 'react-router';
import { useVerificationRedirectSlug } from '../routing-utilities';
export default function BasePanel({
const BasePanel = ({
children,
focusOnMount,
name,
title,
}) {
}) => {
const headingRef = useRef();
// focus heading element on mount
@@ -29,7 +29,7 @@ export default function BasePanel({
{children}
</div>
);
}
};
BasePanel.propTypes = {
children: PropTypes.node.isRequired,
@@ -41,3 +41,5 @@ BasePanel.propTypes = {
BasePanel.defaultProps = {
focusOnMount: true,
};
export default BasePanel;

View File

@@ -3,7 +3,7 @@ import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import messages from '../IdVerification.messages';
export function EnableCameraDirectionsPanel(props) {
export const EnableCameraDirectionsPanel = (props) => {
if (props.browserName === 'Internet Explorer') {
return (
<>
@@ -65,7 +65,7 @@ export function EnableCameraDirectionsPanel(props) {
}
// eslint-disable-next-line react/jsx-no-useless-fragment
return <></>;
}
};
EnableCameraDirectionsPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -11,7 +11,7 @@ import IdVerificationContext from '../IdVerificationContext';
import messages from '../IdVerification.messages';
function GetNameIdPanel(props) {
const GetNameIdPanel = (props) => {
const { push, location } = useHistory();
const nameInputRef = useRef();
const panelSlug = 'get-name-id';
@@ -89,7 +89,7 @@ function GetNameIdPanel(props) {
</div>
</BasePanel>
);
}
};
GetNameIdPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -8,7 +8,7 @@ import CameraHelp from '../CameraHelp';
import messages from '../IdVerification.messages';
import exampleCard from '../assets/example-card.png';
function IdContextPanel(props) {
const IdContextPanel = (props) => {
const panelSlug = 'id-context';
const nextPanelSlug = useNextPanelSlug(panelSlug);
return (
@@ -47,7 +47,7 @@ function IdContextPanel(props) {
</div>
</BasePanel>
);
}
};
IdContextPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -7,7 +7,7 @@ import BasePanel from './BasePanel';
import CameraHelp from '../CameraHelp';
import messages from '../IdVerification.messages';
function PortraitPhotoContextPanel(props) {
const PortraitPhotoContextPanel = (props) => {
const panelSlug = 'portrait-photo-context';
const nextPanelSlug = useNextPanelSlug(panelSlug);
return (
@@ -44,7 +44,7 @@ function PortraitPhotoContextPanel(props) {
</div>
</BasePanel>
);
}
};
PortraitPhotoContextPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -14,7 +14,7 @@ import { UnsupportedCameraDirectionsPanel } from './UnsupportedCameraDirectionsP
import messages from '../IdVerification.messages';
function RequestCameraAccessPanel(props) {
const RequestCameraAccessPanel = (props) => {
const { location: returnUrl, text: returnText } = useRedirect();
const panelSlug = 'request-camera-access';
const nextPanelSlug = useNextPanelSlug(panelSlug);
@@ -118,7 +118,7 @@ function RequestCameraAccessPanel(props) {
</BasePanel>
);
}
};
RequestCameraAccessPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -12,7 +12,7 @@ import IdVerificationContext from '../IdVerificationContext';
import messages from '../IdVerification.messages';
import exampleCard from '../assets/example-card.png';
function ReviewRequirementsPanel(props) {
const ReviewRequirementsPanel = (props) => {
const { userId, profileDataManager } = useContext(IdVerificationContext);
const panelSlug = 'review-requirements';
const nextPanelSlug = useNextPanelSlug(panelSlug);
@@ -124,7 +124,7 @@ function ReviewRequirementsPanel(props) {
</div>
</BasePanel>
);
}
};
ReviewRequirementsPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -10,7 +10,7 @@ import messages from '../IdVerification.messages';
import BasePanel from './BasePanel';
function SubmittedPanel(props) {
const SubmittedPanel = (props) => {
const { userId } = useContext(IdVerificationContext);
const { location: returnUrl, text: returnText } = useRedirect();
const panelSlug = 'submitted';
@@ -39,7 +39,7 @@ function SubmittedPanel(props) {
</a>
</BasePanel>
);
}
};
SubmittedPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -16,7 +16,7 @@ import messages from '../IdVerification.messages';
import CameraHelpWithUpload from '../CameraHelpWithUpload';
import SupportedMediaTypes from '../SupportedMediaTypes';
function SummaryPanel(props) {
const SummaryPanel = (props) => {
const panelSlug = 'summary';
const nextPanelSlug = useNextPanelSlug(panelSlug);
const {
@@ -60,7 +60,7 @@ function SummaryPanel(props) {
}
// eslint-disable-next-line react/no-unstable-nested-components
function SubmitButton() {
const SubmitButton = () => {
const handleClick = async () => {
setIsSubmitting(true);
const verificationData = {
@@ -97,7 +97,7 @@ function SummaryPanel(props) {
{props.intl.formatMessage(messages['id.verification.review.confirm'])}
</Button>
);
}
};
function getError() {
if (submissionError.status === 400) {
@@ -240,7 +240,7 @@ function SummaryPanel(props) {
{isSubmitting && <Spinner animation="border" variant="primary" />}
</BasePanel>
);
}
};
SummaryPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -14,7 +14,7 @@ import ImageFileUpload from '../ImageFileUpload';
import CollapsibleImageHelp from '../CollapsibleImageHelp';
import SupportedMediaTypes from '../SupportedMediaTypes';
function TakeIdPhotoPanel(props) {
const TakeIdPhotoPanel = (props) => {
const panelSlug = 'take-id-photo';
const nextPanelSlug = useNextPanelSlug(panelSlug);
const { setIdPhotoFile, idPhotoFile, useCameraForId } = useContext(IdVerificationContext);
@@ -67,7 +67,7 @@ function TakeIdPhotoPanel(props) {
</div>
</BasePanel>
);
}
};
TakeIdPhotoPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -10,7 +10,7 @@ import IdVerificationContext from '../IdVerificationContext';
import messages from '../IdVerification.messages';
function TakePortraitPhotoPanel(props) {
const TakePortraitPhotoPanel = (props) => {
const panelSlug = 'take-portrait-photo';
const nextPanelSlug = useNextPanelSlug(panelSlug);
const { setFacePhotoFile, facePhotoFile } = useContext(IdVerificationContext);
@@ -41,7 +41,7 @@ function TakePortraitPhotoPanel(props) {
</div>
</BasePanel>
);
}
};
TakePortraitPhotoPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -3,15 +3,13 @@ import React from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import messages from '../IdVerification.messages';
export function UnsupportedCameraDirectionsPanel(props) {
return (
<>
{props.browserName === 'Chrome' && <span>{props.intl.formatMessage(messages['id.verification.camera.access.failure.unsupported.chrome.explanation'])}</span>}
<span> </span>
<span>{props.intl.formatMessage(messages['id.verification.camera.access.failure.unsupported.instructions'])}</span>
</>
);
}
export const UnsupportedCameraDirectionsPanel = (props) => (
<>
{props.browserName === 'Chrome' && <span>{props.intl.formatMessage(messages['id.verification.camera.access.failure.unsupported.chrome.explanation'])}</span>}
<span> </span>
<span>{props.intl.formatMessage(messages['id.verification.camera.access.failure.unsupported.instructions'])}</span>
</>
);
UnsupportedCameraDirectionsPanel.propTypes = {
intl: intlShape.isRequired,

View File

@@ -5,14 +5,14 @@ import { render, cleanup, waitFor } from '@testing-library/react';
import { getVerifiedNameHistory } from '../../account-settings/data/service';
import { VerifiedNameContext, VerifiedNameContextProvider } from '../VerifiedNameContext';
function VerifiedNameContextTestComponent() {
const VerifiedNameContextTestComponent = () => {
const { verifiedName } = useContext(VerifiedNameContext);
return (
<>
{verifiedName && (<div data-testid="verified-name">{verifiedName}</div>)}
</>
);
}
};
jest.mock('../../account-settings/data/service', () => ({
getVerifiedNameHistory: jest.fn(() => ({})),

View File

@@ -4,7 +4,7 @@ import { render, waitFor } from '@testing-library/react';
import { useAsyncCall } from '../hooks';
import { LOADING_STATUS, SUCCESS_STATUS, FAILURE_STATUS } from '../constants';
function TestUseAsyncCallHookComponent({ asyncFunc }) {
const TestUseAsyncCallHookComponent = ({ asyncFunc }) => {
const { status, data } = useAsyncCall(asyncFunc);
return (
<>
@@ -12,7 +12,7 @@ function TestUseAsyncCallHookComponent({ asyncFunc }) {
{data && Object.keys(data).length !== 0 && <div data-testid="data">{ data.data }</div>}
</>
);
}
};
TestUseAsyncCallHookComponent.propTypes = {
asyncFunc: PropTypes.func.isRequired,