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';