feat: implemented new i18n system

This commit is contained in:
Benjamin Singleton 2025-06-14 11:57:28 -05:00
parent 4b4e8b7aa8
commit 032cfb2bfd
11 changed files with 254 additions and 124 deletions

View file

@ -0,0 +1,43 @@
<script setup lang="ts">
import { LOCALE_IDS, localeId, useLocale, type LocaleId } from "@/i18n";
import { ref } from "vue";
const isOpen = ref<boolean>(false);
const toggleOpen = (): void => {
isOpen.value = !isOpen.value;
};
const setLocaleId = (id: LocaleId): void => {
localeId.value = id;
};
</script>
<template>
<div :class="['dropdown', isOpen && 'is-active']">
<div class="dropdown-trigger">
<button
class="button"
aria-haspopup="true"
aria-controls="dropdown-menu"
@click="toggleOpen()">
<span>{{ useLocale().value.localeName }}</span>
<span class="icon is-small">
<i class="fas fa-angle-down" aria-hidden="true"></i>
</span>
</button>
</div>
<div class="dropdown-menu" id="dropdown-menu" role="menu">
<div class="dropdown-content">
<a
v-for="(id, index) in LOCALE_IDS"
:key="index"
href="#"
:class="['dropdown-item', localeId === id && 'is-active']"
@click="setLocaleId(id)">
{{ useLocale({ locale: id }).value.localeName }}
</a>
</div>
</div>
</div>
</template>

View file

@ -1,25 +1,9 @@
<script setup lang="ts">
import HomeSectionWrapper from "@/components/molecules/HomeSectionWrapper.vue";
import "@/assets/style.scss";
import { useI18n } from "vue-i18n";
import type { MessageSchema } from "@/i18n/types";
import { computed } from "vue";
import { useLocale } from "@/i18n";
import { localizeLayout } from "@/utils/localizeLayout";
const { tm } = useI18n();
const sectionList = computed<MessageSchema["sections"]>(() => tm("sections"));
const sectionsWithImages = computed(() =>
sectionList.value.map((section) => {
if (!section.image) return section;
return {
...section,
image: new URL(`../../assets/${section.image}`, import.meta.url)
.href,
};
}),
);
console.log(sectionList.value);
const locale = useLocale();
</script>
<template>
@ -35,12 +19,12 @@ console.log(sectionList.value);
<section class="section container">
<HomeSectionWrapper
v-for="(section, index) in sectionsWithImages"
v-for="(section, index) in localizeLayout(locale.home)"
:key="index"
:title="section.title"
:text="section.text"
:image="section.image"
:alt="section.alt"
:image="section.image ?? undefined"
:alt="section.alt ?? undefined"
:reverse="index % 2 !== 0" />
</section>
</div>

View file

@ -1,25 +1,9 @@
<script setup lang="ts">
import LearningResourceWrapper from "@/components/molecules/LearningResourceWrapper.vue";
import "@/assets/style.scss";
import { useI18n } from "vue-i18n";
import type { MessageSchema } from "@/i18n/types";
import { computed } from "vue";
import { useLocale } from "@/i18n";
import { localizeLayout } from "@/utils/localizeLayout";
const { tm } = useI18n();
const resourceList = computed<MessageSchema["resources"]>(() =>
tm("resources"),
);
const resourcesWithImages = computed(() =>
resourceList.value.map((resource) => {
if (!resource.image) return resource;
return {
...resource,
image: new URL(`../../assets/${resource.image}`, import.meta.url)
.href,
};
}),
);
const locale = useLocale();
</script>
<template>
@ -30,7 +14,7 @@ const resourcesWithImages = computed(() =>
<section class="section container">
<LearningResourceWrapper
v-for="(resource, index) in resourcesWithImages"
v-for="(resource, index) in localizeLayout(locale.resources)"
:key="index"
:title="resource.title"
:subtitle="resource.subtitle"