Make settings page localizable (#5294)

* make settings localizable

* move plan names to common messages

* unknown -> plan-unknown

* prepr:frontend
This commit is contained in:
xinyihl
2026-03-18 16:16:04 +00:00
committed by GitHub
parent 61754efca4
commit cf1b5f5e2d
12 changed files with 1420 additions and 271 deletions
@@ -2,11 +2,13 @@
<div>
<section class="card">
<Breadcrumbs
current-title="Past charges"
:link-stack="[{ href: '/settings/billing', label: 'Billing and subscriptions' }]"
:current-title="formatMessage(messages.title)"
:link-stack="[
{ href: '/settings/billing', label: formatMessage(commonSettingsMessages.billing) },
]"
/>
<h2>Past charges</h2>
<p>All of your past charges to your Modrinth account will be listed here:</p>
<h2>{{ formatMessage(messages.title) }}</h2>
<p>{{ formatMessage(messages.description) }}</p>
<div
v-for="charge in charges"
:key="charge.id"
@@ -15,11 +17,13 @@
<div class="flex flex-col gap-1">
<div class="flex items-center gap-1">
<span class="font-bold text-primary">
<template v-if="charge.product?.metadata?.type === 'midas'"> Modrinth Plus </template>
<template v-else-if="charge.product?.metadata?.type === 'pyro'">
Modrinth Hosting
<template v-if="charge.product?.metadata?.type === 'midas'">
{{ formatMessage(messages.productMidas) }}
</template>
<template v-else> Medal Server Trial </template>
<template v-else-if="charge.product?.metadata?.type === 'pyro'">
{{ formatMessage(messages.productPyro) }}
</template>
<template v-else> {{ formatMessage(messages.productMedalTrial) }} </template>
<template v-if="charge.subscription_interval">
{{ charge.subscription_interval }}
</template>
@@ -41,6 +45,8 @@
import {
Badge,
Breadcrumbs,
commonSettingsMessages,
defineMessages,
injectModrinthClient,
useFormatDateTime,
useFormatPrice,
@@ -53,6 +59,7 @@ definePageMeta({
middleware: 'auth',
})
const { formatMessage } = useVIntl()
const client = injectModrinthClient()
const formatPrice = useFormatPrice()
@@ -62,6 +69,25 @@ const formatDate = useFormatDateTime({
day: '2-digit',
})
const messages = defineMessages({
description: {
id: 'settings.billing.charges.description',
defaultMessage: 'All of your past charges to your Modrinth account will be listed here:',
},
productMidas: {
id: 'settings.billing.charges.product.midas',
defaultMessage: 'Modrinth Plus',
},
productPyro: {
id: 'settings.billing.charges.product.pyro',
defaultMessage: 'Modrinth Hosting',
},
productMedalTrial: {
id: 'settings.billing.charges.product.medal-trial',
defaultMessage: 'Medal Server Trial',
},
})
const { data: charges } = useQuery({
queryKey: ['billing', 'payments'],
queryFn: async () => {
@@ -14,34 +14,36 @@
<div class="flex flex-wrap justify-between gap-4">
<div class="flex flex-col gap-4">
<template v-if="midasCharge">
<span v-if="midasCharge.status === 'open'"> You're currently subscribed to: </span>
<span v-if="midasCharge.status === 'open'">
{{ formatMessage(messages.midasStatusOpen) }}
</span>
<span v-else-if="midasCharge.status === 'processing'" class="text-orange">
Your payment is being processed. Perks will activate once payment is complete.
{{ formatMessage(messages.midasStatusProcessing) }}
</span>
<span v-else-if="midasCharge.status === 'cancelled'">
You've cancelled your subscription. <br />
You will retain your perks until the end of the current billing cycle.
{{ formatMessage(messages.midasStatusCancelledLine1) }} <br />
{{ formatMessage(messages.midasStatusCancelledLine2) }}
</span>
<span v-else-if="midasCharge.status === 'failed'" class="text-red">
Your subscription payment failed. Please update your payment method.
{{ formatMessage(messages.midasStatusFailed) }}
</span>
</template>
<span v-else>Become a subscriber to Modrinth Plus!</span>
<span v-else>{{ formatMessage(messages.midasUpsell) }}</span>
<ModrinthPlusIcon class="h-8 w-min" />
<div class="flex flex-col gap-2">
<span class="font-bold">Benefits</span>
<span class="font-bold">{{ formatMessage(messages.midasBenefitsTitle) }}</span>
<div class="flex items-center gap-2">
<CheckCircleIcon class="h-5 w-5 shrink-0 text-brand" />
<span> Ad-free browsing on modrinth.com and Modrinth App </span>
<span>{{ formatMessage(messages.midasBenefitAdFree) }}</span>
</div>
<div class="flex items-center gap-2">
<CheckCircleIcon class="h-5 w-5 shrink-0 text-brand" />
<span>Modrinth+ badge on your profile</span>
<span>{{ formatMessage(messages.midasBenefitBadge) }}</span>
</div>
<div class="flex items-center gap-2">
<CheckCircleIcon class="h-5 w-5 shrink-0 text-brand" />
<span>Support Modrinth and creators directly</span>
<span>{{ formatMessage(messages.midasBenefitSupport) }}</span>
</div>
</div>
</div>
@@ -50,17 +52,22 @@
<span class="text-2xl font-bold text-dark">
<template v-if="midasCharge">
{{
formatPrice(
midasSubscriptionPrice.prices.intervals[midasSubscription.interval],
midasSubscriptionPrice.currency_code,
)
formatMessage(messages.pricePerInterval, {
price: formatPrice(
midasSubscriptionPrice.prices.intervals[midasSubscription.interval],
midasSubscriptionPrice.currency_code,
),
interval: getIntervalNounLabel(midasSubscription.interval),
})
}}
/
{{ midasSubscription.interval }}
</template>
<template v-else>
{{ formatPrice(price.prices.intervals.monthly, price.currency_code) }}
/ month
{{
formatMessage(messages.pricePerInterval, {
price: formatPrice(price.prices.intervals.monthly, price.currency_code),
interval: formatMessage(messages.intervalMonth),
})
}}
</template>
</span>
<!-- Next charge preview for Midas when interval is changing -->
@@ -74,32 +81,56 @@
"
class="-mt-1 flex items-baseline gap-2 text-sm text-secondary"
>
<span class="opacity-70">Next:</span>
<span class="opacity-70">{{ formatMessage(messages.nextLabel) }}</span>
<span class="font-semibold text-contrast">
{{ formatPrice(midasCharge.amount, midasCharge.currency_code) }}
</span>
<span>/{{ midasCharge.subscription_interval.replace('ly', '') }}</span>
<span>
{{
formatMessage(messages.slashInterval, {
interval: getIntervalNounLabel(midasCharge.subscription_interval),
})
}}
</span>
</div>
<template v-if="midasCharge">
<span
v-if="
midasCharge.status === 'open' && midasCharge.subscription_interval === 'monthly'
midasCharge.status === 'open' &&
midasCharge.subscription_interval === 'monthly' &&
oppositePrice != null
"
class="text-sm text-purple"
>
Save
{{
formatPrice(midasCharge.amount * 12 - oppositePrice, midasCharge.currency_code)
}}/year by switching to yearly billing!
formatMessage(messages.savePerYearBySwitchingToYearly, {
amount: formatPrice(
midasCharge.amount * 12 - oppositePrice,
midasCharge.currency_code,
),
})
}}
</span>
<span class="text-sm text-secondary">
Since {{ formatDate(midasSubscription.created) }}
{{
formatMessage(messages.sinceDate, {
date: formatDate(midasSubscription.created),
})
}}
</span>
<span v-if="midasCharge.status === 'open'" class="text-sm text-secondary">
Renews {{ formatDate(midasCharge.due) }}
{{
formatMessage(messages.renewsDate, {
date: formatDate(midasCharge.due),
})
}}
</span>
<span v-else-if="midasCharge.status === 'cancelled'" class="text-sm text-secondary">
Expires {{ formatDate(midasCharge.due) }}
{{
formatMessage(messages.expiresDate, {
date: formatDate(midasCharge.due),
})
}}
</span>
<span
v-if="
@@ -110,17 +141,25 @@
"
class="text-sm text-secondary"
>
Switches to {{ midasCharge.subscription_interval }} billing on
{{ formatDate(midasCharge.due) }}
{{
formatMessage(messages.switchesToBillingOn, {
interval: getIntervalAdjectiveLabel(midasCharge.subscription_interval),
date: formatDate(midasCharge.due),
})
}}
</span>
</template>
<span v-else class="text-sm text-secondary">
Or
{{ formatPrice(price.prices.intervals.yearly, price.currency_code) }} / year (save
{{
calculateSavings(price.prices.intervals.monthly, price.prices.intervals.yearly)
}}%)!
formatMessage(messages.orYearlySave, {
price: formatPrice(price.prices.intervals.yearly, price.currency_code),
percent: calculateSavings(
price.prices.intervals.monthly,
price.prices.intervals.yearly,
),
})
}}
</span>
</div>
<div
@@ -136,7 +175,7 @@
"
>
<UpdatedIcon />
Update method
{{ formatMessage(messages.updateMethod) }}
</button>
</ButtonStyled>
<ButtonStyled type="transparent" circular>
@@ -153,7 +192,9 @@
]"
>
<MoreVerticalIcon />
<template #cancel><XIcon /> Cancel</template>
<template #cancel
><XIcon /> {{ formatMessage(commonMessages.cancelButton) }}</template
>
</OverflowMenu>
</ButtonStyled>
</div>
@@ -171,7 +212,7 @@
}
"
>
<XIcon /> Cancel
<XIcon /> {{ formatMessage(commonMessages.cancelButton) }}
</button>
</ButtonStyled>
<ButtonStyled
@@ -181,18 +222,28 @@
<button
v-tooltip="
midasCharge.subscription_interval === 'yearly'
? `Monthly billing will cost you an additional ${formatPrice(
oppositePrice * 12 - midasCharge.amount,
midasCharge.currency_code,
)} per year`
? formatMessage(messages.monthlyBillingAdditionalPerYearTooltip, {
amount: formatPrice(
oppositePrice * 12 - midasCharge.amount,
midasCharge.currency_code,
),
})
: undefined
"
:disabled="changingInterval"
@click="switchMidasInterval(oppositeInterval)"
>
<SpinnerIcon v-if="changingInterval" class="animate-spin" />
<TransferIcon v-else /> {{ changingInterval ? 'Switching' : 'Switch' }} to
{{ oppositeInterval }}
<TransferIcon v-else />
{{
changingInterval
? formatMessage(messages.switchingToInterval, {
interval: getIntervalAdjectiveLabel(oppositeInterval),
})
: formatMessage(messages.switchToInterval, {
interval: getIntervalAdjectiveLabel(oppositeInterval),
})
}}
</button>
</ButtonStyled>
</div>
@@ -201,7 +252,7 @@
color="purple"
>
<button class="ml-auto" @click="cancelSubscription(midasSubscription.id, false)">
Resubscribe <RightArrowIcon />
{{ formatMessage(messages.resubscribe) }} <RightArrowIcon />
</button>
</ButtonStyled>
<ButtonStyled v-else color="purple" size="large">
@@ -213,7 +264,7 @@
}
"
>
Subscribe <RightArrowIcon />
{{ formatMessage(messages.subscribe) }} <RightArrowIcon />
</button>
</ButtonStyled>
</div>
@@ -236,31 +287,45 @@
/>
<div v-else class="w-fit">
<p>
A linked server couldn't be found for this subscription. There are a few possible
explanations for this. If you just purchased your server, this is normal. It could
take up to an hour for your server to be provisioned. Otherwise, if you purchased
this server a while ago, it has likely since been suspended. If this is not what
you were expecting, please contact Modrinth Support with the following
information:
{{ formatMessage(messages.pyroLinkedServerNotFound) }}
</p>
<div class="flex w-full flex-col gap-2">
<CopyCode
class="whitespace-nowrap"
:text="'Server ID: ' + subscription.metadata.id"
:text="
formatMessage(messages.pyroServerIdLabel, {
id: subscription.metadata.id,
})
"
/>
<CopyCode
class="whitespace-nowrap"
:text="
formatMessage(messages.pyroStripeIdLabel, {
id: subscription.id,
})
"
/>
<CopyCode class="whitespace-nowrap" :text="'Stripe ID: ' + subscription.id" />
</div>
</div>
<h3 class="m-0 mt-4 text-xl font-semibold leading-none text-contrast">
{{ getProductSize(getPyroProduct(subscription)) }} Plan
{{
formatMessage(messages.planTitle, {
size: getProductSize(getPyroProduct(subscription)),
})
}}
</h3>
<div class="flex flex-row justify-between">
<div class="mt-2 flex flex-col gap-2">
<div class="flex items-center gap-2">
<CheckCircleIcon class="h-5 w-5 text-brand" />
<span>
{{ getPyroProduct(subscription)?.metadata?.cpu / 2 }} Shared CPUs (Bursts up
to {{ getPyroProduct(subscription)?.metadata?.cpu }} CPUs)
{{
formatMessage(messages.pyroCpuLine, {
shared: getPyroProduct(subscription)?.metadata?.cpu / 2,
bursts: getPyroProduct(subscription)?.metadata?.cpu,
})
}}
</span>
</div>
<div class="flex items-center gap-2">
@@ -268,7 +333,9 @@
<span>
{{
getPyroProduct(subscription)?.metadata?.ram
? getPyroProduct(subscription).metadata.ram / 1024 + ' GB RAM'
? formatMessage(messages.pyroRamLine, {
gb: getPyroProduct(subscription).metadata.ram / 1024,
})
: ''
}}
</span>
@@ -278,7 +345,9 @@
<span>
{{
getPyroProduct(subscription)?.metadata?.swap
? getPyroProduct(subscription).metadata.swap / 1024 + ' GB Swap'
? formatMessage(messages.pyroSwapLine, {
gb: getPyroProduct(subscription).metadata.swap / 1024,
})
: ''
}}
</span>
@@ -288,7 +357,9 @@
<span>
{{
getPyroProduct(subscription)?.metadata?.storage
? getPyroProduct(subscription).metadata.storage / 1024 + ' GB SSD'
? formatMessage(messages.pyroStorageLine, {
gb: getPyroProduct(subscription).metadata.storage / 1024,
})
: ''
}}
</span>
@@ -309,7 +380,13 @@
: ''
}}
</span>
<span>/{{ subscription.interval.replace('ly', '') }}</span>
<span>
{{
formatMessage(messages.slashInterval, {
interval: getIntervalNounLabel(subscription.interval),
})
}}
</span>
</div>
<div
v-if="
@@ -323,7 +400,7 @@
"
class="-mt-1 flex items-baseline gap-2 text-sm text-secondary"
>
<span class="opacity-70">Next:</span>
<span class="opacity-70">{{ formatMessage(messages.nextLabel) }}</span>
<span class="font-semibold text-contrast">
{{
formatPrice(
@@ -333,24 +410,33 @@
}}
</span>
<span>
/
{{
(
getPyroCharge(subscription).subscription_interval ||
subscription.interval
).replace('ly', '')
formatMessage(messages.slashInterval, {
interval: getIntervalNounLabel(
getPyroCharge(subscription).subscription_interval ||
subscription.interval,
),
})
}}
</span>
</div>
<div v-if="getPyroCharge(subscription)" class="mb-4 flex flex-col items-end">
<span class="text-sm text-secondary">
Since {{ formatDate(subscription.created) }}
{{
formatMessage(messages.sinceDate, {
date: formatDate(subscription.created),
})
}}
</span>
<span
v-if="getPyroCharge(subscription).status === 'open'"
class="text-sm text-secondary"
>
Renews {{ formatDate(getPyroCharge(subscription).due) }}
{{
formatMessage(messages.renewsDate, {
date: formatDate(getPyroCharge(subscription).due),
})
}}
</span>
<span
v-if="
@@ -361,30 +447,36 @@
"
class="text-sm text-secondary"
>
Switches to
{{ getPyroCharge(subscription).subscription_interval }}
billing on
{{ formatDate(getPyroCharge(subscription).due) }}
{{
formatMessage(messages.switchesToBillingOn, {
interval: getIntervalAdjectiveLabel(
getPyroCharge(subscription).subscription_interval,
),
date: formatDate(getPyroCharge(subscription).due),
})
}}
</span>
<span
v-else-if="getPyroCharge(subscription).status === 'processing'"
class="text-sm text-orange"
>
Your payment is being processed. Your server will activate once payment is
complete.
{{ formatMessage(messages.pyroStatusProcessing) }}
</span>
<span
v-else-if="getPyroCharge(subscription).status === 'cancelled'"
class="text-sm text-secondary"
>
Expires {{ formatDate(getPyroCharge(subscription).due) }}
{{
formatMessage(messages.expiresDate, {
date: formatDate(getPyroCharge(subscription).due),
})
}}
</span>
<span
v-else-if="getPyroCharge(subscription).status === 'failed'"
class="text-sm text-red"
>
Your subscription payment failed. Please update your payment method, then
resubscribe.
{{ formatMessage(messages.pyroStatusFailed) }}
</span>
</div>
</div>
@@ -397,7 +489,7 @@
>
<button @click="showCancellationSurvey(subscription)">
<XIcon />
Cancel
{{ formatMessage(commonMessages.cancelButton) }}
</button>
</ButtonStyled>
<ButtonStyled
@@ -411,7 +503,7 @@
>
<button @click="showPyroUpgradeModal(subscription)">
<ArrowBigUpDashIcon />
Upgrade
{{ formatMessage(messages.upgrade) }}
</button>
</ButtonStyled>
<ButtonStyled
@@ -430,7 +522,7 @@
)
"
>
Resubscribe <RightArrowIcon />
{{ formatMessage(messages.resubscribe) }} <RightArrowIcon />
</button>
</ButtonStyled>
</div>
@@ -463,7 +555,7 @@
:on-error="
(err) =>
addNotification({
title: 'An error occurred',
title: formatMessage(commonMessages.errorNotificationTitle),
type: 'error',
text: err.message ?? (err.data ? err.data.description : err),
})
@@ -735,8 +827,205 @@ const messages = defineMessages({
id: 'settings.billing.pyro_subscription.description',
defaultMessage: 'Manage your Modrinth Server subscriptions.',
},
intervalMonth: {
id: 'settings.billing.interval.month',
defaultMessage: 'month',
},
intervalYear: {
id: 'settings.billing.interval.year',
defaultMessage: 'year',
},
intervalMonthly: {
id: 'settings.billing.interval.monthly',
defaultMessage: 'monthly',
},
intervalYearly: {
id: 'settings.billing.interval.yearly',
defaultMessage: 'yearly',
},
pricePerInterval: {
id: 'settings.billing.price.per-interval',
defaultMessage: '{price} / {interval}',
},
slashInterval: {
id: 'settings.billing.price.slash-interval',
defaultMessage: '/{interval}',
},
nextLabel: {
id: 'settings.billing.next',
defaultMessage: 'Next:',
},
midasStatusOpen: {
id: 'settings.billing.midas.status.open',
defaultMessage: "You're currently subscribed to:",
},
midasStatusProcessing: {
id: 'settings.billing.midas.status.processing',
defaultMessage:
'Your payment is being processed. Perks will activate once payment is complete.',
},
midasStatusCancelledLine1: {
id: 'settings.billing.midas.status.cancelled.line1',
defaultMessage: "You've cancelled your subscription.",
},
midasStatusCancelledLine2: {
id: 'settings.billing.midas.status.cancelled.line2',
defaultMessage: 'You will retain your perks until the end of the current billing cycle.',
},
midasStatusFailed: {
id: 'settings.billing.midas.status.failed',
defaultMessage: 'Your subscription payment failed. Please update your payment method.',
},
midasUpsell: {
id: 'settings.billing.midas.upsell',
defaultMessage: 'Become a subscriber to Modrinth Plus!',
},
midasBenefitsTitle: {
id: 'settings.billing.midas.benefits.title',
defaultMessage: 'Benefits',
},
midasBenefitAdFree: {
id: 'settings.billing.midas.benefits.ad-free',
defaultMessage: 'Ad-free browsing on modrinth.com and Modrinth App',
},
midasBenefitBadge: {
id: 'settings.billing.midas.benefits.badge',
defaultMessage: 'Modrinth+ badge on your profile',
},
midasBenefitSupport: {
id: 'settings.billing.midas.benefits.support',
defaultMessage: 'Support Modrinth and creators directly',
},
savePerYearBySwitchingToYearly: {
id: 'settings.billing.midas.save-per-year',
defaultMessage: 'Save {amount}/year by switching to yearly billing!',
},
sinceDate: {
id: 'settings.billing.since',
defaultMessage: 'Since {date}',
},
renewsDate: {
id: 'settings.billing.renews',
defaultMessage: 'Renews {date}',
},
expiresDate: {
id: 'settings.billing.expires',
defaultMessage: 'Expires {date}',
},
switchesToBillingOn: {
id: 'settings.billing.switches-to-billing-on',
defaultMessage: 'Switches to {interval} billing on {date}',
},
orYearlySave: {
id: 'settings.billing.or-yearly-save',
defaultMessage: 'Or {price} / year (save {percent}%)!',
},
updateMethod: {
id: 'settings.billing.update-method',
defaultMessage: 'Update method',
},
switchToInterval: {
id: 'settings.billing.switch.to-interval',
defaultMessage: 'Switch to {interval}',
},
switchingToInterval: {
id: 'settings.billing.switch.switching-to-interval',
defaultMessage: 'Switching to {interval}',
},
monthlyBillingAdditionalPerYearTooltip: {
id: 'settings.billing.switch.tooltip.monthly-additional-per-year',
defaultMessage: 'Monthly billing will cost you an additional {amount} per year',
},
resubscribe: {
id: 'settings.billing.resubscribe',
defaultMessage: 'Resubscribe',
},
subscribe: {
id: 'settings.billing.subscribe',
defaultMessage: 'Subscribe',
},
upgrade: {
id: 'settings.billing.upgrade',
defaultMessage: 'Upgrade',
},
pyroLinkedServerNotFound: {
id: 'settings.billing.pyro.linked-server.not-found',
defaultMessage:
"A linked server couldn't be found for this subscription. There are a few possible explanations for this. If you just purchased your server, this is normal. It could take up to an hour for your server to be provisioned. Otherwise, if you purchased this server a while ago, it has likely since been suspended. If this is not what you were expecting, please contact Modrinth Support with the following information:",
},
pyroServerIdLabel: {
id: 'settings.billing.pyro.linked-server.server-id',
defaultMessage: 'Server ID: {id}',
},
pyroStripeIdLabel: {
id: 'settings.billing.pyro.linked-server.stripe-id',
defaultMessage: 'Stripe ID: {id}',
},
planTitle: {
id: 'settings.billing.plan.title',
defaultMessage: '{size} Plan',
},
pyroCpuLine: {
id: 'settings.billing.pyro.cpu',
defaultMessage: '{shared} Shared CPUs (Bursts up to {bursts} CPUs)',
},
pyroRamLine: {
id: 'settings.billing.pyro.ram',
defaultMessage: '{gb} GB RAM',
},
pyroSwapLine: {
id: 'settings.billing.pyro.swap',
defaultMessage: '{gb} GB Swap',
},
pyroStorageLine: {
id: 'settings.billing.pyro.storage',
defaultMessage: '{gb} GB SSD',
},
pyroStatusProcessing: {
id: 'settings.billing.pyro.status.processing',
defaultMessage:
'Your payment is being processed. Your server will activate once payment is complete.',
},
pyroStatusFailed: {
id: 'settings.billing.pyro.status.failed',
defaultMessage:
'Your subscription payment failed. Please update your payment method, then resubscribe.',
},
pyroResubscribeRequestSubmittedTitle: {
id: 'settings.billing.pyro.resubscribe.request-submitted.title',
defaultMessage: 'Resubscription request submitted',
},
pyroResubscribeRequestSubmittedText: {
id: 'settings.billing.pyro.resubscribe.request-submitted.text',
defaultMessage:
'If the server is currently suspended, it may take up to 10 minutes for another charge attempt to be made.',
},
pyroResubscribeSuccessText: {
id: 'settings.billing.pyro.resubscribe.success.text',
defaultMessage: 'Server subscription resubscribed successfully',
},
pyroResubscribeErrorTitle: {
id: 'settings.billing.pyro.resubscribe.error.title',
defaultMessage: 'Error resubscribing',
},
pyroResubscribeErrorText: {
id: 'settings.billing.pyro.resubscribe.error.text',
defaultMessage: 'An error occurred while resubscribing to your Modrinth server.',
},
})
function getIntervalNounLabel(interval) {
return interval === 'yearly'
? formatMessage(messages.intervalYear)
: formatMessage(messages.intervalMonth)
}
function getIntervalAdjectiveLabel(interval) {
return interval === 'yearly'
? formatMessage(messages.intervalYearly)
: formatMessage(messages.intervalMonthly)
}
const queryClient = useQueryClient()
const { data: paymentMethods } = useQuery({
@@ -860,7 +1149,7 @@ async function editPaymentMethod(index, primary) {
await refresh()
} catch (err) {
addNotification({
title: 'An error occurred',
title: formatMessage(commonMessages.errorNotificationTitle),
text: err.data ? err.data.description : err,
type: 'error',
})
@@ -875,7 +1164,7 @@ async function removePaymentMethod(index) {
await refresh()
} catch (err) {
addNotification({
title: 'An error occurred',
title: formatMessage(commonMessages.errorNotificationTitle),
text: err.data ? err.data.description : err,
type: 'error',
})
@@ -893,7 +1182,7 @@ async function cancelSubscription(id, cancelled) {
await refresh()
} catch (err) {
addNotification({
title: 'An error occurred',
title: formatMessage(commonMessages.errorNotificationTitle),
text: err.data ? err.data.description : err,
type: 'error',
})
@@ -920,12 +1209,12 @@ const getPyroCharge = (subscription) => {
}
const getProductSize = (product) => {
if (!product || !product.metadata) return 'Unknown'
if (!product || !product.metadata) return formatMessage(commonMessages.planUnknownLabel)
const ramSize = product.metadata.ram
if (ramSize === 4096) return 'Small'
if (ramSize === 6144) return 'Medium'
if (ramSize === 8192) return 'Large'
return 'Custom'
if (ramSize === 4096) return formatMessage(commonMessages.planSmallLabel)
if (ramSize === 6144) return formatMessage(commonMessages.planMediumLabel)
if (ramSize === 8192) return formatMessage(commonMessages.planLargeLabel)
return formatMessage(commonMessages.planCustomLabel)
}
const getProductPrice = (product, interval) => {
@@ -962,21 +1251,21 @@ const resubscribePyro = async (subscriptionId, wasSuspended) => {
await refresh()
if (wasSuspended) {
addNotification({
title: 'Resubscription request submitted',
text: 'If the server is currently suspended, it may take up to 10 minutes for another charge attempt to be made.',
title: formatMessage(messages.pyroResubscribeRequestSubmittedTitle),
text: formatMessage(messages.pyroResubscribeRequestSubmittedText),
type: 'success',
})
} else {
addNotification({
title: 'Success',
text: 'Server subscription resubscribed successfully',
title: formatMessage(commonMessages.successLabel),
text: formatMessage(messages.pyroResubscribeSuccessText),
type: 'success',
})
}
} catch {
addNotification({
title: 'Error resubscribing',
text: 'An error occurred while resubscribing to your Modrinth server.',
title: formatMessage(messages.pyroResubscribeErrorTitle),
text: formatMessage(messages.pyroResubscribeErrorText),
type: 'error',
})
}