feat(SPA): i18n internationzalization, english and french

This commit is contained in:
fsylvain committed 2026-10-03 01:53:49 +02:00
1 parent 7f1e8e572d
commit 721311a643
88 files changed
+4438 -1148

No files matched your search

+32 -18
View File
@@ -1,4 +1,6 @@
<script setup lang="ts">
import { t, translate } from '@/i18n'
import { computed, nextTick, ref, watch } from 'vue'
import CharacterCounter from '@/components/CharacterCounter.vue'
import { ApiError, useApi } from '@/composables/useApi'
@@ -34,10 +36,10 @@ const titleLengthError = computed(() => {
return ''
}
if (titleLength.value < TITLE_MIN_LENGTH) {
return 'Use at least 3 characters.'
return t('Use at least 3 characters.')
}
if (titleLength.value > TITLE_MAX_LENGTH) {
return 'Use 3 to 200 characters.'
return t('Use 3 to 200 characters.')
}
return ''
})
@@ -46,7 +48,7 @@ const titleError = computed(() => titleServerError.value || titleLengthError.val
const bodyError = computed(() =>
bodyTouched.value && !bodyValid.value
? 'Add a first paragraph. It can be a single sentence.'
? t('Add a first paragraph. It can be a single sentence.')
: '',
)
@@ -56,10 +58,10 @@ const showHelp = computed(() => !submitting.value && formAlert.value === '')
const alertMessage = computed(() => {
if (formAlert.value === 'invalid') {
return "Something in the form isn't valid. Check the highlighted fields."
return t("Something in the form isn't valid. Check the highlighted fields.")
}
if (formAlert.value === 'failed') {
return "Couldn't create the article. Your text is still here. Try again in a moment."
return t("Couldn't create the article. Your text is still here. Try again in a moment.")
}
return ''
})
@@ -78,7 +80,9 @@ function resetForm() {
async function focusTitleField() {
await nextTick()
await nextTick()
document.querySelector<HTMLInputElement>(`input[placeholder="${TITLE_PLACEHOLDER}"]`)?.focus()
document
.querySelector<HTMLInputElement>(`input[placeholder="${t(TITLE_PLACEHOLDER)}"]`)
?.focus()
titleFocused.value = true
}
@@ -147,8 +151,8 @@ function onCancel() {
<template>
<UModal
v-model:open="open"
title="New article"
description="It's saved as a draft. Titles can't be changed later, so check it now."
:title="t('New article')"
:description="t('It\'s saved as a draft. Titles can\'t be changed later, so check it now.')"
:dismissible="!submitting"
:ui="{
content:
@@ -173,7 +177,11 @@ function onCancel() {
:description="alertMessage"
/>
<UForm :state="{ title, body }" class="flex flex-col gap-4">
<UFormField label="Title" name="title" :error="titleError || undefined">
<UFormField
:label="t('Title')"
name="title"
:error="translate(titleError) || undefined"
>
<template #hint>
<CharacterCounter
:value="titleLength"
@@ -188,13 +196,15 @@ function onCancel() {
name="i-lucide-circle-alert"
class="size-3.5 shrink-0 text-error"
/>
{{ error }}
{{ t(error) }}
</span>
</template>
<template v-else-if="showHelp" #help>3 to 200 characters.</template>
<template v-else-if="showHelp" #help>{{
t('3 to 200 characters.')
}}</template>
<UInput
v-model="title"
:placeholder="TITLE_PLACEHOLDER"
:placeholder="t(TITLE_PLACEHOLDER)"
:disabled="submitting"
color="primary"
:highlight="titleFocused || !!titleError"
@@ -204,22 +214,26 @@ function onCancel() {
@blur="onTitleBlur"
/>
</UFormField>
<UFormField label="First paragraph" name="body" :error="bodyError || undefined">
<UFormField
:label="t('First paragraph')"
name="body"
:error="bodyError || undefined"
>
<template v-if="bodyError" #error="{ error }">
<span class="flex items-center gap-1.5">
<UIcon
name="i-lucide-circle-alert"
class="size-3.5 shrink-0 text-error"
/>
{{ error }}
{{ t(error) }}
</span>
</template>
<template v-else-if="showHelp" #help>
You can format it and add images in the editor.
{{ t('You can format it and add images in the editor.') }}
</template>
<UTextarea
v-model="body"
placeholder="Start writing. You'll continue in the editor."
:placeholder="t('Start writing. You\'ll continue in the editor.')"
:disabled="submitting"
:highlight="!!bodyError"
:rows="3"
@@ -244,7 +258,7 @@ function onCancel() {
:disabled="submitting"
@click="onCancel"
>
Cancel
{{ t('Cancel') }}
</UButton>
<UButton
block
@@ -254,7 +268,7 @@ function onCancel() {
:disabled="submitting"
@click="onSubmit"
>
{{ submitting ? 'Creating…' : 'Create draft' }}
{{ submitting ? t('Creating…') : t('Create draft') }}
</UButton>
</div>
</template>