From e9ece7a04efc51ba09596b9a56951aa3fe5b2578 Mon Sep 17 00:00:00 2001
From: ErickMascarenhas <159568716+ErickMascarenhas@users.noreply.github.com>
Date: Wed, 5 Aug 2026 22:19:41 -0300
Subject: [PATCH] feat: add undefined support level, lock tutorial and i18n
---
app.json | 2 +-
app/settings.tsx | 14 ++++-
components/header.tsx | 11 +++-
features/settings/constants/translations.ts | 3 +
features/settings/contexts/i18n-context.tsx | 6 +-
features/students/components/new-student.tsx | 1 +
features/students/hooks/use-students.ts | 57 ++++++++++++++-----
...0260730120000_nivel_suporte_indefinido.sql | 12 ++++
8 files changed, 84 insertions(+), 22 deletions(-)
create mode 100644 supabase/migrations/20260730120000_nivel_suporte_indefinido.sql
diff --git a/app.json b/app.json
index e3456135..70436504 100644
--- a/app.json
+++ b/app.json
@@ -2,7 +2,7 @@
"expo": {
"name": "BaseAut",
"slug": "baseaut",
- "version": "1.1.1",
+ "version": "1.1.2",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "baseaut",
diff --git a/app/settings.tsx b/app/settings.tsx
index 901e92b6..1bde1a73 100644
--- a/app/settings.tsx
+++ b/app/settings.tsx
@@ -1,11 +1,13 @@
import { Header } from "@/components/header";
import { PageHeader } from "@/components/page-header";
-import { LOCALE_OPTIONS } from "@/features/settings/constants/translations";
+// IDIOMA DESATIVADO — para reativar, descomente esta linha.
+// import { LOCALE_OPTIONS } from "@/features/settings/constants/translations";
import { FeedbackModal } from "@/features/settings/components/feedback-modal";
import { useI18n } from "@/features/settings/contexts/i18n-context";
import { ThemeMode, useTheme, useThemeColors } from "@/features/settings/contexts/theme-context";
import { useRouter } from "expo-router";
-import { Check, GraduationCap, Languages, MessageSquareText, Monitor, Moon, Sun } from "lucide-react-native";
+// TUTORIAL/IDIOMA DESATIVADOS — ao reativar, volte a importar GraduationCap e Languages.
+import { Check, MessageSquareText, Monitor, Moon, Sun } from "lucide-react-native";
import React, { useState } from "react";
import { Pressable, ScrollView, Text, View } from "react-native";
@@ -48,7 +50,8 @@ export default function SettingsRoute() {
const router = useRouter();
const colors = useThemeColors();
const { mode, setMode } = useTheme();
- const { t, preference, setPreference } = useI18n();
+ // IDIOMA DESATIVADO — ao reativar, volte a extrair preference e setPreference.
+ const { t } = useI18n();
const [feedbackVisible, setFeedbackVisible] = useState(false);
const themeOptions: { value: ThemeMode; label: string; icon: React.ReactNode }[] = [
@@ -99,6 +102,8 @@ export default function SettingsRoute() {
+ {/* IDIOMA DESATIVADO — o app fica só em português por ora.
+ Para reativar, descomente este bloco.
{t("settings.language")}
@@ -116,7 +121,9 @@ export default function SettingsRoute() {
))}
+ */}
+ {/* TUTORIAL DESATIVADO — para reativar, descomente este bloco.
{t("settings.tutorial")}
@@ -130,6 +137,7 @@ export default function SettingsRoute() {
+ */}
)}
+ {/* TUTORIAL DESATIVADO — para reativar, descomente este bloco.
{!tutorialAllCompleted && (
router.push("/tutorial" as never)} className="p-1 active:opacity-70" style={{ marginLeft: 20 }}>
)}
+ */}
router.push("/account")} className="p-1 active:opacity-70" style={{ marginLeft: 20 }}>
diff --git a/features/settings/constants/translations.ts b/features/settings/constants/translations.ts
index 70b20158..20a8872c 100644
--- a/features/settings/constants/translations.ts
+++ b/features/settings/constants/translations.ts
@@ -624,6 +624,7 @@ export type TranslationKey =
| "students.form.supportOption1"
| "students.form.supportOption2"
| "students.form.supportOption3"
+ | "students.form.supportOptionUndefined"
| "students.form.healthConditions"
| "students.form.healthConditionsPlaceholder"
| "students.form.observations"
@@ -1734,6 +1735,7 @@ export const translations: Record> = {
"students.form.supportOption1": "Transtorno do Espectro Autista Nível 1",
"students.form.supportOption2": "Transtorno do Espectro Autista Nível 2",
"students.form.supportOption3": "Transtorno do Espectro Autista Nível 3",
+ "students.form.supportOptionUndefined": "Indefinido",
"students.form.healthConditions": "Outras condições de saúde",
"students.form.healthConditionsPlaceholder": "Outras condições de saúde (opcional)",
"students.form.observations": "Observações",
@@ -2852,6 +2854,7 @@ export const translations: Record> = {
"students.form.supportOption1": "Autism Spectrum Disorder Level 1",
"students.form.supportOption2": "Autism Spectrum Disorder Level 2",
"students.form.supportOption3": "Autism Spectrum Disorder Level 3",
+ "students.form.supportOptionUndefined": "Undefined",
"students.form.healthConditions": "Other health conditions",
"students.form.healthConditionsPlaceholder": "Other health conditions (optional)",
"students.form.observations": "Notes",
diff --git a/features/settings/contexts/i18n-context.tsx b/features/settings/contexts/i18n-context.tsx
index 75001640..d76a5b1a 100644
--- a/features/settings/contexts/i18n-context.tsx
+++ b/features/settings/contexts/i18n-context.tsx
@@ -76,7 +76,11 @@ export function I18nProvider({ children }: { children: React.ReactNode }) {
AsyncStorage.setItem(STORAGE_KEY, next);
}, []);
- const locale: Locale = preference === "system" ? getDeviceLocale() : preference;
+ // IDIOMA TRAVADO EM PORTUGUÊS — a escolha de idioma saiu de Configurações, e
+ // sem esta trava um aparelho com outro idioma cairia no inglês pela
+ // preferência "system". Para reativar, troque pela linha comentada abaixo.
+ const locale: Locale = "pt";
+ // const locale: Locale = preference === "system" ? getDeviceLocale() : preference;
const t = useCallback(
(key: TranslationKey) =>
diff --git a/features/students/components/new-student.tsx b/features/students/components/new-student.tsx
index d8f5a29e..2ae03c42 100644
--- a/features/students/components/new-student.tsx
+++ b/features/students/components/new-student.tsx
@@ -75,6 +75,7 @@ export function NewStudent({
t("students.form.supportOption1"),
t("students.form.supportOption2"),
t("students.form.supportOption3"),
+ t("students.form.supportOptionUndefined"),
];
useEffect(() => {
diff --git a/features/students/hooks/use-students.ts b/features/students/hooks/use-students.ts
index 27198901..52ce655d 100644
--- a/features/students/hooks/use-students.ts
+++ b/features/students/hooks/use-students.ts
@@ -1,5 +1,6 @@
import { supabase } from "@/lib/supabase";
import { calculateAge } from "@/lib/date-utils";
+import type { TranslationKey } from "@/features/settings/constants/translations";
import { useI18n } from "@/features/settings/contexts/i18n-context";
import { resolveEquipeId } from "@/lib/resolve-equipe-id";
import { uploadImage } from "@/lib/upload-image";
@@ -24,6 +25,45 @@ export type Student = {
pendencyAlert: boolean;
};
+/** Support level values stored in the `nivel_suporte_tea` enum. */
+type NivelSuporteDb = "nivel_1" | "nivel_2" | "nivel_3" | "indefinido";
+
+/**
+ * Converts the stored support level into the label shown in the UI.
+ *
+ * @remarks
+ * "indefinido" exists for children whose level is not known yet (report still
+ * pending), so the form no longer has to record a level nobody confirmed.
+ */
+function supportLevelFromDb(
+ raw: string | null | undefined,
+ t: (key: TranslationKey) => string,
+): string {
+ if (raw === "nivel_1") return "Nível 1";
+ if (raw === "nivel_2") return "Nível 2";
+ if (raw === "nivel_3") return "Nível 3";
+ return t("students.form.supportOptionUndefined");
+}
+
+/**
+ * Converts the label picked in the form back into the stored enum value.
+ *
+ * @remarks
+ * The undefined option is matched against its own translated label, so it works
+ * in every language; the numbered levels are matched by their digit, which the
+ * label carries in every language.
+ */
+function supportLevelToDb(
+ label: string,
+ t: (key: TranslationKey) => string,
+): NivelSuporteDb {
+ if (label === t("students.form.supportOptionUndefined")) return "indefinido";
+ if (label.includes("2")) return "nivel_2";
+ if (label.includes("3")) return "nivel_3";
+ if (label.includes("1")) return "nivel_1";
+ return "indefinido";
+}
+
/** Seed students for the tutorial's mock mode (kept entirely in memory). */
const MOCK_STUDENTS: Student[] = [
{
@@ -125,11 +165,7 @@ const loadStudents = useCallback(async (showLoader = true) => {
weight: Number(aluno.peso) || 0,
height: Number(aluno.altura) || 0,
waist: Number(aluno.cintura) || 0,
- supportLevel:
- aluno.nivel_suporte === "nivel_1" ? "Nível 1"
- : aluno.nivel_suporte === "nivel_2"
- ? "Nível 2"
- : "Nível 3",
+ supportLevel: supportLevelFromDb(aluno.nivel_suporte, t),
healthConditions: aluno.diagnostico_detalhado || "",
observations: aluno.observacoes_clinicas || "",
avatarUrl: aluno.avatar_url,
@@ -188,10 +224,7 @@ const loadStudents = useCallback(async (showLoader = true) => {
: (await uploadImage("avatares", photoUri, "alunos")) ?? null;
}
- let nivelSuporteDb = "nivel_1";
- const supportLower = data.supportLevel.toLowerCase();
- if (supportLower.includes("2")) nivelSuporteDb = "nivel_2";
- if (supportLower.includes("3")) nivelSuporteDb = "nivel_3";
+ const nivelSuporteDb = supportLevelToDb(data.supportLevel, t);
let formattedDate = data.birthDate;
if (formattedDate.includes("/")) {
@@ -271,11 +304,7 @@ const loadStudents = useCallback(async (showLoader = true) => {
}
if (data.supportLevel !== undefined) {
- let nivelSuporteDb = "nivel_1";
- const supportLower = data.supportLevel.toLowerCase();
- if (supportLower.includes("2")) nivelSuporteDb = "nivel_2";
- if (supportLower.includes("3")) nivelSuporteDb = "nivel_3";
- payload.nivel_suporte = nivelSuporteDb;
+ payload.nivel_suporte = supportLevelToDb(data.supportLevel, t);
}
if (data.birthDate !== undefined) {
diff --git a/supabase/migrations/20260730120000_nivel_suporte_indefinido.sql b/supabase/migrations/20260730120000_nivel_suporte_indefinido.sql
new file mode 100644
index 00000000..a75152d7
--- /dev/null
+++ b/supabase/migrations/20260730120000_nivel_suporte_indefinido.sql
@@ -0,0 +1,12 @@
+-- =======================================================================
+-- Migration: nível de suporte "Indefinido"
+-- =======================================================================
+-- O nível de suporte do TEA nem sempre é conhecido no momento do cadastro
+-- (laudo ainda não emitido, criança em avaliação). Até aqui o formulário
+-- obrigava escolher entre os níveis 1, 2 e 3, o que levava a registrar um
+-- nível que ninguém confirmou.
+--
+-- Passa a existir o valor 'indefinido' no enum. Os registros existentes não
+-- são tocados: quem já tem um nível declarado permanece como está.
+
+ALTER TYPE nivel_suporte_tea ADD VALUE IF NOT EXISTS 'indefinido';