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 {t('doc_auth.headings.welcome')}; } 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'); + }); +});