mirror of
https://github.com/modrinth/code.git
synced 2026-08-26 17:44:50 +00:00
chore(frontend): i18n pass on mostly-translated frontend components (#6786)
* i18n pass on mostly-translated frontend components * Run prepr * Fix SRV-records text and unescape tooltip braces * Fix changed wording * Remove unneeded strings * Use ICU-safe placeholder
This commit is contained in:
@@ -213,6 +213,10 @@ export const analyticsMessages = defineMessages({
|
||||
id: 'analytics.filter.game-version-type.all',
|
||||
defaultMessage: 'All',
|
||||
},
|
||||
dependentProjectSearchFailedTitle: {
|
||||
id: 'analytics.filter.dependent-project-search-failed-title',
|
||||
defaultMessage: 'Dependent projects failed to load',
|
||||
},
|
||||
})
|
||||
|
||||
export const analyticsStatMessages = defineMessages({
|
||||
|
||||
@@ -492,7 +492,7 @@ watch(dependentProjectSearchError, (error) => {
|
||||
if (!error) return
|
||||
|
||||
addNotification({
|
||||
title: 'Dependent projects failed to load',
|
||||
title: formatMessage(analyticsMessages.dependentProjectSearchFailedTitle),
|
||||
text: getDependentProjectSearchErrorMessage(error),
|
||||
type: 'error',
|
||||
})
|
||||
|
||||
@@ -40,6 +40,30 @@ const messages = defineMessages({
|
||||
defaultMessage:
|
||||
'NOT AN OFFICIAL MINECRAFT SERVICE. NOT APPROVED BY OR ASSOCIATED WITH MOJANG OR MICROSOFT.',
|
||||
},
|
||||
basedOnLabel: {
|
||||
id: 'layout.footer.based-on-label',
|
||||
defaultMessage: 'Based on',
|
||||
},
|
||||
unknownCommit: {
|
||||
id: 'layout.footer.unknown-commit',
|
||||
defaultMessage: 'unknown',
|
||||
},
|
||||
developerModeActivatedTitle: {
|
||||
id: 'layout.footer.developer-mode-activated.title',
|
||||
defaultMessage: 'Developer mode activated',
|
||||
},
|
||||
developerModeActivatedText: {
|
||||
id: 'layout.footer.developer-mode-activated.text',
|
||||
defaultMessage: 'Developer mode has been enabled',
|
||||
},
|
||||
developerModeDeactivatedTitle: {
|
||||
id: 'layout.footer.developer-mode-deactivated.title',
|
||||
defaultMessage: 'Developer mode deactivated',
|
||||
},
|
||||
developerModeDeactivatedText: {
|
||||
id: 'layout.footer.developer-mode-deactivated.text',
|
||||
defaultMessage: 'Developer mode has been disabled',
|
||||
},
|
||||
})
|
||||
|
||||
const socialLinks: {
|
||||
@@ -215,14 +239,14 @@ function developerModeIncrement() {
|
||||
saveFeatureFlags()
|
||||
if (flags.value.developerMode) {
|
||||
addNotification({
|
||||
title: 'Developer mode activated',
|
||||
text: 'Developer mode has been enabled',
|
||||
title: formatMessage(messages.developerModeActivatedTitle),
|
||||
text: formatMessage(messages.developerModeActivatedText),
|
||||
type: 'success',
|
||||
})
|
||||
} else {
|
||||
addNotification({
|
||||
title: 'Developer mode deactivated',
|
||||
text: 'Developer mode has been disabled',
|
||||
title: formatMessage(messages.developerModeDeactivatedTitle),
|
||||
text: formatMessage(messages.developerModeDeactivatedText),
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
@@ -320,7 +344,7 @@ function developerModeIncrement() {
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="flags.developerMode" class="m-0 text-sm text-secondary">
|
||||
Based on
|
||||
{{ formatMessage(messages.basedOnLabel) }}
|
||||
<a
|
||||
v-if="config.public.owner && config.public.branch"
|
||||
class="hover:underline"
|
||||
@@ -330,7 +354,9 @@ function developerModeIncrement() {
|
||||
{{ config.public.owner }}/{{ config.public.branch }}
|
||||
</a>
|
||||
@
|
||||
<span v-if="config.public.hash === 'unknown'">unknown</span>
|
||||
<span v-if="config.public.hash === 'unknown'">{{
|
||||
formatMessage(messages.unknownCommit)
|
||||
}}</span>
|
||||
<AutoLink
|
||||
v-else
|
||||
class="text-link"
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<NewModal ref="modalOpen" header="Transfer projects" no-padding width="60rem">
|
||||
<NewModal
|
||||
ref="modalOpen"
|
||||
:header="formatMessage(messages.transferProjectsTitle)"
|
||||
no-padding
|
||||
width="60rem"
|
||||
>
|
||||
<div class="max-h-[70vh] overflow-y-auto">
|
||||
<Table
|
||||
class="!rounded-none !border-0"
|
||||
@@ -12,7 +17,7 @@
|
||||
>
|
||||
<template #empty-state>
|
||||
<div class="flex h-48 items-center justify-center text-secondary">
|
||||
No projects available to transfer.
|
||||
{{ formatMessage(messages.noProjectsAvailable) }}
|
||||
</div>
|
||||
</template>
|
||||
<template #header-select>
|
||||
@@ -38,7 +43,7 @@
|
||||
<img
|
||||
v-if="project.icon_url"
|
||||
:src="project.icon_url"
|
||||
:alt="'Icon for ' + project.title"
|
||||
:alt="formatMessage(messages.projectIconAlt, { name: project.title })"
|
||||
class="h-full w-full rounded object-cover"
|
||||
/>
|
||||
<BoxIcon v-else class="h-full w-full" />
|
||||
@@ -69,8 +74,11 @@
|
||||
<ButtonStyled color="brand">
|
||||
<button :disabled="selectedProjects.length === 0" @click="submitTransfer()">
|
||||
<TransferIcon />
|
||||
Transfer {{ selectedProjects.length }}
|
||||
{{ selectedProjects.length === 1 ? 'project' : 'projects' }}
|
||||
{{
|
||||
formatMessage(messages.transferSelectedProjects, {
|
||||
count: selectedProjects.length,
|
||||
})
|
||||
}}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -79,7 +87,7 @@
|
||||
<ButtonStyled>
|
||||
<button @click="show($event)">
|
||||
<TransferIcon />
|
||||
<span>Transfer projects</span>
|
||||
<span>{{ formatMessage(messages.transferProjectsTitle) }}</span>
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -92,6 +100,7 @@ import {
|
||||
Checkbox,
|
||||
commonMessages,
|
||||
CopyCode,
|
||||
defineMessages,
|
||||
NewModal,
|
||||
Table,
|
||||
useVIntl,
|
||||
@@ -112,10 +121,41 @@ const props = defineProps({
|
||||
const emit = defineEmits(['submit'])
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const messages = defineMessages({
|
||||
transferProjectsTitle: {
|
||||
id: 'organization.project-transfer.title',
|
||||
defaultMessage: 'Transfer projects',
|
||||
},
|
||||
noProjectsAvailable: {
|
||||
id: 'organization.project-transfer.no-projects-available',
|
||||
defaultMessage: 'No projects available to transfer.',
|
||||
},
|
||||
projectIconAlt: {
|
||||
id: 'organization.project-transfer.project-icon-alt',
|
||||
defaultMessage: 'Icon for {name}',
|
||||
},
|
||||
transferSelectedProjects: {
|
||||
id: 'organization.project-transfer.transfer-selected-projects',
|
||||
defaultMessage: 'Transfer {count, plural, one {# project} other {# projects}}',
|
||||
},
|
||||
nameColumn: {
|
||||
id: 'organization.project-transfer.name-column',
|
||||
defaultMessage: 'Name',
|
||||
},
|
||||
idColumn: {
|
||||
id: 'organization.project-transfer.id-column',
|
||||
defaultMessage: 'ID',
|
||||
},
|
||||
typeColumn: {
|
||||
id: 'organization.project-transfer.type-column',
|
||||
defaultMessage: 'Type',
|
||||
},
|
||||
})
|
||||
|
||||
const modalOpen = ref(null)
|
||||
const selectedProjectIds = ref([])
|
||||
|
||||
const projectTableColumns = [
|
||||
const projectTableColumns = computed(() => [
|
||||
{
|
||||
key: 'select',
|
||||
width: '3rem',
|
||||
@@ -124,21 +164,21 @@ const projectTableColumns = [
|
||||
},
|
||||
{
|
||||
key: 'name',
|
||||
label: 'Name',
|
||||
label: formatMessage(messages.nameColumn),
|
||||
width: '22rem',
|
||||
},
|
||||
{
|
||||
key: 'id',
|
||||
label: 'ID',
|
||||
label: formatMessage(messages.idColumn),
|
||||
width: '13rem',
|
||||
cellClass: '!overflow-visible',
|
||||
},
|
||||
{
|
||||
key: 'type',
|
||||
label: 'Type',
|
||||
label: formatMessage(messages.typeColumn),
|
||||
width: '10rem',
|
||||
},
|
||||
]
|
||||
])
|
||||
|
||||
const transferableProjects = computed(() =>
|
||||
props.projects.filter((project) => !isProjectTransferDisabled(project)),
|
||||
|
||||
@@ -11,19 +11,21 @@
|
||||
v-if="handlingNewFiles || !(filesToAdd.length || draftVersion.existing_files?.length)"
|
||||
>
|
||||
<DropzoneFileInput
|
||||
aria-label="Upload file"
|
||||
:aria-label="formatMessage(messages.uploadFileAriaLabel)"
|
||||
multiple
|
||||
:accept="acceptFileFromProjectType(projectV2.project_type)"
|
||||
:max-size="524288000"
|
||||
primary-prompt="Upload primary and supporting files"
|
||||
secondary-prompt="Drag and drop files or click to browse"
|
||||
:primary-prompt="formatMessage(messages.uploadPrimaryPrompt)"
|
||||
:secondary-prompt="formatMessage(messages.uploadSecondaryPrompt)"
|
||||
@change="handleNewFiles"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-base font-semibold text-contrast">Primary file</span>
|
||||
<span class="text-base font-semibold text-contrast">{{
|
||||
formatMessage(messages.primaryFileLabel)
|
||||
}}</span>
|
||||
<div class="flex flex-col gap-2.5">
|
||||
<VersionFileRow
|
||||
v-if="primaryFile"
|
||||
@@ -36,7 +38,7 @@
|
||||
/>
|
||||
</div>
|
||||
<span>
|
||||
The primary file is the default file a user downloads when installing the project.
|
||||
{{ formatMessage(messages.primaryFileDescription) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -46,16 +48,18 @@
|
||||
{{ formatMessage(messages.addFilesAdmonition) }}
|
||||
</Admonition>
|
||||
|
||||
<span class="text-base font-semibold text-contrast">Supplementary files</span>
|
||||
<span class="text-base font-semibold text-contrast">{{
|
||||
formatMessage(messages.supplementaryFilesLabel)
|
||||
}}</span>
|
||||
|
||||
<DropzoneFileInput
|
||||
aria-label="Upload additional file"
|
||||
:aria-label="formatMessage(messages.uploadAdditionalFileAriaLabel)"
|
||||
multiple
|
||||
:accept="acceptFileFromProjectType(projectV2.project_type)"
|
||||
:max-size="524288000"
|
||||
size="small"
|
||||
:primary-prompt="null"
|
||||
secondary-prompt="Drag and drop files or click to browse"
|
||||
:secondary-prompt="formatMessage(messages.uploadSecondaryPrompt)"
|
||||
@change="handleNewFiles"
|
||||
/>
|
||||
|
||||
@@ -84,8 +88,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<span>
|
||||
You can optionally add supplementary files such as source code, documentation, or required
|
||||
resource packs.
|
||||
{{ formatMessage(messages.supplementaryFilesDescription) }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -124,11 +127,11 @@ const {
|
||||
handleNewFiles,
|
||||
} = injectManageVersionContext()
|
||||
|
||||
const editTabs: TabsTab[] = [
|
||||
{ label: 'Metadata', value: 'metadata' },
|
||||
{ label: 'Details', value: 'add-details' },
|
||||
{ label: 'Files', value: 'add-files' },
|
||||
]
|
||||
const editTabs = computed<TabsTab[]>(() => [
|
||||
{ label: formatMessage(messages.metadataTab), value: 'metadata' },
|
||||
{ label: formatMessage(messages.detailsTab), value: 'add-details' },
|
||||
{ label: formatMessage(messages.filesTab), value: 'add-files' },
|
||||
])
|
||||
|
||||
function setEditTab(tab: TabsTab) {
|
||||
modal.value?.setStage(tab.value)
|
||||
@@ -171,5 +174,51 @@ const messages = defineMessages({
|
||||
defaultMessage:
|
||||
'Supplementary files are for supporting resources like source code, not for alternative versions or variants.',
|
||||
},
|
||||
uploadFileAriaLabel: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.upload-file-aria-label',
|
||||
defaultMessage: 'Upload file',
|
||||
},
|
||||
uploadAdditionalFileAriaLabel: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.upload-additional-file-aria-label',
|
||||
defaultMessage: 'Upload additional file',
|
||||
},
|
||||
uploadPrimaryPrompt: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.upload-primary-prompt',
|
||||
defaultMessage: 'Upload primary and supporting files',
|
||||
},
|
||||
uploadSecondaryPrompt: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.upload-secondary-prompt',
|
||||
defaultMessage: 'Drag and drop files or click to browse',
|
||||
},
|
||||
primaryFileLabel: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.primary-file-label',
|
||||
defaultMessage: 'Primary file',
|
||||
},
|
||||
primaryFileDescription: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.primary-file-description',
|
||||
defaultMessage:
|
||||
'The primary file is the default file a user downloads when installing the project.',
|
||||
},
|
||||
supplementaryFilesLabel: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.supplementary-files-label',
|
||||
defaultMessage: 'Supplementary files',
|
||||
},
|
||||
supplementaryFilesDescription: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.supplementary-files-description',
|
||||
defaultMessage:
|
||||
'You can optionally add supplementary files such as source code, documentation, or required resource packs.',
|
||||
},
|
||||
metadataTab: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.metadata-tab',
|
||||
defaultMessage: 'Metadata',
|
||||
},
|
||||
detailsTab: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.details-tab',
|
||||
defaultMessage: 'Details',
|
||||
},
|
||||
filesTab: {
|
||||
id: 'create-project-version.create-modal.stage.add-files.files-tab',
|
||||
defaultMessage: 'Files',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="flex w-full flex-col gap-6">
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="font-semibold text-contrast">
|
||||
Version type <span class="text-red">*</span>
|
||||
{{ formatMessage(messages.versionType) }} <span class="text-red">*</span>
|
||||
</span>
|
||||
<Chips
|
||||
v-model="draftVersion.version_type"
|
||||
@@ -22,31 +22,33 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="font-semibold text-contrast">
|
||||
Version number <span class="text-red">*</span>
|
||||
{{ formatMessage(messages.versionNumber) }} <span class="text-red">*</span>
|
||||
</span>
|
||||
<StyledInput
|
||||
id="version-number"
|
||||
v-model="draftVersion.version_number"
|
||||
:disabled="isUploading"
|
||||
placeholder="Enter version number, e.g. 1.2.3-alpha.1"
|
||||
:placeholder="formatMessage(messages.versionNumberPlaceholder)"
|
||||
autocomplete="off"
|
||||
:maxlength="32"
|
||||
/>
|
||||
<span> The version number differentiates this specific version from others. </span>
|
||||
<span>{{ formatMessage(messages.versionNumberDescription) }}</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="font-semibold text-contrast"> Version subtitle </span>
|
||||
<span class="font-semibold text-contrast">{{ formatMessage(messages.versionSubtitle) }}</span>
|
||||
<StyledInput
|
||||
id="version-number"
|
||||
v-model="draftVersion.name"
|
||||
placeholder="Enter subtitle..."
|
||||
:placeholder="formatMessage(messages.versionSubtitlePlaceholder)"
|
||||
autocomplete="off"
|
||||
:maxlength="256"
|
||||
:disabled="isUploading"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="font-semibold text-contrast"> Version changelog </span>
|
||||
<span class="font-semibold text-contrast">{{
|
||||
formatMessage(messages.versionChangelog)
|
||||
}}</span>
|
||||
|
||||
<div class="w-full">
|
||||
<MarkdownEditor
|
||||
@@ -61,18 +63,70 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Chips, MarkdownEditor, StyledInput, Tabs, type TabsTab } from '@modrinth/ui'
|
||||
import {
|
||||
Chips,
|
||||
defineMessages,
|
||||
MarkdownEditor,
|
||||
StyledInput,
|
||||
Tabs,
|
||||
type TabsTab,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
import { useImageUpload } from '~/composables/image-upload.ts'
|
||||
import { injectManageVersionContext } from '~/providers/version/manage-version-modal'
|
||||
|
||||
const { draftVersion, isUploading, editingVersion, modal } = injectManageVersionContext()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const editTabs: TabsTab[] = [
|
||||
{ label: 'Metadata', value: 'metadata' },
|
||||
{ label: 'Details', value: 'add-details' },
|
||||
{ label: 'Files', value: 'add-files' },
|
||||
]
|
||||
const messages = defineMessages({
|
||||
versionType: {
|
||||
id: 'create-project-version.create-modal.stage.details.version-type',
|
||||
defaultMessage: 'Version type',
|
||||
},
|
||||
versionNumber: {
|
||||
id: 'create-project-version.create-modal.stage.details.version-number',
|
||||
defaultMessage: 'Version number',
|
||||
},
|
||||
versionNumberPlaceholder: {
|
||||
id: 'create-project-version.create-modal.stage.details.version-number-placeholder',
|
||||
defaultMessage: 'Enter version number, e.g. 1.2.3-alpha.1',
|
||||
},
|
||||
versionNumberDescription: {
|
||||
id: 'create-project-version.create-modal.stage.details.version-number-description',
|
||||
defaultMessage: 'The version number differentiates this specific version from others.',
|
||||
},
|
||||
versionSubtitle: {
|
||||
id: 'create-project-version.create-modal.stage.details.version-subtitle',
|
||||
defaultMessage: 'Version subtitle',
|
||||
},
|
||||
versionSubtitlePlaceholder: {
|
||||
id: 'create-project-version.create-modal.stage.details.version-subtitle-placeholder',
|
||||
defaultMessage: 'Enter subtitle...',
|
||||
},
|
||||
versionChangelog: {
|
||||
id: 'create-project-version.create-modal.stage.details.version-changelog',
|
||||
defaultMessage: 'Version changelog',
|
||||
},
|
||||
metadataTab: {
|
||||
id: 'create-project-version.create-modal.stage.details.metadata-tab',
|
||||
defaultMessage: 'Metadata',
|
||||
},
|
||||
detailsTab: {
|
||||
id: 'create-project-version.create-modal.stage.details.details-tab',
|
||||
defaultMessage: 'Details',
|
||||
},
|
||||
filesTab: {
|
||||
id: 'create-project-version.create-modal.stage.details.files-tab',
|
||||
defaultMessage: 'Files',
|
||||
},
|
||||
})
|
||||
|
||||
const editTabs = computed<TabsTab[]>(() => [
|
||||
{ label: formatMessage(messages.metadataTab), value: 'metadata' },
|
||||
{ label: formatMessage(messages.detailsTab), value: 'add-details' },
|
||||
{ label: formatMessage(messages.filesTab), value: 'add-files' },
|
||||
])
|
||||
|
||||
function setEditTab(tab: TabsTab) {
|
||||
modal.value?.setStage(tab.value)
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
<div class="flex flex-col gap-6">
|
||||
<div v-if="!editingVersion" class="flex flex-col gap-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-semibold text-contrast"> Uploaded files </span>
|
||||
<span class="font-semibold text-contrast">{{ formatMessage(messages.uploadedFiles) }}</span>
|
||||
|
||||
<ButtonStyled type="transparent" size="standard">
|
||||
<button @click="editFiles">
|
||||
<EditIcon />
|
||||
Edit
|
||||
{{ formatMessage(messages.editButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -43,23 +43,27 @@
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-semibold text-contrast">
|
||||
{{ usingDetectedLoaders ? 'Detected loaders' : 'Loaders' }}
|
||||
{{
|
||||
usingDetectedLoaders
|
||||
? formatMessage(messages.detectedLoaders)
|
||||
: formatMessage(messages.loaders)
|
||||
}}
|
||||
</span>
|
||||
|
||||
<ButtonStyled type="transparent" size="standard">
|
||||
<button
|
||||
v-tooltip="
|
||||
isModpack
|
||||
? 'Modpack loaders cannot be edited'
|
||||
? formatMessage(messages.modpackLoadersTooltip)
|
||||
: isResourcePack
|
||||
? 'Resource pack loaders cannot be edited'
|
||||
? formatMessage(messages.resourcePackLoadersTooltip)
|
||||
: undefined
|
||||
"
|
||||
:disabled="isModpack || isResourcePack"
|
||||
@click="editLoaders"
|
||||
>
|
||||
<EditIcon />
|
||||
Edit
|
||||
{{ formatMessage(messages.editButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -88,9 +92,11 @@
|
||||
v-if="!draftVersionLoaders.length && projectType === 'modpack'"
|
||||
class="border !border-solid border-surface-5 hover:no-underline"
|
||||
>
|
||||
No mod loader
|
||||
{{ formatMessage(messages.noModLoader) }}
|
||||
</TagItem>
|
||||
<span v-else-if="!draftVersionLoaders.length">No loaders selected.</span>
|
||||
<span v-else-if="!draftVersionLoaders.length">{{
|
||||
formatMessage(messages.noLoadersSelected)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -98,17 +104,21 @@
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-semibold text-contrast">
|
||||
{{ usingDetectedVersions ? 'Detected versions' : 'Versions' }}
|
||||
{{
|
||||
usingDetectedVersions
|
||||
? formatMessage(messages.detectedVersions)
|
||||
: formatMessage(messages.versions)
|
||||
}}
|
||||
</span>
|
||||
|
||||
<ButtonStyled type="transparent" size="standard">
|
||||
<button
|
||||
v-tooltip="isModpack ? 'Modpack versions cannot be edited' : undefined"
|
||||
v-tooltip="isModpack ? formatMessage(messages.modpackVersionsTooltip) : undefined"
|
||||
:disabled="isModpack"
|
||||
@click="editVersions"
|
||||
>
|
||||
<EditIcon />
|
||||
Edit
|
||||
{{ formatMessage(messages.editButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -125,7 +135,9 @@
|
||||
{{ version }}
|
||||
</TagItem>
|
||||
|
||||
<span v-if="!draftVersion.game_versions.length">No versions selected.</span>
|
||||
<span v-if="!draftVersion.game_versions.length">{{
|
||||
formatMessage(messages.noVersionsSelected)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,14 +146,16 @@
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-semibold text-contrast"> Environment </span>
|
||||
<UnknownIcon v-tooltip="'Pre-filled from a previous similar version'" />
|
||||
<span class="font-semibold text-contrast">{{
|
||||
formatMessage(messages.environment)
|
||||
}}</span>
|
||||
<UnknownIcon v-tooltip="formatMessage(messages.prefilledEnvironmentTooltip)" />
|
||||
</div>
|
||||
|
||||
<ButtonStyled type="transparent" size="standard">
|
||||
<button @click="editEnvironment">
|
||||
<EditIcon />
|
||||
Edit
|
||||
{{ formatMessage(messages.editButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -154,7 +168,9 @@
|
||||
<div class="text-sm font-medium">{{ environmentCopy.description }}</div>
|
||||
</div>
|
||||
|
||||
<span v-else class="text-sm font-medium">No environment has been set.</span>
|
||||
<span v-else class="text-sm font-medium">{{
|
||||
formatMessage(messages.noEnvironmentSet)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -163,12 +179,14 @@
|
||||
<div class="flex flex-col gap-2.5">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-semibold text-contrast"> Dependencies </span>
|
||||
<span class="font-semibold text-contrast">{{
|
||||
formatMessage(messages.dependencies)
|
||||
}}</span>
|
||||
|
||||
<ButtonStyled type="transparent" size="standard">
|
||||
<button @click="addDependency">
|
||||
<PlusIcon />
|
||||
Add dependency
|
||||
{{ formatMessage(messages.addDependency) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -177,13 +195,15 @@
|
||||
<DependenciesList />
|
||||
</div>
|
||||
<div v-else class="flex flex-col gap-1.5 gap-y-4 rounded-xl bg-surface-2 p-3 py-4">
|
||||
<span class="text-sm font-medium">No dependencies added.</span>
|
||||
<span class="text-sm font-medium">{{
|
||||
formatMessage(messages.noDependenciesAdded)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="visibleSuggestedDependencies.length" class="flex flex-col gap-2.5">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-medium"> Suggested </span>
|
||||
<span class="font-medium">{{ formatMessage(messages.suggested) }}</span>
|
||||
</div>
|
||||
<SuggestedDependencies @on-add-suggestion="handleAddSuggestedDependency" />
|
||||
</div>
|
||||
@@ -231,11 +251,11 @@ const { projectV2 } = injectProjectPageContext()
|
||||
const generatedState = useGeneratedState()
|
||||
const loaders = computed(() => generatedState.value.loaders)
|
||||
|
||||
const editTabs: TabsTab[] = [
|
||||
{ label: 'Metadata', value: 'metadata' },
|
||||
{ label: 'Details', value: 'add-details' },
|
||||
{ label: 'Files', value: 'add-files' },
|
||||
]
|
||||
const editTabs = computed<TabsTab[]>(() => [
|
||||
{ label: formatMessage(messages.metadataTab), value: 'metadata' },
|
||||
{ label: formatMessage(messages.detailsTab), value: 'add-details' },
|
||||
{ label: formatMessage(messages.filesTab), value: 'add-files' },
|
||||
])
|
||||
|
||||
function setEditTab(tab: TabsTab) {
|
||||
modal.value?.setStage(tab.value)
|
||||
@@ -341,6 +361,97 @@ const supplementaryExistingFiles = computed(() => {
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const messages = defineMessages({
|
||||
uploadedFiles: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.uploaded-files',
|
||||
defaultMessage: 'Uploaded files',
|
||||
},
|
||||
editButton: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.edit-button',
|
||||
defaultMessage: 'Edit',
|
||||
},
|
||||
detectedLoaders: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.detected-loaders',
|
||||
defaultMessage: 'Detected loaders',
|
||||
},
|
||||
loaders: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.loaders',
|
||||
defaultMessage: 'Loaders',
|
||||
},
|
||||
modpackLoadersTooltip: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.modpack-loaders-tooltip',
|
||||
defaultMessage: 'Modpack loaders cannot be edited',
|
||||
},
|
||||
resourcePackLoadersTooltip: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.resource-pack-loaders-tooltip',
|
||||
defaultMessage: 'Resource pack loaders cannot be edited',
|
||||
},
|
||||
noModLoader: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.no-mod-loader',
|
||||
defaultMessage: 'No mod loader',
|
||||
},
|
||||
noLoadersSelected: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.no-loaders-selected',
|
||||
defaultMessage: 'No loaders selected.',
|
||||
},
|
||||
detectedVersions: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.detected-versions',
|
||||
defaultMessage: 'Detected versions',
|
||||
},
|
||||
versions: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.versions',
|
||||
defaultMessage: 'Versions',
|
||||
},
|
||||
modpackVersionsTooltip: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.modpack-versions-tooltip',
|
||||
defaultMessage: 'Modpack versions cannot be edited',
|
||||
},
|
||||
noVersionsSelected: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.no-versions-selected',
|
||||
defaultMessage: 'No versions selected.',
|
||||
},
|
||||
environment: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.environment',
|
||||
defaultMessage: 'Environment',
|
||||
},
|
||||
prefilledEnvironmentTooltip: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.prefilled-environment-tooltip',
|
||||
defaultMessage: 'Pre-filled from a previous similar version',
|
||||
},
|
||||
noEnvironmentSet: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.no-environment-set',
|
||||
defaultMessage: 'No environment has been set.',
|
||||
},
|
||||
dependencies: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.dependencies',
|
||||
defaultMessage: 'Dependencies',
|
||||
},
|
||||
addDependency: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.add-dependency',
|
||||
defaultMessage: 'Add dependency',
|
||||
},
|
||||
noDependenciesAdded: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.no-dependencies-added',
|
||||
defaultMessage: 'No dependencies added.',
|
||||
},
|
||||
suggested: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.suggested',
|
||||
defaultMessage: 'Suggested',
|
||||
},
|
||||
metadataTab: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.metadata-tab',
|
||||
defaultMessage: 'Metadata',
|
||||
},
|
||||
detailsTab: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.details-tab',
|
||||
defaultMessage: 'Details',
|
||||
},
|
||||
filesTab: {
|
||||
id: 'create-project-version.create-modal.stage.metadata.files-tab',
|
||||
defaultMessage: 'Files',
|
||||
},
|
||||
})
|
||||
|
||||
const noEnvironmentMessage = defineMessages({
|
||||
title: {
|
||||
id: 'version.environment.none.title',
|
||||
|
||||
@@ -246,6 +246,18 @@ const messages = defineMessages({
|
||||
id: 'create.project.missing-fields-tooltip',
|
||||
defaultMessage: 'Missing fields: {fields}',
|
||||
},
|
||||
unknownUser: {
|
||||
id: 'create.project.unknown-user',
|
||||
defaultMessage: 'Unknown user',
|
||||
},
|
||||
userAvatarAlt: {
|
||||
id: 'create.project.user-avatar-alt',
|
||||
defaultMessage: 'User Avatar',
|
||||
},
|
||||
organizationIconAlt: {
|
||||
id: 'create.project.organization-icon-alt',
|
||||
defaultMessage: '{name} Icon',
|
||||
},
|
||||
})
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -318,7 +330,7 @@ const cancel = () => {
|
||||
|
||||
const userOption = computed(() => ({
|
||||
value: 'self',
|
||||
label: auth.value.user?.username || 'Unknown user',
|
||||
label: auth.value.user?.username || formatMessage(messages.unknownUser),
|
||||
icon: auth.value.user?.avatar_url
|
||||
? markRaw(
|
||||
defineAsyncComponent(() =>
|
||||
@@ -326,7 +338,7 @@ const userOption = computed(() => ({
|
||||
setup: () => () =>
|
||||
h('img', {
|
||||
src: auth.value.user?.avatar_url,
|
||||
alt: 'User Avatar',
|
||||
alt: formatMessage(messages.userAvatarAlt),
|
||||
class: 'h-5 w-5 rounded-full',
|
||||
}),
|
||||
}),
|
||||
@@ -357,7 +369,7 @@ async function fetchOrganizations() {
|
||||
setup: () => () =>
|
||||
h('img', {
|
||||
src: org.icon_url,
|
||||
alt: `${org.name} Icon`,
|
||||
alt: formatMessage(messages.organizationIconAlt, { name: org.name }),
|
||||
class: 'h-5 w-5 rounded',
|
||||
}),
|
||||
}),
|
||||
|
||||
@@ -137,7 +137,9 @@
|
||||
</div>
|
||||
<div class="flex w-full flex-row justify-stretch gap-2">
|
||||
<ButtonStyled>
|
||||
<button class="w-full text-contrast" @click="handleClose">{{ closeButtonText }}</button>
|
||||
<button class="w-full text-contrast" @click="handleClose">
|
||||
{{ props.closeButtonText ?? formatMessage(messages.closeButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="green">
|
||||
<button class="w-full text-contrast" @click="downloadTaxForm">
|
||||
@@ -182,7 +184,7 @@ const props = withDefaults(
|
||||
emitSuccessOnClose?: boolean
|
||||
}>(),
|
||||
{
|
||||
closeButtonText: 'Close',
|
||||
closeButtonText: undefined,
|
||||
emitSuccessOnClose: true,
|
||||
},
|
||||
)
|
||||
@@ -268,6 +270,18 @@ const messages = defineMessages({
|
||||
id: 'dashboard.creator-tax-form-modal.confirmation.download-button',
|
||||
defaultMessage: 'Download {formType}',
|
||||
},
|
||||
closeButton: {
|
||||
id: 'dashboard.creator-tax-form-modal.close-button',
|
||||
defaultMessage: 'Close',
|
||||
},
|
||||
incompleteTitle: {
|
||||
id: 'dashboard.creator-tax-form-modal.incomplete.title',
|
||||
defaultMessage: 'Tax form incomplete',
|
||||
},
|
||||
incompleteText: {
|
||||
id: 'dashboard.creator-tax-form-modal.incomplete.text',
|
||||
defaultMessage: 'You have not completed the tax form. Please try again.',
|
||||
},
|
||||
})
|
||||
|
||||
const isUSCitizen = ref<'yes' | 'no' | null>(null)
|
||||
@@ -371,8 +385,8 @@ async function continueForm() {
|
||||
}
|
||||
|
||||
addNotification({
|
||||
title: 'Tax form incomplete',
|
||||
text: 'You have not completed the tax form. Please try again.',
|
||||
title: formatMessage(messages.incompleteTitle),
|
||||
text: formatMessage(messages.incompleteText),
|
||||
type: 'warning',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<MuralpayDetailsStage v-else-if="currentStage === 'muralpay-details'" />
|
||||
<LegacyPaypalDetailsStage v-else-if="currentStage === 'paypal-details'" />
|
||||
<CompletionStage v-else-if="currentStage === 'completion'" />
|
||||
<div v-else>Something went wrong</div>
|
||||
<div v-else>{{ formatMessage(commonMessages.errorNotificationTitle) }}</div>
|
||||
</div>
|
||||
<template #actions>
|
||||
<div v-if="currentStage === 'completion'" class="mt-4 flex w-full gap-3">
|
||||
@@ -96,7 +96,7 @@
|
||||
</NewModal>
|
||||
<CreatorTaxFormModal
|
||||
ref="taxFormModal"
|
||||
close-button-text="Continue"
|
||||
:close-button-text="formatMessage(commonMessages.continueButton)"
|
||||
@success="onTaxFormSuccess"
|
||||
@cancelled="onTaxFormCancelled"
|
||||
/>
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
v-model="formData.dateOfBirth"
|
||||
:max-date="maxDate"
|
||||
autocomplete="bday"
|
||||
placeholder="Select date of birth"
|
||||
:placeholder="formatMessage(messages.dateOfBirthPlaceholder)"
|
||||
wrapper-class="w-full"
|
||||
/>
|
||||
</div>
|
||||
@@ -162,7 +162,7 @@
|
||||
:options="subdivisionOptions"
|
||||
:placeholder="formatMessage(formFieldPlaceholders.statePlaceholder)"
|
||||
searchable
|
||||
search-placeholder="Search subdivisions..."
|
||||
:search-placeholder="formatMessage(messages.searchSubdivisionsPlaceholder)"
|
||||
/>
|
||||
<StyledInput
|
||||
v-else
|
||||
@@ -201,7 +201,7 @@
|
||||
:options="countryOptions"
|
||||
:placeholder="formatMessage(formFieldPlaceholders.countryPlaceholder)"
|
||||
searchable
|
||||
search-placeholder="Search countries..."
|
||||
:search-placeholder="formatMessage(messages.searchCountriesPlaceholder)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -361,5 +361,17 @@ const messages = defineMessages({
|
||||
id: 'dashboard.creator-withdraw-modal.kyc.business-entity',
|
||||
defaultMessage: 'Business entity',
|
||||
},
|
||||
dateOfBirthPlaceholder: {
|
||||
id: 'dashboard.creator-withdraw-modal.kyc.date-of-birth-placeholder',
|
||||
defaultMessage: 'Select date of birth',
|
||||
},
|
||||
searchSubdivisionsPlaceholder: {
|
||||
id: 'dashboard.creator-withdraw-modal.kyc.search-subdivisions-placeholder',
|
||||
defaultMessage: 'Search subdivisions...',
|
||||
},
|
||||
searchCountriesPlaceholder: {
|
||||
id: 'dashboard.creator-withdraw-modal.kyc.search-countries-placeholder',
|
||||
defaultMessage: 'Search countries...',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
+102
-53
@@ -58,9 +58,17 @@
|
||||
<Combobox
|
||||
v-model="selectedGiftCardId"
|
||||
:options="rewardOptions"
|
||||
:placeholder="`Select ${categoryLabel.toLowerCase()}`"
|
||||
:placeholder="
|
||||
formatMessage(messages.selectCategoryPlaceholder, {
|
||||
category: categoryLabel.toLowerCase(),
|
||||
})
|
||||
"
|
||||
searchable
|
||||
:search-placeholder="`Search ${categoryLabelPlural.toLowerCase()}...`"
|
||||
:search-placeholder="
|
||||
formatMessage(messages.searchCategoryPlaceholder, {
|
||||
category: categoryLabelPlural.toLowerCase(),
|
||||
})
|
||||
"
|
||||
class="h-10"
|
||||
>
|
||||
<template #selected>
|
||||
@@ -90,47 +98,21 @@
|
||||
</Combobox>
|
||||
</div>
|
||||
<span v-if="selectedMethodDetails" class="text-secondary">
|
||||
{{ formatMoney(displayMinUsd)
|
||||
}}<template v-if="selectedMethodCurrencyCode && selectedMethodCurrencyCode !== 'USD'"
|
||||
>({{
|
||||
formatAmountForDisplay(
|
||||
displayMinLocal,
|
||||
selectedMethodCurrencyCode,
|
||||
selectedMethodExchangeRate,
|
||||
)
|
||||
}})</template
|
||||
>
|
||||
min<template v-if="displayMinUsd <= roundedMaxAmount"
|
||||
>, {{ formatMoney(displayMaxUsd)
|
||||
}}<template v-if="selectedMethodCurrencyCode && selectedMethodCurrencyCode !== 'USD'"
|
||||
>({{
|
||||
formatAmountForDisplay(
|
||||
displayMaxLocal,
|
||||
selectedMethodCurrencyCode,
|
||||
selectedMethodExchangeRate,
|
||||
)
|
||||
}})</template
|
||||
>
|
||||
max</template
|
||||
>
|
||||
withdrawal amount.
|
||||
<template v-if="displayMinUsd <= roundedMaxAmount">{{
|
||||
formatMessage(messages.withdrawalAmountMinMax, {
|
||||
min: minAmountDisplay,
|
||||
max: maxAmountDisplay,
|
||||
})
|
||||
}}</template>
|
||||
<template v-else>{{
|
||||
formatMessage(messages.withdrawalAmountMinOnly, { min: minAmountDisplay })
|
||||
}}</template>
|
||||
</span>
|
||||
<span
|
||||
v-if="selectedMethodDetails && effectiveMinAmount > roundedMaxAmount"
|
||||
class="text-sm text-red"
|
||||
>
|
||||
You need at least
|
||||
{{ formatMoney(displayMinUsd)
|
||||
}}<template v-if="selectedMethodCurrencyCode && selectedMethodCurrencyCode !== 'USD'"
|
||||
>({{
|
||||
formatAmountForDisplay(
|
||||
displayMinLocal,
|
||||
selectedMethodCurrencyCode,
|
||||
selectedMethodExchangeRate,
|
||||
)
|
||||
}})</template
|
||||
>
|
||||
to use this gift card.
|
||||
{{ formatMessage(messages.needAtLeastGiftCard, { min: minAmountDisplay }) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -280,19 +262,13 @@
|
||||
v-if="!useDenominationSuggestions && denominationOptions.length === 0"
|
||||
class="text-error text-sm"
|
||||
>
|
||||
<template v-if="rawFixedDenominationMin !== null">
|
||||
The minimum denomination is
|
||||
{{
|
||||
formatAmountForDisplay(
|
||||
rawFixedDenominationMin,
|
||||
selectedMethodCurrencyCode,
|
||||
selectedMethodExchangeRate,
|
||||
)
|
||||
}}<template v-if="selectedMethodCurrencyCode && selectedMethodCurrencyCode !== 'USD'">
|
||||
({{ formatMoney(convertToUsd(rawFixedDenominationMin)) }})</template
|
||||
>, which exceeds your balance of {{ formatMoney(roundedMaxAmount) }}.
|
||||
</template>
|
||||
<template v-else>No denominations available for your current balance</template>
|
||||
<template v-if="rawFixedDenominationMin !== null">{{
|
||||
formatMessage(messages.minimumDenominationExceedsBalance, {
|
||||
min: minDenominationDisplay,
|
||||
balance: formatMoney(roundedMaxAmount),
|
||||
})
|
||||
}}</template>
|
||||
<template v-else>{{ formatMessage(messages.noDenominationsAvailable) }}</template>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -683,13 +659,50 @@ const noSuggestionsMessage = computed(() => {
|
||||
selectedMethodCurrencyCode.value,
|
||||
selectedMethodExchangeRate.value,
|
||||
)
|
||||
return `No denominations near this amount. The highest available is ${maxInLocal}.`
|
||||
return formatMessage(messages.noSuggestionsWithMax, { max: maxInLocal })
|
||||
}
|
||||
return 'No denominations near this amount'
|
||||
return formatMessage(messages.noSuggestionsNoMax)
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const minAmountDisplay = computed(() => {
|
||||
const base = formatMoney(displayMinUsd.value)
|
||||
if (selectedMethodCurrencyCode.value && selectedMethodCurrencyCode.value !== 'USD') {
|
||||
return `${base} (${formatAmountForDisplay(
|
||||
displayMinLocal.value,
|
||||
selectedMethodCurrencyCode.value,
|
||||
selectedMethodExchangeRate.value,
|
||||
)})`
|
||||
}
|
||||
return base
|
||||
})
|
||||
|
||||
const maxAmountDisplay = computed(() => {
|
||||
const base = formatMoney(displayMaxUsd.value)
|
||||
if (selectedMethodCurrencyCode.value && selectedMethodCurrencyCode.value !== 'USD') {
|
||||
return `${base} (${formatAmountForDisplay(
|
||||
displayMaxLocal.value,
|
||||
selectedMethodCurrencyCode.value,
|
||||
selectedMethodExchangeRate.value,
|
||||
)})`
|
||||
}
|
||||
return base
|
||||
})
|
||||
|
||||
const minDenominationDisplay = computed(() => {
|
||||
if (rawFixedDenominationMin.value === null) return ''
|
||||
const local = formatAmountForDisplay(
|
||||
rawFixedDenominationMin.value,
|
||||
selectedMethodCurrencyCode.value,
|
||||
selectedMethodExchangeRate.value,
|
||||
)
|
||||
if (selectedMethodCurrencyCode.value && selectedMethodCurrencyCode.value !== 'USD') {
|
||||
return `${local} (${formatMoney(convertToUsd(rawFixedDenominationMin.value))})`
|
||||
}
|
||||
return local
|
||||
})
|
||||
|
||||
const hasSelectedDenomination = computed(() => {
|
||||
return (
|
||||
formData.value.amount !== undefined &&
|
||||
@@ -1124,5 +1137,41 @@ const messages = defineMessages({
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.select-denomination-required',
|
||||
defaultMessage: 'Please select a denomination to continue',
|
||||
},
|
||||
selectCategoryPlaceholder: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.select-category-placeholder',
|
||||
defaultMessage: 'Select {category}',
|
||||
},
|
||||
searchCategoryPlaceholder: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.search-category-placeholder',
|
||||
defaultMessage: 'Search {category}...',
|
||||
},
|
||||
withdrawalAmountMinMax: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.withdrawal-amount-min-max',
|
||||
defaultMessage: '{min} min, {max} max withdrawal amount.',
|
||||
},
|
||||
withdrawalAmountMinOnly: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.withdrawal-amount-min-only',
|
||||
defaultMessage: '{min} min withdrawal amount.',
|
||||
},
|
||||
needAtLeastGiftCard: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.need-at-least-gift-card',
|
||||
defaultMessage: 'You need at least {min} to use this gift card.',
|
||||
},
|
||||
minimumDenominationExceedsBalance: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.minimum-denomination-exceeds-balance',
|
||||
defaultMessage: 'The minimum denomination is {min}, which exceeds your balance of {balance}.',
|
||||
},
|
||||
noDenominationsAvailable: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.no-denominations-available',
|
||||
defaultMessage: 'No denominations available for your current balance',
|
||||
},
|
||||
noSuggestionsWithMax: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.no-suggestions-with-max',
|
||||
defaultMessage: 'No denominations near this amount. The highest available is {max}.',
|
||||
},
|
||||
noSuggestionsNoMax: {
|
||||
id: 'dashboard.creator-withdraw-modal.tremendous-details.no-suggestions-no-max',
|
||||
defaultMessage: 'No denominations near this amount',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -27,10 +27,14 @@ const messages = defineMessages({
|
||||
id: 'hosting.plan.select-plan',
|
||||
defaultMessage: 'Select plan',
|
||||
},
|
||||
billedInterval: {
|
||||
id: 'servers.purchase.step.plan.billed',
|
||||
perMonthBilling: {
|
||||
id: 'servers.purchase.step.plan.per-month-billing',
|
||||
defaultMessage:
|
||||
'billed {interval, select, monthly {monthly} quarterly {quarterly} yearly {yearly} other {{interval}}}',
|
||||
'/ month{interval, select, monthly {} other {, billed {interval, select, quarterly {quarterly} yearly {yearly} other {{interval}}}}}',
|
||||
},
|
||||
mostPopularBadge: {
|
||||
id: 'servers.purchase.step.plan.most-popular',
|
||||
defaultMessage: 'Most popular',
|
||||
},
|
||||
})
|
||||
|
||||
@@ -131,15 +135,13 @@ const billingMonths = computed(() => {
|
||||
v-if="plans[plan].mostPopular"
|
||||
class="rounded-full bg-brand-highlight px-2 py-1 text-xs font-bold text-brand"
|
||||
>
|
||||
Most popular
|
||||
{{ formatMessage(messages.mostPopularBadge) }}
|
||||
</div>
|
||||
</div>
|
||||
<span class="m-0 text-2xl font-bold text-contrast">
|
||||
{{ formatPrice(price / billingMonths, currency, true) }}
|
||||
<span class="text-lg font-semibold text-secondary">
|
||||
/ month<template v-if="interval !== 'monthly'"
|
||||
>, {{ formatMessage(messages.billedInterval, { interval }) }}</template
|
||||
>
|
||||
{{ formatMessage(messages.perMonthBilling, { interval }) }}
|
||||
</span>
|
||||
</span>
|
||||
<p class="m-0 max-w-[18rem]">{{ formatMessage(plans[plan].description) }}</p>
|
||||
|
||||
Reference in New Issue
Block a user