ComuniTEA’s parental gate uses a PIN-protected lock to prevent children from accidentally changing settings, vocabulary, or other configuration screens.
Use this file to discover all available pages before exploring further.
ComuniTEA is designed to be used directly by a child, which means the communication board must be as tap-friendly and distraction-free as possible. Left unprotected, configuration screens like the Vocabulary Manager, Activity Editor, or Settings could be accidentally opened and modified by the child mid-session. The parental gate solves this by introducing a two-state model — child mode (locked) and caregiver mode (unlocked) — controlled by a 4-digit PIN modal. Caregivers can freely navigate all configuration screens once the PIN is entered; locking requires only a single toggle and no PIN. The gate is backed by Supabase (parental_settings table) and local AsyncStorage so that preferences survive app restarts.
The EditModeContext (context/EditModeContext.tsx) provides the global edit-mode state. Every part of the app that must be restricted from child interaction reads isEditMode from this context.
interface EditModeContextProps { isEditMode: boolean; hasPin: boolean; /** Show PIN modal and unlock if correct. */ requestUnlock: () => void; /** Unlock directly (use only after identity has already been verified). */ enterEditMode: () => void; /** Lock without PIN. */ lockEditMode: () => void; /** Open the change-PIN flow. */ changePinRequest: () => void;}
State
Who has access
Description
isEditMode: false
Child
Communication board is fully functional; Settings, Vocabulary Manager, Activity Editor, and Team Manager are PIN-gated
isEditMode: true
Caregiver
All configuration screens are accessible; edit handles and delete buttons appear on the board
The useEditMode() hook exposes this context to any component:
PinModal (components/PinModal.tsx) is a full-screen numeric keypad overlay that supports two modes:
mode
Purpose
'setup'
Create a new 4-digit PIN. The caregiver enters a PIN and then confirms it. If the two entries match, the PIN is saved; if not, the modal shakes and resets.
'verify'
Enter an existing 4-digit PIN. The onSuccess callback is called immediately when all 4 digits are entered; the parent context (EditModeContext) is responsible for comparing the entered value to the stored PIN.
The PIN is stored in AsyncStorage under STORAGE_KEYS.PARENTAL_PIN as a plain 4-digit string. On Settings screen load, the app reads this value and shows PinModal in 'verify' mode before rendering the settings content:
useEffect(() => { AsyncStorage.getItem(STORAGE_KEYS.PARENTAL_PIN).then(pin => { setProfileStoredPin(pin); if (pin === null) { setPinVerified(true); // No PIN set yet — grant access } else { setShowProfilePin(true); // PIN exists — show verification modal } });}, []);
useParental() (from lib/hooks/useParental.ts) loads and updates the parental_settings row for the authenticated user. It exposes the full ParentalSettings interface along with update helpers:
The AnimationIntensity type controls how much visual motion the app uses during pictogram selection and phrase playback:
export type AnimationIntensity = 'none' | 'soft' | 'normal';
Value
Label
Description
'none'
Sin animaciones
Fully static screen — no transitions, no celebratory effects
'soft'
Suaves
Light transitions only — no celebration animations, muted feedback
'normal'
Normal
Full animations — confetti on level completion, bounce effects on selection
This setting is surfaced in Settings → Configuración sensorial → Intensidad de animaciones and maps directly to the animation_intensity column in parental_settings.
The following screens are only fully accessible when the caregiver has authenticated through the parental gate:
Settings
The main settings screen (app/settings.tsx) requires PIN verification on every visit. If the stored PIN is null, access is granted immediately so the caregiver can set one.
Vocabulary Manager
app/vocabulary-manager.tsx — enables or disables individual pictograms per category. Accessible from Settings → Control parental → Gestión de vocabulario.
Activity Editor
app/activity-editor.tsx — creates and manages guided activity sequences for the child. Accessible from Settings → Control parental → Actividades guiadas.
Team Manager
app/team-manager.tsx — invites therapists and other professionals to view the child’s usage data. Accessible from Settings → Control parental → Equipo del niño.
The parental_settings table (created by migrations 20260307000001_parental_settings.sql and 20260331000004_phase3_parental_sensory_config.sql) stores all caregiver-controlled preferences server-side, scoped to each user by Row Level Security:
CREATE TABLE IF NOT EXISTS public.parental_settings ( user_id uuid PRIMARY KEY REFERENCES public.profiles(id) ON DELETE CASCADE, daily_limit_minutes int NOT NULL DEFAULT 30, used_seconds_today int NOT NULL DEFAULT 0, date_today date NOT NULL DEFAULT (CURRENT_DATE AT TIME ZONE 'UTC'), tts_speed numeric(3,1) NOT NULL DEFAULT 1.0 CHECK (tts_speed BETWEEN 0.5 AND 2.0), animation_intensity text NOT NULL DEFAULT 'normal' CHECK (animation_intensity IN ('none', 'soft', 'normal')), game_mode_enabled boolean NOT NULL DEFAULT false);
Every change to tts_speed or animation_intensity via updateSensoryConfig() is also written to the config_audit_log table (created in the same migration), which records the field name, old value, and new value with a timestamp. This audit trail can be used by therapists to review configuration history.
Caregivers can set an optional daily usage cap from Settings → Control parental → Límite de uso diario:
Option
daily_limit_minutes
Disabled
0
15 minutes
15
30 minutes
30
60 minutes
60
used_seconds_today is reset automatically when date_today differs from the current UTC date. When isBlocked becomes true, the communication board is replaced by a time-limit screen until the next day.
To change the PIN, the caregiver taps changePinRequest() from EditModeContext. This triggers a two-step flow:
Verify current PIN — PinModal is shown in 'verify' mode with title “Ingresa el PIN actual”
Enter new PIN — On success, PinModal is shown in 'setup' mode with title “Nuevo PIN Parental”
The new PIN is written to AsyncStorage under STORAGE_KEYS.PARENTAL_PIN and replaces the previous value immediately.
There is no PIN recovery mechanism in the current version of ComuniTEA. If the caregiver forgets their PIN, the only way to regain access to Settings and other protected screens is to reinstall the application, which will also clear all local AsyncStorage data including the PIN. Make sure to store your PIN in a safe place.