Move locales to single json files & Replace laravel-vue-i18n with vue-i18n

This commit is contained in:
Bubka
2025-06-20 18:14:21 +02:00
parent 01e56284ca
commit 6f419cfbcb
412 changed files with 3531 additions and 30057 deletions

View File

@@ -142,23 +142,23 @@
<nav v-if="props.showSearch" class="level is-mobile mb-2">
<div class="level-item has-text-centered">
<div class="buttons">
<button id="btnShowOneMonth" :title="$t('admin.show_last_month_log')" v-on:click="setPeriod(periods.aMonth)" :class="{ 'has-text-grey' : period !== periods.aMonth }" type="button" class="button is-ghost p-1">
{{ $t('commons.one_month') }}
<button id="btnShowOneMonth" :title="$t('message.admin.show_last_month_log')" v-on:click="setPeriod(periods.aMonth)" :class="{ 'has-text-grey' : period !== periods.aMonth }" type="button" class="button is-ghost p-1">
{{ $t('message.one_month') }}
</button>
<button id="btnShowThreeMonths" :title="$t('admin.show_three_months_log')" v-on:click="setPeriod(periods.threeMonths)" :class="{ 'has-text-grey' : period !== periods.threeMonths }" type="button" class="button is-ghost p-1">
{{ $t('commons.x_month', { 'x' : '3' }) }}
<button id="btnShowThreeMonths" :title="$t('message.admin.show_three_months_log')" v-on:click="setPeriod(periods.threeMonths)" :class="{ 'has-text-grey' : period !== periods.threeMonths }" type="button" class="button is-ghost p-1">
{{ $t('message.x_month', { 'x' : '3' }) }}
</button>
<button id="btnShowSixMonths" :title="$t('admin.show_six_months_log')" v-on:click="setPeriod(periods.halfYear)" :class="{ 'has-text-grey' : period !== periods.halfYear }" type="button" class="button is-ghost p-1">
{{ $t('commons.x_month', { 'x' : '6' }) }}
<button id="btnShowSixMonths" :title="$t('message.admin.show_six_months_log')" v-on:click="setPeriod(periods.halfYear)" :class="{ 'has-text-grey' : period !== periods.halfYear }" type="button" class="button is-ghost p-1">
{{ $t('message.x_month', { 'x' : '6' }) }}
</button>
<button id="btnShowOneYear" :title="$t('admin.show_one_year_log')" v-on:click="setPeriod(periods.aYear)" :class="{ 'has-text-grey' : period !== periods.aYear }" type="button" class="button is-ghost p-1 mr-5">
{{ $t('commons.one_year') }}
<button id="btnShowOneYear" :title="$t('message.admin.show_one_year_log')" v-on:click="setPeriod(periods.aYear)" :class="{ 'has-text-grey' : period !== periods.aYear }" type="button" class="button is-ghost p-1 mr-5">
{{ $t('message.one_year') }}
</button>
<button id="btnSortLogDesc" v-on:click="setDesc" :title="$t('admin.sort_by_date_desc')" :class="{ 'has-text-grey' : !orderIsDesc }" type="button" class="button p-1 is-ghost">
<button id="btnSortLogDesc" v-on:click="setDesc" :title="$t('message.admin.sort_by_date_desc')" :class="{ 'has-text-grey' : !orderIsDesc }" type="button" class="button p-1 is-ghost">
<FontAwesomeIcon :icon="['fas', 'arrow-up-long']" flip="vertical" />
<FontAwesomeIcon :icon="['far', 'calendar']" />
</button>
<button id="btnSortLogAsc" v-on:click="setAsc" :title="$t('admin.sort_by_date_asc')" :class="{ 'has-text-grey' : orderIsDesc }" type="button" class="button p-1 is-ghost">
<button id="btnSortLogAsc" v-on:click="setAsc" :title="$t('message.admin.sort_by_date_asc')" :class="{ 'has-text-grey' : orderIsDesc }" type="button" class="button p-1 is-ghost">
<FontAwesomeIcon :icon="['fas', 'arrow-up-long']" />
<FontAwesomeIcon :icon="['far', 'calendar']" />
</button>
@@ -170,15 +170,31 @@
<UseColorMode v-slot="{ mode }">
<div>
<div>
<span v-if="isFailedEntry(authentication)" v-html="$t('admin.failed_login_on', { login_at: authentication.login_at })" />
<span v-else-if="isSuccessfulLogout(authentication)" v-html="$t('admin.successful_logout_on', { login_at: authentication.logout_at })" />
<span v-else-if="$2fauth.config.proxyAuth" v-html="$t('admin.viewed_on', { login_at: authentication.login_at })" />
<span v-else v-html="$t('admin.successful_login_on', { login_at: authentication.login_at })" />
<i18n-t v-if="isFailedEntry(authentication)" keypath="message.admin.failed_login_on" tag="span">
<template v-slot:login_at>
<span class="light-or-darker">{{ authentication.login_at }}</span>
</template>
</i18n-t>
<i18n-t v-else-if="isSuccessfulLogout(authentication)" keypath="message.admin.successful_logout_on" tag="span">
<template v-slot:logout_at>
<span class="light-or-darker">{{ authentication.logout_at }}</span>
</template>
</i18n-t>
<i18n-t v-else-if="$2fauth.config.proxyAuth" keypath="message.admin.viewed_on" tag="span">
<template v-slot:login_at>
<span class="light-or-darker">{{ authentication.login_at }}</span>
</template>
</i18n-t>
<i18n-t v-else keypath="message.admin.successful_login_on" tag="span">
<template v-slot:login_at>
<span class="light-or-darker">{{ authentication.login_at }}</span>
</template>
</i18n-t>
</div>
<div>
{{ $t('commons.IP') }}: <span class="light-or-darker">{{ authentication.ip_address }}</span> -
{{ $t('commons.browser') }}: <span class="light-or-darker">{{ authentication.browser }}</span> -
{{ $t('commons.operating_system_short') }}: <span class="light-or-darker">{{ authentication.platform }}</span>
{{ $t('message.IP') }}: <span class="light-or-darker">{{ authentication.ip_address }}</span> -
{{ $t('message.browser') }}: <span class="light-or-darker">{{ authentication.browser }}</span> -
{{ $t('message.operating_system_short') }}: <span class="light-or-darker">{{ authentication.platform }}</span>
</div>
</div>
<div :class="mode == 'dark' ? 'has-text-grey-darker' : 'has-text-grey-lighter'" class="is-align-self-center ">
@@ -193,10 +209,10 @@
</div>
</div>
<div v-else-if="authentications.length == 0" class="mt-4">
{{ $t('commons.no_entry_yet') }}
{{ $t('message.no_entry_yet') }}
</div>
<div v-else class="mt-5 pl-3">
{{ $t('commons.no_result') }}
{{ $t('message.no_result') }}
</div>
<Spinner :isVisible="isFetching" />
</template>

