refactor(astralrinth): localize account auth modal copy

This commit is contained in:
2026-06-19 21:27:28 +03:00
parent e9a917012f
commit f8ebcf8f17
4 changed files with 336 additions and 33 deletions
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Button } from '@modrinth/ui'
import { Button, defineMessages, useVIntl } from '@modrinth/ui'
import { ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
@@ -20,11 +20,75 @@ const emit = defineEmits<{
(event: 'retry-offline'): void
}>()
const { formatMessage } = useVIntl()
const authenticationElyByErrorModal = ref<ModalHandle | null>(null)
const inputElyByErrorModal = ref<ModalHandle | null>(null)
const inputOfflineErrorModal = ref<ModalHandle | null>(null)
const unexpectedErrorModal = ref<ModalHandle | null>(null)
const messages = defineMessages({
authenticationElyByHeader: {
id: 'astralrinth.app.minecraft-account.error.authentication-elyby.header',
defaultMessage: 'Error while proceeding authentication event with Ely.by',
},
authenticationElyByDescription: {
id: 'astralrinth.app.minecraft-account.error.authentication-elyby.description',
defaultMessage: 'An error occurred while logging in.',
},
inputElyByHeader: {
id: 'astralrinth.app.minecraft-account.error.input-elyby.header',
defaultMessage: 'Error while proceeding input event with Ely.by',
},
inputElyByDescription: {
id: 'astralrinth.app.minecraft-account.error.input-elyby.description',
defaultMessage:
'An error occurred while adding the Ely.by account. Please follow the instructions below.',
},
inputElyByNameOrEmailHint: {
id: 'astralrinth.app.minecraft-account.error.input-elyby.name-or-email-hint',
defaultMessage: 'Check that you have entered the correct player name or email.',
},
inputElyByPasswordHint: {
id: 'astralrinth.app.minecraft-account.error.input-elyby.password-hint',
defaultMessage: 'Check that you have entered the correct password.',
},
inputOfflineHeader: {
id: 'astralrinth.app.minecraft-account.error.input-offline.header',
defaultMessage: 'Error while proceeding input event with offline account',
},
inputOfflineDescription: {
id: 'astralrinth.app.minecraft-account.error.input-offline.description',
defaultMessage:
'An error occurred while adding the offline account. Please follow the instructions below.',
},
inputOfflineNameHint: {
id: 'astralrinth.app.minecraft-account.error.input-offline.name-hint',
defaultMessage: 'Check that you have entered the correct player name.',
},
inputOfflineLengthHint: {
id: 'astralrinth.app.minecraft-account.error.input-offline.length-hint',
defaultMessage:
'Player name must be at least {min} characters long and no more than {max} characters.',
},
inputOfflineFormatHint: {
id: 'astralrinth.app.minecraft-account.error.input-offline.format-hint',
defaultMessage: 'Make sure your name meets the format requirement `{nameExp}`',
},
unexpectedHeader: {
id: 'astralrinth.app.minecraft-account.error.unexpected.header',
defaultMessage: 'Unexpected error occurred',
},
unexpectedDescription: {
id: 'astralrinth.app.minecraft-account.error.unexpected.description',
defaultMessage: 'An unexpected error has occurred. Please try again later.',
},
retryAction: {
id: 'astralrinth.app.minecraft-account.error.retry-action',
defaultMessage: 'Try again',
},
})
defineExpose({
hideAuthenticationElyByError: () => authenticationElyByErrorModal.value?.hide(),
hideInputElyByError: () => inputElyByErrorModal.value?.hide(),
@@ -40,60 +104,76 @@ defineExpose({
<ModalWrapper
ref="authenticationElyByErrorModal"
class="modal"
header="Error while proceeding authentication event with Ely.by"
:header="formatMessage(messages.authenticationElyByHeader)"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="text-base font-medium text-red-700">
An error occurred while logging in.
{{ formatMessage(messages.authenticationElyByDescription) }}
</label>
<div class="mt-6 ml-auto">
<Button color="primary" @click="emit('retry-elyby')">Try again</Button>
<Button color="primary" @click="emit('retry-elyby')">
{{ formatMessage(messages.retryAction) }}
</Button>
</div>
</div>
</ModalWrapper>
<ModalWrapper
ref="inputElyByErrorModal"
class="modal"
header="Error while proceeding input event with Ely.by"
:header="formatMessage(messages.inputElyByHeader)"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="text-base font-medium text-red-700">
An error occurred while adding the Ely.by account. Please follow the instructions below.
{{ formatMessage(messages.inputElyByDescription) }}
</label>
<ul class="list-disc list-inside text-sm space-y-1">
<li>Check that you have entered the correct player name or email.</li>
<li>Check that you have entered the correct password.</li>
<li>{{ formatMessage(messages.inputElyByNameOrEmailHint) }}</li>
<li>{{ formatMessage(messages.inputElyByPasswordHint) }}</li>
</ul>
<div class="mt-6 ml-auto">
<Button color="primary" @click="emit('retry-elyby')">Try again</Button>
<Button color="primary" @click="emit('retry-elyby')">
{{ formatMessage(messages.retryAction) }}
</Button>
</div>
</div>
</ModalWrapper>
<ModalWrapper
ref="inputOfflineErrorModal"
class="modal"
header="Error while proceeding input event with offline account"
:header="formatMessage(messages.inputOfflineHeader)"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="text-base font-medium text-red-700">
An error occurred while adding the offline account. Please follow the instructions below.
{{ formatMessage(messages.inputOfflineDescription) }}
</label>
<ul class="list-disc list-inside text-sm space-y-1">
<li>Check that you have entered the correct player name.</li>
<li>{{ formatMessage(messages.inputOfflineNameHint) }}</li>
<li>
Player name must be at least {{ minOfflinePlayerNameLength }} characters long and no more
than {{ maxOfflinePlayerNameLength }} characters.
{{
formatMessage(messages.inputOfflineLengthHint, {
min: minOfflinePlayerNameLength,
max: maxOfflinePlayerNameLength,
})
}}
</li>
<li>
{{ formatMessage(messages.inputOfflineFormatHint, { nameExp }) }}
</li>
<li>Make sure your name meets the format requirement `{{ nameExp }}`</li>
</ul>
<div class="mt-6 ml-auto">
<Button color="primary" @click="emit('retry-offline')">Try again</Button>
<Button color="primary" @click="emit('retry-offline')">
{{ formatMessage(messages.retryAction) }}
</Button>
</div>
</div>
</ModalWrapper>
<ModalWrapper ref="unexpectedErrorModal" class="modal" header="Unexpected error occurred">
<ModalWrapper
ref="unexpectedErrorModal"
class="modal"
:header="formatMessage(messages.unexpectedHeader)"
>
<div class="modal-body">
<label class="label">An unexpected error has occurred. Please try again later.</label>
<label class="label">{{ formatMessage(messages.unexpectedDescription) }}</label>
</div>
</ModalWrapper>
</template>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Button } from '@modrinth/ui'
import { Button, defineMessages, useVIntl } from '@modrinth/ui'
import { ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
@@ -27,10 +27,67 @@ const emit = defineEmits<{
(event: 'update:offlinePlayerName', value: string): void
}>()
const { formatMessage } = useVIntl()
const addOfflineModal = ref<ModalHandle | null>(null)
const addElyByModal = ref<ModalHandle | null>(null)
const requestElyByTwoFactorCodeModal = ref<ModalHandle | null>(null)
const messages = defineMessages({
addElyByHeader: {
id: 'astralrinth.app.minecraft-account.input.elyby.header',
defaultMessage: 'Authenticate with Ely.by',
},
requestTwoFactorHeader: {
id: 'astralrinth.app.minecraft-account.input.elyby.two-factor.header',
defaultMessage: 'Ely.by requested 2FA code for authentication',
},
requestTwoFactorLabel: {
id: 'astralrinth.app.minecraft-account.input.elyby.two-factor.label',
defaultMessage: 'Enter your 2FA code',
},
requestTwoFactorPlaceholder: {
id: 'astralrinth.app.minecraft-account.input.elyby.two-factor.placeholder',
defaultMessage: 'Your 2FA code here...',
},
continueAction: {
id: 'astralrinth.app.minecraft-account.input.elyby.two-factor.continue-action',
defaultMessage: 'Continue',
},
elyByLoginLabel: {
id: 'astralrinth.app.minecraft-account.input.elyby.login.label',
defaultMessage: 'Enter your player name or email (preferred)',
},
elyByLoginPlaceholder: {
id: 'astralrinth.app.minecraft-account.input.elyby.login.placeholder',
defaultMessage: 'Your player name or email here...',
},
elyByPasswordLabel: {
id: 'astralrinth.app.minecraft-account.input.elyby.password.label',
defaultMessage: 'Enter your password',
},
elyByPasswordPlaceholder: {
id: 'astralrinth.app.minecraft-account.input.elyby.password.placeholder',
defaultMessage: 'Your password here...',
},
loginAction: {
id: 'astralrinth.app.minecraft-account.input.login-action',
defaultMessage: 'Login',
},
addOfflineHeader: {
id: 'astralrinth.app.minecraft-account.input.offline.header',
defaultMessage: 'Add new offline account',
},
offlineNameLabel: {
id: 'astralrinth.app.minecraft-account.input.offline.name.label',
defaultMessage: 'Enter your player name',
},
offlineNamePlaceholder: {
id: 'astralrinth.app.minecraft-account.input.offline.name.placeholder',
defaultMessage: 'Your player name here...',
},
})
defineExpose({
hideElyBy: () => addElyByModal.value?.hide(),
hideElyByTwoFactor: () => requestElyByTwoFactorCodeModal.value?.hide(),
@@ -42,18 +99,18 @@ defineExpose({
</script>
<template>
<ModalWrapper ref="addElyByModal" class="modal" header="Authenticate with Ely.by">
<ModalWrapper ref="addElyByModal" class="modal" :header="formatMessage(messages.addElyByHeader)">
<ModalWrapper
ref="requestElyByTwoFactorCodeModal"
class="modal"
header="Ely.by requested 2FA code for authentication"
:header="formatMessage(messages.requestTwoFactorHeader)"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="label form-label">Enter your 2FA code</label>
<label class="label form-label">{{ formatMessage(messages.requestTwoFactorLabel) }}</label>
<input
:value="props.elyByTwoFactorCode"
type="text"
placeholder="Your 2FA code here..."
:placeholder="formatMessage(messages.requestTwoFactorPlaceholder)"
class="input soft-input"
@input="
emit('update:elyByTwoFactorCode', ($event.target as HTMLInputElement).value)
@@ -61,48 +118,52 @@ defineExpose({
/>
<div class="mt-6 ml-auto">
<Button color="primary" :disabled="props.elyByLoginDisabled" @click="emit('submit-elyby')">
Continue
{{ formatMessage(messages.continueAction) }}
</Button>
</div>
</div>
</ModalWrapper>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="label form-label">Enter your player name or email (preferred)</label>
<label class="label form-label">{{ formatMessage(messages.elyByLoginLabel) }}</label>
<input
:value="props.elyByLoginValue"
type="text"
placeholder="Your player name or email here..."
:placeholder="formatMessage(messages.elyByLoginPlaceholder)"
class="input soft-input"
@input="emit('update:elyByLoginValue', ($event.target as HTMLInputElement).value)"
/>
<label class="label form-label">Enter your password</label>
<label class="label form-label">{{ formatMessage(messages.elyByPasswordLabel) }}</label>
<input
:value="props.elyByPassword"
type="password"
placeholder="Your password here..."
:placeholder="formatMessage(messages.elyByPasswordPlaceholder)"
class="input soft-input"
@input="emit('update:elyByPassword', ($event.target as HTMLInputElement).value)"
/>
<div class="mt-6 ml-auto">
<Button color="primary" :disabled="props.elyByLoginDisabled" @click="emit('submit-elyby')">
Login
{{ formatMessage(messages.loginAction) }}
</Button>
</div>
</div>
</ModalWrapper>
<ModalWrapper ref="addOfflineModal" class="modal" header="Add new offline account">
<ModalWrapper
ref="addOfflineModal"
class="modal"
:header="formatMessage(messages.addOfflineHeader)"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="label form-label">Enter your player name</label>
<label class="label form-label">{{ formatMessage(messages.offlineNameLabel) }}</label>
<input
:value="props.offlinePlayerName"
type="text"
placeholder="Your player name here..."
:placeholder="formatMessage(messages.offlineNamePlaceholder)"
class="input soft-input"
@input="emit('update:offlinePlayerName', ($event.target as HTMLInputElement).value)"
/>
<div class="mt-6 ml-auto">
<Button color="primary" :disabled="props.offlineLoginDisabled" @click="emit('submit-offline')">
Login
{{ formatMessage(messages.loginAction) }}
</Button>
</div>
</div>