diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7b5f41d..29ad3ba 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Check Theeth Kids + Check Teeth Kids CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - Check Theeth Kids + Check Teeth Kids CFBundlePackageType APPL CFBundleShortVersionString diff --git a/lib/logged_home.dart b/lib/logged_home.dart index ce52f3c..d1f29c5 100644 --- a/lib/logged_home.dart +++ b/lib/logged_home.dart @@ -62,8 +62,7 @@ class _LoggedHomeScreenState extends State static const String _kPendingQuizScopeKey = 'pending_quiz_scope_v1'; static const double _collapsedAppBarHeight = kToolbarHeight; - static const double _expandedAppBarHeight = 226; - static const double _nameOnlyAppBarHeight = 160; + static const double _expandedAppBarHeight = 256; int _index = 0; @@ -349,9 +348,11 @@ class _LoggedHomeScreenState extends State // um NestedScrollView em vez do AppBar fixo usado nas outras abas, // para que a altura acompanhe o scroll em vez de ficar sempre cheia // (o que cortava o conteúdo do card do quiz contra a barra ao rolar). - final double expandedHeight = hasScore - ? _expandedAppBarHeight - : _nameOnlyAppBarHeight; + // A app bar mantém sempre a mesma altura e mostra sempre os dois + // gauges — vazios (sem número, sem rótulo) quando ainda não há + // resultado, para o utilizador já perceber que aquele espaço é para + // o resultado do quiz mesmo antes de o fazer. + const double expandedHeight = _expandedAppBarHeight; return Scaffold( body: NestedScrollView( @@ -385,7 +386,7 @@ class _LoggedHomeScreenState extends State Positioned( left: 0, right: 0, - top: kToolbarHeight + 34, + top: kToolbarHeight + 50, child: Center( child: Text( (_selectedChildName ?? '').trim(), @@ -397,54 +398,35 @@ class _LoggedHomeScreenState extends State ), ), ), - ) - else if ((_selectedChildName ?? '').trim().isNotEmpty) - Positioned( - left: 0, - right: 0, - top: kToolbarHeight, - bottom: 0, - child: Center( - child: Text( - _selectedChildName!.trim(), - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.w800, - color: Colors.white.withValues(alpha: 0.92), - fontSize: 14, - ), - ), - ), ), //posição da app bar relativamente ao nome - if (hasScore) - Positioned( - left: 0, - right: 0, - top: kToolbarHeight + 60, - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - _RiskArcGauge( - // Usa sempre o máximo atual do quiz (não - // o que foi gravado na última avaliação) - // para não mostrar um denominador antigo - // quando o número de perguntas muda. - value: result.signs, - max: kSignsMax, - label: 'Sinais', - ), - const SizedBox(width: 18), - _RiskArcGauge( - value: result.factors, - max: kFactorsMax, - label: 'Fatores de risco', - ), - ], - ), + Positioned( + left: 0, + right: 0, + top: kToolbarHeight + 96, + child: Center( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + _RiskArcGauge( + // Usa sempre o máximo atual do quiz (não + // o que foi gravado na última avaliação) + // para não mostrar um denominador antigo + // quando o número de perguntas muda. + value: hasScore ? result.signs : null, + max: hasScore ? kSignsMax : null, + label: 'Sinais de má\noclusão', + ), + const SizedBox(width: 18), + _RiskArcGauge( + value: hasScore ? result.factors : null, + max: hasScore ? kFactorsMax : null, + label: 'Fatores de risco', + ), + ], ), ), + ), ], ), ), @@ -587,19 +569,23 @@ class _LoggedHomeScreenState extends State } class _RiskArcGauge extends StatelessWidget { - const _RiskArcGauge({ - required this.value, - required this.max, - required this.label, - }); + const _RiskArcGauge({required this.value, required this.max, this.label}); - final int value; - final int max; - final String label; + /// Quando [value]/[max] são nulos (sem criança selecionada, ou criança + /// ainda sem quiz feito), o gauge mostra-se vazio — só o anel em branco, + /// sem número nem rótulo — em vez de desaparecer, para o espaço já + /// indicar onde o resultado vai aparecer assim que existir. + final int? value; + final int? max; + final String? label; + + bool get _isEmpty => value == null || max == null; @override Widget build(BuildContext context) { - final progress = max > 0 ? (value / max).clamp(0, 1).toDouble() : 0.0; + final progress = _isEmpty || max! <= 0 + ? 0.0 + : (value! / max!).clamp(0, 1).toDouble(); return TweenAnimationBuilder( duration: const Duration(milliseconds: 700), @@ -621,38 +607,40 @@ class _RiskArcGauge extends StatelessWidget { painter: _RiskArcGaugePainter(progress: animatedProgress), ), ), - Positioned( - top: 38, - left: 0, - right: 0, - child: Center( - child: Text( - '$value/$max', - style: const TextStyle( - color: Colors.white, - fontSize: 17, - fontWeight: FontWeight.w900, - height: 1, + if (!_isEmpty) ...[ + Positioned( + top: 38, + left: 0, + right: 0, + child: Center( + child: Text( + '$value/$max', + style: const TextStyle( + color: Colors.white, + fontSize: 17, + fontWeight: FontWeight.w900, + height: 1, + ), ), ), ), - ), - Positioned( - top: 68, - left: 0, - right: 0, - child: Text( - label, - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white.withValues(alpha: 0.85), - fontSize: 10.5, - fontWeight: FontWeight.w700, - height: 1.15, - letterSpacing: 0.1, + Positioned( + top: 68, + left: 0, + right: 0, + child: Text( + label ?? '', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white.withValues(alpha: 0.85), + fontSize: 10.5, + fontWeight: FontWeight.w700, + height: 1.15, + letterSpacing: 0.1, + ), ), ), - ), + ], ], ), ); @@ -1350,7 +1338,7 @@ class _HeroQuizCard extends StatelessWidget { ), const SizedBox(height: 5), Text( - '28 perguntas rápidas · menos de 3 minutos', + '29 perguntas rápidas · menos de 3 minutos', style: TextStyle( color: Colors.white.withValues(alpha: 0.92), fontWeight: FontWeight.w600, diff --git a/lib/quiz/quiz1.dart b/lib/quiz/quiz1.dart index 45066db..ef90ec7 100644 --- a/lib/quiz/quiz1.dart +++ b/lib/quiz/quiz1.dart @@ -83,7 +83,7 @@ class Quiz1Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 1/28', + title: 'Quiz 1/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a tem problemas respiratórios diagnosticados?', answers: const [ @@ -127,7 +127,7 @@ class Quiz2Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 2/28', + title: 'Quiz 2/29', fallbackColor: const Color(0xFF2F9E94), question: 'O seu filho/a respira habitualmente pela boca?', answers: const [ @@ -171,7 +171,7 @@ class Quiz3Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 3/28', + title: 'Quiz 3/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a ressona habitualmente durante a noite?', answers: const [ @@ -215,7 +215,7 @@ class Quiz4Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 4/28', + title: 'Quiz 4/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a sente habitualmente o nariz "tapado"?', answers: const [ @@ -259,7 +259,7 @@ class Quiz5Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 5/28', + title: 'Quiz 5/29', fallbackColor: const Color(0xFFFF55A7), question: 'Durante o sono, o seu filho/a tem habitualmente interrupções da respiração?', @@ -305,7 +305,7 @@ class Quiz6Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 6/28', + title: 'Quiz 6/29', fallbackColor: const Color(0xFF2F9E94), question: 'O seu filho/a range os dentes com frequência?', answers: const [ @@ -342,7 +342,7 @@ class Quiz7Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 7/28', + title: 'Quiz 7/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a habitualmente tem alergias sazonais?', answers: const [ @@ -386,7 +386,7 @@ class Quiz8Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 8/28', + title: 'Quiz 8/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a acorda com saliva seca na cara ou na almofada?', answers: const [ @@ -430,7 +430,7 @@ class Quiz9Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 9/28', + title: 'Quiz 9/29', fallbackColor: const Color(0xFF2F9E94), question: 'O seu filho/a teve ou costuma ter com frequência otites?', answers: const [ @@ -474,7 +474,7 @@ class Quiz10Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 10/28', + title: 'Quiz 10/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a teve ou costuma ter com frequência amigdalites?', answers: const [ @@ -518,7 +518,7 @@ class Quiz11Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 11/28', + title: 'Quiz 11/29', fallbackColor: const Color(0xFF2F9E94), question: 'O seu filho/a teve ou costuma ter com frequência bronquiolites?', @@ -563,7 +563,7 @@ class Quiz12Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 12/28', + title: 'Quiz 12/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a apresenta dificuldades a mastigar?', answers: const [ @@ -600,7 +600,7 @@ class Quiz13Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 13/28', + title: 'Quiz 13/29', fallbackColor: const Color(0xFF2F9E94), question: 'O seu filho/a habitualmente é lento a comer?', answers: const [ @@ -637,7 +637,7 @@ class Quiz14Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 14/28', + title: 'Quiz 14/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a habitualmente prefere comer alimentos moles?', answers: const [ @@ -674,7 +674,7 @@ class Quiz15Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 15/28', + title: 'Quiz 15/29', fallbackColor: const Color(0xFFFF55A7), question: 'Em bebé apenas foi alimentado por biberão?', answers: const [ @@ -718,7 +718,7 @@ class Quiz16Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 16/28', + title: 'Quiz 16/29', fallbackColor: const Color(0xFF2F9E94), question: 'O seu filho/a usa ou usou chupeta com frequência?', answers: const [ @@ -762,7 +762,7 @@ class Quiz17Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 17/28', + title: 'Quiz 17/29', fallbackColor: const Color(0xFFFF55A7), question: 'O seu filho/a chucha ou já chuchou o dedo com frequência?', answers: const [ @@ -814,7 +814,7 @@ class Quiz18Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 18/28', + title: 'Quiz 18/29', fallbackColor: const Color(0xFFFF55A7), answerImageAspectRatio: 1.5, question: @@ -857,7 +857,7 @@ class Quiz19Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 19/28', + title: 'Quiz 19/29', fallbackColor: const Color(0xFFFF55A7), question: 'Qual das seguintes imagens é mais parecida com o perfil do seu filho/a?', @@ -919,7 +919,7 @@ class Quiz20Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 20/28', + title: 'Quiz 20/29', fallbackColor: const Color(0xFF2F9E94), question: 'Qual é a posição da boca do seu filho/a habitualmente?', answers: [ @@ -964,7 +964,7 @@ class Quiz21Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 21/28', + title: 'Quiz 21/29', fallbackColor: const Color(0xFFFF55A7), question: 'Qual das imagens, na zona abaixo dos olhos, se assemelha mais ao seu filho/a?', @@ -1014,7 +1014,7 @@ class Quiz22Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 22/28', + title: 'Quiz 22/29', fallbackColor: const Color(0xFFFF55A7), isSignQuestion: true, question: @@ -1070,12 +1070,20 @@ class Quiz23Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 23/28', + title: 'Quiz 23/29', fallbackColor: const Color(0xFF2F9E94), isSignQuestion: true, question: 'Qual das seguintes imagens se assemelha à boca do seu filho/a?', answers: const [ + QuizAnswer( + title: 'Dentição sobreposta', + description: 'Dentes sobrepostos/tortos', + weight: 2, + hideTitle: true, + value: 'dentes_sobrepostos', + imagePath: 'assets/mockup_images/10.png', + ), QuizAnswer( title: 'Dentição alinhada', description: 'Dentição bem alinhada, sem apinhamento', @@ -1092,14 +1100,6 @@ class Quiz23Screen extends StatelessWidget { value: 'dentes_desalinhados', imagePath: 'assets/mockup_images/13.png', ), - QuizAnswer( - title: 'Dentição sobreposta', - description: 'Dentes sobrepostos/tortos', - weight: 2, - hideTitle: true, - value: 'dentes_sobrepostos', - imagePath: 'assets/mockup_images/10.png', - ), ], currentScore: currentScore, nextRoute: (context, nextScore) => quizPageRoute( @@ -1121,7 +1121,7 @@ class Quiz24Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 24/28', + title: 'Quiz 24/29', fallbackColor: const Color(0xFF2F9E94), isSignQuestion: true, question: @@ -1172,7 +1172,7 @@ class Quiz25Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 25/28', + title: 'Quiz 25/29', fallbackColor: const Color(0xFFFF55A7), question: 'Qual das seguintes imagens se assemelha ao freio labial do seu filho/a?', @@ -1214,7 +1214,7 @@ class Quiz26Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 26/28', + title: 'Quiz 26/29', fallbackColor: const Color(0xFFFF55A7), question: 'Qual das seguintes imagens se assemelha ao freio lingual do seu filho/a?', @@ -1256,7 +1256,58 @@ class Quiz27Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 27/28', + title: 'Quiz 27/29', + fallbackColor: const Color(0xFF2F9E94), + isSignQuestion: true, + question: + 'Qual das seguintes imagens se assemelha com a boca do seu filho/a?', + answers: const [ + QuizAnswer( + title: 'Dentição desalinhada', + description: 'Dentição desalinhada/apinhada', + weight: 2, + hideTitle: true, + value: 'dentes_desalinhados_3', + imagePath: 'assets/mockup_images/23.JPEG', + ), + QuizAnswer( + title: 'Dentição sobreposta', + description: 'Dentes sobrepostos/tortos', + weight: 2, + hideTitle: true, + value: 'dentes_sobrepostos_3', + imagePath: 'assets/mockup_images/24.png', + ), + QuizAnswer( + title: 'Dentição alinhada', + description: 'Dentição bem alinhada, sem apinhamento', + weight: 1, + hideTitle: true, + value: 'dentes_alinhados_3', + imagePath: 'assets/mockup_images/25.jpg', + ), + ], + currentScore: currentScore, + nextRoute: (context, nextScore) => quizPageRoute( + builder: (_) => Quiz28Screen(currentScore: nextScore, scopeId: scopeId), + ), + answerType: QuizAnswerType.image, + showBackButton: true, + ); + } +} + +// Quiz 28: Boca / dentição 2 (Image-choice) +class Quiz28Screen extends StatelessWidget { + const Quiz28Screen({super.key, required this.currentScore, this.scopeId}); + + final QuizScore currentScore; + final String? scopeId; + + @override + Widget build(BuildContext context) { + return QuizQuestionScreen( + title: 'Quiz 28/29', fallbackColor: const Color(0xFF2F9E94), isSignQuestion: true, question: @@ -1281,7 +1332,7 @@ class Quiz27Screen extends StatelessWidget { ], currentScore: currentScore, nextRoute: (context, nextScore) => quizPageRoute( - builder: (_) => Quiz28Screen(currentScore: nextScore, scopeId: scopeId), + builder: (_) => Quiz29Screen(currentScore: nextScore, scopeId: scopeId), ), answerType: QuizAnswerType.image, showBackButton: true, @@ -1289,9 +1340,9 @@ class Quiz27Screen extends StatelessWidget { } } -// Quiz 28: Céu da boca (Image-choice, final) -class Quiz28Screen extends StatelessWidget { - const Quiz28Screen({super.key, required this.currentScore, this.scopeId}); +// Quiz 29: Céu da boca (Image-choice, final) +class Quiz29Screen extends StatelessWidget { + const Quiz29Screen({super.key, required this.currentScore, this.scopeId}); final QuizScore currentScore; final String? scopeId; @@ -1299,9 +1350,10 @@ class Quiz28Screen extends StatelessWidget { @override Widget build(BuildContext context) { return QuizQuestionScreen( - title: 'Quiz 28/28', + title: 'Quiz 29/29', fallbackColor: const Color(0xFFFF55A7), isSignQuestion: true, + correctBadgeLabel: 'Posição saudável', question: 'Qual das seguintes imagens se assemelha ao céu da boca do seu filho/a?', answers: const [ diff --git a/lib/quiz/quiz_question_screen.dart b/lib/quiz/quiz_question_screen.dart index 7884fda..2152719 100644 --- a/lib/quiz/quiz_question_screen.dart +++ b/lib/quiz/quiz_question_screen.dart @@ -82,6 +82,7 @@ class QuizQuestionScreen extends StatefulWidget { this.suggestedVideoTitle, this.fallbackColor, this.answerImageAspectRatio, + this.correctBadgeLabel = 'Posição certa', }); final String title; @@ -115,6 +116,11 @@ class QuizQuestionScreen extends StatefulWidget { /// imagem colapsar, mostra-se um bloco colorido com o ícone da app. final Color? fallbackColor; + /// Texto do selo mostrado sobre a imagem certa ao revelar a resposta — + /// customizável por pergunta (ex.: "Posição saudável" em vez do genérico + /// "Posição certa", quando faz mais sentido para o contexto da pergunta). + final String correctBadgeLabel; + @override State createState() => _QuizQuestionScreenState(); } @@ -445,6 +451,8 @@ class _QuizQuestionScreenState extends State { ? 2.3 : 1.5), reveal: _revealed, + correctLabel: widget + .correctBadgeLabel, onTap: _revealed ? null : () => @@ -820,6 +828,7 @@ class _QuizAnswerTile extends StatelessWidget { required this.onTap, this.imageAspectRatio = 4 / 3, this.reveal = false, + this.correctLabel = 'Posição certa', }); final QuizAnswer answer; @@ -831,6 +840,10 @@ class _QuizAnswerTile extends StatelessWidget { /// errada — ver [_QuizQuestionScreenState._revealed]. final bool reveal; + /// Texto do selo quando [isCorrect] — customizável por pergunta (ex.: + /// "Posição saudável" em vez do genérico "Posição certa"). + final String correctLabel; + @override Widget build(BuildContext context) { final bool isCorrect = answer.weight == 1; @@ -991,7 +1004,7 @@ class _QuizAnswerTile extends StatelessWidget { ), const SizedBox(width: 4), Text( - isCorrect ? 'Resposta certa' : 'Resposta inadequada', + isCorrect ? correctLabel : 'Posição inadequada', style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w800, diff --git a/lib/quiz/quiz_result.dart b/lib/quiz/quiz_result.dart index e1f8a76..5177311 100644 --- a/lib/quiz/quiz_result.dart +++ b/lib/quiz/quiz_result.dart @@ -13,11 +13,12 @@ import 'quiz_video_guide.dart'; const String _resultGuideYoutubeId = '3q7C7txH1dE'; -// Fase 3 tem 28 perguntas no total: 5 são sinais de má oclusão já -// instalados (queixo, boca/dentição, apinhamento, boca/dentição 2, céu da -// boca) — as restantes 23 são fatores de risco associados. Ver o diagrama -// de planeamento partilhado com o utilizador para o racional completo. -const int kSignsMax = 5; +// Fase 3 tem 29 perguntas no total: 6 são sinais de má oclusão já +// instalados (queixo, boca/dentição, apinhamento, boca/dentição 2, +// boca/dentição 3, céu da boca) — as restantes 23 são fatores de risco +// associados. Ver o diagrama de planeamento partilhado com o utilizador +// para o racional completo. +const int kSignsMax = 6; const int kFactorsMax = 23; /// A partir de quantos sinais/fatores presentes se recomenda avaliação. @@ -73,13 +74,16 @@ class _QuizResultScreenState extends State { scope.startsWith('${userId}_')) { final childId = scope.substring(userId.length + 1).trim(); if (childId.isNotEmpty) { - // Fire-and-forget: avoid blocking UI on erros de rede. Requer as + // Aguarda a gravação (em vez de fire-and-forget) para que, ao voltar + // à Home logo a seguir, _loadQuizResult já encontre o valor novo na + // base de dados — caso contrário havia uma corrida em que a Home + // consultava a tabela antes desta escrita terminar, mostrando o + // resultado antigo até trocar de aba ou reabrir a app. Requer as // colunas last_signs/last_signs_max/last_factors/last_factors_max - // na tabela children — se ainda não existirem na base de dados, - // esta chamada falha silenciosamente e o resultado fica só local - // (SharedPreferences, acima), tal como já acontecia antes. - unawaited( - supabase + // na tabela children — se ainda não existirem, falha silenciosamente + // e o resultado fica só local (SharedPreferences, acima). + try { + await supabase .from('children') .update({ 'last_signs': widget.finalScore.signs, @@ -87,13 +91,12 @@ class _QuizResultScreenState extends State { 'last_factors': widget.finalScore.factors, 'last_factors_max': kFactorsMax, }) - .eq('id', childId) - .catchError((e) { - debugPrint( - '[QuizResult] Falha ao gravar score na base de dados: $e', - ); - }), - ); + .eq('id', childId); + } catch (e) { + debugPrint( + '[QuizResult] Falha ao gravar score na base de dados: $e', + ); + } } } } @@ -112,7 +115,11 @@ class _QuizResultScreenState extends State { 'de leite como de permanentes).\n\nO seu propósito é ' 'identificar, prevenir ou reduzir a gravidade de maloclusões ' 'e problemas no desenvolvimento dos maxilares enquanto os ' - 'ossos e dentes ainda estão em crescimento.', + 'ossos e dentes ainda estão em crescimento.\n\nEsta ' + 'intervenção aproveita a fase de desenvolvimento craniofacial ' + 'para influenciar o crescimento ósseo, redirecionar a ' + 'mandíbula, corrigir o alinhamento dos maxilares ou criar ' + 'espaço para a erupção correta dos dentes permanentes.', onAdvance: (context) => Navigator.of(context).popUntil((r) => r.isFirst), ),