View File

@@ -33,7 +33,7 @@
<!-- New item buttons -->
<p class="control" v-if="!inManagementMode">
<button type="button" class="button is-link is-rounded is-focus" @click="goAddNewAccount">
<span>{{ $t('commons.new') }}</span>
<span>{{ $t('message.new') }}</span>
<span class="icon is-small">
<FontAwesomeIcon :icon="['fas', 'qrcode']" />
</span>
@@ -41,7 +41,7 @@
</p>
<!-- Manage button -->
<p class="control" v-if="!inManagementMode">
<button type="button" id="btnManage" class="button is-rounded" :class="{'is-dark' : mode == 'dark'}" @click="$emit('update:inManagementMode', true)">{{ $t('commons.manage') }}</button>
<button type="button" id="btnManage" class="button is-rounded" :class="{'is-dark' : mode == 'dark'}" @click="$emit('update:inManagementMode', true)">{{ $t('message.manage') }}</button>
</p>
<!-- move button -->
<p class="control" v-if="inManagementMode">
@@ -50,8 +50,8 @@
:disabled='areDisabled' class="button is-rounded"
:class="[{ 'is-outlined': mode == 'dark' || areDisabled }, areDisabled ? 'is-dark': 'is-link']"
@click="$emit('move-button-clicked')"
:title="$t('groups.move_selected_to_group')" >
{{ $t('commons.move') }}
:title="$t('message.groups.move_selected_to_group')" >
{{ $t('message.move') }}
</button>
</p>
<!-- delete button -->
@@ -61,7 +61,7 @@
:disabled='areDisabled' class="button is-rounded"
:class="[{ 'is-outlined': mode == 'dark' || areDisabled }, areDisabled ? 'is-dark': 'is-link']"
@click="$emit('delete-button-clicked')" >
{{ $t('commons.delete') }}
{{ $t('message.delete') }}
</button>
</p>
<!-- export button -->
@@ -71,8 +71,8 @@
:disabled='areDisabled' class="button is-rounded"
:class="[{ 'is-outlined': mode == 'dark' || areDisabled }, areDisabled ? 'is-dark': 'is-link']"
@click="$emit('export-button-clicked')"
:title="$t('twofaccounts.export_selected_accounts')" >
{{ $t('commons.export') }}
:title="$t('message.twofaccounts.export_selected_accounts')" >
{{ $t('message.export') }}
</button>
</p>
</UseColorMode>

