The tablero is the heart of ComuniTEA — a full-screen, landscape-oriented AAC (Augmentative and Alternative Communication) board modeled on the PECS communication system. Children navigate pictogram categories, tap individual symbols to compose a structured sentence in the frase strip at the top of the screen, and press the play button to hear the complete phrase read aloud in a warm, natural voice. Every interaction is designed for low cognitive load: navigation is always one or two taps deep, and the visual language is consistent throughout.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ElthonJohan/comunitea/llms.txt
Use this file to discover all available pages before exploring further.
How the tablero works
Choose a category
The bottom section of the screen shows subcategory tiles organized by topic (Frutas, Comida, Emociones, Actividades, etc.). The child taps a tile to open its pictograms inline, scrolling the list into view. A category overlay drawer is also available for quick jumping between topics.
Tap a pictogram
Tapping a pictogram immediately plays its individual audio clip and routes it into the correct slot in the frase strip. Pictograms from the
personas category go into the Persona slot; pictograms from peticiones go into the Petición slot; everything else fills the Objeto slots (up to two objects can be added).Build the sentence strip
The frase strip at the top of the screen shows up to four ordered slots:
[Persona] [Petición] [Objeto 1] [Objeto 2]. The strip becomes active (the play button enables) as soon as a petición has been selected. The child can tap any slot to remove that pictogram, or use the clear button to reset the entire strip.Play the full sentence
Pressing the play (▶) button speaks the complete phrase aloud. The app expands short pictogram labels into natural-sounding sentences before handing them to the TTS engine — for example,
"Yo" + "Quiero" + "Manzana" becomes “Yo quiero una manzana”. Each completed playback is recorded via recordSentenceSpoken() for the progress reports.The Pictograma interface
Every symbol on the tablero is represented by a Pictograma object. The interface is defined in features/tablero/data/tablero.ts:
getPictogramAudioKey(p) returns p.audioAssetKey ?? p.id, ensuring that pictograms with aliased MP3 names (e.g. fresa → fresas.mp3) resolve correctly while keeping id values clean for database logging.
Fixed rows: personas and peticiones
Two rows are always visible at the top of the vocabulary area regardless of which subcategory is active.PERSONAS_ROW — family and caregivers
important_people in the child’s profile, the default row is replaced entirely by custom entries. The child’s own avatar ("Yo", audio key core-yo) is always prepended as the first persona.
PETICIONES_ROW — communicative intents
Subcategories (ALL_SUBCATS)
The default vocabulary is organized into seven subcategories. Each Subcategoria bundles its pictograms and carries its own emoji and nombre for display in the category tiles.
| ID | Nombre | Emoji | Pictograms |
|---|---|---|---|
frutas | Frutas | 🍎 | Manzana, Plátano, Naranja, Uvas, Fresa |
comida | Comida | 🍽️ | Jugo, Galleta, Huevo, Pan, Arroz |
juguetes | Juguetes | 🧸 | Auto, Pelota, Oso, Estrella |
verduras | Verduras | 🥕 | Zanahoria, Tomate, Brócoli |
golosinas | Golosinas | 🍬 | Caramelo, Chocolate, Helado |
actividades | Actividades | 🎮 | Dormir, Baño, Jugar, Leer |
emociones | Emociones | 😊 | Feliz, Triste, Enojado, Asustado |
preferred_activities profile field and is injected at the top of the list when present.
buildMergedBoard() — merging custom pictograms
features/tablero/buildMergedBoard.ts exports two merge functions that combine the static board data with per-child personalizations stored in Supabase:
"emoji|Nombre" pipe-delimited strings (e.g. "👩|Mamá"). The formatImportantPersonLine / parseImportantPersonLine helpers handle encoding and decoding. To seed the list from the defaults when a user adds their first custom person, call seedImportantPeopleFromPersonasRow().
The sentence strip (useFrase)
The useFrase hook manages the four-slot sentence buffer and all audio playback for the frase bar. The FraseState interface describes the slot layout:
| Return value | Type | Description |
|---|---|---|
slotPersona | Pictograma | Currently set persona (defaults to child avatar) |
slotPeticion | Pictograma | null | Currently set petición |
slotsObjeto | [Pictograma | null, Pictograma | null] | Up to two objeto slots |
slots | (Pictograma | null)[] | All four slots as a flat array [persona, peticion, obj1, obj2] |
fraseLista | boolean | true when slotPeticion !== null — enables the ▶ button |
puedeHablar | boolean | Alias for fraseLista |
agregarPersona(p) | (p: Pictograma) => void | Sets the persona slot directly |
agregarPeticion(p) | (p: Pictograma) => void | Sets the petición slot directly |
agregarObjeto(p) | (p: Pictograma) => void | Adds to next available objeto slot |
agregarPictograma(p) | (p: Pictograma) => void | Routes p to the correct slot by p.categoria |
quitarPictograma(index) | (index: number) => void | Removes the pictogram at slot 0–3 |
limpiarFrase() | () => void | Resets petición and objeto slots; resets persona to the child’s avatar |
leerFrase() | () => Promise<void> | Plays the full sentence using speakFrasePhrase() |
agregarPictograma handles routing automatically: categoria === 'personas' → persona slot; categoria === 'peticiones' → petición slot; anything else → next available objeto slot (slot 2 then slot 3, overwriting slot 3 if both are full).
Voice audio system
ComuniTEA ships with bundled MP3 audio clips for both a femenina and masculina voice profile. Audio is resolved throughgetAudioAssets(perfil) from constants/AudioAssets.ts, which maps pictogram IDs to the correct require’d module.
When a pictogram is played individually (on tap), the clip for that pictogram’s audioAssetKey (or id) is looked up in the asset map and played immediately. For full-sentence playback, speakFrasePhrase() in lib/speakFrasePhrase.ts is used. This function:
- Passes the phrase through
expandTableroSlots()to generate a natural-language sentence (using the user’s XP level to choose expansion complexity). - Checks network connectivity via
useNetwork(). - If online, calls the ElevenLabs TTS API for higher-quality neural speech.
- If offline or if ElevenLabs fails, falls back to
expo-speech(on-device TTS) with Spanish (es-MX) locale and the configuredtts_speedfrom parental settings.
All individual pictogram audio clips are bundled inside the app binary. Core vocabulary (quiero, no quiero, ayuda, all food items, emotions, etc.) plays instantly even with no internet connection. ElevenLabs neural voice is used only for full-sentence playback when online.
useTablero hook
The useTablero hook is the top-level state coordinator for the tablero screen. It composes mergeAllSubcats, mergePersonasRow, useChildProfile, and useUserGroup to produce a fully resolved board state:
maxSubcategoriasVisibles limit comes from useUserGroup() and ensures that children assigned to lower exercise groups see a simplified vocabulary set, reducing visual overload. categorias is derived by grouping all subcategories from mergeAllSubcats (the full unsliced list) via categoriasFromSubcats(), so the overlay always shows the complete category index even when subcategorias is trimmed.