Skip to content

Commit 04151ba

Browse files
committed
feat(i18n): extract text from admin results page
1 parent 74f29af commit 04151ba

File tree

14 files changed

+369
-206
lines changed

14 files changed

+369
-206
lines changed

frontend/src/features/admin-form/responses/IndividualResponsePage/IndividualResponseNavbar.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ export const IndividualResponseNavbar = (): JSX.Element => {
113113
return `..?${searchParams}`
114114
}, [lastNavPage, lastNavSubmissionId])
115115

116-
const { t } = useTranslation()
116+
const { t } = useTranslation('translation', {
117+
keyPrefix: 'features.adminForm.responses.individualResponse',
118+
})
117119

118120
const { user } = useUser()
119121
const gb = useGrowthBook()
@@ -159,20 +161,20 @@ export const IndividualResponseNavbar = (): JSX.Element => {
159161
to={backLink}
160162
>
161163
<Icon as={BiLeftArrowAlt} fontSize="1.5rem" mr="0.5rem" />
162-
{t('features.adminForm.responses.individualResponse.backToList')}
164+
{t('backToList')}
163165
</Link>
164166
</Flex>
165167
<Flex gridArea="respondent" justify="center" align="center">
166168
<Skeleton isLoaded={!isLoading}>
167169
<Stack direction="row" justify="center" align="center">
168170
<Text textStyle="h2" as="h2">
169-
{t('features.common.response')}
171+
{t('features.common.response', { ns: 'translation', keyPrefix: '' })}
170172
{currentResponseNumber ? ` #${currentResponseNumber}` : ''}
171173
</Text>
172174
{isAdminPrintPdfEnabled && (
173175
<Box>
174176
<IconButton
175-
aria-label="Print"
177+
aria-label={t('individualResponseNavbar.printAriaLabel')}
176178
icon={<FaRegFilePdf />}
177179
isLoading={isLoading || isFormLoading}
178180
onClick={() => {
@@ -201,17 +203,13 @@ export const IndividualResponseNavbar = (): JSX.Element => {
201203
isDisabled={!prevSubmissionId || isAnyFetching}
202204
onClick={handleNavigatePrev}
203205
icon={<BiChevronLeft />}
204-
aria-label={t(
205-
'features.adminForm.responses.individualResponse.previousSubmission',
206-
)}
206+
aria-label={t('previousSubmission')}
207207
/>
208208
<IconButton
209209
isDisabled={!nextSubmissionId || isAnyFetching}
210210
onClick={handleNavigateNext}
211211
icon={<BiChevronRight />}
212-
aria-label={t(
213-
'features.adminForm.responses.individualResponse.nextSubmission',
214-
)}
212+
aria-label={t('nextSubmission')}
215213
/>
216214
</ButtonGroup>
217215
</Grid>

frontend/src/features/admin-form/responses/IndividualResponsePage/IndividualResponsePage.tsx

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ const StackRow = ({
113113
}
114114

115115
export const IndividualResponsePage = (): JSX.Element => {
116-
const { t } = useTranslation()
116+
const { t } = useTranslation('translation', {
117+
keyPrefix: 'features.adminForm.responses.individualResponse',
118+
})
117119
const { submissionId, formId } = useParams()
118120
if (!submissionId) throw new Error('Missing submissionId')
119121
if (!formId) throw new Error('Missing formId')
@@ -168,12 +170,8 @@ export const IndividualResponsePage = (): JSX.Element => {
168170
return (
169171
<SecretKeyVerification
170172
heroSvg={<FormActivationSvg />}
171-
ctaText={t(
172-
'features.adminForm.responses.individualResponse.secretKeyVerification.ctaText',
173-
)}
174-
label={t(
175-
'features.adminForm.responses.individualResponse.secretKeyVerification.label',
176-
)}
173+
ctaText={t('secretKeyVerification.ctaText')}
174+
label={t('secretKeyVerification.label')}
177175
/>
178176
)
179177

@@ -210,15 +208,15 @@ export const IndividualResponsePage = (): JSX.Element => {
210208
>
211209
<Stack bg="primary.100" p="1.5rem" textStyle="monospace">
212210
<StackRow
213-
label="Response ID"
211+
label={t('labels.responseId')}
214212
value={submissionId}
215213
isLoading={isLoading}
216214
isError={isError}
217215
/>
218216
<StackRow
219-
label={isMrf ? MRF_RESPONSE_TIMESTAMP_LABEL : 'Timestamp'}
217+
label={isMrf ? MRF_RESPONSE_TIMESTAMP_LABEL : t('labels.timestamp')}
220218
value={
221-
data?.submissionTime ?? t('features.common.loadingWithEllipsis')
219+
data?.submissionTime ?? t('features.common.loadingWithEllipsis', { ns: 'translation', keyPrefix: '' })
222220
}
223221
isLoading={isLoading}
224222
isError={isError}
@@ -238,11 +236,14 @@ export const IndividualResponsePage = (): JSX.Element => {
238236
workflowCurrentStepNumber === undefined ||
239237
workflowNumTotalSteps === undefined
240238
? '-'
241-
: getPendingResponseAtString({
242-
workflowStatus,
243-
workflowCurrentStepNumber,
244-
workflowNumTotalSteps,
245-
})
239+
: getPendingResponseAtString(
240+
{
241+
workflowStatus,
242+
workflowCurrentStepNumber,
243+
workflowNumTotalSteps,
244+
},
245+
t,
246+
)
246247
}
247248
isLoading={isLoading}
248249
isError={isError}
@@ -266,7 +267,7 @@ export const IndividualResponsePage = (): JSX.Element => {
266267
textStyle="subhead-1"
267268
py={{ base: '0', md: '0.25rem' }}
268269
>
269-
{t('features.common.attachments')}:
270+
{t('features.common.attachments', { ns: 'translation', keyPrefix: '' })}:
270271
</Text>
271272
<Skeleton isLoaded={!isLoading && !isError}>
272273
<Button
@@ -281,20 +282,17 @@ export const IndividualResponsePage = (): JSX.Element => {
281282
)
282283
}
283284
>
284-
{t(
285-
'features.adminForm.responses.individualResponse.downloadAttachmentsAsZip',
286-
{ attachmentSize: attachmentDownloadUrls.size },
287-
)}
285+
{t('downloadAttachmentsAsZip', {
286+
attachmentSize: attachmentDownloadUrls.size,
287+
})}
288288
</Button>
289289
</Skeleton>
290290
</Stack>
291291
)}
292292
{form?.responseMode === FormResponseMode.Multirespondent &&
293293
user?.betaFlags?.mrfAdminSubmissionKey && (
294294
<StackRow
295-
label={t(
296-
'features.adminForm.responses.individualResponse.responseLinkLabel',
297-
)}
295+
label={t('responseLinkLabel')}
298296
value={responseLinkWithKey}
299297
isLoading={isLoading}
300298
isError={isError}

frontend/src/features/admin-form/responses/IndividualResponsePage/PaymentSection.tsx

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,54 +20,50 @@ export const PaymentSection = ({
2020
payment,
2121
formId,
2222
}: PaymentSectionProps): JSX.Element | null => {
23-
const { t } = useTranslation()
23+
const { t } = useTranslation('translation', {
24+
keyPrefix: 'features.adminForm.responses.individualResponse',
25+
})
2426

2527
if (!payment) return null
2628

2729
const paymentDataMap = keyBy(
28-
getPaymentDataView(window.location.origin, payment, formId),
30+
getPaymentDataView(window.location.origin, payment, formId, t),
2931
'key',
3032
)
3133

3234
const paymentTagProps =
3335
payment.status === PaymentStatus.Succeeded
3436
? {
35-
label: t('features.common.success'),
37+
label: t('features.common.success', { ns: 'translation', keyPrefix: '' }),
3638
colorScheme: 'success',
3739
rightIcon: BiCheck,
3840
}
3941
: payment.status === PaymentStatus.PartiallyRefunded
4042
? {
41-
label: t(
42-
'features.adminForm.responses.individualResponse.paymentSection.paymentStatusLabel.partiallyRefunded',
43-
),
43+
label: t('paymentSection.paymentStatusLabel.partiallyRefunded'),
4444
colorScheme: 'secondary',
4545
}
4646
: payment.status === PaymentStatus.FullyRefunded
4747
? {
48-
label: t(
49-
'features.adminForm.responses.individualResponse.paymentSection.paymentStatusLabel.fullyRefunded',
50-
),
48+
label: t('paymentSection.paymentStatusLabel.fullyRefunded'),
5149
colorScheme: 'secondary',
5250
}
5351
: payment.status === PaymentStatus.Disputed
5452
? {
55-
label: t(
56-
'features.adminForm.responses.individualResponse.paymentSection.paymentStatusLabel.disputed',
57-
),
53+
label: t('paymentSection.paymentStatusLabel.disputed'),
5854
colorScheme: 'warning',
5955
}
6056
: undefined // The remaining options should never appear.
6157

6258
const payoutTagProps =
6359
payment.payoutId || payment.payoutDate
6460
? {
65-
label: t('features.common.success'),
61+
label: t('features.common.success', { ns: 'translation', keyPrefix: '' }),
6662
colorScheme: 'success',
6763
rightIcon: BiCheck,
6864
}
6965
: {
70-
label: t('features.common.pending'),
66+
label: t('features.common.pending', { ns: 'translation', keyPrefix: '' }),
7167
colorScheme: 'secondary',
7268
}
7369

@@ -77,7 +73,10 @@ export const PaymentSection = ({
7773
return (
7874
<Flex flexDir="column" gap="4rem">
7975
<Flex flexDir="column" gap="1.25rem">
80-
<PaymentDataHeader name="Payment" {...paymentTagProps} />
76+
<PaymentDataHeader
77+
name={t('paymentSection.headers.payment')}
78+
{...paymentTagProps}
79+
/>
8180
<Flex flexDir="column" gap="0.75rem">
8281
<PaymentDataItem {...paymentDataMap['email']} />
8382
<PaymentDataItem {...paymentDataMap['receiptUrl']} isUrl />
@@ -95,7 +94,10 @@ export const PaymentSection = ({
9594
</Flex>
9695
</Flex>
9796
<Flex flexDir="column" gap="1.25rem">
98-
<PayoutDataHeader name="Payout to bank account" {...payoutTagProps} />
97+
<PayoutDataHeader
98+
name={t('paymentSection.headers.payout')}
99+
{...payoutTagProps}
100+
/>
99101
<Flex flexDir="column" gap="0.75rem">
100102
<PaymentDataItem {...paymentDataMap['payoutId']} isMonospace />
101103
<PaymentDataItem {...paymentDataMap['payoutDate']} />
@@ -118,7 +120,9 @@ function PayoutDataHeader({
118120
colorScheme,
119121
rightIcon,
120122
}: PaymentDataHeaderProps) {
121-
const { t } = useTranslation()
123+
const { t } = useTranslation('translation', {
124+
keyPrefix: 'features.adminForm.responses.individualResponse',
125+
})
122126

123127
return (
124128
<Flex gap="1rem" align="center">
@@ -127,12 +131,7 @@ function PayoutDataHeader({
127131
{name}
128132
</Text>
129133

130-
<Tooltip
131-
placement="top"
132-
label={t(
133-
'features.adminForm.responses.individualResponse.paymentSection.tooltipLabel',
134-
)}
135-
>
134+
<Tooltip placement="top" label={t('paymentSection.tooltipLabel')}>
136135
<Flex justify="center" align="center">
137136
<Icon as={BiInfoCircle} fontSize="1.25rem" ml="0.5rem" />
138137
</Flex>
@@ -186,16 +185,16 @@ function PaymentDataItem({
186185
isMonospace,
187186
isUrl,
188187
}: PaymentDataItemProps): JSX.Element {
189-
const { t } = useTranslation()
188+
const { t } = useTranslation('translation', {
189+
keyPrefix: 'features.adminForm.responses.individualResponse',
190+
})
190191
return (
191192
<Flex flexDir={{ base: 'column', md: 'row' }} gap="0.25rem">
192193
<Text textStyle="subhead-1">{name}:</Text>
193194
<Text textStyle={isMonospace ? 'monospace' : undefined}>
194195
{isUrl ? (
195196
<Link href={value} target="_blank">
196-
{t(
197-
'features.adminForm.responses.individualResponse.paymentSection.paymentDataItemPdfDownloadLabel',
198-
)}
197+
{t('paymentSection.paymentDataItemPdfDownloadLabel')}
199198
</Link>
200199
) : (
201200
value

frontend/src/features/admin-form/responses/ResponsesPage/ResponsesPage.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useTranslation } from 'react-i18next'
12
import { FormResponseMode } from '~shared/types/form'
23

34
import { useToast } from '~hooks/useToast'
@@ -9,6 +10,9 @@ import { ResponsesPageSkeleton } from './ResponsesPageSkeleton'
910
import { StorageResponsesTab } from './storage'
1011

1112
export const ResponsesPage = (): JSX.Element => {
13+
const { t } = useTranslation('translation', {
14+
keyPrefix: 'features.adminForm.responses.responsesPage',
15+
})
1216
const { data: form, isLoading } = useAdminForm()
1317

1418
const toast = useToast({ status: 'danger' })
@@ -17,8 +21,7 @@ export const ResponsesPage = (): JSX.Element => {
1721

1822
if (!form) {
1923
toast({
20-
description:
21-
'There was an error retrieving your form. Please try again later.',
24+
description: t('errors.formRetrievalError'),
2225
})
2326
return <ResponsesPageSkeleton />
2427
}

frontend/src/features/admin-form/responses/ResponsesPage/storage/UnlockedResponses/DownloadButton.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { useCallback, useMemo, useState } from 'react'
22
import { useTranslation } from 'react-i18next'
33
import { useThrottle } from 'react-use'
44
import { Box, MenuButton, Text, useDisclosure } from '@chakra-ui/react'
5-
import simplur from 'simplur'
65

76
import { BxsChevronDown } from '~assets/icons/BxsChevronDown'
87
import { BxsChevronUp } from '~assets/icons/BxsChevronUp'
@@ -71,29 +70,34 @@ export const DownloadButton = (): JSX.Element => {
7170
onSuccess: ({ successCount, expectedCount, errorCount }) => {
7271
if (downloadParams?.responsesCount === 0) {
7372
toast({
74-
description: 'No responses to download',
73+
description: t('storage.unlockedResponses.downloadButton.toasts.noResponses'),
7574
})
7675
return
7776
}
7877
if (errorCount > 0) {
7978
toast({
8079
status: 'warning',
81-
description: simplur`Partial success. ${successCount}/${expectedCount} ${[
80+
description: t('storage.unlockedResponses.downloadButton.toasts.partialSuccess', {
8281
successCount,
83-
]}response[|s] [was|were] decrypted. ${errorCount} failed.`,
82+
expectedCount,
83+
count: successCount,
84+
errorCount,
85+
}),
8486
})
8587
return
8688
}
8789
toast({
88-
description: simplur`Success. ${successCount}/${expectedCount} ${[
90+
description: t('storage.unlockedResponses.downloadButton.toasts.success', {
8991
successCount,
90-
]}response[|s] [was|were] decrypted.`,
92+
expectedCount,
93+
count: successCount,
94+
}),
9195
})
9296
},
9397
onError: () => {
9498
toast({
9599
status: 'danger',
96-
description: 'Failed to start download. Please try again later.',
100+
description: t('storage.unlockedResponses.downloadButton.toasts.failedToStart'),
97101
})
98102
},
99103
onSettled: (decryptResult) => {
@@ -138,17 +142,19 @@ export const DownloadButton = (): JSX.Element => {
138142
handleModalClose()
139143
toast({
140144
status: 'warning',
141-
description: 'Responses download has been canceled.',
145+
description: t('storage.unlockedResponses.downloadButton.toasts.downloadCanceled'),
142146
})
143147
setDownloadMetadata({ isCanceled: true })
144-
}, [handleModalClose, toast])
148+
}, [handleModalClose, t, toast])
145149

146150
const handleAttachmentsDownloadCancel = useCallback(() => {
147151
resetDownload()
148152
setDownloadMetadata({ isCanceled: true })
149153
}, [resetDownload])
150154

151-
const { t } = useTranslation()
155+
const { t } = useTranslation('translation', {
156+
keyPrefix: 'features.adminForm.responses.responsesPage',
157+
})
152158

153159
return (
154160
<>

0 commit comments

Comments
 (0)