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..70c91c459df 100644 --- a/app/javascript/app/document-capture/components/document-capture.jsx +++ b/app/javascript/app/document-capture/components/document-capture.jsx @@ -1,5 +1,9 @@ +import useI18n from '../hooks/use-i18n'; + function DocumentCapture() { - return 'Document Capture'; + const t = useI18n(); + + return t('doc_auth.headings.welcome'); } export default DocumentCapture; 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-i18n.js b/app/javascript/app/document-capture/hooks/use-i18n.js new file mode 100644 index 00000000000..f8017bbddb5 --- /dev/null +++ b/app/javascript/app/document-capture/hooks/use-i18n.js @@ -0,0 +1,12 @@ +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 + ); + return t; +} + +export default useI18n; diff --git a/app/javascript/packs/document-capture.jsx b/app/javascript/packs/document-capture.jsx index d40212cbd71..26e77f3dde9 100644 --- a/app/javascript/packs/document-capture.jsx +++ b/app/javascript/packs/document-capture.jsx @@ -1,10 +1,15 @@ import React from 'react'; import { render } from 'react-dom'; import DocumentCapture from '../app/document-capture/components/document-capture'; +import I18nContext from '../app/document-capture/context/i18n'; + +const { I18n: i18n } = 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..eeed86a6570 100644 --- a/spec/javascripts/app/document-capture/components/document-capture-spec.jsx +++ b/spec/javascripts/app/document-capture/components/document-capture-spec.jsx @@ -9,7 +9,7 @@ describe('document-capture/components/document-capture', () => { it('renders', () => { const { getByText } = render(); - const button = getByText('Document Capture'); + const button = getByText('doc_auth.headings.welcome'); expect(button).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'); + }); +});