View File

@@ -1,5 +1,7 @@
<script setup>
import { useNotifyStore } from '@/stores/notify'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const notify = useNotifyStore()
const { copy } = useClipboard({ legacy: true })
@@ -10,12 +12,12 @@
function copyToClipboard() {
copy(props.token)
notify.success({ text: trans('commons.copied_to_clipboard') })
notify.success({ text: t('message.copied_to_clipboard') })
}
</script>
<template>
<button type="button" :aria-label="$t('commons.copy_to_clipboard')" :title="$t('commons.copy_to_clipboard')" class="button is-like-text is-pulled-right is-small is-text" @click.stop="copyToClipboard()">
<button type="button" :aria-label="$t('message.copy_to_clipboard')" :title="$t('message.copy_to_clipboard')" class="button is-like-text is-pulled-right is-small is-text" @click.stop="copyToClipboard()">
<FontAwesomeIcon :icon="['fas', 'copy']" />
</button>
</template>

View File

@@ -33,7 +33,7 @@
<div class="container group-selector">
<div class="columns is-centered is-multiline">
<div class="column is-full has-text-centered">
{{ $t('groups.move_selected_to') }}
{{ $t('message.groups.move_selected_to') }}
</div>
<div class="column is-one-third-tablet is-one-quarter-desktop is-one-quarter-widescreen is-one-quarter-fullhd">
<div class="columns is-multiline">
@@ -41,7 +41,7 @@
<UseColorMode v-slot="{ mode }">
<button type="button" class="button is-fullwidth" :class="{'is-link' : destinationGroupId === group.id, 'is-dark has-text-light is-outlined': mode == 'dark'}" @click="destinationGroupId = group.id">
<span v-if="group.id === 0" class="is-italic">
{{ $t('groups.no_group') }}
{{ $t('message.groups.no_group') }}
</span>
<span v-else>
{{ group.name }}
@@ -52,7 +52,7 @@
</div>
<div class="columns is-centered">
<div class="column has-text-centered">
<RouterLink :to="{ name: 'groups' }" >{{ $t('groups.manage_groups') }}</RouterLink>
<RouterLink :to="{ name: 'groups' }" >{{ $t('message.groups.manage_groups') }}</RouterLink>
</div>
</div>
</div>
@@ -60,7 +60,7 @@
<VueFooter :showButtons="true">
<!-- Move to selected group button -->
<p class="control">
<button type="button" class="button is-link is-rounded" @click="moveAccounts">{{ $t('commons.move') }}</button>
<button type="button" class="button is-link is-rounded" @click="moveAccounts">{{ $t('message.move') }}</button>
</p>
<NavigationButton action="cancel" :useLinkTag="false" @canceled="$emit('update:showDestinationGroupSelector', false)" />
</VueFooter>

View File

