mirror of
https://github.com/ArthurDanjou/spanish-learner.git
synced 2026-01-14 12:14:39 +01:00
Working
This commit is contained in:
@@ -1,14 +1,11 @@
|
|||||||
export default defineAppConfig({
|
export default defineAppConfig({
|
||||||
ui: {
|
ui: {
|
||||||
gray: 'zinc',
|
gray: 'neutral',
|
||||||
primary: 'red',
|
primary: 'red',
|
||||||
container: {
|
container: {
|
||||||
constrained: 'max-w-xl',
|
constrained: 'max-w-xl',
|
||||||
padding: 'px-4 sm:px-6 lg:px-8 py-4',
|
padding: 'px-4 sm:px-6 lg:px-8 py-4',
|
||||||
},
|
},
|
||||||
divider: {
|
|
||||||
base: 'flex border-gray-700',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
collections: ['heroicons', 'ph'],
|
collections: ['heroicons', 'ph'],
|
||||||
|
|||||||
97
app/app.vue
97
app/app.vue
@@ -1,103 +1,20 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ModalColumns, ModalRows, VerbColumns, VerbRows } from '~~/types'
|
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
link: [{ rel: 'icon', type: 'image/png', href: '/favicon.ico' }],
|
link: [{ rel: 'icon', type: 'image/png', href: '/favicon.ico' }],
|
||||||
title: 'Spanish Learning Process • By Arthur Danjou',
|
title: 'Spanish Learning Process • By Arthur Danjou',
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data: verb, refresh: refreshVerbData } = await useAsyncData('verb', async () => $fetch('/api/verb'))
|
|
||||||
const { data: word, refresh: refreshWordData } = await useAsyncData('word', async () => $fetch('/api/word'))
|
|
||||||
|
|
||||||
const revealedVerb = ref(false)
|
|
||||||
async function refreshVerb() {
|
|
||||||
revealedVerb.value = false
|
|
||||||
await refreshVerbData()
|
|
||||||
}
|
|
||||||
|
|
||||||
const revealedWord = ref(false)
|
|
||||||
async function refreshWord() {
|
|
||||||
revealedWord.value = false
|
|
||||||
await refreshWordData()
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<NuxtLoadingIndicator />
|
<NuxtLoadingIndicator />
|
||||||
<UContainer>
|
<UContainer>
|
||||||
<div class="bg-neutral-800 rounded-lg max-h-[96vh] h-[96vh] overflow-scroll p-4">
|
<div class="bg-neutral-900 rounded-lg max-h-[96vh] h-[96vh] overflow-scroll p-4">
|
||||||
<div v-if="verb" class="space-y-4 mx-auto flex flex-col justify-center">
|
<Verbs />
|
||||||
<div class="flex gap-2 items-end">
|
<Words />
|
||||||
<h3 class="text-xl text-neutral-500">
|
<Modals />
|
||||||
Verbos:
|
<Terminaisons />
|
||||||
</h3>
|
<Prononciation />
|
||||||
<h1 class="text-3xl font-bold">
|
|
||||||
{{ verb.verb }}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2 items-end">
|
|
||||||
<h3 class="text-xl text-neutral-500">
|
|
||||||
Typo:
|
|
||||||
</h3>
|
|
||||||
<h1 class="text-3xl font-bold">
|
|
||||||
{{ verb.type }}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2 items-end cursor-pointer" @click.prevent="revealedVerb = true">
|
|
||||||
<h3 class="text-xl text-neutral-500">
|
|
||||||
Traduccion:
|
|
||||||
</h3>
|
|
||||||
<h1 class="text-3xl font-bold" :class="revealedVerb ? 'duration-300' : 'bg-black text-black'">
|
|
||||||
{{ verb.translation }}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<UButton
|
|
||||||
:color="revealedVerb ? 'green' : 'red'"
|
|
||||||
variant="solid"
|
|
||||||
:label="revealedVerb ? 'Change Verb' : 'Reveal Verb'"
|
|
||||||
:block="true"
|
|
||||||
@click.prevent="revealedVerb ? refreshVerb() : revealedVerb = true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<UDivider class="mt-8 mb-4" label="Palabras" />
|
|
||||||
<div v-if="word" class="space-y-4 mx-auto flex flex-col justify-center">
|
|
||||||
<div class="flex gap-2 items-end">
|
|
||||||
<h3 class="text-xl text-neutral-500">
|
|
||||||
Palabra:
|
|
||||||
</h3>
|
|
||||||
<h1 class="text-3xl font-bold">
|
|
||||||
{{ word.word }}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2 items-end">
|
|
||||||
<h3 class="text-xl text-neutral-500">
|
|
||||||
Typo:
|
|
||||||
</h3>
|
|
||||||
<h1 class="text-3xl font-bold">
|
|
||||||
{{ word.type }}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2 items-end cursor-pointer" @click.prevent="revealedWord = true">
|
|
||||||
<h3 class="text-xl text-neutral-500">
|
|
||||||
Traducción:
|
|
||||||
</h3>
|
|
||||||
<h1 class="text-3xl font-bold" :class="revealedWord ? 'duration-300' : 'bg-black text-black'">
|
|
||||||
{{ word.translation }}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<UButton
|
|
||||||
:color="revealedWord ? 'green' : 'blue'"
|
|
||||||
variant="solid"
|
|
||||||
:label="revealedWord ? 'Change Word' : 'Reveal Word'"
|
|
||||||
:block="true"
|
|
||||||
@click.prevent="revealedWord ? refreshWord() : revealedWord = true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<UDivider class="mt-8 mb-4" label="Ser, Estar, Tener, Haber" />
|
|
||||||
<UTable :columns="ModalColumns" :rows="ModalRows" />
|
|
||||||
<UDivider class="mt-8 mb-4" label="Terminaisons" />
|
|
||||||
<UTable :columns="VerbColumns" :rows="VerbRows" />
|
|
||||||
</div>
|
</div>
|
||||||
</UContainer>
|
</UContainer>
|
||||||
</div>
|
</div>
|
||||||
@@ -107,6 +24,6 @@ async function refreshWord() {
|
|||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: 'DM Sans', sans-serif;
|
font-family: 'DM Sans', sans-serif;
|
||||||
@apply h-full w-full text-neutral-300;
|
@apply h-full w-full text-neutral-400;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
68
app/components/Modals.vue
Normal file
68
app/components/Modals.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const ModalColumns = [
|
||||||
|
{
|
||||||
|
key: 'ser',
|
||||||
|
label: 'Ser',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'estar',
|
||||||
|
label: 'Estar',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'tener',
|
||||||
|
label: 'Tener',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'haber',
|
||||||
|
label: 'Haber',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const ModalRows = [
|
||||||
|
{
|
||||||
|
ser: 'soy',
|
||||||
|
estar: 'estoy',
|
||||||
|
tener: 'tengo',
|
||||||
|
haber: 'he',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ser: 'eres',
|
||||||
|
estar: 'estás',
|
||||||
|
tener: 'tienes',
|
||||||
|
haber: 'has',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ser: 'es',
|
||||||
|
estar: 'está',
|
||||||
|
tener: 'tiene',
|
||||||
|
haber: 'ha',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ser: 'somos',
|
||||||
|
estar: 'estamos',
|
||||||
|
tener: 'tenemos',
|
||||||
|
haber: 'hemos',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ser: 'sois',
|
||||||
|
estar: 'estáis',
|
||||||
|
tener: 'tenéis',
|
||||||
|
haber: 'habéis',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ser: 'son',
|
||||||
|
estar: 'están',
|
||||||
|
tener: 'tienen',
|
||||||
|
haber: 'han',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UDivider class="mt-12 mb-8" size="lg" label="Ser, Estar, Tener, Haber" />
|
||||||
|
<UTable :columns="ModalColumns" :rows="ModalRows" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
68
app/components/Prononciation.vue
Normal file
68
app/components/Prononciation.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const PrononciationRows = [
|
||||||
|
{
|
||||||
|
sound: 'ca co cu',
|
||||||
|
pronunciation: '/k/',
|
||||||
|
ejemplos: 'casa, coco, cucaracha',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'ce ci',
|
||||||
|
pronunciation: '/θ/',
|
||||||
|
ejemplos: 'cena, cine',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'ga go',
|
||||||
|
pronunciation: '/g/',
|
||||||
|
ejemplos: 'gato, gorra',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'ge gi',
|
||||||
|
pronunciation: '/x/',
|
||||||
|
ejemplos: 'gente, gira',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'z',
|
||||||
|
pronunciation: '/θ/',
|
||||||
|
ejemplos: 'zapato',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 's',
|
||||||
|
pronunciation: '/s/',
|
||||||
|
ejemplos: 'sol',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'rr',
|
||||||
|
pronunciation: '/r/',
|
||||||
|
ejemplos: 'perro',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'j',
|
||||||
|
pronunciation: '/x/',
|
||||||
|
ejemplos: 'jirafa',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'll',
|
||||||
|
pronunciation: '/ʎ/',
|
||||||
|
ejemplos: 'llama',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'e',
|
||||||
|
pronunciation: '/e/',
|
||||||
|
ejemplos: 'elefante',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sound: 'ñ',
|
||||||
|
pronunciation: '/ɲ/',
|
||||||
|
ejemplos: 'niño',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UDivider class="mt-12 mb-8" size="lg" label="Prononciation" />
|
||||||
|
<UTable :rows="PrononciationRows" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
67
app/components/Terminaisons.vue
Normal file
67
app/components/Terminaisons.vue
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const VerbRows = [
|
||||||
|
{
|
||||||
|
person: 'yo',
|
||||||
|
er: 'o',
|
||||||
|
ir: 'o',
|
||||||
|
ar: 'o',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
person: 'tu',
|
||||||
|
er: 'es',
|
||||||
|
ir: 'es',
|
||||||
|
ar: 'as',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
person: 'el/ella/usted',
|
||||||
|
er: 'e',
|
||||||
|
ir: 'e',
|
||||||
|
ar: 'a',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
person: 'nosotros/nosotras',
|
||||||
|
er: 'emos',
|
||||||
|
ir: 'imos',
|
||||||
|
ar: 'amos',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
person: 'vosotros/vosotras',
|
||||||
|
er: 'éis',
|
||||||
|
ir: 'ís',
|
||||||
|
ar: 'áis',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
person: 'ellos/ellas/ustedes',
|
||||||
|
er: 'en',
|
||||||
|
ir: 'en',
|
||||||
|
ar: 'an',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const VerbColumns = [
|
||||||
|
{
|
||||||
|
key: 'person',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'er',
|
||||||
|
label: '-ER',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ir',
|
||||||
|
label: '-IR',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ar',
|
||||||
|
label: '-AR',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UDivider class="mt-12 mb-8" size="lg" label="Terminaisons" />
|
||||||
|
<UTable :columns="VerbColumns" :rows="VerbRows" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
49
app/components/Verbs.vue
Normal file
49
app/components/Verbs.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const { data: verb, refresh: refreshVerbData } = await useAsyncData('verb', async () => $fetch('/api/verb'))
|
||||||
|
|
||||||
|
const revealedVerb = ref(false)
|
||||||
|
async function refreshVerb() {
|
||||||
|
revealedVerb.value = false
|
||||||
|
await refreshVerbData()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="verb" class="space-y-4 mx-auto flex flex-col justify-center">
|
||||||
|
<div class="flex gap-2 items-end">
|
||||||
|
<h3 class="text-neutral-500">
|
||||||
|
Verbos:
|
||||||
|
</h3>
|
||||||
|
<h1 class="font-bold">
|
||||||
|
{{ verb.verb }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-end">
|
||||||
|
<h3 class="text-neutral-500">
|
||||||
|
Typo:
|
||||||
|
</h3>
|
||||||
|
<h1 class="font-bold">
|
||||||
|
{{ verb.type }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-end cursor-pointer" @click.prevent="revealedVerb = true">
|
||||||
|
<h3 class="text-neutral-500">
|
||||||
|
Traduccion:
|
||||||
|
</h3>
|
||||||
|
<h1 class="font-bold" :class="revealedVerb ? 'duration-300' : 'bg-black text-black'">
|
||||||
|
{{ verb.translation }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<UButton
|
||||||
|
:color="revealedVerb ? 'green' : 'red'"
|
||||||
|
variant="solid"
|
||||||
|
:label="revealedVerb ? 'Change Verb' : 'Reveal Verb'"
|
||||||
|
:block="true"
|
||||||
|
@click.prevent="revealedVerb ? refreshVerb() : revealedVerb = true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
49
app/components/Words.vue
Normal file
49
app/components/Words.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const { data: word, refresh: refreshWordData } = await useAsyncData('word', async () => $fetch('/api/word'))
|
||||||
|
const revealedWord = ref(false)
|
||||||
|
async function refreshWord() {
|
||||||
|
revealedWord.value = false
|
||||||
|
await refreshWordData()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UDivider class="mt-12 mb-8" size="lg" label="Palabras" />
|
||||||
|
<div v-if="word" class="space-y-4 mx-auto flex flex-col justify-center">
|
||||||
|
<div class="flex gap-2 items-end">
|
||||||
|
<h3 class="text-neutral-500">
|
||||||
|
Palabra:
|
||||||
|
</h3>
|
||||||
|
<h1 class="font-bold">
|
||||||
|
{{ word.word }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-end">
|
||||||
|
<h3 class="text-neutral-500">
|
||||||
|
Typo:
|
||||||
|
</h3>
|
||||||
|
<h1 class="font-bold">
|
||||||
|
{{ word.type }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-end cursor-pointer" @click.prevent="revealedWord = true">
|
||||||
|
<h3 class="text-neutral-500">
|
||||||
|
Traducción:
|
||||||
|
</h3>
|
||||||
|
<h1 class="font-bold" :class="revealedWord ? 'duration-300' : 'bg-black text-black'">
|
||||||
|
{{ word.translation }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<UButton
|
||||||
|
:color="revealedWord ? 'green' : 'blue'"
|
||||||
|
variant="solid"
|
||||||
|
:label="revealedWord ? 'Change Word' : 'Reveal Word'"
|
||||||
|
:block="true"
|
||||||
|
@click.prevent="revealedWord ? refreshWord() : revealedWord = true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
"drizzle-orm": "^0.32.1",
|
"drizzle-orm": "^0.32.1",
|
||||||
"h3-zod": "^0.5.3",
|
"h3-zod": "^0.5.3",
|
||||||
"nuxt": "^3.12.4",
|
"nuxt": "^3.12.4",
|
||||||
|
"vue": "^3.4.35",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
407
pnpm-lock.yaml
generated
407
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
114
types/index.ts
114
types/index.ts
@@ -1,114 +0,0 @@
|
|||||||
export const VerbRows = [
|
|
||||||
{
|
|
||||||
person: 'yo',
|
|
||||||
er: 'o',
|
|
||||||
ir: 'o',
|
|
||||||
ar: 'o',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
person: 'tu',
|
|
||||||
er: 'es',
|
|
||||||
ir: 'es',
|
|
||||||
ar: 'as',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
person: 'el/ella/usted',
|
|
||||||
er: 'e',
|
|
||||||
ir: 'e',
|
|
||||||
ar: 'a',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
person: 'nosotros/nosotras',
|
|
||||||
er: 'emos',
|
|
||||||
ir: 'imos',
|
|
||||||
ar: 'amos',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
person: 'vosotros/vosotras',
|
|
||||||
er: 'éis',
|
|
||||||
ir: 'ís',
|
|
||||||
ar: 'áis',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
person: 'ellos/ellas/ustedes',
|
|
||||||
er: 'en',
|
|
||||||
ir: 'en',
|
|
||||||
ar: 'an',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export const VerbColumns = [
|
|
||||||
{
|
|
||||||
key: 'person',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'er',
|
|
||||||
label: '-ER',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ir',
|
|
||||||
label: '-IR',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'ar',
|
|
||||||
label: '-AR',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export const ModalColumns = [
|
|
||||||
{
|
|
||||||
key: 'ser',
|
|
||||||
label: 'Ser',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'estar',
|
|
||||||
label: 'Estar',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'tener',
|
|
||||||
label: 'Tener',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'haber',
|
|
||||||
label: 'Haber',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export const ModalRows = [
|
|
||||||
{
|
|
||||||
ser: 'soy',
|
|
||||||
estar: 'estoy',
|
|
||||||
tener: 'tengo',
|
|
||||||
haber: 'he',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ser: 'eres',
|
|
||||||
estar: 'estás',
|
|
||||||
tener: 'tienes',
|
|
||||||
haber: 'has',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ser: 'es',
|
|
||||||
estar: 'está',
|
|
||||||
tener: 'tiene',
|
|
||||||
haber: 'ha',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ser: 'somos',
|
|
||||||
estar: 'estamos',
|
|
||||||
tener: 'tenemos',
|
|
||||||
haber: 'hemos',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ser: 'sois',
|
|
||||||
estar: 'estáis',
|
|
||||||
tener: 'tenéis',
|
|
||||||
haber: 'habéis',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ser: 'son',
|
|
||||||
estar: 'están',
|
|
||||||
tener: 'tienen',
|
|
||||||
haber: 'han',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
Reference in New Issue
Block a user