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

+54 -15
View File
@@ -1,4 +1,6 @@
<script setup lang="ts">
import { t } from '@/i18n'
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import ArticleStatusBadge from '@/components/ArticleStatusBadge.vue'
@@ -27,10 +29,37 @@ const columnWidths =
const sorting = ref([{ id: 'updated_at', desc: true }])
const columns = [
{ accessorKey: 'title', header: 'Title', enableSorting: true },
{ accessorKey: 'is_online', header: 'Status', size: 110, enableSorting: true },
{ accessorKey: 'created_at', header: 'Created', size: 130, enableSorting: true },
{ accessorKey: 'updated_at', header: 'Updated', size: 140, enableSorting: true },
{
accessorKey: 'title',
get header() {
return t('Title')
},
enableSorting: true,
},
{
accessorKey: 'is_online',
get header() {
return t('Status')
},
size: 110,
enableSorting: true,
},
{
accessorKey: 'created_at',
get header() {
return t('Created')
},
size: 130,
enableSorting: true,
},
{
accessorKey: 'updated_at',
get header() {
return t('Updated')
},
size: 140,
enableSorting: true,
},
{ id: 'actions', header: '', size: 44 },
]
@@ -64,12 +93,16 @@ function actionsFor(article: Article) {
return [
[
{
label: 'Edit',
get label() {
return t('Edit')
},
icon: 'i-lucide-pencil',
onSelect: () => router.push(editPath(article)),
},
{
label: article.is_online ? 'Unpublish' : 'Publish',
get label() {
return article.is_online ? t('Unpublish') : t('Publish')
},
icon: article.is_online ? 'i-lucide-globe-lock' : 'i-lucide-globe',
disabled: isBusy(article),
onSelect: () => {
@@ -81,14 +114,18 @@ function actionsFor(article: Article) {
},
},
{
label: 'Copy API URL',
get label() {
return t('Copy API URL')
},
icon: 'i-lucide-link',
onSelect: () => emit('copy-url', article.id),
},
],
[
{
label: 'Delete…',
get label() {
return t('Delete…')
},
icon: 'i-lucide-trash-2',
color: 'error' as const,
onSelect: () => emit('delete', article),
@@ -104,7 +141,7 @@ function onSelect(_event: Event, row: { original: Article }) {
<template>
<div v-if="loading" aria-busy="true" class="hidden border border-default bg-default md:block">
<span role="status" class="sr-only">Loading articles</span>
<span role="status" class="sr-only">{{ t('Loading articles') }}</span>
<div
v-for="n in 5"
:key="n"
@@ -131,7 +168,9 @@ function onSelect(_event: Event, row: { original: Article }) {
>
<template #caption>
<caption class="sr-only">
Articles, sorted by last updated, newest first
{{
t('Articles, sorted by last updated, newest first')
}}
</caption>
</template>
@@ -141,7 +180,7 @@ function onSelect(_event: Event, row: { original: Article }) {
class="inline-flex items-center gap-1 text-highlighted"
@click.stop="column.toggleSorting()"
>
Title
{{ t('Title') }}
<UIcon v-if="sortIcon(column)" :name="sortIcon(column)!" class="size-3" />
</button>
</template>
@@ -152,7 +191,7 @@ function onSelect(_event: Event, row: { original: Article }) {
class="inline-flex items-center gap-1 text-highlighted"
@click.stop="column.toggleSorting()"
>
Status
{{ t('Status') }}
<UIcon v-if="sortIcon(column)" :name="sortIcon(column)!" class="size-3" />
</button>
</template>
@@ -163,7 +202,7 @@ function onSelect(_event: Event, row: { original: Article }) {
class="inline-flex items-center gap-1 text-highlighted"
@click.stop="column.toggleSorting()"
>
Created
{{ t('Created') }}
<UIcon v-if="sortIcon(column)" :name="sortIcon(column)!" class="size-3" />
</button>
</template>
@@ -174,7 +213,7 @@ function onSelect(_event: Event, row: { original: Article }) {
class="inline-flex items-center gap-1 text-highlighted"
@click.stop="column.toggleSorting()"
>
Updated
{{ t('Updated') }}
<UIcon v-if="sortIcon(column)" :name="sortIcon(column)!" class="size-3" />
</button>
</template>
@@ -217,7 +256,7 @@ function onSelect(_event: Event, row: { original: Article }) {
icon="i-lucide-ellipsis"
color="neutral"
variant="ghost"
:aria-label="`Actions for ${row.original.title}`"
:aria-label="t('Actions for {0}', [row.original.title])"
class="size-8 justify-center text-toned"
@click.stop
/>