Registrar filho atualizado
This commit is contained in:
@@ -2,7 +2,6 @@ import 'package:firebase_auth/firebase_auth.dart';
|
|||||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lottie/lottie.dart';
|
import 'package:lottie/lottie.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
@@ -35,10 +34,7 @@ class _AnimatedAuthSheet extends StatelessWidget {
|
|||||||
builder: (context, t, w) {
|
builder: (context, t, w) {
|
||||||
return Opacity(
|
return Opacity(
|
||||||
opacity: t,
|
opacity: t,
|
||||||
child: Transform.translate(
|
child: Transform.translate(offset: Offset(0, (1 - t) * 12), child: w),
|
||||||
offset: Offset(0, (1 - t) * 12),
|
|
||||||
child: w,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
@@ -54,10 +50,7 @@ class _AnimatedAuthSheet extends StatelessWidget {
|
|||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
colors: [
|
colors: [Color(0xFFFFE6F1), Color(0xFFFFC9DF)],
|
||||||
Color(0xFFFFE6F1),
|
|
||||||
Color(0xFFFFC9DF),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -106,42 +99,22 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
final _emailController = TextEditingController();
|
final _emailController = TextEditingController();
|
||||||
final _passwordController = TextEditingController();
|
final _passwordController = TextEditingController();
|
||||||
|
|
||||||
final _childNameController = TextEditingController();
|
|
||||||
final _childAgeController = TextEditingController();
|
|
||||||
String? _childGender;
|
|
||||||
|
|
||||||
bool _loading = false;
|
bool _loading = false;
|
||||||
|
|
||||||
static const String _kPendingQuizScopeKey = 'pending_quiz_scope_v1';
|
|
||||||
|
|
||||||
Future<void> _persistRegistrationData({
|
Future<void> _persistRegistrationData({
|
||||||
required String uid,
|
required String uid,
|
||||||
required String name,
|
required String name,
|
||||||
required String email,
|
required String email,
|
||||||
required String childId,
|
|
||||||
required String childName,
|
|
||||||
required int childAge,
|
|
||||||
required String childGender,
|
|
||||||
}) async {
|
}) async {
|
||||||
await Future.wait([
|
await FirebaseFirestore.instance
|
||||||
FirebaseFirestore.instance.collection('users').doc(uid).set({
|
.collection('users')
|
||||||
'name': name,
|
.doc(uid)
|
||||||
'email': email,
|
.set({
|
||||||
'createdAt': FieldValue.serverTimestamp(),
|
'name': name,
|
||||||
}, SetOptions(merge: true)).timeout(const Duration(seconds: 20)),
|
'email': email,
|
||||||
FirebaseFirestore.instance
|
'createdAt': FieldValue.serverTimestamp(),
|
||||||
.collection('users')
|
}, SetOptions(merge: true))
|
||||||
.doc(uid)
|
.timeout(const Duration(seconds: 20));
|
||||||
.collection('children')
|
|
||||||
.doc(childId)
|
|
||||||
.set({
|
|
||||||
'id': childId,
|
|
||||||
'name': childName,
|
|
||||||
'age': childAge,
|
|
||||||
'gender': childGender,
|
|
||||||
'createdAt': FieldValue.serverTimestamp(),
|
|
||||||
}, SetOptions(merge: true)).timeout(const Duration(seconds: 20)),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -149,8 +122,6 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
_nameController.dispose();
|
_nameController.dispose();
|
||||||
_emailController.dispose();
|
_emailController.dispose();
|
||||||
_passwordController.dispose();
|
_passwordController.dispose();
|
||||||
_childNameController.dispose();
|
|
||||||
_childAgeController.dispose();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,13 +179,23 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
border: underlineBorder,
|
border: underlineBorder,
|
||||||
enabledBorder: underlineBorder,
|
enabledBorder: underlineBorder,
|
||||||
focusedBorder: underlineBorder.copyWith(
|
focusedBorder: underlineBorder.copyWith(
|
||||||
borderSide: const BorderSide(color: primaryTeal, width: 1.6),
|
borderSide: const BorderSide(
|
||||||
|
color: primaryTeal,
|
||||||
|
width: 1.6,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingLabelStyle: const TextStyle(
|
||||||
|
color: primaryTeal,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
),
|
),
|
||||||
floatingLabelStyle: const TextStyle(color: primaryTeal, fontWeight: FontWeight.w700),
|
|
||||||
),
|
),
|
||||||
validator: (v) {
|
validator: (v) {
|
||||||
if (v == null || v.trim().isEmpty) return 'Informe seu nome';
|
if (v == null || v.trim().isEmpty) {
|
||||||
if (v.trim().length < 2) return 'Nome muito curto';
|
return 'Informe seu nome';
|
||||||
|
}
|
||||||
|
if (v.trim().length < 2) {
|
||||||
|
return 'Nome muito curto';
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -228,9 +209,15 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
border: underlineBorder,
|
border: underlineBorder,
|
||||||
enabledBorder: underlineBorder,
|
enabledBorder: underlineBorder,
|
||||||
focusedBorder: underlineBorder.copyWith(
|
focusedBorder: underlineBorder.copyWith(
|
||||||
borderSide: const BorderSide(color: primaryTeal, width: 1.6),
|
borderSide: const BorderSide(
|
||||||
|
color: primaryTeal,
|
||||||
|
width: 1.6,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingLabelStyle: const TextStyle(
|
||||||
|
color: primaryTeal,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
),
|
),
|
||||||
floatingLabelStyle: const TextStyle(color: primaryTeal, fontWeight: FontWeight.w700),
|
|
||||||
),
|
),
|
||||||
validator: (v) {
|
validator: (v) {
|
||||||
final value = (v ?? '').trim();
|
final value = (v ?? '').trim();
|
||||||
@@ -249,9 +236,15 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
border: underlineBorder,
|
border: underlineBorder,
|
||||||
enabledBorder: underlineBorder,
|
enabledBorder: underlineBorder,
|
||||||
focusedBorder: underlineBorder.copyWith(
|
focusedBorder: underlineBorder.copyWith(
|
||||||
borderSide: const BorderSide(color: primaryTeal, width: 1.6),
|
borderSide: const BorderSide(
|
||||||
|
color: primaryTeal,
|
||||||
|
width: 1.6,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingLabelStyle: const TextStyle(
|
||||||
|
color: primaryTeal,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
),
|
),
|
||||||
floatingLabelStyle: const TextStyle(color: primaryTeal, fontWeight: FontWeight.w700),
|
|
||||||
),
|
),
|
||||||
validator: (v) {
|
validator: (v) {
|
||||||
final value = (v ?? '');
|
final value = (v ?? '');
|
||||||
@@ -260,72 +253,6 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 18),
|
|
||||||
TextFormField(
|
|
||||||
controller: _childNameController,
|
|
||||||
textInputAction: TextInputAction.next,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'Nome do filho(a)',
|
|
||||||
border: underlineBorder,
|
|
||||||
enabledBorder: underlineBorder,
|
|
||||||
focusedBorder: underlineBorder.copyWith(
|
|
||||||
borderSide: const BorderSide(color: primaryTeal, width: 1.6),
|
|
||||||
),
|
|
||||||
floatingLabelStyle: const TextStyle(color: primaryTeal, fontWeight: FontWeight.w700),
|
|
||||||
),
|
|
||||||
validator: (v) {
|
|
||||||
final value = (v ?? '').trim();
|
|
||||||
if (value.isEmpty) return 'Informe o nome do filho(a)';
|
|
||||||
if (value.length < 2) return 'Nome muito curto';
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
TextFormField(
|
|
||||||
controller: _childAgeController,
|
|
||||||
keyboardType: TextInputType.number,
|
|
||||||
textInputAction: TextInputAction.next,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'Idade do filho(a)',
|
|
||||||
border: underlineBorder,
|
|
||||||
enabledBorder: underlineBorder,
|
|
||||||
focusedBorder: underlineBorder.copyWith(
|
|
||||||
borderSide: const BorderSide(color: primaryTeal, width: 1.6),
|
|
||||||
),
|
|
||||||
floatingLabelStyle: const TextStyle(color: primaryTeal, fontWeight: FontWeight.w700),
|
|
||||||
),
|
|
||||||
validator: (v) {
|
|
||||||
final raw = (v ?? '').trim();
|
|
||||||
if (raw.isEmpty) return 'Informe a idade do filho(a)';
|
|
||||||
final age = int.tryParse(raw);
|
|
||||||
if (age == null) return 'Idade inválida';
|
|
||||||
if (age < 0 || age > 25) return 'Idade inválida';
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
DropdownButtonFormField<String>(
|
|
||||||
initialValue: _childGender,
|
|
||||||
items: const [
|
|
||||||
DropdownMenuItem(value: 'Masculino', child: Text('Masculino')),
|
|
||||||
DropdownMenuItem(value: 'Feminino', child: Text('Feminino')),
|
|
||||||
DropdownMenuItem(value: 'Outro', child: Text('Outro')),
|
|
||||||
],
|
|
||||||
onChanged: (v) => setState(() => _childGender = v),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'Gênero do filho(a)',
|
|
||||||
border: underlineBorder,
|
|
||||||
enabledBorder: underlineBorder,
|
|
||||||
focusedBorder: underlineBorder.copyWith(
|
|
||||||
borderSide: const BorderSide(color: primaryTeal, width: 1.6),
|
|
||||||
),
|
|
||||||
floatingLabelStyle: const TextStyle(color: primaryTeal, fontWeight: FontWeight.w700),
|
|
||||||
),
|
|
||||||
validator: (v) {
|
|
||||||
if (v == null || v.trim().isEmpty) return 'Selecione o gênero';
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 46,
|
height: 46,
|
||||||
@@ -348,7 +275,9 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: _loading ? null : () => Navigator.of(context).pop(),
|
onPressed: _loading
|
||||||
|
? null
|
||||||
|
: () => Navigator.of(context).pop(),
|
||||||
child: const Text('Fechar'),
|
child: const Text('Fechar'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -368,15 +297,8 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
final email = _emailController.text.trim();
|
final email = _emailController.text.trim();
|
||||||
final password = _passwordController.text;
|
final password = _passwordController.text;
|
||||||
|
|
||||||
final childName = _childNameController.text.trim();
|
|
||||||
final childAge = int.parse(_childAgeController.text.trim());
|
|
||||||
final childGender = (_childGender ?? '').trim();
|
|
||||||
|
|
||||||
final credential = await FirebaseAuth.instance
|
final credential = await FirebaseAuth.instance
|
||||||
.createUserWithEmailAndPassword(
|
.createUserWithEmailAndPassword(email: email, password: password)
|
||||||
email: email,
|
|
||||||
password: password,
|
|
||||||
)
|
|
||||||
.timeout(const Duration(seconds: 20));
|
.timeout(const Duration(seconds: 20));
|
||||||
|
|
||||||
final user = credential.user;
|
final user = credential.user;
|
||||||
@@ -386,19 +308,6 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
|
|
||||||
final uid = user.uid;
|
final uid = user.uid;
|
||||||
|
|
||||||
// Gera o childId antes de fechar o sheet para termos um scopeId determinístico.
|
|
||||||
final childId = FirebaseFirestore.instance
|
|
||||||
.collection('users')
|
|
||||||
.doc(uid)
|
|
||||||
.collection('children')
|
|
||||||
.doc()
|
|
||||||
.id;
|
|
||||||
final scopeId = '${uid}_$childId';
|
|
||||||
|
|
||||||
// Marca para o LoggedHome abrir automaticamente o quiz desta criança.
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
|
||||||
await prefs.setString(_kPendingQuizScopeKey, scopeId);
|
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
// Fecha o sheet imediatamente após autenticar.
|
// Fecha o sheet imediatamente após autenticar.
|
||||||
@@ -410,27 +319,27 @@ class _RegisterBottomSheetState extends State<RegisterBottomSheet> {
|
|||||||
uid: uid,
|
uid: uid,
|
||||||
name: name,
|
name: name,
|
||||||
email: email,
|
email: email,
|
||||||
childId: childId,
|
|
||||||
childName: childName,
|
|
||||||
childAge: childAge,
|
|
||||||
childGender: childGender,
|
|
||||||
).catchError((_) {}),
|
).catchError((_) {}),
|
||||||
);
|
);
|
||||||
} on FirebaseAuthException catch (e) {
|
} on FirebaseAuthException catch (e) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(
|
||||||
SnackBar(content: Text(_friendlyAuthError(e))),
|
context,
|
||||||
);
|
).showSnackBar(SnackBar(content: Text(_friendlyAuthError(e))));
|
||||||
} on TimeoutException {
|
} on TimeoutException {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Tempo esgotado. Verifique sua conexão e tente novamente.')),
|
const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Tempo esgotado. Verifique sua conexão e tente novamente.',
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(
|
||||||
SnackBar(content: Text('Erro: $e')),
|
context,
|
||||||
);
|
).showSnackBar(SnackBar(content: Text('Erro: $e')));
|
||||||
} finally {
|
} finally {
|
||||||
if (mounted && _loading) setState(() => _loading = false);
|
if (mounted && _loading) setState(() => _loading = false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'quiz3.dart';
|
|
||||||
import 'quiz_question_screen.dart';
|
|
||||||
|
|
||||||
class Quiz2Screen extends StatelessWidget {
|
|
||||||
const Quiz2Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 2/5',
|
|
||||||
question: 'Quando devo trocar a escova de dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'A cada 3 meses (ou antes se estragar)',
|
|
||||||
description:
|
|
||||||
'O ideal é trocar a cada ~3 meses. Se as cerdas abrirem antes, troque antes. Cerdas abertas limpam pior.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só quando a escova “quebrar”',
|
|
||||||
description:
|
|
||||||
'Esperar demais reduz a eficiência da escovação e pode acumular microrganismos na escova.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Todo mês, obrigatoriamente',
|
|
||||||
description:
|
|
||||||
'Não é regra fixa. Um mês pode ser cedo demais se a escova estiver em bom estado. O principal é o estado das cerdas.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz3Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'quiz4.dart';
|
|
||||||
import 'quiz_question_screen.dart';
|
|
||||||
|
|
||||||
class Quiz3Screen extends StatelessWidget {
|
|
||||||
const Quiz3Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 3/5',
|
|
||||||
question: 'Qual a quantidade ideal de pasta de dente para crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Um grão de arroz (pequenos) / ervilha (maiores)',
|
|
||||||
description:
|
|
||||||
'Para crianças pequenas, um “grão de arroz” já basta. Conforme cresce, pode ser do tamanho de uma ervilha. Isso ajuda a evitar excesso de flúor ingerido.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Cobrir toda a escova com pasta',
|
|
||||||
description:
|
|
||||||
'Muito produto não significa melhor limpeza. Em crianças, aumenta o risco de engolir pasta em excesso.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Nenhuma pasta, só água',
|
|
||||||
description:
|
|
||||||
'A pasta com flúor (na quantidade correta) ajuda a prevenir cáries. Em geral, água sozinha não oferece a mesma proteção.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz4Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'quiz5.dart';
|
|
||||||
import 'quiz_question_screen.dart';
|
|
||||||
|
|
||||||
class Quiz4Screen extends StatelessWidget {
|
|
||||||
const Quiz4Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 4/5',
|
|
||||||
question: 'Qual é o melhor horário para usar fio dental?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Uma vez ao dia, com calma (geralmente à noite)',
|
|
||||||
description:
|
|
||||||
'O importante é a frequência diária. À noite costuma ser mais fácil, pois remove restos e placa antes de dormir.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só quando algo fica preso',
|
|
||||||
description:
|
|
||||||
'O fio dental não serve apenas para tirar restos visíveis; ele remove placa bacteriana entre os dentes onde a escova não alcança.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Depois de toda refeição (obrigatório)',
|
|
||||||
description:
|
|
||||||
'Pode ser útil em alguns casos, mas não é obrigatório para todos. O essencial é fazer bem feito ao menos 1x ao dia.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz5Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'quiz_result.dart';
|
|
||||||
import 'quiz_question_screen.dart';
|
|
||||||
|
|
||||||
class Quiz5Screen extends StatelessWidget {
|
|
||||||
const Quiz5Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 5/5',
|
|
||||||
question: 'O que ajuda mais a prevenir cáries no dia a dia?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escovar + flúor + reduzir açúcar frequente',
|
|
||||||
description:
|
|
||||||
'A prevenção é um conjunto: boa higiene com flúor e menos “beliscos” açucarados ao longo do dia.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só enxaguante bucal',
|
|
||||||
description:
|
|
||||||
'Enxaguante pode ajudar em alguns casos, mas não substitui escovação e fio dental.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Evitar completamente dentista',
|
|
||||||
description:
|
|
||||||
'Consultas regulares são importantes para prevenção e orientação. O dentista também identifica problemas bem no começo.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => QuizResultScreen(finalScore: nextScore, maxScore: 25, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
@@ -1,825 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'quiz_question_screen.dart';
|
|
||||||
import 'quiz_result.dart';
|
|
||||||
|
|
||||||
// Quiz 1: Tipos de Escova (antiga Quiz 6)
|
|
||||||
class Quiz1Screen extends StatelessWidget {
|
|
||||||
const Quiz1Screen({super.key, this.currentScore = 0, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 1/20',
|
|
||||||
question: 'Qual tipo de escova é mais recomendada para crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escova macia com cabeça pequena',
|
|
||||||
description:
|
|
||||||
'Escovas macias protegem a gengiva sensível das crianças e a cabeça pequena alcança melhor todos os dentes.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escova dura para limpar melhor',
|
|
||||||
description:
|
|
||||||
'Escovas duras podem machucar a gengiva e desgastar o esmalte dos dentes das crianças.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escova elétrica sempre é melhor',
|
|
||||||
description:
|
|
||||||
'Escova elétrica pode ajudar, mas não é essencial. O mais importante é a técnica e frequência.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz2Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 2: Alimentos que Causam Cáries (antiga Quiz 7)
|
|
||||||
class Quiz2Screen extends StatelessWidget {
|
|
||||||
const Quiz2Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 2/20',
|
|
||||||
question: 'Qual alimento é mais prejudicial para os dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Balas e chicletes pegajosos',
|
|
||||||
description:
|
|
||||||
'Alimentos pegajosos ficam presos nos dentes por mais tempo, aumentando o risco de cáries.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Frutas frescas',
|
|
||||||
description:
|
|
||||||
'Frutas são saudáveis, mas algumas são ácidas. O problema maior são os alimentos açucarados e pegajosos.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Vegetais crus',
|
|
||||||
description:
|
|
||||||
'Vegetais são geralmente seguros para os dentes e muitos ajudam na limpeza natural.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz3Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 3: Primeira Visita ao Dentista (antiga Quiz 8)
|
|
||||||
class Quiz3Screen extends StatelessWidget {
|
|
||||||
const Quiz3Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 3/20',
|
|
||||||
question: 'Qual a idade ideal para a primeira visita ao dentista?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'A partir dos 1 ano de idade',
|
|
||||||
description:
|
|
||||||
'O recomendado é levar ao dentista assim que o primeiro dentição aparecer ou até 1 ano.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só depois dos 6 anos',
|
|
||||||
description:
|
|
||||||
'Esperar demais pode permitir que problemas sérios se desenvolvam sem detecção precoce.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Apenas quando houver dor',
|
|
||||||
description:
|
|
||||||
'Dor geralmente indica que o problema já está avançado. Prevenção é melhor que tratamento.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz4Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 4: Uso de Fio Dental (antiga Quiz 9)
|
|
||||||
class Quiz4Screen extends StatelessWidget {
|
|
||||||
const Quiz4Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 4/20',
|
|
||||||
question: 'Com que frequência crianças devem usar fio dental?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Pelo menos uma vez ao dia',
|
|
||||||
description:
|
|
||||||
'O uso diário de fio dental é importante para remover placa entre os dentes onde a escova não alcança.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só quando os dentes estiverem muito juntos',
|
|
||||||
description:
|
|
||||||
'Fio dental é necessário independentemente do espaçamento dos dentes para remover placa bacteriana.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Uma vez por semana é suficiente',
|
|
||||||
description:
|
|
||||||
'Uso semanal é insuficiente. Placa bacteriana se forma diariamente e precisa ser removida.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz5Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 5: Flúor (antiga Quiz 10)
|
|
||||||
class Quiz5Screen extends StatelessWidget {
|
|
||||||
const Quiz5Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 5/20',
|
|
||||||
question: 'O flúor é seguro para crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Sim, na quantidade correta para cada idade',
|
|
||||||
description:
|
|
||||||
'Flúor é seguro e eficaz quando usado nas quantidades recomendadas para cada faixa etária.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não, deve ser evitado completamente',
|
|
||||||
description:
|
|
||||||
'Flúor é essencial para prevenir cáries. O problema é o excesso, não o uso adequado.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só necessário depois dos 12 anos',
|
|
||||||
description:
|
|
||||||
'Flúor é importante em todas as idades, com ajuste na quantidade conforme a idade da criança.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz6Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 6: Chupetas e Mamadeiras (antiga Quiz 11)
|
|
||||||
class Quiz6Screen extends StatelessWidget {
|
|
||||||
const Quiz6Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 6/20',
|
|
||||||
question: 'Até que idade é aceitável usar chupeta?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Até 2-3 anos, com desmame gradual',
|
|
||||||
description:
|
|
||||||
'Após 2-3 anos, chupeta pode afetar o desenvolvimento da dentição e fala. O desmame deve ser gradual.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Até os 6 anos, não tem problema',
|
|
||||||
description:
|
|
||||||
'Uso prolongado pode causar problemas na mordida e fala, além de dificultar o alinhamento dos dentes.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só até 1 ano',
|
|
||||||
description:
|
|
||||||
'Um ano pode ser muito cedo para algumas crianças. O importante é começar o desmame após 2 anos.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz7Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 7: Bebidas e Dentição (antiga Quiz 12)
|
|
||||||
class Quiz7Screen extends StatelessWidget {
|
|
||||||
const Quiz7Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 7/20',
|
|
||||||
question: 'Qual bebida é mais prejudicial para os dentes das crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Refrigerantes e sucos industrializados',
|
|
||||||
description:
|
|
||||||
'Bebidas açucaradas e ácidas são as principais causas de cáries infantis, especialmente se consumidas frequentemente.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Leite e água',
|
|
||||||
description:
|
|
||||||
'Leite e água são seguros para os dentes. O problema são bebidas açucaradas e ácidas.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Sucos naturais sem açúcar',
|
|
||||||
description:
|
|
||||||
'Sucos naturais são melhores que industrializados, mas alguns são ácidos. Moderação é importante.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz8Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 8: Hábitos Noturnos (antiga Quiz 13)
|
|
||||||
class Quiz8Screen extends StatelessWidget {
|
|
||||||
const Quiz8Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 8/20',
|
|
||||||
question: 'Crianças devem escovar os dentes antes de dormir?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Sim, é fundamental antes de dormir',
|
|
||||||
description:
|
|
||||||
'Escovação noturna é crucial porque durante a noite a produção de saliva diminui, aumentando o risco de cáries.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só se comeu doce',
|
|
||||||
description:
|
|
||||||
'Placa bacteriana se acumula durante o dia independentemente do que foi comido. Escovação noturna é sempre necessária.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não precisa se escovou durante o dia',
|
|
||||||
description:
|
|
||||||
'Mesmo com escovação diurna, a noturna é essencial devido à redução de saliva durante o sono.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz9Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 9: Traumatismos Dentários (antiga Quiz 14)
|
|
||||||
class Quiz9Screen extends StatelessWidget {
|
|
||||||
const Quiz9Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 9/20',
|
|
||||||
question: 'O que fazer se uma criança cair e quebrar um dente?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Procurar dentista imediatamente',
|
|
||||||
description:
|
|
||||||
'Traumatismo dentário é emergência. Quanto mais rápido o atendimento, melhor o prognóstico.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Esperar alguns dias para observar',
|
|
||||||
description:
|
|
||||||
'Esperar pode comprometer o tratamento. Dentes fraturados podem infectar ou morrer se não tratados.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Dar analgésico e observar',
|
|
||||||
description:
|
|
||||||
'Analgésico pode ajudar com dor, mas não resolve o problema dentário que precisa de tratamento profissional.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz10Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 10: Selantes (antiga Quiz 15)
|
|
||||||
class Quiz10Screen extends StatelessWidget {
|
|
||||||
const Quiz10Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 10/20',
|
|
||||||
question: 'Para que servem os selantes dentários?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Proteger contra cáries em dentes profundos',
|
|
||||||
description:
|
|
||||||
'Selantes criam uma barreira protetora em sulcos e fissuras, locais difíceis de limpar e propensos a cáries.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Clarear os dentes',
|
|
||||||
description:
|
|
||||||
'Selantes não têm função estética de clareamento, apenas protetiva contra cáries.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Substituir a escovação',
|
|
||||||
description:
|
|
||||||
'Selantes complementam a higiene, não substituem a escovação e o fio dental.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz11Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 11: Aparelhos Ortodônticos (antiga Quiz 16)
|
|
||||||
class Quiz11Screen extends StatelessWidget {
|
|
||||||
const Quiz11Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 11/20',
|
|
||||||
question: 'Qual a melhor idade para avaliar necessidade de aparelho?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Entre 7-9 anos para avaliação',
|
|
||||||
description:
|
|
||||||
'Avaliação precoce permite identificar problemas e planejar o melhor momento para intervenção.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só depois dos 12 anos',
|
|
||||||
description:
|
|
||||||
'Esperar demais pode perder a oportunidade de tratamento interceptativo que simplifica casos complexos.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Qualquer idade, não faz diferença',
|
|
||||||
description:
|
|
||||||
'Existem momentos ideais para diferentes tipos de tratamento. Avaliação precoce é importante.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz12Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 12: Respiração Bucal (antiga Quiz 17)
|
|
||||||
class Quiz12Screen extends StatelessWidget {
|
|
||||||
const Quiz12Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 12/20',
|
|
||||||
question: 'Respirar pela boca afeta os dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Sim, pode causar vários problemas',
|
|
||||||
description:
|
|
||||||
'Respiração bucal pode alterar o desenvolvimento facial, causar cáries e problemas ortodônticos.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não, é apenas uma questão de hábito',
|
|
||||||
description:
|
|
||||||
'Respiração bucal tem consequências reais na saúde bucal e desenvolvimento facial da criança.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só afeta adultos, não crianças',
|
|
||||||
description:
|
|
||||||
'Em crianças, os efeitos são mais sérios pois afetam o desenvolvimento dos ossos faciais.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz13Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 13: Gengivas (antiga Quiz 18)
|
|
||||||
class Quiz13Screen extends StatelessWidget {
|
|
||||||
const Quiz13Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 13/20',
|
|
||||||
question: 'O que causa gengivas inflamadas em crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Higiene inadequada e acúmulo de placa',
|
|
||||||
description:
|
|
||||||
'Placa bacteriana não removida properly causa inflamação gengival, a forma mais comum de gengivite.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'É normal na infância, não precisa tratar',
|
|
||||||
description:
|
|
||||||
'Gengivite não é normal e precisa tratamento. Se não tratada, pode evoluir para periodontite.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Apenas mudanças hormonais',
|
|
||||||
description:
|
|
||||||
'Hormônios podem influenciar, mas a causa principal é acúmulo de placa por higiene inadequada.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz14Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 14: Lanche Escolar (antiga Quiz 19)
|
|
||||||
class Quiz14Screen extends StatelessWidget {
|
|
||||||
const Quiz14Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 14/20',
|
|
||||||
question: 'Qual lanche escolar é melhor para os dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Frutas, queijo e água',
|
|
||||||
description:
|
|
||||||
'Lanches naturais e sem açúcar são ideais. Queijo até ajuda neutralizar ácidos e fortalecer dentes.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Bolachas recheadas e suco de caixa',
|
|
||||||
description:
|
|
||||||
'Lanches industrializados e açucarados são os principais vilões da saúde bucal escolar.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Salgadinhos de pacote',
|
|
||||||
description:
|
|
||||||
'Salgadinhos são amiláceos e se transformam em açúcar, além de ficarem presos nos dentes.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz15Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 15: Medo do Dentista (antiga Quiz 20)
|
|
||||||
class Quiz15Screen extends StatelessWidget {
|
|
||||||
const Quiz15Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 15/20',
|
|
||||||
question: 'Como lidar com o medo do dentista em crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Conversar positivamente e visitar regularmente',
|
|
||||||
description:
|
|
||||||
'Linguagem positiva e visitas frequentes sem necessidade de tratamento ajudam a criar confiança.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Evitar falar sobre dentista',
|
|
||||||
description:
|
|
||||||
'Não falar sobre o assunto pode aumentar o medo. É importante preparar a criança positivamente.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Levar só quando houver problema',
|
|
||||||
description:
|
|
||||||
'Visitas só em caso de problema associam dentista a dor. Visitas regulares preventivas são melhores.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz16Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 16: Tempo ideal para escovar (antiga Quiz 1)
|
|
||||||
class Quiz16Screen extends StatelessWidget {
|
|
||||||
const Quiz16Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 16/20',
|
|
||||||
question: 'Qual é o tempo ideal para escovar os dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Cerca de 2 minutos',
|
|
||||||
description:
|
|
||||||
'O recomendado é escovar por aproximadamente 2 minutos, cobrindo todas as superfícies dos dentes e a linha da gengiva sem pressa.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só 30 segundos, se fizer rápido',
|
|
||||||
description:
|
|
||||||
'Muito pouco tempo costuma deixar placa bacteriana para trás, principalmente nos dentes de trás e perto da gengiva.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: '5 minutos com força para "limpar bem"',
|
|
||||||
description:
|
|
||||||
'Tempo demais e força excessiva podem irritar a gengiva e desgastar o esmalte. Prefira movimentos suaves e tempo adequado.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz17Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 17: Troca da escova (antiga Quiz 2)
|
|
||||||
class Quiz17Screen extends StatelessWidget {
|
|
||||||
const Quiz17Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 17/20',
|
|
||||||
question: 'Quando devo trocar a escova de dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'A cada 3 meses (ou antes se estragar)',
|
|
||||||
description:
|
|
||||||
'O ideal é trocar a cada ~3 meses. Se as cerdas abrirem antes, troque antes. Cerdas abertas limpam pior.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só quando a escova "quebrar"',
|
|
||||||
description:
|
|
||||||
'Esperar demais reduz a eficiência da escovação e pode acumular microrganismos na escova.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Todo mês, obrigatoriamente',
|
|
||||||
description:
|
|
||||||
'Não é regra fixa. Um mês pode ser cedo demais se a escova estiver em bom estado. O principal é o estado das cerdas.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz18Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 18: Quantidade de pasta (antiga Quiz 3)
|
|
||||||
class Quiz18Screen extends StatelessWidget {
|
|
||||||
const Quiz18Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 18/20',
|
|
||||||
question: 'Qual a quantidade ideal de pasta de dente para crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Um grão de arroz (pequenos) / ervilha (maiores)',
|
|
||||||
description:
|
|
||||||
'Para crianças pequenas, um "grão de arroz" já basta. Conforme cresce, pode ser do tamanho de uma ervilha. Isso ajuda a evitar excesso de flúor ingerido.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Cobrir toda a escova com pasta',
|
|
||||||
description:
|
|
||||||
'Muito produto não significa melhor limpeza. Em crianças, aumenta o risco de engolir pasta em excesso.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Nenhuma pasta, só água',
|
|
||||||
description:
|
|
||||||
'A pasta com flúor (na quantidade correta) ajuda a prevenir cáries. Em geral, água sozinha não oferece a mesma proteção.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz19Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 19: Fio dental (antiga Quiz 4)
|
|
||||||
class Quiz19Screen extends StatelessWidget {
|
|
||||||
const Quiz19Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 19/20',
|
|
||||||
question: 'Qual é o melhor horário para usar fio dental?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Uma vez ao dia, com calma (geralmente à noite)',
|
|
||||||
description:
|
|
||||||
'O importante é a frequência diária. À noite costuma ser mais fácil, pois remove restos e placa antes de dormir.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só quando algo fica preso',
|
|
||||||
description:
|
|
||||||
'O fio dental não serve apenas para tirar restos visíveis; ele remove placa bacteriana entre os dentes onde a escova não alcança.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Depois de toda refeição (obrigatório)',
|
|
||||||
description:
|
|
||||||
'Pode ser útil em alguns casos, mas não é obrigatório para todos. O essencial é fazer bem feito ao menos 1x ao dia.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz20Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 20: Prevenção de cáries (antiga Quiz 5)
|
|
||||||
class Quiz20Screen extends StatelessWidget {
|
|
||||||
const Quiz20Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 20/20',
|
|
||||||
question: 'O que ajuda mais a prevenir cáries no dia a dia?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escovar + flúor + reduzir açúcar frequente',
|
|
||||||
description:
|
|
||||||
'A prevenção é um conjunto: boa higiene com flúor e menos "beliscos" açucarados ao longo do dia.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só enxaguante bucal',
|
|
||||||
description:
|
|
||||||
'Enxaguante pode ajudar em alguns casos, mas não substitui escovação e fio dental.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Evitar completamente dentista',
|
|
||||||
description:
|
|
||||||
'Consultas regulares são importantes para prevenção e orientação. O dentista também identifica problemas bem no começo.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => QuizResultScreen(finalScore: nextScore, maxScore: 100, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
isFinal: true,
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,620 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'quiz_question_screen.dart';
|
|
||||||
import 'quiz_result.dart';
|
|
||||||
|
|
||||||
// Quiz 6: Tipos de Escova
|
|
||||||
class Quiz6Screen extends StatelessWidget {
|
|
||||||
const Quiz6Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 6/20',
|
|
||||||
question: 'Qual tipo de escova é mais recomendada para crianças?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escova macia com cabeça pequena',
|
|
||||||
description:
|
|
||||||
'Escovas macias protegem a gengiva sensível das crianças e a cabeça pequena alcança melhor todos os dentes.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escova dura para limpar melhor',
|
|
||||||
description:
|
|
||||||
'Escovas duras podem machucar a gengiva e desgastar o esmalte dos dentes das crianças.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Escova elétrica sempre é melhor',
|
|
||||||
description:
|
|
||||||
'Escova elétrica pode ajudar, mas não é essencial. O mais importante é a técnica e frequência.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz7Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 7: Alimentos que Causam Cáries
|
|
||||||
class Quiz7Screen extends StatelessWidget {
|
|
||||||
const Quiz7Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 7/20',
|
|
||||||
question: 'Qual alimento é mais prejudicial para os dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Balas e chicletes pegajosos',
|
|
||||||
description:
|
|
||||||
'Alimentos pegajosos ficam presos nos dentes por mais tempo, aumentando o risco de cáries.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Maçã e cenoura',
|
|
||||||
description:
|
|
||||||
'Frutas e vegetais crus ajudam a limpar os dentes naturalmente e são saudáveis.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Água e leite',
|
|
||||||
description:
|
|
||||||
'Água ajuda a limpar e leite tem cálcio. São opções saudáveis para os dentes.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz8Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 8: Primeira Visita ao Dentista
|
|
||||||
class Quiz8Screen extends StatelessWidget {
|
|
||||||
const Quiz8Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 8/20',
|
|
||||||
question: 'Quando deve ser a primeira visita ao dentista?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Por volta dos 1 ano de idade',
|
|
||||||
description:
|
|
||||||
'A primeira visita deve ser assim que o primeiro dentinho nascer ou até o primeiro aniversário.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só quando tiver todos os dentes',
|
|
||||||
description:
|
|
||||||
'Esperar demais pode permitir que problemas comecem sem detecção precoce.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Apenas se sentir dor',
|
|
||||||
description:
|
|
||||||
'Dor geralmente indica que o problema já está avançado. Prevenção é melhor que tratamento.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz9Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 9: Chupeta e Sucção
|
|
||||||
class Quiz9Screen extends StatelessWidget {
|
|
||||||
const Quiz9Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 9/20',
|
|
||||||
question: 'Até que idade é aceitável usar chupeta?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Até 2-3 anos no máximo',
|
|
||||||
description:
|
|
||||||
'Após 2-3 anos, chupeta pode causar problemas na dentição e no desenvolvimento da fala.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Até 6-7 anos',
|
|
||||||
description:
|
|
||||||
'Essa idade já é muito tarde e pode causar problemas sérios na arcada dentária.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não tem problema usar sempre',
|
|
||||||
description:
|
|
||||||
'Uso prolongado pode causar má oclusão, problemas na fala e alterações faciais.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz10Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 10: Água Fluoretada
|
|
||||||
class Quiz10Screen extends StatelessWidget {
|
|
||||||
const Quiz10Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 10/20',
|
|
||||||
question: 'O flúor na água de abastecimento ajuda?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Sim, reduz cáries em até 60%',
|
|
||||||
description:
|
|
||||||
'Flúor na água é uma das medidas de saúde pública mais eficazes na prevenção de cáries.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não faz diferença nenhuma',
|
|
||||||
description:
|
|
||||||
'Estudos comprovam que flúor na água reduz significativamente a incidência de cáries.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'É perigoso e causa problemas',
|
|
||||||
description:
|
|
||||||
'Nas concentrações corretas, flúor é seguro. O problema é o excesso, não o uso adequado.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz11Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 11: Escovação Noturna
|
|
||||||
class Quiz11Screen extends StatelessWidget {
|
|
||||||
const Quiz11Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 11/20',
|
|
||||||
question: 'Por que a escovação noturna é tão importante?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Menos saliva durante o sono',
|
|
||||||
description:
|
|
||||||
'Durante a noite produzimos menos saliva, que protege os dentes. Escovação remove placa antes desse período vulnerável.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'É igual aos outros horários',
|
|
||||||
description:
|
|
||||||
'A noite é especial porque a produção de saliva diminui, aumentando o risco de cáries.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só por tradição',
|
|
||||||
description:
|
|
||||||
'Tem fundamento científico. A noite é o período mais crítico para formação de cáries.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz12Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 12: Bebidas Ácidas
|
|
||||||
class Quiz12Screen extends StatelessWidget {
|
|
||||||
const Quiz12Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 12/20',
|
|
||||||
question: 'Qual bebida é mais ácida para os dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Refrigerantes e sucos industrializados',
|
|
||||||
description:
|
|
||||||
'Refrigerantes e sucos artificiais têm pH muito baixo, corroem o esmalte e causam erosão dental.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Água e leite',
|
|
||||||
description:
|
|
||||||
'Água tem pH neutro e leite é levemente ácido mas protege os dentes com cálcio.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Chá sem açúcar',
|
|
||||||
description:
|
|
||||||
'Chá pode manchar mas é muito menos ácido que refrigerantes e sucos artificiais.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz13Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 13: Dentes de Leite
|
|
||||||
class Quiz13Screen extends StatelessWidget {
|
|
||||||
const Quiz13Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 13/20',
|
|
||||||
question: 'É importante cuidar dos dentes de leite?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Sim, são fundamentais para o desenvolvimento',
|
|
||||||
description:
|
|
||||||
'Dentes de leite mantêm espaço para os permanentes, auxiliam na fala e mastigação.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não, vão cair de qualquer jeito',
|
|
||||||
description:
|
|
||||||
'Dentes de leite doentes podem afetar os permanentes e causar problemas no desenvolvimento.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só se doerem',
|
|
||||||
description:
|
|
||||||
'Mesmo sem dor, problemas nos dentes de leite podem ter consequências sérias futuras.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz14Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 14: Técnica de Escovação
|
|
||||||
class Quiz14Screen extends StatelessWidget {
|
|
||||||
const Quiz14Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 14/20',
|
|
||||||
question: 'Qual é a técnica correta de escovação?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Movimentos circulares suaves',
|
|
||||||
description:
|
|
||||||
'Movimentos circulares ou vibratórios suaves limpam sem machucar a gengiva e removem a placa eficientemente.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Força de um lado para o outro',
|
|
||||||
description:
|
|
||||||
'Movimentos horizontais fortes podem machucar a gengiva e causar recessão gengival.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só na frente dos dentes',
|
|
||||||
description:
|
|
||||||
'Precisa escovar todas as faces: frente, atrás e superfície de mastigação.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz15Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 15: Enxaguante Bucal
|
|
||||||
class Quiz15Screen extends StatelessWidget {
|
|
||||||
const Quiz15Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 15/20',
|
|
||||||
question: 'Crianças pequenas podem usar enxaguante bucal?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Só com orientação e produtos específicos',
|
|
||||||
description:
|
|
||||||
'Crianças pequenas podem engolir o produto. Existem enxaguantes infantis sem álcool e com flúor adequado.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Sim, qualquer um serve',
|
|
||||||
description:
|
|
||||||
'Enxaguantes para adultos podem ter álcool e concentração de flúor inadequada para crianças.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Nunca, é perigoso',
|
|
||||||
description:
|
|
||||||
'Com produto adequado e supervisão, pode ser usado como complemento à higiene oral.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz16Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 16: Lanche Escolar
|
|
||||||
class Quiz16Screen extends StatelessWidget {
|
|
||||||
const Quiz16Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 16/20',
|
|
||||||
question: 'Qual lanche escolar é melhor para os dentes?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Frutas frescas e queijo',
|
|
||||||
description:
|
|
||||||
'Frutas estimulam salivação e queijo neutraliza ácidos. São opções saudáveis para os dentes.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Bolachas recheadas e sucos de caixinha',
|
|
||||||
description:
|
|
||||||
'Açúcar e amido ficam presos nos dentes, aumentando risco de cáries.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Salgadinhos de pacote',
|
|
||||||
description:
|
|
||||||
'Amidos processados ficam nos dentes e se transformam em açúcar, causando cáries.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz17Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 17: Traumas Dentários
|
|
||||||
class Quiz17Screen extends StatelessWidget {
|
|
||||||
const Quiz17Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 17/20',
|
|
||||||
question: 'O que fazer se um dente de leite cair por trauma?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Procurar dentista imediatamente',
|
|
||||||
description:
|
|
||||||
'Mesmo sendo dente de leite, é importante avaliar se houve dano nos permanentes ou nosso tecidos.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não fazer nada, nasce outro',
|
|
||||||
description:
|
|
||||||
'Trauma pode afetar o dente permanente que está em formação ou causar infecções.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Tentar recolocar no lugar',
|
|
||||||
description:
|
|
||||||
'Não se deve recolocar dente de leite avulsionado, apenas os permanentes.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz18Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 18: Mordedura Cruzada
|
|
||||||
class Quiz18Screen extends StatelessWidget {
|
|
||||||
const Quiz18Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 18/20',
|
|
||||||
question: 'O que pode causar problemas na mordida?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Chupeta e sucção de dedo prolongadas',
|
|
||||||
description:
|
|
||||||
'Hábitos prolongados podem causar mordida cruzada, mordida aberta e outros problemas ortodônticos.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Genética apenas',
|
|
||||||
description:
|
|
||||||
'Embora genética influencie, hábitos como chupeta e sucção são grandes fatores causais.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Não tem prevenção possível',
|
|
||||||
description:
|
|
||||||
'Evitar hábitos prejudiciais e fazer acompanhamento odontológico previne muitos problemas.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz19Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 19: Gengivas Sangrando
|
|
||||||
class Quiz19Screen extends StatelessWidget {
|
|
||||||
const Quiz19Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 19/20',
|
|
||||||
question: 'Gengiva sangrando ao escovar significa?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Inflamação que precisa de tratamento',
|
|
||||||
description:
|
|
||||||
'Sangramento indica gengivite. Não deve parar de escovar, mas sim procurar tratamento e melhorar a higiene.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Normal e não precisa se preocupar',
|
|
||||||
description:
|
|
||||||
'Sangramento não é normal. Indica inflamação que pode evoluir para problemas mais sérios.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Está escovando com força demais',
|
|
||||||
description:
|
|
||||||
'Força excessiva pode machucar, mas geralmente sangramento indica inflamação gengival.',
|
|
||||||
weight: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => Quiz20Screen(currentScore: nextScore, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quiz 20: Selantes
|
|
||||||
class Quiz20Screen extends StatelessWidget {
|
|
||||||
const Quiz20Screen({super.key, required this.currentScore, this.scopeId});
|
|
||||||
|
|
||||||
final int currentScore;
|
|
||||||
final String? scopeId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return QuizQuestionScreen(
|
|
||||||
title: 'Quiz 20/20',
|
|
||||||
question: 'Para que servem os selantes dentários?',
|
|
||||||
answers: const [
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Proteger sulcos dos dentes contra cáries',
|
|
||||||
description:
|
|
||||||
'Selantes são uma resina que preenche sulcos e fissuras dos dentes, protegendo contra cáries.',
|
|
||||||
weight: 2,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Clarear os dentes',
|
|
||||||
description:
|
|
||||||
'Selantes não têm função estética de clareamento, apenas protetiva contra cáries.',
|
|
||||||
weight: 5,
|
|
||||||
),
|
|
||||||
QuizAnswer(
|
|
||||||
title: 'Substituir a escovação',
|
|
||||||
description:
|
|
||||||
'Selantes complementam a higiene, não substituem a escovação e o fio dental.',
|
|
||||||
weight: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
currentScore: currentScore,
|
|
||||||
nextRoute: (context, nextScore) => MaterialPageRoute<void>(
|
|
||||||
builder: (_) => QuizResultScreen(finalScore: nextScore, maxScore: 100, scopeId: scopeId),
|
|
||||||
),
|
|
||||||
isFinal: true,
|
|
||||||
showBackButton: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user