+ { (mediaAccess === MEDIA_ACCESS.PENDING && !shouldUseCamera)
+ ? (
+ // if a user has not enabled camera access yet, and they are trying to switch
+ // to camera mode, direct them to panel that requests camera access
+
+ {props.intl.formatMessage(messages['id.verification.photo.camera.help.button'])}
+
+ )
+ : (
+
+ )}
+
+ );
+ }
+
+ return null;
+}
+
+CollapsibleImageHelp.propTypes = {
+ intl: intlShape.isRequired,
+ isPortrait: PropTypes.bool.isRequired,
+};
+
+export default injectIntl(CollapsibleImageHelp);
diff --git a/src/id-verification/IdVerification.messages.js b/src/id-verification/IdVerification.messages.js
index 823f781..0a42a02 100644
--- a/src/id-verification/IdVerification.messages.js
+++ b/src/id-verification/IdVerification.messages.js
@@ -641,6 +641,56 @@ const messages = defineMessages({
defaultMessage: 'Return to Course',
description: 'Return to the course which ID verification was accessed from.',
},
+ 'id.verification.photo.upload.help.title': {
+ id: 'id.verification.photo.upload.help.title',
+ defaultMessage: 'Upload a Photo Instead',
+ description: 'Title for section that allows switching to photo upload mode.',
+ },
+ 'id.verification.photo.camera.help.title': {
+ id: 'id.verification.photo.camera.help.title',
+ defaultMessage: 'Use Your Camera Instead',
+ description: 'Title for section that allows switching to camera mode.',
+ },
+ 'id.verification.photo.upload.help.text': {
+ id: 'id.verification.photo.upload.help.text',
+ defaultMessage: 'If you are having trouble using the photo capture above, you may want to upload a photo instead. To upload a photo, click the button below.',
+ description: 'Help text for switching to upload mode.',
+ },
+ 'id.verification.photo.camera.help.text': {
+ id: 'id.verification.photo.camera.help.text',
+ defaultMessage: 'If you are having trouble uploading a photo above, you may want to use your camera instead. To use your camera, click the button below.',
+ description: 'Help text for switching to camera mode.',
+ },
+ 'id.verification.photo.upload.help.button': {
+ id: 'id.verification.upload.help.button',
+ defaultMessage: 'Switch to Upload Mode',
+ description: 'Button used to switch to upload mode.',
+ },
+ 'id.verification.photo.camera.help.button': {
+ id: 'id.verification.camera.help.button',
+ defaultMessage: 'Switch to Camera Mode',
+ description: 'Button used to switch to camera mode.',
+ },
+ 'id.verification.choose.mode.title': {
+ id: 'id.verification.choose.mode.title',
+ defaultMessage: 'Photo Requirements Options',
+ description: 'Title for section that allows user to choose photo mode.',
+ },
+ 'id.verification.choose.mode.help.text': {
+ id: 'id.verification.choose.mode.hep.text',
+ defaultMessage: 'To complete verification, please select one of the following options to submit photos. You will be able to switch between these options throughout the process if needed.',
+ description: 'Help text for section that allows user to choose photo mode.',
+ },
+ 'id.verification.choose.mode.radio.upload': {
+ id: 'id.verification.choose.mode.radio.upload',
+ defaultMessage: 'Upload photos from my device',
+ description: 'Radio button to choose to upload photos.',
+ },
+ 'id.verification.choose.mode.radio.camera': {
+ id: 'id.verification.choose.mode.radio.camera',
+ defaultMessage: 'Take pictures using my camera',
+ description: 'Radio button to choose to use camera for photos.',
+ },
});
export default messages;
diff --git a/src/id-verification/IdVerificationContextProvider.jsx b/src/id-verification/IdVerificationContextProvider.jsx
index fa28fa2..52b1f55 100644
--- a/src/id-verification/IdVerificationContextProvider.jsx
+++ b/src/id-verification/IdVerificationContextProvider.jsx
@@ -77,6 +77,7 @@ export default function IdVerificationContextProvider({ children }) {
}, [authenticatedUser]);
const [optimizelyExperimentName, setOptimizelyExperimentName] = useState('');
+ const [shouldUseCamera, setShouldUseCamera] = useState(false);
const contextValue = {
existingIdVerification,
@@ -89,16 +90,19 @@ export default function IdVerificationContextProvider({ children }) {
nameOnAccount: authenticatedUser.name,
profileDataManager,
optimizelyExperimentName,
+ shouldUseCamera,
setExistingIdVerification,
setFacePhotoFile,
setIdPhotoFile,
setIdPhotoName,
setOptimizelyExperimentName,
+ setShouldUseCamera,
tryGetUserMedia: async () => {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
setMediaAccess(MEDIA_ACCESS.GRANTED);
setMediaStream(stream);
+ setShouldUseCamera(true);
// stop the stream, as we are not using it yet
const tracks = stream.getTracks();
tracks.forEach(track => track.stop());
diff --git a/src/id-verification/IdVerificationPage.jsx b/src/id-verification/IdVerificationPage.jsx
index 278d920..6a44f9e 100644
--- a/src/id-verification/IdVerificationPage.jsx
+++ b/src/id-verification/IdVerificationPage.jsx
@@ -11,6 +11,7 @@ import './getUserMediaShim';
import IdVerificationContextProvider from './IdVerificationContextProvider';
import ReviewRequirementsPanel from './panels/ReviewRequirementsPanel';
+import ChooseModePanel from './panels/ChooseModePanel';
import RequestCameraAccessPanel from './panels/RequestCameraAccessPanel';
import PortraitPhotoContextPanel from './panels/PortraitPhotoContextPanel';
import TakePortraitPhotoPanel from './panels/TakePortraitPhotoPanel';
@@ -52,6 +53,7 @@ function IdVerificationPage(props) {
+
diff --git a/src/id-verification/ImageFileUpload.jsx b/src/id-verification/ImageFileUpload.jsx
index e4fc982..2f966a4 100644
--- a/src/id-verification/ImageFileUpload.jsx
+++ b/src/id-verification/ImageFileUpload.jsx
@@ -27,7 +27,7 @@ export default function ImageFileUpload({ onFileChange, intl }) {
<>
diff --git a/src/id-verification/panels/ChooseModePanel.jsx b/src/id-verification/panels/ChooseModePanel.jsx
new file mode 100644
index 0000000..d9bfb7f
--- /dev/null
+++ b/src/id-verification/panels/ChooseModePanel.jsx
@@ -0,0 +1,60 @@
+import React, { useContext } from 'react';
+import { Link } from 'react-router-dom';
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import { Form } from '@edx/paragon';
+
+import { useNextPanelSlug } from '../routing-utilities';
+import BasePanel from './BasePanel';
+import IdVerificationContext from '../IdVerificationContext';
+import messages from '../IdVerification.messages';
+
+function ChooseModePanel(props) {
+ const panelSlug = 'choose-mode';
+ const { shouldUseCamera, setShouldUseCamera } = useContext(IdVerificationContext);
+
+ function onPhotoModeChange(value) {
+ setShouldUseCamera(value);
+ }
+
+ return (
+
+