Atulização do quiz | Porcentagem na base de dados | Telas de Contrato com o usuario

This commit is contained in:
Carlos Correia
2026-07-13 22:28:01 +01:00
parent 824fdb8089
commit 4fcf3a475a
23 changed files with 2061 additions and 369 deletions

View File

@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
const Color kPrivacyTeal = Color(0xFF2F9E94);
/// Um dos três itens de consentimento mostrados no ecrã de privacidade.
class PrivacyConsentItem {
const PrivacyConsentItem({required this.id, required this.text});
final String id;
final String text;
}
/// Texto fixo dos consentimentos de privacidade, mostrado no cadastro.
const List<PrivacyConsentItem> kPrivacyConsentItems = [
PrivacyConsentItem(
id: 'health_data',
text:
'Concordo com o processamento dos meus dados pessoais de saúde para '
'ter acesso aos recursos do aplicativo Check-Teeth Kids. Veja mais '
'na Política de Privacidade.',
),
PrivacyConsentItem(
id: 'privacy_policy',
text: 'Concordo com a Política de Privacidade e com os Termos de Uso.',
),
PrivacyConsentItem(
id: 'tracking',
text:
'Autorizo o CK-T-KD a rastrear a minha atividade na app. Podem '
'receber dados como minha faixa etária, status da assinatura, '
'momento de abertura da app e identificadores técnicos, conforme '
'descrito na Política de Privacidade. Isso ajuda a CK-T-KD a '
'aprimorar as suas campanhas publicitárias. *',
),
];
/// Emblema circular + título "Privacidade em primeiro lugar", reutilizado
/// onde este conteúdo for mostrado.
class PrivacyHeader extends StatelessWidget {
const PrivacyHeader({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
width: 76,
height: 76,
decoration: BoxDecoration(
color: kPrivacyTeal.withValues(alpha: 0.12),
shape: BoxShape.circle,
),
child: const Icon(
Icons.privacy_tip_rounded,
color: kPrivacyTeal,
size: 36,
),
),
const SizedBox(height: 16),
const Text(
'Privacidade em primeiro lugar',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w900,
color: Colors.black,
),
),
],
);
}
}

View File

@@ -0,0 +1,108 @@
import 'package:flutter/material.dart';
const Color kTermsPink = Color(0xFFFF55A7);
/// Parágrafos dos Termos e Condições — texto fixo, igual em todo o app
/// (ecrã de bloqueio no cadastro e ecrã informativo em Ajustes).
const List<String> kTermsParagraphs = [
'© 2026, Francisca Salgado Ferreira Pacheco Silva. A aplicação, o método '
'de avaliação, arquitetura e conteúdos são propriedade intelectual '
'exclusiva da autora.',
'A Check Teeth Kids é uma aplicação desenvolvida com o propósito de '
'promover a literacia em saúde oral infantil, através de conteúdos '
'educativos e questionários interativos, com especial enfoque na '
'identificação precoce de sinais associados à má oclusão dentária.',
'Pertence-se uma avaliação orientadora do risco de má oclusão nas '
'crianças, com base nas respostas fornecidas. É gerada uma estimativa '
'percentual de risco, que pretende auxiliar os utilizadores na tomada '
'de decisão quanto à necessidade de procurar uma avaliação clínica '
'especializada.',
'Não tem como objetivo realizar diagnósticos clínicos nem substituir a '
'avaliação por um profissional de saúde oral. Esta ferramenta digital '
'destina-se exclusivamente a uma triagem inicial e informativa, '
'promovendo o encaminhamento atempado para um médico dentista '
'especialista (ortodontista ou odontopediatra).',
'A utilização desta aplicação deve ser encarada como um complemento '
'educativo e de sensibilização, reforçando a importância do '
'acompanhamento regular por profissionais qualificados e contribuindo '
'para a deteção precoce de possíveis alterações no desenvolvimento '
'oral infantil.',
];
/// Emblema circular rosa + título "Termos e Condições", reutilizado nos
/// dois ecrãs que mostram este conteúdo.
class TermsHeader extends StatelessWidget {
const TermsHeader({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
width: 76,
height: 76,
decoration: BoxDecoration(
color: kTermsPink.withValues(alpha: 0.12),
shape: BoxShape.circle,
),
child: const Icon(
Icons.gavel_rounded,
color: kTermsPink,
size: 36,
),
),
const SizedBox(height: 16),
const Text(
'Termos e Condições',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w900,
color: Colors.black,
),
),
],
);
}
}
/// Corpo de texto dos Termos, dentro de um cartão branco.
class TermsBody extends StatelessWidget {
const TermsBody({super.key});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(18),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.9),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 14,
offset: const Offset(0, 6),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (var i = 0; i < kTermsParagraphs.length; i++) ...[
if (i > 0) const SizedBox(height: 14),
Text(
kTermsParagraphs[i],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
height: 1.5,
color: Colors.black.withValues(alpha: 0.78),
),
),
],
],
),
);
}
}