Skip to content

Commit 66ef4fa

Browse files
committed
chore: ttag for subscription-related UI
1 parent 61bf8ca commit 66ef4fa

13 files changed

Lines changed: 114 additions & 84 deletions

File tree

packages/web/src/javascripts/Components/NoSubscriptionBanner/NoSubscriptionBanner.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { classNames } from '@standardnotes/utils'
33
import Button from '../Button/Button'
44
import Icon from '../Icon/Icon'
55
import { PremiumFeatureIconClass, PremiumFeatureIconName } from '../Icon/PremiumFeatureIcon'
6+
import { c } from 'ttag'
67

78
const NoSubscriptionBanner = ({
89
application,
@@ -31,7 +32,7 @@ const NoSubscriptionBanner = ({
3132
</div>
3233
<p className="col-start-1 col-end-3 m-0 mt-1 text-sm">{message}</p>
3334
<Button primary small className="col-start-1 col-end-3 mt-3 justify-self-start uppercase" onClick={onClick}>
34-
Upgrade Features
35+
{c('Action').t`Upgrade Features`}
3536
</Button>
3637
</div>
3738
)

packages/web/src/javascripts/Components/Preferences/Panes/Account/NoProSubscription.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { FunctionComponent, ReactNode, useState } from 'react'
22
import { LinkButton, Text } from '@/Components/Preferences/PreferencesComponents/Content'
33
import Button from '@/Components/Button/Button'
44
import { WebApplication } from '@/Application/WebApplication'
5+
import { c } from 'ttag'
56

67
type Props = {
78
application: WebApplication
@@ -13,7 +14,7 @@ const NoProSubscription: FunctionComponent<Props> = ({ application, text }) => {
1314
const [purchaseFlowError, setPurchaseFlowError] = useState<string | undefined>(undefined)
1415

1516
const onPurchaseClick = async () => {
16-
const errorMessage = 'There was an error when attempting to redirect you to the subscription page.'
17+
const errorMessage = c('Error').t`There was an error when attempting to redirect you to the subscription page.`
1718
setIsLoadingPurchaseFlow(true)
1819
try {
1920
if (application.isNativeIOS()) {
@@ -33,15 +34,19 @@ const NoProSubscription: FunctionComponent<Props> = ({ application, text }) => {
3334
return (
3435
<>
3536
<Text>{text}</Text>
36-
{isLoadingPurchaseFlow && <Text>Redirecting you to the subscription page...</Text>}
37+
{isLoadingPurchaseFlow && <Text>{c('Info').t`Redirecting you to the subscription page...`}</Text>}
3738
{purchaseFlowError && <Text className="text-danger">{purchaseFlowError}</Text>}
3839

3940
<div className="flex">
4041
{!application.hideOutboundSubscriptionLinks && (
41-
<LinkButton className="mr-3 mt-3 min-w-20" label="Learn More" link={window.plansUrl as string} />
42+
<LinkButton
43+
className="mr-3 mt-3 min-w-20"
44+
label={c('Action').t`Learn More`}
45+
link={window.plansUrl as string}
46+
/>
4247
)}
4348
{application.hasAccount() && (
44-
<Button className="mt-3 min-w-20" primary label="Upgrade" onClick={onPurchaseClick} />
49+
<Button className="mt-3 min-w-20" primary label={c('Action').t`Upgrade`} onClick={onPurchaseClick} />
4550
)}
4651
</div>
4752
</>

packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/NoSubscription.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { FunctionComponent, useState } from 'react'
22
import { LinkButton, Text } from '@/Components/Preferences/PreferencesComponents/Content'
33
import Button from '@/Components/Button/Button'
44
import { WebApplication } from '@/Application/WebApplication'
5+
import { c } from 'ttag'
56

67
type Props = {
78
application: WebApplication
@@ -12,7 +13,7 @@ const NoSubscription: FunctionComponent<Props> = ({ application }) => {
1213
const [purchaseFlowError, setPurchaseFlowError] = useState<string | undefined>(undefined)
1314

1415
const onPurchaseClick = async () => {
15-
const errorMessage = 'There was an error when attempting to redirect you to the subscription page.'
16+
const errorMessage = c('Error').t`There was an error when attempting to redirect you to the subscription page.`
1617
setIsLoadingPurchaseFlow(true)
1718
try {
1819
if (application.isNativeIOS()) {
@@ -29,15 +30,19 @@ const NoSubscription: FunctionComponent<Props> = ({ application }) => {
2930

3031
return (
3132
<>
32-
<Text>You don't have a Standard Notes subscription yet.</Text>
33-
{isLoadingPurchaseFlow && <Text>Redirecting you to the subscription page...</Text>}
33+
<Text>{c('Info').t`You don't have a Standard Notes subscription yet.`}</Text>
34+
{isLoadingPurchaseFlow && <Text>{c('Info').t`Redirecting you to the subscription page...`}</Text>}
3435
{purchaseFlowError && <Text className="text-danger">{purchaseFlowError}</Text>}
3536
<div className="flex">
3637
{!application.hideOutboundSubscriptionLinks && (
37-
<LinkButton className="mr-3 mt-3 min-w-20" label="Learn More" link={window.plansUrl as string} />
38+
<LinkButton
39+
className="mr-3 mt-3 min-w-20"
40+
label={c('Action').t`Learn More`}
41+
link={window.plansUrl as string}
42+
/>
3843
)}
3944
{application.hasAccount() && (
40-
<Button className="mt-3 min-w-20" primary label="Subscribe" onClick={onPurchaseClick} />
45+
<Button className="mt-3 min-w-20" primary label={c('Action').t`Subscribe`} onClick={onPurchaseClick} />
4146
)}
4247
</div>
4348
</>

packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/Subscription.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
2+
import { c } from 'ttag'
23
import SubscriptionInformation from './SubscriptionInformation'
34
import NoSubscription from './NoSubscription'
45
import { observer } from 'mobx-react-lite'
@@ -32,7 +33,7 @@ const Subscription: FunctionComponent = () => {
3233
<PreferencesSegment>
3334
<div className="flex flex-row items-center">
3435
<div className="flex flex-grow flex-col">
35-
<Title>Subscription</Title>
36+
<Title>{c('Title').t`Subscription`}</Title>
3637
{onlineSubscription ? <SubscriptionInformation /> : <NoSubscription application={application} />}
3738
</div>
3839
</div>

packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/SubscriptionInformation.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { observer } from 'mobx-react-lite'
22
import Button from '@/Components/Button/Button'
33
import SubscriptionStatusText from './SubscriptionStatusText'
44
import { useApplication } from '@/Components/ApplicationProvider'
5+
import { c } from 'ttag'
56

67
const SubscriptionInformation = () => {
78
const application = useApplication()
@@ -15,7 +16,11 @@ const SubscriptionInformation = () => {
1516
<>
1617
<SubscriptionStatusText />
1718
{!isSharedSubscription && (
18-
<Button className="mr-3 mt-3 min-w-20" label="Manage subscription" onClick={manageSubscription} />
19+
<Button
20+
className="mr-3 mt-3 min-w-20"
21+
label={c('Action').t`Manage subscription`}
22+
onClick={manageSubscription}
23+
/>
1924
)}
2025
</>
2126
)

packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/SubscriptionStatusText.tsx

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { observer } from 'mobx-react-lite'
22
import { Text } from '@/Components/Preferences/PreferencesComponents/Content'
33
import { useApplication } from '@/Components/ApplicationProvider'
4+
import { c } from 'ttag'
45

56
const SubscriptionStatusText = () => {
67
const application = useApplication()
@@ -18,25 +19,28 @@ const SubscriptionStatusText = () => {
1819
<>
1920
<br />
2021
<br />
21-
This subscription has been shared with you and can only be managed by the owner.
22+
{c('Info').t`This subscription has been shared with you and can only be managed by the owner.`}
2223
</>
2324
) : null
2425

26+
const planName = `Standard Notes${userSubscriptionName ? ` ${userSubscriptionName}` : ''}`
27+
const planNameSpan = <span className="font-bold">{planName}</span>
28+
const dateSpan = <span className="font-bold">{expirationDateString}</span>
29+
2530
if (isUserSubscriptionCanceled) {
31+
if (isUserSubscriptionExpired) {
32+
return (
33+
<Text className="mt-1">
34+
{c('Info')
35+
.jt`Your ${planNameSpan} subscription has been canceled and expired on ${dateSpan}. You may resubscribe below if you wish.`}
36+
{sharedMessage}
37+
</Text>
38+
)
39+
}
2640
return (
2741
<Text className="mt-1">
28-
Your{' '}
29-
<span className="font-bold">
30-
Standard Notes{userSubscriptionName ? ' ' : ''}
31-
{userSubscriptionName}
32-
</span>{' '}
33-
subscription has been canceled{' '}
34-
{isUserSubscriptionExpired ? (
35-
<span className="font-bold">and expired on {expirationDateString}</span>
36-
) : (
37-
<span className="font-bold">but will remain valid until {expirationDateString}</span>
38-
)}
39-
. You may resubscribe below if you wish.
42+
{c('Info')
43+
.jt`Your ${planNameSpan} subscription has been canceled but will remain valid until ${dateSpan}. You may resubscribe below if you wish.`}
4044
{sharedMessage}
4145
</Text>
4246
)
@@ -45,26 +49,16 @@ const SubscriptionStatusText = () => {
4549
if (isUserSubscriptionExpired) {
4650
return (
4751
<Text className="mt-1">
48-
Your{' '}
49-
<span className="font-bold">
50-
Standard Notes{userSubscriptionName ? ' ' : ''}
51-
{userSubscriptionName}
52-
</span>{' '}
53-
subscription <span className="font-bold">expired on {expirationDateString}</span>. You may resubscribe below if
54-
you wish.
52+
{c('Info').jt`Your ${planNameSpan} subscription expired on ${dateSpan}. You may resubscribe below if you wish.`}
5553
{sharedMessage}
5654
</Text>
5755
)
5856
}
5957

6058
return (
6159
<Text className="mt-1">
62-
Your{' '}
63-
<span className="font-bold">
64-
Standard Notes{userSubscriptionName ? ' ' : ''}
65-
{userSubscriptionName}
66-
</span>{' '}
67-
subscription will be <span className="font-bold">renewed on {expirationDateString}</span>.{sharedMessage}
60+
{c('Info').jt`Your ${planNameSpan} subscription will be renewed on ${dateSpan}.`}
61+
{sharedMessage}
6862
</Text>
6963
)
7064
}

packages/web/src/javascripts/Components/Preferences/Panes/Account/SubscriptionSharing/InvitationsList.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { SubscriptionController } from '@/Controllers/Subscription/SubscriptionC
77
import Button from '@/Components/Button/Button'
88
import { WebApplication } from '@/Application/WebApplication'
99
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
10+
import { c } from 'ttag'
1011

1112
type Props = {
1213
subscriptionState: SubscriptionController
@@ -24,15 +25,15 @@ const InvitationsList = ({ subscriptionState, application }: Props) => {
2425

2526
const handleCancel = async (invitationUuid: string) => {
2627
if (lockContinue) {
27-
application.alerts.alert('Cancelation already in progress.').catch(console.error)
28+
application.alerts.alert(c('Info').t`Cancelation already in progress.`).catch(console.error)
2829

2930
return
3031
}
3132

3233
const confirmed = await application.alerts.confirm(
33-
'All uploaded files of this user will be removed. This action cannot be undone.',
34-
'Are you sure you want to cancel this invitation?',
35-
'Cancel Invitation',
34+
c('Info').t`All uploaded files of this user will be removed. This action cannot be undone.`,
35+
c('Title').t`Are you sure you want to cancel this invitation?`,
36+
c('Action').t`Cancel Invitation`,
3637
ButtonType.Danger,
3738
)
3839
if (!confirmed) {
@@ -47,25 +48,29 @@ const InvitationsList = ({ subscriptionState, application }: Props) => {
4748

4849
if (!success) {
4950
application.alerts
50-
.alert('Could not cancel invitation. Please try again or contact support if the issue persists.')
51+
.alert(c('Error').t`Could not cancel invitation. Please try again or contact support if the issue persists.`)
5152
.catch(console.error)
5253
}
5354
}
5455

5556
if (usedInvitationsCount === 0) {
56-
return <Text className="mb-3 mt-1">Make your first subscription invite below.</Text>
57+
return <Text className="mb-3 mt-1">{c('Info').t`Make your first subscription invite below.`}</Text>
5758
}
5859

5960
return (
6061
<div>
61-
<SubtitleLight className="mb-2 text-info">Active Invites</SubtitleLight>
62+
<SubtitleLight className="mb-2 text-info">{c('Subtitle').t`Active Invites`}</SubtitleLight>
6263
{activeSubscriptions?.map((invitation) => (
6364
<div key={invitation.uuid} className="mb-4 mt-1">
6465
<Text>
6566
{invitation.inviteeIdentifier} <span className="text-info">({invitation.status})</span>
6667
</Text>
6768
{invitation.status !== InvitationStatus.Canceled && (
68-
<Button className="mt-2 min-w-20" label="Cancel" onClick={() => handleCancel(invitation.uuid)} />
69+
<Button
70+
className="mt-2 min-w-20"
71+
label={c('Action').t`Cancel`}
72+
onClick={() => handleCancel(invitation.uuid)}
73+
/>
6974
)}
7075
</div>
7176
))}

packages/web/src/javascripts/Components/Preferences/Panes/Account/SubscriptionSharing/Invite/Invite.tsx

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ import { SubscriptionController } from '@/Controllers/Subscription/SubscriptionC
77
import InviteForm from './InviteForm'
88
import InviteSuccess from './InviteSuccess'
99
import Modal, { ModalAction } from '@/Components/Modal/Modal'
10-
11-
enum SubmitButtonTitles {
12-
Default = 'Invite',
13-
Sending = 'Sending...',
14-
Finish = 'Finish',
15-
}
10+
import { c } from 'ttag'
1611

1712
enum Steps {
1813
InitialStep,
@@ -26,7 +21,7 @@ type Props = {
2621
}
2722

2823
const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscriptionState }) => {
29-
const [submitButtonTitle, setSubmitButtonTitle] = useState(SubmitButtonTitles.Default)
24+
const [submitButtonTitle, setSubmitButtonTitle] = useState(() => c('Action').t`Invite`)
3025
const [inviteeEmail, setInviteeEmail] = useState('')
3126
const [isContinuing, setIsContinuing] = useState(false)
3227
const [lockContinue, setLockContinue] = useState(false)
@@ -35,7 +30,7 @@ const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscrip
3530
const validateInviteeEmail = useCallback(async () => {
3631
if (!isEmailValid(inviteeEmail)) {
3732
application.alerts
38-
.alert('The email you entered has an invalid format. Please review your input and try again.')
33+
.alert(c('Error').t`The email you entered has an invalid format. Please review your input and try again.`)
3934
.catch(console.error)
4035

4136
return false
@@ -46,14 +41,14 @@ const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscrip
4641

4742
const handleDialogClose = useCallback(() => {
4843
if (lockContinue) {
49-
application.alerts.alert('Cannot close window until pending tasks are complete.').catch(console.error)
44+
application.alerts.alert(c('Info').t`Cannot close window until pending tasks are complete.`).catch(console.error)
5045
} else {
5146
onCloseDialog()
5247
}
5348
}, [application.alerts, lockContinue, onCloseDialog])
5449

5550
const resetProgressState = () => {
56-
setSubmitButtonTitle(SubmitButtonTitles.Default)
51+
setSubmitButtonTitle(c('Action').t`Invite`)
5752
setIsContinuing(false)
5853
}
5954

@@ -79,7 +74,7 @@ const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscrip
7974
}
8075

8176
setIsContinuing(true)
82-
setSubmitButtonTitle(SubmitButtonTitles.Sending)
77+
setSubmitButtonTitle(c('Action').t`Sending...`)
8378

8479
const valid = await validateInviteeEmail()
8580

@@ -92,7 +87,10 @@ const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscrip
9287
const success = await processInvite()
9388
if (!success) {
9489
application.alerts
95-
.alert('An error occurred while sending the invite. Please try again or contact support if the issue persists.')
90+
.alert(
91+
c('Error')
92+
.t`An error occurred while sending the invite. Please try again or contact support if the issue persists.`,
93+
)
9694
.catch(console.error)
9795

9896
resetProgressState()
@@ -101,7 +99,7 @@ const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscrip
10199
}
102100

103101
setIsContinuing(false)
104-
setSubmitButtonTitle(SubmitButtonTitles.Finish)
102+
setSubmitButtonTitle(c('Action').t`Finish`)
105103
setCurrentStep(Steps.FinishStep)
106104
}, [
107105
application.alerts,
@@ -123,7 +121,7 @@ const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscrip
123121
disabled: lockContinue,
124122
},
125123
{
126-
label: 'Cancel',
124+
label: c('Action').t`Cancel`,
127125
onClick: handleDialogClose,
128126
type: 'cancel',
129127
mobileSlot: 'left',
@@ -134,7 +132,7 @@ const Invite: FunctionComponent<Props> = ({ onCloseDialog, application, subscrip
134132
)
135133

136134
return (
137-
<Modal title="Share Your Subscription" close={handleDialogClose} actions={modalActions}>
135+
<Modal title={c('Title').t`Share Your Subscription`} close={handleDialogClose} actions={modalActions}>
138136
<div className="px-4.5 py-4">
139137
{currentStep === Steps.InitialStep && <InviteForm setInviteeEmail={setInviteeEmail} />}
140138
{currentStep === Steps.FinishStep && <InviteSuccess />}

0 commit comments

Comments
 (0)