@@ -11,29 +11,29 @@
<div class="block">
<UseColorMode v-slot="{ mode }">
<p class="has-text-weight-bold has-text-grey">
{{ $t('twofaccounts.twofauth_export_format_sub') }}
{{ $t('message.twofaccounts.twofauth_export_format_sub') }}
</p>
</UseColorMode>
<p class="is-size-7-mobile">
{{ $t('twofaccounts.twofauth_export_format_desc') }}
{{ $t('twofaccounts.twofauth_export_format_url') }}
{{ $t('message.twofaccounts.twofauth_export_format_desc') }}
{{ $t('message.twofaccounts.twofauth_export_format_url') }}
<a id="lnkExportSchemaUrl" class="is-link" tabindex="0" :href="$2fauth.urls.exportSchemaUrl" target="_blank">
{{ $t('twofaccounts.twofauth_export_schema') }}
{{ $t('message.twofaccounts.twofauth_export_schema') }}
</a>
</p>
<button type="button" id="btnExport2FAuth" class="button is-link is-rounded is-focus my-3" @click="$emit('export-twofauth-format')" :title="$t('twofaccounts.twofauth_export_format_sub')">
{{ $t('twofaccounts.twofauth_export_format') }}
<button type="button" id="btnExport2FAuth" class="button is-link is-rounded is-focus my-3" @click="$emit('export-twofauth-format')" :title="$t('message.twofaccounts.twofauth_export_format_sub')">
{{ $t('message.twofaccounts.twofauth_export_format') }}
</button>
</div>
<div class="block">
<p class="has-text-weight-bold has-text-grey">
{{ $t('twofaccounts.otpauth_export_format_sub') }}
{{ $t('message.twofaccounts.otpauth_export_format_sub') }}
</p>
<p class="is-size-7-mobile">
{{ $t('twofaccounts.otpauth_export_format_desc') }}
{{ $t('message.twofaccounts.otpauth_export_format_desc') }}
</p>
<button type="button" id="btnExportOtpauth" class="button is-link is-rounded is-focus my-3" @click="$emit('export-otpauth-format')" :title="$t('twofaccounts.otpauth_export_format_sub')">
{{ $t('twofaccounts.otpauth_export_format') }}
<button type="button" id="btnExportOtpauth" class="button is-link is-rounded is-focus my-3" @click="$emit('export-otpauth-format')" :title="$t('message.twofaccounts.otpauth_export_format_sub')">
{{ $t('message.twofaccounts.otpauth_export_format') }}
</button>
</div>
</template>

View File

@@ -39,7 +39,7 @@
</div>
<div class="columns is-centered">
<div class="column has-text-centered">
<RouterLink :to="{ name: 'groups' }" >{{ $t('groups.manage_groups') }}</RouterLink>
<RouterLink :to="{ name: 'groups' }" >{{ $t('message.groups.manage_groups') }}</RouterLink>
</div>
</div>
</div>

View File

@@ -1,4 +1,5 @@
<script setup>
import { useI18n } from 'vue-i18n'
import Spinner from '@/components/Spinner.vue'
import TotpLooper from '@/components/TotpLooper.vue'
import Dots from '@/components/Dots.vue'
@@ -8,6 +9,7 @@
import { UseColorMode } from '@vueuse/components'
import { useDisplayablePassword } from '@/composables/helpers'
const { t } = useI18n()
const user = useUserStore()
const notify = useNotifyStore()
const $2fauth = inject('2fauth')
@@ -115,10 +117,10 @@
}
// Case 3
else if (! props.secret) {
notify.error(new Error(trans('errors.cannot_create_otp_without_secret')))
notify.error(new Error(t('error.cannot_create_otp_without_secret')))
}
else if (! isTimeBased(otpauthParams.value.otp_type) && ! isHMacBased(otpauthParams.value.otp_type)) {
notify.error(new Error(trans('errors.not_a_supported_otp_type')))
notify.error(new Error(t('error.not_a_supported_otp_type')))
}
try {
@@ -267,7 +269,7 @@
: user.preferences.defaultGroup
}
notify.success({ text: trans('commons.copied_to_clipboard') })
notify.success({ text: t('message.copied_to_clipboard') })
}
}
@@ -318,7 +320,7 @@
<template>
<div>
<figure class="image is-64x64" :class="{ 'no-icon': !otpauthParams.icon }" style="display: inline-flex">
<img :src="$2fauth.config.subdirectory + '/storage/icons/' + otpauthParams.icon" v-if="otpauthParams.icon" :alt="$t('twofaccounts.icon_to_illustrate_the_account')">
<img :src="$2fauth.config.subdirectory + '/storage/icons/' + otpauthParams.icon" v-if="otpauthParams.icon" :alt="$t('message.twofaccounts.icon_to_illustrate_the_account')">
</figure>
<UseColorMode v-slot="{ mode }">
<p class="is-size-4 has-ellipsis" :class="mode == 'dark' ? 'has-text-grey-light' : 'has-text-grey'">{{ otpauthParams.service }}</p>
@@ -334,7 +336,7 @@
:class="mode == 'dark' ? 'has-text-white' : 'has-text-grey-dark'"
@click="copyOTP(password, true)"
@keyup.enter="copyOTP(password, true)"
:title="$t('commons.copy_to_clipboard')"
:title="$t('message.copy_to_clipboard')"
>
{{ useDisplayablePassword(password, user.preferences.showOtpAsDot && user.preferences.revealDottedOTP && revealPassword) }}
</span>
@@ -345,7 +347,7 @@
</UseColorMode>
<Dots v-show="isTimeBased(otpauthParams.otp_type)" ref="dots"></Dots>
<p v-show="isHMacBased(otpauthParams.otp_type)">
{{ $t('twofaccounts.forms.counter.label') }}: {{ otpauthParams.counter }}
{{ $t('message.twofaccounts.forms.counter.label') }}: {{ otpauthParams.counter }}
</p>
<p v-if="user.preferences.showNextOtp" class="mt-3 is-size-4">
<span
@@ -354,7 +356,7 @@
:class="opacity"
@click="copyOTP(next_password, true)"
@keyup.enter="copyOTP(next_password, true)"
:title="$t('commons.copy_next_password')"
:title="$t('message.copy_next_password')"
>
{{ useDisplayablePassword(next_password, user.preferences.showOtpAsDot && user.preferences.revealDottedOTP && revealPassword) }}
</span>

