diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js
index 63bcdc8fdd6..e4f69fe1dbc 100644
--- a/app/assets/config/manifest.js
+++ b/app/assets/config/manifest.js
@@ -3,6 +3,7 @@
//= link application.css
//= link i18n-strings.js
+//= link asset-strings.js
//= link email.css
//= link es5-shim.min.js
//= link html5shiv.js
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index be141f9340b..45282728b53 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -1,2 +1,3 @@
//= require i18n-strings
//= require local-time
+//= require asset-strings
diff --git a/app/assets/javascripts/asset-strings.js.erb b/app/assets/javascripts/asset-strings.js.erb
new file mode 100644
index 00000000000..dab4649d27d
--- /dev/null
+++ b/app/assets/javascripts/asset-strings.js.erb
@@ -0,0 +1,12 @@
+window.LoginGov = window.LoginGov || {}
+<% image_keys = [
+ 'idv/phone.png'
+] %>
+
+window.LoginGov.AssetStrings = {
+ images: {}
+};
+
+<% image_keys.each do |key| %>
+ window.LoginGov.AssetStrings.images['<%=key %>'] = '<%= ActionController::Base.helpers.image_path(key) %>';
+<% end %>
diff --git a/app/assets/javascripts/i18n-strings.js.erb b/app/assets/javascripts/i18n-strings.js.erb
index e96923d8398..1041c540cec 100644
--- a/app/assets/javascripts/i18n-strings.js.erb
+++ b/app/assets/javascripts/i18n-strings.js.erb
@@ -45,7 +45,8 @@ window.LoginGov = window.LoginGov || {};
'zxcvbn.feedback.this_is_a_very_common_password',
'zxcvbn.feedback.this_is_similar_to_a_commonly_used_password',
'zxcvbn.feedback.for_a_stronger_password_use_a_few_words_separated_by_spaces_but_avoid_common_phrases',
- 'zxcvbn.feedback.use_a_longer_keyboard_pattern_with_more_turns'
+ 'zxcvbn.feedback.use_a_longer_keyboard_pattern_with_more_turns',
+ 'doc_auth.headings.welcome'
] %>
window.LoginGov.I18n = {
diff --git a/app/javascript/app/document-capture/components/document-capture.jsx b/app/javascript/app/document-capture/components/document-capture.jsx
index f02d1277032..ac74d489f58 100644
--- a/app/javascript/app/document-capture/components/document-capture.jsx
+++ b/app/javascript/app/document-capture/components/document-capture.jsx
@@ -1,5 +1,11 @@
+import React from 'react';
+import useI18n from '../hooks/use-i18n';
+import { useImage } from '../hooks/use-assets';
+
function DocumentCapture() {
- return 'Document Capture';
+ const t = useI18n();
+ const imageTag = useImage();
+ return
;
}
export default DocumentCapture;
diff --git a/app/javascript/app/document-capture/context/assets.js b/app/javascript/app/document-capture/context/assets.js
new file mode 100644
index 00000000000..91173cbe6d9
--- /dev/null
+++ b/app/javascript/app/document-capture/context/assets.js
@@ -0,0 +1,5 @@
+import { createContext } from 'react';
+
+const AssetContext = createContext({});
+
+export default AssetContext;
diff --git a/app/javascript/app/document-capture/context/i18n.js b/app/javascript/app/document-capture/context/i18n.js
new file mode 100644
index 00000000000..0d3df099687
--- /dev/null
+++ b/app/javascript/app/document-capture/context/i18n.js
@@ -0,0 +1,5 @@
+import { createContext } from 'react';
+
+const I18nContext = createContext({});
+
+export default I18nContext;
diff --git a/app/javascript/app/document-capture/hooks/use-assets.js b/app/javascript/app/document-capture/hooks/use-assets.js
new file mode 100644
index 00000000000..e6aac5bc067
--- /dev/null
+++ b/app/javascript/app/document-capture/hooks/use-assets.js
@@ -0,0 +1,14 @@
+import { useContext } from 'react';
+import AssetContext from '../context/assets';
+
+function useImage() {
+ const strings = useContext(AssetContext);
+ const imageStrings = strings.images || {};
+ const imageTag = (key) => {
+ const resolvedImage = imageStrings[key];
+ return resolvedImage !== undefined ? resolvedImage : key;
+ };
+ return imageTag;
+}
+
+export { useImage };
diff --git a/app/javascript/app/document-capture/hooks/use-i18n.js b/app/javascript/app/document-capture/hooks/use-i18n.js
new file mode 100644
index 00000000000..36885150d30
--- /dev/null
+++ b/app/javascript/app/document-capture/hooks/use-i18n.js
@@ -0,0 +1,10 @@
+import { useContext } from 'react';
+import I18nContext from '../context/i18n';
+
+function useI18n() {
+ const strings = useContext(I18nContext);
+ const t = (key) => (Object.prototype.hasOwnProperty.call(strings, key) ? strings[key] : key); // eslint-disable-line
+ return t;
+}
+
+export default useI18n;
diff --git a/app/javascript/packs/document-capture.jsx b/app/javascript/packs/document-capture.jsx
index d40212cbd71..1fabf802f02 100644
--- a/app/javascript/packs/document-capture.jsx
+++ b/app/javascript/packs/document-capture.jsx
@@ -1,10 +1,18 @@
import React from 'react';
import { render } from 'react-dom';
import DocumentCapture from '../app/document-capture/components/document-capture';
+import AssetContext from '../app/document-capture/context/assets';
+import I18nContext from '../app/document-capture/context/i18n';
+
+const { I18n: i18n, AssetStrings } = window.LoginGov;
const appRoot = document.getElementById('document-capture-form');
appRoot.innerHTML = '';
render(
- ,
+
+
+
+
+ ,
appRoot,
);
diff --git a/spec/javascripts/app/document-capture/components/document-capture-spec.jsx b/spec/javascripts/app/document-capture/components/document-capture-spec.jsx
index f1b7b0dac71..30f0610ba43 100644
--- a/spec/javascripts/app/document-capture/components/document-capture-spec.jsx
+++ b/spec/javascripts/app/document-capture/components/document-capture-spec.jsx
@@ -7,10 +7,9 @@ describe('document-capture/components/document-capture', () => {
useDOM();
it('renders', () => {
- const { getByText } = render();
+ const { getByAltText } = render();
- const button = getByText('Document Capture');
-
- expect(button).to.be.ok();
+ const img = getByAltText('doc_auth.headings.welcome');
+ expect(img).to.be.ok();
});
});
diff --git a/spec/javascripts/app/document-capture/context/i18n-spec.jsx b/spec/javascripts/app/document-capture/context/i18n-spec.jsx
new file mode 100644
index 00000000000..33ba21b6656
--- /dev/null
+++ b/spec/javascripts/app/document-capture/context/i18n-spec.jsx
@@ -0,0 +1,16 @@
+import React, { useContext } from 'react';
+import { render } from '@testing-library/react';
+import I18nContext from '../../../../../app/javascript/app/document-capture/context/i18n';
+import { useDOM } from '../../../support/dom';
+
+describe('document-capture/context/i18n', () => {
+ useDOM();
+
+ const ContextValue = () => JSON.stringify(useContext(I18nContext));
+
+ it('defaults to empty object', () => {
+ const { container } = render();
+
+ expect(container.textContent).to.equal('{}');
+ });
+});
diff --git a/spec/javascripts/app/document-capture/hooks/use-i18n-spec.jsx b/spec/javascripts/app/document-capture/hooks/use-i18n-spec.jsx
new file mode 100644
index 00000000000..d625823dfed
--- /dev/null
+++ b/spec/javascripts/app/document-capture/hooks/use-i18n-spec.jsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import { render } from '@testing-library/react';
+import I18nContext from '../../../../../app/javascript/app/document-capture/context/i18n';
+import useI18n from '../../../../../app/javascript/app/document-capture/hooks/use-i18n';
+import { useDOM } from '../../../support/dom';
+
+describe('document-capture/hooks/use-i18n', () => {
+ useDOM();
+
+ const LocalizedString = ({ stringKey }) => useI18n()(stringKey);
+
+ it('returns localized key value', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(container.textContent).to.equal('translation');
+ });
+
+ it('falls back to key value', () => {
+ const { container } = render();
+
+ expect(container.textContent).to.equal('sample');
+ });
+});