PronounsPage/components/nouns/NounsConventionPage.vue
2025-07-27 23:43:57 +02:00

132 lines
3.9 KiB
Vue

<script setup lang="ts">
import useSimpleHead from '~/composables/useSimpleHead.ts';
import { loadNounsData } from '~/src/data.ts';
import { Example } from '~/src/language/examples.ts';
import { MorphemeValues } from '~/src/language/morphemes.ts';
import type { NounConvention } from '~/src/nouns.ts';
const props = defineProps<{
nounConvention: WithKey<NounConvention>;
}>();
const { $translator: translator } = useNuxtApp();
const nounsData = await loadNounsData();
if (nounsData === undefined) {
throw new Error('nounsData is undefined');
}
useSimpleHead({
title: `${translator.translate('nouns.conventions.intro')}: ${props.nounConvention.name}`,
description: [
translator.translate('pronouns.examples.header', {}, false),
translator.translate('pronouns.grammarTable', {}, false),
].filter((x) => !!x).join(', '),
}, translator);
const exampleValues = computed(() => {
return {
morphemeValues: new MorphemeValues(props.nounConvention.morphemes),
nounConvention: props.nounConvention,
nounDeclensions: nounsData.declensions,
};
});
const examples = computed(() => {
if (exampleValues.value === undefined) {
return undefined;
}
return nounsData.examples?.map((example) => Example.parse(example))
.filter((example) => example.areRequiredExampleValuesPresent(exampleValues.value!));
});
const nounConventionGroup = computed(() => {
return Object.values(nounsData.groups ?? []).find((nounConventionGroup) => {
return nounConventionGroup.conventions.includes(props.nounConvention.key);
});
});
</script>
<template>
<h2>
<Icon v="book-alt" />
<T>nouns.conventions.intro</T><T>quotation.colon</T>
</h2>
<section>
<div class="alert alert-primary">
<h2 class="text-center mb-0">
<strong><Spelling :text="nounConvention.name" /></strong>
</h2>
</div>
</section>
<section>
<h2 class="h4">
<Icon v="file-signature" />
<T>pronouns.examples.header</T><T>quotation.colon</T>
</h2>
<ul>
<li v-for="(example, index) of examples" :key="index">
<ExampleItem
:example
:example-values
/>
</li>
</ul>
</section>
<section v-if="nounConvention.warning || nounConvention.description">
<div v-if="nounConvention.warning" class="alert alert-warning">
<Icon v="exclamation-triangle" />
<LinkedText :text="nounConvention.warning" />
</div>
<div v-for="(text, index) of nounConvention.description" :key="index" class="alert alert-light">
<Icon v="info-circle" />
<LinkedText :text />
</div>
</section>
<section>
<h2 class="h4">
<Icon v="spell-check" />
<T>pronouns.grammarTable</T><T>quotation.colon</T>
</h2>
<GrammarTable
v-for="(grammarTable, t) in nounsData.grammarTables"
:key="t"
:grammar-table="grammarTable"
:example-values
:examples
/>
</section>
<section>
<div class="row d-flex">
<NounsClassItem
v-for="(nounClass, key) of nounsData.classes"
:key
:noun-class="{ ...nounClass, key }"
:noun-convention
/>
</div>
</section>
<section v-if="nounConventionGroup">
<ul class="list-group mt-4">
<li class="list-group-item">
<NounsConventionsIndexGroup :noun-convention-group />
</li>
<nuxt-link
:to="{ name: 'nouns' }"
class="list-group-item list-group-item-action text-center"
:title="$t('nouns.conventions.header')"
>
<Icon v="ellipsis-h-alt" />
</nuxt-link>
</ul>
</section>
</template>