View File

@@ -1,7 +1,9 @@
<script setup>
const { copy } = useClipboard({ legacy: true })
import { useNotifyStore } from '@/stores/notify'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const notify = useNotifyStore()
const props = defineProps({
@@ -38,26 +40,26 @@
*/
function copyToClipboard(data) {
copy(data)
notify.success({ text: trans('commons.copied_to_clipboard') })
notify.success({ text: t('message.copied_to_clipboard') })
}
</script>
<template>
<div class="too-bad"></div>
<div class="block">
{{ $t('errors.data_of_qrcode_is_not_valid_URI') }}
{{ $t('error.data_of_qrcode_is_not_valid_URI') }}
</div>
<div class="block mb-6 light-or-darker">{{ qrContent ? qrContent : '[' + trans('commons.nothing') + ']' }}</div>
<div class="block mb-6 light-or-darker">{{ qrContent ? qrContent : '[' + $t('message.nothing') + ']' }}</div>
<!-- Copy to clipboard -->
<div class="block has-text-link" v-if="qrContent">
<button type="button" class="button is-link is-outlined is-rounded" @click.stop="copyToClipboard(qrContent)">
{{ $t('commons.copy_to_clipboard') }}
{{ $t('message.copy_to_clipboard') }}
</button>
</div>
<!-- Open in browser -->
<div class="block has-text-link" v-if="isUrl(qrContent)" @click="openInBrowser(qrContent)">
<button type="button" class="button is-link is-outlined is-rounded">
<span>{{ $t('commons.open_in_browser') }}</span>
<span>{{ $t('message.open_in_browser') }}</span>
<span class="icon is-small">
<FontAwesomeIcon :icon="['fas', 'external-link-alt']" />
</span>

View File

@@ -64,13 +64,13 @@
id="txtSearch"
type="search"
tabindex="1"
:aria-label="$t('commons.search')"
:title="$t('commons.search')"
:aria-label="$t('message.search')"
:title="$t('message.search')"
:placeholder="placeholder"
class="input is-rounded is-search"
:class="{ 'has-no-background': hasNoBackground }">
<span class="icon is-small is-right">
<button type="button" v-if="keyword != ''" id="btnClearSearch" tabindex="1" :title="$t('commons.clear_search')" class="clear-selection delete" @click="clearSearch"></button>
<button type="button" v-if="keyword != ''" id="btnClearSearch" tabindex="1" :title="$t('message.clear_search')" class="clear-selection delete" @click="clearSearch"></button>
<FontAwesomeIcon v-else :icon="['fas', 'search']" />
</span>
</div>

View File

@@ -7,7 +7,7 @@
},
message: {
type: String,
default: 'commons.generating_otp'
default: 'message.generating_otp'
}
})
</script>

View File

@@ -24,7 +24,7 @@
<template>
<a :id="'lnkSignWith' + props.provider" class="button is-link" :href="'socialite/redirect/' + props.provider">
{{ $t('auth.sso_providers.' + props.provider) }}
{{ $t('message.auth.sso_providers.' + props.provider) }}
<FontAwesomeIcon class="ml-2" :icon="[icons[props.provider].collection, icons[props.provider].icon]" />
</a>
</template>

View File

