From 5d09127cb1272009402e0f170ab52ea25cd21d9f Mon Sep 17 00:00:00 2001 From: Matt Bemis Date: Fri, 11 Oct 2024 18:49:10 -0400 Subject: [PATCH] [JN-1294] In-person kit i18n (#1138) --- .../seed/i18n/dev/languageTexts.json | 35 +++++++++- .../resources/seed/i18n/en/languageTexts.json | 35 +++++++++- .../resources/seed/i18n/es/languageTexts.json | 35 +++++++++- .../src/study/kits/KitEnrolleeSelection.tsx | 6 +- ui-core/src/participant/ParticipantNavbar.tsx | 2 +- ui-participant/src/hub/kit/KitBanner.test.tsx | 24 +++++-- ui-participant/src/hub/kit/KitBanner.tsx | 5 +- ui-participant/src/hub/kit/KitsPage.test.tsx | 22 +++--- ui-participant/src/hub/kit/KitsPage.tsx | 68 ++++++++++++------- .../kit/in-person/KitInstructions.test.tsx | 43 +++++++----- .../src/hub/kit/in-person/KitInstructions.tsx | 58 ++++++++-------- 11 files changed, 233 insertions(+), 100 deletions(-) diff --git a/populate/src/main/resources/seed/i18n/dev/languageTexts.json b/populate/src/main/resources/seed/i18n/dev/languageTexts.json index 247e1a0218..f9157a6093 100644 --- a/populate/src/main/resources/seed/i18n/dev/languageTexts.json +++ b/populate/src/main/resources/seed/i18n/dev/languageTexts.json @@ -101,5 +101,38 @@ {"keyName": "pageNotFoundMessage", "text": "DEV_If you believe this is an error, please contact ${studyContactEmail}", "language": "dev"}, {"keyName": "pageNotFoundReturnHome", "text": "DEV_Return to the home page", "language": "dev"}, {"keyName": "authErrorPageTitle", "text": "DEV_Something went wrong", "language": "dev"}, - {"keyName": "authErrorPageMessage", "text": "DEV_There was an issue with our authentication service. Please try again. If the problem persists, please contact ${studyContactEmail}.", "language": "dev"} + {"keyName": "authErrorPageMessage", "text": "DEV_There was an issue with our authentication service. Please try again. If the problem persists, please contact ${studyContactEmail}.", "language": "dev"}, + {"keyName": "navbarSampleKits", "text": "DEV_Sample Kits", "language": "dev"}, + {"keyName": "kitsPageTitle", "text": "DEV_Sample collection kits", "language": "dev"}, + {"keyName": "kitsPageDescription", "text": "DEV_Sample collection kits are a valuable part of the study process and can help provide researchers with important insights. Below you will find the status of all kits that have been provided to you.", "language": "dev"}, + {"keyName": "kitsPageInPersonTitle", "text": "DEV_Provide a sample in-person", "language": "dev"}, + {"keyName": "kitsPageInPersonDescription", "text": "DEV_This study is currently offering the option to complete a sample collection kit in-person.", "language": "dev"}, + {"keyName": "kitsPageInPersonCompleteButton", "text": "DEV_Complete a kit in-person", "language": "dev"}, + {"keyName": "kitsPageYourKitsTitle", "text": "DEV_Your kits", "language": "dev"}, + {"keyName": "kitsPageStatusPreparing", "text": "DEV_Preparing", "language": "dev"}, + {"keyName": "kitsPageStatusShipped", "text": "DEV_Shipped", "language": "dev"}, + {"keyName": "kitsPageStatusReturned", "text": "DEV_Returned", "language": "dev"}, + {"keyName": "kitsPageStatusCreated", "text": "DEV_Created", "language": "dev"}, + {"keyName": "kitsPageStatusCollected", "text": "DEV_Collected", "language": "dev"}, + {"keyName": "kitsPageNoKits", "text": "DEV_You do not have any sample collection kits at this time.", "language": "dev"}, + {"keyName": "kitsInPersonTitle", "text": "DEV_Sample kit instructions", "language": "dev"}, + {"keyName": "kitsInPersonDescription", "text": "DEV_If you are completing a sample collection kit in-person, please follow the instructions provided by a member of the study team. Any additional information that you may need, such as your unique participant identifier, will be provided below.", "language": "dev"}, + {"keyName": "kitsInPersonSubDescription", "text": "DEV_If you have any questions, please ask a member of the study team.", "language": "dev"}, + {"keyName": "kitsInPersonYourKitTitle", "text": "DEV_Your sample collection kit", "language": "dev"}, + {"keyName": "kitsInPersonYourKitDescription", "text": "DEV_A member of the team has provided you with a sample collection kit. This sample kit is associated with your account. If you are assisting someone else with their sample collection kit, please ensure that each participant completes the sample collection kit that was assigned to them.", "language": "dev"}, + {"keyName": "kitsInPersonYourKitIdentifier", "text": "DEV_Your kit identifier", "language": "dev"}, + {"keyName": "kitsInPersonReturnToDashboard", "text": "DEV_Return to dashboard", "language": "dev"}, + {"keyName": "kitsInPersonRefreshPage", "text": "DEV_Refresh", "language": "dev"}, + {"keyName": "kitsInPersonConsentRequiredTitle", "text": "DEV_Consent Required", "language": "dev"}, + {"keyName": "kitsInPersonConsentRequiredDescription", "text": "DEV_Before completing a sample collection kit, you must first be enrolled in the study. If of interest, you may find and sign the consent form via the link below.", "language": "dev"}, + {"keyName": "kitsInPersonStartConsent", "text": "DEV_Start Consent", "language": "dev"}, + {"keyName": "kitsInPersonError", "text": "DEV_There was an error loading your kit information. Please contact a member of the study team for assistance.", "language": "dev"}, + {"keyName": "kitsInPersonCreatedInstructions", "text": "DEV_After you have completed the sample collection kit, please return it to a member of the study team and allow them to scan your participation code below.", "language": "dev"}, + {"keyName": "kitsInPersonNoKitInstructions", "text": "DEV_To receive a sample collection kit, a member of the study team will scan your unique participation code below to associate a sample kit with your account.", "language": "dev"}, + {"keyName": "kitsInPersonNoKitSubInstructions", "text": "DEV_Once you have received a kit, please refresh this page to view your kit information and receive further instructions.", "language": "dev"}, + {"keyName": "kitsInPersonCollectedDescription", "text": "DEV_A member of the study team has received your sample collection kit. You will receive an email notification when your sample has been processed, and you will be able to view the status of the sample on your study dashboard.", "language": "dev"}, + {"keyName": "kitsInPersonCollectedThankYou", "text": "DEV_Thank you for your participation.", "language": "dev"}, + {"keyName": "kitTypeSaliva", "text": "DEV_Saliva kit", "language": "dev"}, + {"keyName": "kitTypeStool", "text": "DEV_Stool kit", "language": "dev"}, + {"keyName": "kitTypeBlood", "text": "DEV_Blood kit", "language": "dev"} ] diff --git a/populate/src/main/resources/seed/i18n/en/languageTexts.json b/populate/src/main/resources/seed/i18n/en/languageTexts.json index 6801c01284..0fdeb988f3 100644 --- a/populate/src/main/resources/seed/i18n/en/languageTexts.json +++ b/populate/src/main/resources/seed/i18n/en/languageTexts.json @@ -101,5 +101,38 @@ {"keyName": "pageNotFoundMessage", "text": "If you believe this is an error, please contact ${studyContactEmail}", "language": "en"}, {"keyName": "pageNotFoundReturnHome", "text": "Return to the home page", "language": "en"}, {"keyName": "authErrorPageTitle", "text": "Something went wrong", "language": "en"}, - {"keyName": "authErrorPageMessage", "text": "There was an issue with our authentication service. Please try again. If the problem persists, please contact ${studyContactEmail}.", "language": "en"} + {"keyName": "authErrorPageMessage", "text": "There was an issue with our authentication service. Please try again. If the problem persists, please contact ${studyContactEmail}.", "language": "en"}, + {"keyName": "navbarSampleKits", "text": "Sample Kits", "language": "en"}, + {"keyName": "kitsPageTitle", "text": "Sample collection kits", "language": "en"}, + {"keyName": "kitsPageDescription", "text": "Sample collection kits are a valuable part of the study process and can help provide researchers with important insights. Below you will find the status of all kits that have been provided to you.", "language": "en"}, + {"keyName": "kitsPageInPersonTitle", "text": "Provide a sample in-person", "language": "en"}, + {"keyName": "kitsPageInPersonDescription", "text": "This study is currently offering the option to complete a sample collection kit in-person.", "language": "en"}, + {"keyName": "kitsPageInPersonCompleteButton", "text": "Complete a kit in-person", "language": "en"}, + {"keyName": "kitsPageYourKitsTitle", "text": "Your kits", "language": "en"}, + {"keyName": "kitsPageStatusPreparing", "text": "Preparing", "language": "en"}, + {"keyName": "kitsPageStatusShipped", "text": "Shipped", "language": "en"}, + {"keyName": "kitsPageStatusReturned", "text": "Returned", "language": "en"}, + {"keyName": "kitsPageStatusCreated", "text": "Created", "language": "en"}, + {"keyName": "kitsPageStatusCollected", "text": "Collected", "language": "en"}, + {"keyName": "kitsPageNoKits", "text": "You do not have any sample collection kits at this time.", "language": "en"}, + {"keyName": "kitsInPersonTitle", "text": "Sample kit instructions", "language": "en"}, + {"keyName": "kitsInPersonDescription", "text": "If you are completing a sample collection kit in-person, please follow the instructions provided by a member of the study team. Any additional information that you may need, such as your unique participant identifier, will be provided below.", "language": "en"}, + {"keyName": "kitsInPersonSubDescription", "text": "If you have any questions, please ask a member of the study team.", "language": "en"}, + {"keyName": "kitsInPersonYourKitTitle", "text": "Your sample collection kit", "language": "en"}, + {"keyName": "kitsInPersonYourKitDescription", "text": "A member of the team has provided you with a sample collection kit. This sample kit is associated with your account. If you are assisting someone else with their sample collection kit, please ensure that each participant completes the sample collection kit that was assigned to them.", "language": "en"}, + {"keyName": "kitsInPersonYourKitIdentifier", "text": "Your kit identifier", "language": "en"}, + {"keyName": "kitsInPersonReturnToDashboard", "text": "Return to dashboard", "language": "en"}, + {"keyName": "kitsInPersonRefreshPage", "text": "Refresh", "language": "en"}, + {"keyName": "kitsInPersonConsentRequiredTitle", "text": "Consent Required", "language": "en"}, + {"keyName": "kitsInPersonConsentRequiredDescription", "text": "Before completing a sample collection kit, you must first be enrolled in the study. If of interest, you may find and sign the consent form via the link below.", "language": "en"}, + {"keyName": "kitsInPersonStartConsent", "text": "Start Consent", "language": "en"}, + {"keyName": "kitsInPersonError", "text": "There was an error loading your kit information. Please contact a member of the study team for assistance.", "language": "en"}, + {"keyName": "kitsInPersonCreatedInstructions", "text": "After you have completed the sample collection kit, please return it to a member of the study team and allow them to scan your participation code below.", "language": "en"}, + {"keyName": "kitsInPersonNoKitInstructions", "text": "To receive a sample collection kit, a member of the study team will scan your unique participation code below to associate a sample kit with your account.", "language": "en"}, + {"keyName": "kitsInPersonNoKitSubInstructions", "text": "Once you have received a kit, please refresh this page to view your kit information and receive further instructions.", "language": "en"}, + {"keyName": "kitsInPersonCollectedDescription", "text": "A member of the study team has received your sample collection kit. You will receive an email notification when your sample has been processed, and you will be able to view the status of the sample on your study dashboard.", "language": "en"}, + {"keyName": "kitsInPersonCollectedThankYou", "text": "Thank you for your participation.", "language": "en"}, + {"keyName": "kitTypeSaliva", "text": "Saliva kit", "language": "en"}, + {"keyName": "kitTypeStool", "text": "Stool kit", "language": "en"}, + {"keyName": "kitTypeBlood", "text": "Blood kit", "language": "en"} ] diff --git a/populate/src/main/resources/seed/i18n/es/languageTexts.json b/populate/src/main/resources/seed/i18n/es/languageTexts.json index 5f250d3f14..3b5c875313 100644 --- a/populate/src/main/resources/seed/i18n/es/languageTexts.json +++ b/populate/src/main/resources/seed/i18n/es/languageTexts.json @@ -101,5 +101,38 @@ {"keyName": "pageNotFoundMessage", "text": "Si cree que se trata de un error, comuníquese con ${studyContactEmail}", "language": "es"}, {"keyName": "pageNotFoundReturnHome", "text": "Regresar a la página de inicio", "language": "es"}, {"keyName": "authErrorPageTitle", "text": "Algo salió mal", "language": "es"}, - {"keyName": "authErrorPageMessage", "text": "Hubo un problema con nuestro servicio de autenticación. Inténtalo de nuevo. Si el problema persiste, por favor contacte ${studyContactEmail}", "language": "es"} + {"keyName": "authErrorPageMessage", "text": "Hubo un problema con nuestro servicio de autenticación. Inténtalo de nuevo. Si el problema persiste, por favor contacte ${studyContactEmail}", "language": "es"}, + {"keyName": "navbarSampleKits", "text": "Kits de muestra", "language": "es"}, + {"keyName": "kitsPageTitle", "text": "Kits de recolección de muestras", "language": "es"}, + {"keyName": "kitsPageDescription", "text": "Los kits de recolección de muestras son una parte valiosa del proceso de estudio y pueden ayudar a proporcionar a los investigadores información importante. A continuación, encontrará el estado de todos los kits que se le han proporcionado.", "language": "es"}, + {"keyName": "kitsPageInPersonTitle", "text": "Proporcionar una muestra en persona", "language": "es"}, + {"keyName": "kitsPageInPersonDescription", "text": "Este estudio ofrece actualmente la opción de completar un kit de recolección de muestras en persona.", "language": "es"}, + {"keyName": "kitsPageInPersonCompleteButton", "text": "Completar un kit en persona", "language": "es"}, + {"keyName": "kitsPageYourKitsTitle", "text": "Tus kits", "language": "es"}, + {"keyName": "kitsPageStatusPreparing", "text": "Preparante", "language": "es"}, + {"keyName": "kitsPageStatusShipped", "text": "Enviada", "language": "es"}, + {"keyName": "kitsPageStatusReturned", "text": "Devuelto", "language": "es"}, + {"keyName": "kitsPageStatusCreated", "text": "Creada", "language": "es"}, + {"keyName": "kitsPageStatusCollected", "text": "Coleccionada", "language": "es"}, + {"keyName": "kitsPageNoKits", "text": "No disponemos de ningún kit de recolección de muestras en este momento.", "language": "es"}, + {"keyName": "kitsInPersonTitle", "text": "Instrucciones del kit de muestra", "language": "es"}, + {"keyName": "kitsInPersonDescription", "text": "Si va a completar un kit de recolección de muestras en persona, siga las instrucciones que le proporcione un miembro del equipo del estudio. Cualquier información adicional que pueda necesitar, como su identificador único de participante, se le proporcionará a continuación.", "language": "es"}, + {"keyName": "kitsInPersonSubDescription", "text": "Si tiene alguna pregunta, consulte a un miembro del equipo de estudio.", "language": "es"}, + {"keyName": "kitsInPersonYourKitTitle", "text": "Su kit de recolección de muestras", "language": "es"}, + {"keyName": "kitsInPersonYourKitDescription", "text": "Un miembro del equipo le ha proporcionado un kit de recolección de muestras. Este kit de recolección de muestras está asociado a su cuenta. Si está ayudando a otra persona con su kit de recolección de muestras, asegúrese de que cada participante complete el kit de recolección de muestras que se le asignó.", "language": "es"}, + {"keyName": "kitsInPersonYourKitIdentifier", "text": "Su identificador de kit", "language": "es"}, + {"keyName": "kitsInPersonReturnToDashboard", "text": "Regresar al panel de control", "language": "es"}, + {"keyName": "kitsInPersonRefreshPage", "text": "Refrescar", "language": "es"}, + {"keyName": "kitsInPersonConsentRequiredTitle", "text": "Consentimiento requerido", "language": "es"}, + {"keyName": "kitsInPersonConsentRequiredDescription", "text": "Antes de completar un kit de recolección de muestras, primero debe inscribirse en el estudio. Si está interesado, puede encontrar y firmar el formulario de consentimiento a través del enlace que aparece a continuación.", "language": "es"}, + {"keyName": "kitsInPersonStartConsent", "text": "Iniciar Consentimiento", "language": "es"}, + {"keyName": "kitsInPersonError", "text": "Se produjo un error al cargar la información de su kit. Comuníquese con un miembro del equipo de estudio para obtener ayuda.", "language": "es"}, + {"keyName": "kitsInPersonCreatedInstructions", "text": "Una vez que haya completado el kit de recolección de muestras, devuélvaselo a un miembro del equipo de estudio y permítale escanear su código de participación a continuación.", "language": "es"}, + {"keyName": "kitsInPersonNoKitInstructions", "text": "Para recibir un kit de recolección de muestras, un miembro del equipo de estudio escaneará su código de participación único a continuación para asociar un kit de muestra con su cuenta.", "language": "es"}, + {"keyName": "kitsInPersonNoKitSubInstructions", "text": "Una vez que haya recibido un kit, actualice esta página para ver la información de su kit y recibir más instrucciones.", "language": "es"}, + {"keyName": "kitsInPersonCollectedDescription", "text": "Un miembro del equipo de estudio ha recibido su kit de recolección de muestras. Recibirá una notificación por correo electrónico cuando se haya procesado su muestra y podrá ver el estado de la misma en el panel de control del estudio.", "language": "es"}, + {"keyName": "kitsInPersonCollectedThankYou", "text": "Gracias por su participación.", "language": "es"}, + {"keyName": "kitTypeSaliva", "text": "Kit de saliva", "language": "es"}, + {"keyName": "kitTypeStool", "text": "Kit de heces", "language": "es"}, + {"keyName": "kitTypeBlood", "text": "Kit de sangre", "language": "es"} ] diff --git a/ui-admin/src/study/kits/KitEnrolleeSelection.tsx b/ui-admin/src/study/kits/KitEnrolleeSelection.tsx index 94b4a046fb..3ce023689c 100644 --- a/ui-admin/src/study/kits/KitEnrolleeSelection.tsx +++ b/ui-admin/src/study/kits/KitEnrolleeSelection.tsx @@ -29,7 +29,6 @@ import { enrolleeKitRequestPath } from 'study/participants/enrolleeView/Enrollee import { Button } from 'components/forms/Button' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faPaperPlane, faQrcode } from '@fortawesome/free-solid-svg-icons' -import { useUser } from 'user/UserProvider' type EnrolleeRow = Enrollee & { taskCompletionStatus: Record @@ -54,7 +53,6 @@ export default function KitEnrolleeSelection({ studyEnvContext }: { studyEnvCont { id: 'requiredSurveysComplete', value: true } ]) const [showRequestKitModal, setShowRequestKitModal] = useState(false) - const { user } = useUser() const { isLoading, reload } = useLoadingEffect(async () => { const enrollees = await Api.fetchEnrolleesWithKits( @@ -188,9 +186,9 @@ export default function KitEnrolleeSelection({ studyEnvContext }: { studyEnvCont
- { user?.superuser && + - } + } diff --git a/ui-participant/src/hub/kit/KitBanner.test.tsx b/ui-participant/src/hub/kit/KitBanner.test.tsx index 76c131a53b..9a310164c2 100644 --- a/ui-participant/src/hub/kit/KitBanner.test.tsx +++ b/ui-participant/src/hub/kit/KitBanner.test.tsx @@ -3,7 +3,7 @@ import { render, screen } from '@testing-library/react' import { mockAssignedKitRequest, mockKitRequest } from 'test-utils/test-participant-factory' import KitBanner from './KitBanner' import { instantToDateString } from '../../util/timeUtils' -import { setupRouterTest } from '@juniper/ui-core' +import { MockI18nProvider, setupRouterTest } from '@juniper/ui-core' describe('HubPageKits', () => { it('renders a sent kit banner', () => { @@ -14,10 +14,13 @@ describe('HubPageKits', () => { mockKitRequest('RECEIVED', 'BLOOD') ] - const { RoutedComponent } = setupRouterTest() + const { RoutedComponent } = setupRouterTest( + + + ) render(RoutedComponent) // with two kits, one sent and one received, we should only see the sent kit - expect(screen.getByText('Sample collection kits')).toBeInTheDocument() + expect(screen.getByText('{kitsPageTitle}')).toBeInTheDocument() expect(screen.getByText(sentDate)).toBeInTheDocument() expect(screen.getByText('Your saliva kit is on its way.', { exact: false })).toBeInTheDocument() expect(screen.getByText('A sample kit was shipped')).toBeInTheDocument() @@ -30,10 +33,13 @@ describe('HubPageKits', () => { const sentDate = instantToDateString(mockKitRequest.createdAt) - const { RoutedComponent } = setupRouterTest() + const { RoutedComponent } = setupRouterTest( + + + ) render(RoutedComponent) - expect(screen.getByText('Sample collection kits')).toBeInTheDocument() + expect(screen.getByText('{kitsPageTitle}')).toBeInTheDocument() expect(screen.getByText(sentDate)).toBeInTheDocument() expect(screen.getByText('You have received a sample kit')).toBeInTheDocument() }) @@ -44,10 +50,14 @@ describe('HubPageKits', () => { const sentDate = instantToDateString(mockKitRequest.createdAt) - const { RoutedComponent } = setupRouterTest() + const { RoutedComponent } = setupRouterTest( + + + + ) render(RoutedComponent) - expect(screen.getByText('Sample collection kits')).toBeInTheDocument() + expect(screen.getByText('{kitsPageTitle}')).toBeInTheDocument() expect(screen.getByText(sentDate)).toBeInTheDocument() expect(screen.getByText('Your sample kit has been received')).toBeInTheDocument() }) diff --git a/ui-participant/src/hub/kit/KitBanner.tsx b/ui-participant/src/hub/kit/KitBanner.tsx index 98162ffa6d..a4b117b155 100644 --- a/ui-participant/src/hub/kit/KitBanner.tsx +++ b/ui-participant/src/hub/kit/KitBanner.tsx @@ -1,7 +1,7 @@ import React from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faCircleCheck, faHandHolding, faQuestion, faTruckFast } from '@fortawesome/free-solid-svg-icons' -import { KitRequest } from '@juniper/ui-core' +import { KitRequest, useI18n } from '@juniper/ui-core' import { NavLink } from 'react-router-dom' import { instantToDateString } from 'util/timeUtils' @@ -43,6 +43,7 @@ const renderHeader = () => { /** Renders kit tasks for the hub page */ export default function KitBanner({ kitRequests }: {kitRequests: KitRequest[]}) { + const { i18n } = useI18n() const hasKitRequests = kitRequests.length > 0 if (!hasKitRequests) { return null @@ -59,7 +60,7 @@ export default function KitBanner({ kitRequests }: {kitRequests: KitRequest[]}) return ( <> -

Sample collection kits

+

{i18n('kitsPageTitle')}

{renderHeader()}
    {kitsToDisplay.map(kitRequest => { diff --git a/ui-participant/src/hub/kit/KitsPage.test.tsx b/ui-participant/src/hub/kit/KitsPage.test.tsx index f3a26e3544..ecb4560e27 100644 --- a/ui-participant/src/hub/kit/KitsPage.test.tsx +++ b/ui-participant/src/hub/kit/KitsPage.test.tsx @@ -1,11 +1,11 @@ import React from 'react' import { render, screen } from '@testing-library/react' -import { asMockedFn, KitRequest, KitRequestStatus, setupRouterTest } from '@juniper/ui-core' +import { asMockedFn, KitRequest, KitRequestStatus, MockI18nProvider, setupRouterTest } from '@juniper/ui-core' import KitsPage from './KitsPage' import { mockEnrollee, mockPortalParticipantUser, mockProfile } from 'test-utils/test-participant-factory' import { useActiveUser } from 'providers/ActiveUserProvider' -import { usePortalEnv } from '../../providers/PortalProvider' -import { mockUsePortalEnv } from '../../test-utils/test-portal-factory' +import { usePortalEnv } from 'providers/PortalProvider' +import { mockUsePortalEnv } from 'test-utils/test-portal-factory' jest.mock('providers/PortalProvider', () => ({ usePortalEnv: jest.fn() })) @@ -68,11 +68,11 @@ const inPersonKitStatusToTestIdMap: { [key in KitRequestStatus]: string[] } = { describe('KitsPage', () => { it('should render a message when there are no kits for an enrollee', () => { asMockedFn(useActiveUser).mockReturnValue(mockActiveUserWithKits([])) - const { RoutedComponent } = setupRouterTest() + const { RoutedComponent } = setupRouterTest() render(RoutedComponent) - expect(screen.getByText('Sample collection kits')).toBeInTheDocument() - expect(screen.getByText('Your kits (0)')).toBeInTheDocument() - expect(screen.getByText('You do not have any sample collection kits at this time.')).toBeInTheDocument() + expect(screen.getByText('{kitsPageTitle}')).toBeInTheDocument() + expect(screen.getByText('{kitsPageYourKitsTitle} (0)')).toBeInTheDocument() + expect(screen.getByText('{kitsPageNoKits}')).toBeInTheDocument() }) mailedKitStatuses.forEach(status => { @@ -93,9 +93,9 @@ describe('KitsPage', () => { skipAddressValidation: false } ])) - const { RoutedComponent } = setupRouterTest() + const { RoutedComponent } = setupRouterTest() render(RoutedComponent) - expect(screen.getByText('Sample collection kits')).toBeInTheDocument() + expect(screen.getByText('{kitsPageTitle}')).toBeInTheDocument() const expectedTestIds = mailedKitStatusToTestIdMap[status] expectedTestIds.forEach(testId => { @@ -122,9 +122,9 @@ describe('KitsPage', () => { skipAddressValidation: false } ])) - const { RoutedComponent } = setupRouterTest() + const { RoutedComponent } = setupRouterTest() render(RoutedComponent) - expect(screen.getByText('Sample collection kits')).toBeInTheDocument() + expect(screen.getByText('{kitsPageTitle}')).toBeInTheDocument() const expectedTestIds = inPersonKitStatusToTestIdMap[status] expectedTestIds.forEach(testId => { diff --git a/ui-participant/src/hub/kit/KitsPage.tsx b/ui-participant/src/hub/kit/KitsPage.tsx index 7cef7f2ff2..e70359db5d 100644 --- a/ui-participant/src/hub/kit/KitsPage.tsx +++ b/ui-participant/src/hub/kit/KitsPage.tsx @@ -1,4 +1,4 @@ -import { Enrollee, KitRequest, KitRequestStatus } from '@juniper/ui-core' +import { Enrollee, KitRequest, KitRequestStatus, KitType, useI18n } from '@juniper/ui-core' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faBoxesPacking, faCircleCheck, faTruckFast } from '@fortawesome/free-solid-svg-icons' import React from 'react' @@ -62,36 +62,40 @@ const getStepCompletion = (kit: KitRequest, step: string) => { } const MailedKitStatusBar = ({ kit }: { kit: KitRequest }) => { + const { i18n } = useI18n() + return (
    - - - + + +
    ) } const InPersonKitStatusBar = ({ kit }: { kit: KitRequest }) => { + const { i18n } = useI18n() + return (
    - - + +
    ) } -const ProgressBar = ({ icon, label, width, complete }: { - icon: IconDefinition, label: string, width: string, complete: boolean +const ProgressBar = ({ stepId, icon, label, width, complete }: { + stepId: string, icon: IconDefinition, label: string, width: string, complete: boolean }) => { return (
    @@ -113,36 +117,41 @@ const EnrolleeKitRequests = ({ enrollee }: { enrollee: Enrollee }) => { studyEnv.environmentName === portalEnv.environmentName))?.study.studyEnvironments[0] const isInPersonKitEnabled = currentStudyEnv?.studyEnvironmentConfig.enableInPersonKits + const { i18n } = useI18n() + return
    -

    Sample collection kits

    +

    + {i18n('kitsPageTitle')} +

    - Sample collection kits are a valuable part of the study process and can help provide researchers with - important insights. Below you will find the status of all kits that have been provided to you. + {i18n('kitsPageDescription')}
    { isInPersonKitEnabled && <> -

    Provide a sample in-person

    +

    + {i18n('kitsPageInPersonTitle')} +

    - This study is currently offering the option to complete a sample collection kit in-person. + {i18n('kitsPageInPersonDescription')}
    - Complete a kit in-person + {i18n('kitsPageInPersonCompleteButton')}
    } -

    Your kits ({visibleKitRequests.length})

    +

    {i18n('kitsPageYourKitsTitle')} ({visibleKitRequests.length})

    {visibleKitRequests.length === 0 ? (
    - You do not have any sample collection kits at this time. + {i18n('kitsPageNoKits')}
    ) : ( visibleKitRequests.map((kit, index) => (
    -
    {kit.kitType.displayName} Kit
    +
    {i18n(kitTypeToI18nKey(kit.kitType))}
    {instantToDateString(kit.createdAt)}
    @@ -156,3 +165,16 @@ const EnrolleeKitRequests = ({ enrollee }: { enrollee: Enrollee }) => {
    } + +const kitTypeToI18nKey = (kitType: KitType) => { + switch (kitType.name) { + case 'SALIVA': + return 'kitTypeSaliva' + case 'BLOOD': + return 'kitTypeBlood' + case 'STOOL': + return 'kitTypeStool' + default: + return 'kitTypeUnknown' + } +} diff --git a/ui-participant/src/hub/kit/in-person/KitInstructions.test.tsx b/ui-participant/src/hub/kit/in-person/KitInstructions.test.tsx index 00e8db057a..ea1143f80f 100644 --- a/ui-participant/src/hub/kit/in-person/KitInstructions.test.tsx +++ b/ui-participant/src/hub/kit/in-person/KitInstructions.test.tsx @@ -1,7 +1,7 @@ import React from 'react' import { act, render, screen } from '@testing-library/react' import KitInstructions from './KitInstructions' -import { asMockedFn, setupRouterTest } from '@juniper/ui-core' +import { asMockedFn, MockI18nProvider, setupRouterTest } from '@juniper/ui-core' import { useActiveUser } from 'providers/ActiveUserProvider' import { mockUseActiveUser } from 'test-utils/user-mocking-utils' import { mockAssignedKitRequest, mockEnrollee } from 'test-utils/test-participant-factory' @@ -24,14 +24,16 @@ describe('KitInstructions', () => { }) const { RoutedComponent } = setupRouterTest( - ) + + + ) await act(async () => { render(RoutedComponent) }) - expect(screen.getByText('Sample kit instructions')).toBeInTheDocument() - expect(screen.queryByText('Consent Required')).not.toBeInTheDocument() - expect(screen.getByText('Provide a sample in-person')).toBeInTheDocument() + expect(screen.getByText('{kitsInPersonTitle}')).toBeInTheDocument() + expect(screen.queryByText('{kitsInPersonConsentRequiredTitle}')).not.toBeInTheDocument() + expect(screen.getByText('{kitsPageInPersonTitle}')).toBeInTheDocument() expect(screen.getByLabelText('shortcode-qr')).toBeInTheDocument() }) @@ -48,14 +50,16 @@ describe('KitInstructions', () => { }) const { RoutedComponent } = setupRouterTest( - ) + + + ) await act(async () => { render(RoutedComponent) }) - expect(screen.getByText('Sample kit instructions')).toBeInTheDocument() - expect(screen.queryByText('Consent Required')).not.toBeInTheDocument() - expect(screen.getByText('Your sample collection kit')).toBeInTheDocument() + expect(screen.getByText('{kitsInPersonTitle}')).toBeInTheDocument() + expect(screen.queryByText('{kitsInPersonConsentRequiredTitle}')).not.toBeInTheDocument() + expect(screen.getByText('{kitsInPersonYourKitTitle}')).toBeInTheDocument() expect(screen.getByDisplayValue('assigned-label')).toBeInTheDocument() expect(screen.getByLabelText('shortcode-qr')).toBeInTheDocument() }) @@ -73,18 +77,19 @@ describe('KitInstructions', () => { }) const { RoutedComponent } = setupRouterTest( - ) + + + ) await act(async () => { render(RoutedComponent) }) - expect(screen.getByText('Sample kit instructions')).toBeInTheDocument() - expect(screen.queryByText('Consent Required')).not.toBeInTheDocument() - expect(screen.getByText('Your sample collection kit')).toBeInTheDocument() + expect(screen.getByText('{kitsInPersonTitle}')).toBeInTheDocument() + expect(screen.queryByText('{kitsInPersonConsentRequiredTitle}')).not.toBeInTheDocument() + expect(screen.getByText('{kitsInPersonYourKitTitle}')).toBeInTheDocument() expect(screen.queryByDisplayValue('assigned-label')).not.toBeInTheDocument() expect(screen.queryByLabelText('shortcode-qr')).not.toBeInTheDocument() - expect(screen.getByText('A member of the study team has received your sample collection kit.', - { exact: false })).toBeInTheDocument() + expect(screen.getByText('{kitsInPersonCollectedDescription}')).toBeInTheDocument() }) it('renders Consent Required message if enrollee has not consented', () => { @@ -100,11 +105,13 @@ describe('KitInstructions', () => { }) const { RoutedComponent } = setupRouterTest( - ) + + + ) render(RoutedComponent) - expect(screen.getByText('Sample kit instructions')).toBeInTheDocument() - expect(screen.getByText('Consent Required')).toBeInTheDocument() + expect(screen.getByText('{kitsInPersonTitle}')).toBeInTheDocument() + expect(screen.getByText('{kitsInPersonConsentRequiredTitle}')).toBeInTheDocument() expect(screen.queryByLabelText('shortcode-qr')).not.toBeInTheDocument() }) }) diff --git a/ui-participant/src/hub/kit/in-person/KitInstructions.tsx b/ui-participant/src/hub/kit/in-person/KitInstructions.tsx index 5e3aa6f12e..2abe46659a 100644 --- a/ui-participant/src/hub/kit/in-person/KitInstructions.tsx +++ b/ui-participant/src/hub/kit/in-person/KitInstructions.tsx @@ -1,7 +1,7 @@ import React from 'react' import { Link } from 'react-router-dom' import { useActiveUser } from 'providers/ActiveUserProvider' -import { Enrollee, KitRequest } from '@juniper/ui-core' +import { Enrollee, KitRequest, useI18n } from '@juniper/ui-core' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faCircleExclamation, faRefresh } from '@fortawesome/free-solid-svg-icons' import { EnrolleeShortcodeQR } from './EnrolleeShortcodeQR' @@ -10,6 +10,7 @@ import { EnrolleeShortcodeQR } from './EnrolleeShortcodeQR' export default function KitInstructions() { const { ppUser, enrollees } = useActiveUser() const activeEnrollee = enrollees.find(enrollee => enrollee.profileId === ppUser?.profileId) + const { i18n } = useI18n() return
    -

    Sample kit instructions

    +

    {i18n('kitsInPersonTitle')}

    - If you are completing a sample collection kit in-person, please follow the instructions provided - by a member of the study team. Any additional information that you may need, such as your unique - participant identifier, will be provided below. + {i18n('kitsInPersonDescription')}
    - If you have any questions, please ask a member of the study team. + {i18n('kitsInPersonSubDescription')}
    {activeEnrollee ? :
    - No enrollee found. Please contact a member of the study team for assistance. + {i18n('kitsInPersonError')}
    }
    @@ -59,16 +58,18 @@ const KitContent = ({ enrollee }: { enrollee: Enrollee }) => { } const UnconsentedKitView = () => { + const { i18n } = useI18n() return (<>

    - Consent Required + + {i18n('kitsInPersonConsentRequiredTitle')}

    - Before completing a sample collection kit, you must read and sign the study consent form. + {i18n('kitsInPersonConsentRequiredDescription')}
    - Start Consent + {i18n('kitsInPersonStartConsent')}
    @@ -76,24 +77,23 @@ const UnconsentedKitView = () => { } const NoActiveKitView = ({ enrollee }: { enrollee: Enrollee }) => { + const { i18n } = useI18n() return ( <>

    - Provide a sample in-person + {i18n('kitsPageInPersonTitle')}

    - To receive a sample collection kit, a member of the study team will scan your unique participation code - below to associate a sample kit with your account. + {i18n('kitsInPersonNoKitInstructions')}
    - Once you have received a kit, please refresh this page to view your kit information and - receive further instructions. + {i18n('kitsInPersonNoKitSubInstructions')}
    @@ -101,22 +101,21 @@ const NoActiveKitView = ({ enrollee }: { enrollee: Enrollee }) => { } const CollectedKitView = () => { + const { i18n } = useI18n() return ( <>

    - Your sample collection kit + {i18n('kitsInPersonYourKitTitle')}

    - A member of the study team has received your sample collection kit. - You will receive an email notification when your sample has been processed, and you will be able - to view the status of the sample on your study dashboard. + {i18n('kitsInPersonCollectedDescription')}
    - Thank you for your participation. + {i18n('kitsInPersonCollectedThankYou')}
    - Return to Dashboard + {i18n('kitsInPersonReturnToDashboard')}
    @@ -124,18 +123,16 @@ const CollectedKitView = () => { } const DistributedKitView = ({ enrollee, activeKit }: { enrollee: Enrollee, activeKit: KitRequest }) => { + const { i18n } = useI18n() return ( <>

    - Your sample collection kit + {i18n('kitsInPersonYourKitTitle')}

    - A member of the team has provided you with a sample collection kit. - This sample kit is associated with your account. If you are assisting someone else with their - sample collection kit, please ensure that each participant completes the sample collection - kit that was assigned to them. + {i18n('kitsInPersonYourKitDescription')}
    - +
    - After you have completed the sample collection kit, please return it to a member of the study team - and allow them to scan your participation code below. + {i18n('kitsInPersonCreatedInstructions')}
    - Return to Dashboard + {i18n('kitsInPersonReturnToDashboard')}