@@ -9,19 +9,19 @@
<div class="columns">
<div class="column has-nowrap px-0">
<!-- selected label -->
<span class="has-text-grey mr-1">{{ $t('commons.x_selected', { count: selectedCount }) }}</span>
<span class="has-text-grey mr-1">{{ $t('message.x_selected', { count: selectedCount }) }}</span>
<!-- deselect all -->
<button type="button" id="btnUnselectAll" @click="$emit('clear-selected')" class="clear-selection delete mr-4" :style="{visibility: selectedCount > 0 ? 'visible' : 'hidden'}" :title="$t('commons.clear_selection')"></button>
<button type="button" id="btnUnselectAll" @click="$emit('clear-selected')" class="clear-selection delete mr-4" :style="{visibility: selectedCount > 0 ? 'visible' : 'hidden'}" :title="$t('message.clear_selection')"></button>
<!-- select all button -->
<button type="button" id="btnSelectAll" @click="$emit('select-all')" class="button mr-5 has-line-height p-1 is-ghost has-text-grey" :title="$t('commons.select_all')">
<span>{{ $t('commons.check_all') }}</span>
<button type="button" id="btnSelectAll" @click="$emit('select-all')" class="button mr-5 has-line-height p-1 is-ghost has-text-grey" :title="$t('message.select_all')">
<span>{{ $t('message.check_all') }}</span>
<FontAwesomeIcon class="ml-1" :icon="['fas', 'check-square']" />
</button>
<!-- sort asc/desc buttons -->
<button type="button" id="btnSortAscending" @click="$emit('sort-asc')" class="button has-line-height p-1 is-ghost has-text-grey" :title="$t('commons.sort_ascending')">
<button type="button" id="btnSortAscending" @click="$emit('sort-asc')" class="button has-line-height p-1 is-ghost has-text-grey" :title="$t('message.sort_ascending')">
<FontAwesomeIcon :icon="['fas', 'sort-alpha-down']" />
</button>
<button type="button" id="btnSortDescending" @click="$emit('sort-desc')" class="button has-line-height p-1 is-ghost has-text-grey" :title="$t('commons.sort_descending')">
<button type="button" id="btnSortDescending" @click="$emit('sort-desc')" class="button has-line-height p-1 is-ghost has-text-grey" :title="$t('message.sort_descending')">
<FontAwesomeIcon :icon="['fas', 'sort-alpha-up']" />
</button>
</div>

View File

@@ -28,18 +28,18 @@
<template>
<div class="columns is-mobile is-vcentered">
<div class="column is-narrow">
<button type="button" :class="isScanning ? 'is-loading' : ''" class="button is-link is-rounded is-small" @click="getLatestRelease">{{ $t('admin.check_now') }}</button>
<button type="button" :class="isScanning ? 'is-loading' : ''" class="button is-link is-rounded is-small" @click="getLatestRelease">{{ $t('message.admin.check_now') }}</button>
</div>
<div class="column">
<UseColorMode v-slot="{ mode }">
<span v-if="appSettings.latestRelease" class="mt-2" :class="mode == 'dark' ? 'has-text-warning' : 'has-text-warning-dark'">
<span class="release-flag"></span>{{ $t('admin.x_is_available', { version: appSettings.latestRelease }) }}&nbsp;<a class="is-size-7" href="https://github.com/Bubka/2FAuth/releases">{{ $t('admin.view_on_github') }}</a>
<span class="release-flag"></span>{{ $t('message.admin.x_is_available', { version: appSettings.latestRelease }) }}&nbsp;<a class="is-size-7" href="https://github.com/Bubka/2FAuth/releases">{{ $t('message.admin.view_on_github') }}</a>
</span>
<span v-if="isUpToDate" class="has-text-grey">
<FontAwesomeIcon :icon="['fas', 'check']" class="mr-1 has-text-success" /> {{ $t('commons.you_are_up_to_date') }}
<FontAwesomeIcon :icon="['fas', 'check']" class="mr-1 has-text-success" /> {{ $t('message.you_are_up_to_date') }}
</span>
<span v-else-if="isUpToDate === null" class="has-text-grey">
<FontAwesomeIcon :icon="['fas', 'times']" class="mr-1 has-text-danger" />{{ $t('errors.check_failed_try_later') }}
<FontAwesomeIcon :icon="['fas', 'times']" class="mr-1 has-text-danger" />{{ $t('error.check_failed_try_later') }}
</span>
</UseColorMode>
</div>