From 8249a921b3350f67d1031a21c89f851ff826e2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kau=C3=A3=20Marques?= Date: Thu, 19 Dec 2024 09:30:20 -0300 Subject: [PATCH 01/47] =?UTF-8?q?vers=C3=A3o=20errada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- healthway_app/ios/Flutter/flutter_export_environment.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/healthway_app/ios/Flutter/flutter_export_environment.sh b/healthway_app/ios/Flutter/flutter_export_environment.sh index 0b645f4..770f09b 100755 --- a/healthway_app/ios/Flutter/flutter_export_environment.sh +++ b/healthway_app/ios/Flutter/flutter_export_environment.sh @@ -1,13 +1,13 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/Users/lemuelcavalcante/Documents/dev/flutter" -export "FLUTTER_APPLICATION_PATH=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app" +export "FLUTTER_ROOT=/home/kaua/flutter" +export "FLUTTER_APPLICATION_PATH=/home/kaua/VSCode/Healthway/healthway_app" export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app/lib/main.dart" +export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=true" export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app/.dart_tool/package_config.json" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" From f0b81532cf839fadf34792605fcf4590d6adf28b Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Thu, 19 Dec 2024 19:47:06 -0300 Subject: [PATCH 02/47] barra de pesquisa na listagem de alimentos --- backend/controllers/alimentoController.js | 2 +- backend/controllers/refeicaoController.js | 2 +- backend/package-lock.json | 14 +- backend/package.json | 2 +- .../ios/Flutter/flutter_export_environment.sh | 9 +- .../lib/geral_screens/alimentos_screen.dart | 149 +++++++++++++++--- 6 files changed, 143 insertions(+), 35 deletions(-) diff --git a/backend/controllers/alimentoController.js b/backend/controllers/alimentoController.js index 6786a33..916b8d7 100644 --- a/backend/controllers/alimentoController.js +++ b/backend/controllers/alimentoController.js @@ -1,5 +1,5 @@ const db = require('../firebase-config'); -const Alimento = require('../model/alimento'); +const Alimento = require('../model/Alimento'); const alimentoController = { //Criar um novo alimento diff --git a/backend/controllers/refeicaoController.js b/backend/controllers/refeicaoController.js index 030cb18..2f7d52e 100644 --- a/backend/controllers/refeicaoController.js +++ b/backend/controllers/refeicaoController.js @@ -1,5 +1,5 @@ const db = require('../firebase-config'); -const Refeicao = require('../model/refeicao'); +const Refeicao = require('../model/Refeicao'); const refeicaoController = { //Criar uma nova refeição diff --git a/backend/package-lock.json b/backend/package-lock.json index c02c3ed..4235122 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "backend": "file:", "dotenv": "^16.4.5", - "express": "^4.21.1", + "express": "^4.21.2", "firebase-admin": "^13.0.0" } }, @@ -550,8 +550,15 @@ "optional": true }, "node_modules/backend": { - "resolved": "", - "link": true + "version": "1.0.0", + "resolved": "file:", + "license": "ISC", + "dependencies": { + "backend": "file:", + "dotenv": "^16.4.5", + "express": "^4.21.1", + "firebase-admin": "^13.0.0" + } }, "node_modules/base64-js": { "version": "1.5.1", @@ -873,7 +880,6 @@ "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", diff --git a/backend/package.json b/backend/package.json index 1ac5d7e..67ae27d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -13,7 +13,7 @@ "dependencies": { "backend": "file:", "dotenv": "^16.4.5", - "express": "^4.21.1", + "express": "^4.21.2", "firebase-admin": "^13.0.0" } } diff --git a/healthway_app/ios/Flutter/flutter_export_environment.sh b/healthway_app/ios/Flutter/flutter_export_environment.sh index 0778cb7..491b720 100755 --- a/healthway_app/ios/Flutter/flutter_export_environment.sh +++ b/healthway_app/ios/Flutter/flutter_export_environment.sh @@ -1,12 +1,7 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -<<<<<<< HEAD -export "FLUTTER_ROOT=/home/kaua/flutter" -export "FLUTTER_APPLICATION_PATH=/home/kaua/VSCode/Healthway/healthway_app" -======= -export "FLUTTER_ROOT=/Users/lemuelcavalcante/Documents/development/flutter" -export "FLUTTER_APPLICATION_PATH=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app" ->>>>>>> origin/lemu +export "FLUTTER_ROOT=/opt/flutter" +export "FLUTTER_APPLICATION_PATH=/home/kaua/IdeaProjects/Healthway/healthway_app" export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" diff --git a/healthway_app/lib/geral_screens/alimentos_screen.dart b/healthway_app/lib/geral_screens/alimentos_screen.dart index 1fab533..49b46e6 100644 --- a/healthway_app/lib/geral_screens/alimentos_screen.dart +++ b/healthway_app/lib/geral_screens/alimentos_screen.dart @@ -1,5 +1,3 @@ -// lib/screens/alimentos_screen.dart - import 'package:flutter/material.dart'; import '../services/alimento_services.dart'; import '../models/alimentos.dart'; @@ -12,39 +10,148 @@ class AlimentosScreen extends StatefulWidget { class _AlimentosScreenState extends State { late Future> futureAlimentos; + List alimentos = []; + List alimentosFiltrados = []; + TextEditingController searchController = TextEditingController(); @override void initState() { super.initState(); - futureAlimentos = AlimentoService().fetchAlimentos(); + _carregarAlimentos(); + } + + void _carregarAlimentos() { + setState(() { + futureAlimentos = AlimentoService().fetchAlimentos(); + }); + } + + void _filtrarAlimentos(String query) { + setState(() { + alimentosFiltrados = alimentos + .where((alimento) => + alimento.nome.toLowerCase().contains(query.toLowerCase())) + .toList(); + }); } @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Color(0xFFF5F5F5), appBar: AppBar( title: Text('Alimentos'), + backgroundColor: Color(0xFF31BAC2), + elevation: 0, ), - body: FutureBuilder>( - future: futureAlimentos, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return Center(child: CircularProgressIndicator()); - } else if (snapshot.hasError) { - return Center(child: Text('Erro: ${snapshot.error}')); - } else if (!snapshot.hasData || snapshot.data!.isEmpty) { - return Center(child: Text('Nenhum alimento encontrado')); - } else { - final alimentos = snapshot.data!; - return ListView.builder( - itemCount: alimentos.length, - itemBuilder: (context, index) { - return AlimentoItem(alimento: alimentos[index]); + body: Column( + children: [ + _buildSearchBar(), + Expanded( + child: FutureBuilder>( + future: futureAlimentos, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))); + } else if (snapshot.hasError) { + return _buildErrorWidget(snapshot.error.toString()); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return _buildEmptyWidget(); + } else { + alimentos = snapshot.data!; + if (alimentosFiltrados.isEmpty) { + alimentosFiltrados = alimentos; + } + return _buildAlimentosList(); + } }, - ); - } - }, + ), + ), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: _carregarAlimentos, + child: Icon(Icons.refresh), + backgroundColor: Color(0xFF31BAC2), + ), + ); + } + + Widget _buildSearchBar() { + return Container( + padding: EdgeInsets.all(16), + color: Color(0xFF31BAC2), + child: TextField( + controller: searchController, + onChanged: _filtrarAlimentos, + decoration: InputDecoration( + hintText: 'Pesquisar alimentos...', + prefixIcon: Icon(Icons.search, color: Color(0xFF31BAC2)), + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30), + borderSide: BorderSide.none, + ), + ), + ), + ); + } + + Widget _buildAlimentosList() { + return ListView.builder( + itemCount: alimentosFiltrados.length, + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + child: AlimentoItem(alimento: alimentosFiltrados[index]), + ), + ); + }, + ); + } + + Widget _buildErrorWidget(String error) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.error_outline, size: 60, color: Colors.red), + SizedBox(height: 16), + Text( + 'Erro ao carregar alimentos', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text( + error, + style: TextStyle(color: Colors.grey[600]), + textAlign: TextAlign.center, + ), + ], + ), + ); + } + + Widget _buildEmptyWidget() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.no_food, size: 60, color: Color(0xFF31BAC2)), + SizedBox(height: 16), + Text( + 'Nenhum alimento encontrado', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ], ), ); } } + From 0b58afa5af220f27dd2aba942393b079062ef7c6 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Thu, 19 Dec 2024 20:41:50 -0300 Subject: [PATCH 03/47] pesquisando nutricionistas --- .../geral_screens/nutricionistas_screen.dart | 152 +++++++++++++++--- 1 file changed, 132 insertions(+), 20 deletions(-) diff --git a/healthway_app/lib/geral_screens/nutricionistas_screen.dart b/healthway_app/lib/geral_screens/nutricionistas_screen.dart index dd13f93..fc593e8 100644 --- a/healthway_app/lib/geral_screens/nutricionistas_screen.dart +++ b/healthway_app/lib/geral_screens/nutricionistas_screen.dart @@ -10,37 +10,149 @@ class NutricionistasScreen extends StatefulWidget { class _NutricionistasScreenState extends State { late Future> _nutricionistas; + List nutricionistas = []; + List nutricionistasFiltrados = []; + TextEditingController searchController = TextEditingController(); @override void initState() { super.initState(); - _nutricionistas = NutricionistaService().fetchNutricionistas(); + _carregarNutricionistas(); + } + + void _carregarNutricionistas() { + setState(() { + _nutricionistas = NutricionistaService().fetchNutricionistas(); + }); + } + + void _filtrarNutricionistas(String query) { + setState(() { + nutricionistasFiltrados = nutricionistas + .where((nutricionista) => + nutricionista.nome.toLowerCase().contains(query.toLowerCase()) || + nutricionista.especialidade.toLowerCase().contains(query.toLowerCase())) + .toList(); + }); } @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text('Nutricionistas')), - body: FutureBuilder>( - future: _nutricionistas, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } else if (snapshot.hasError) { - return Center(child: Text('Erro: ${snapshot.error}')); - } else if (!snapshot.hasData || snapshot.data!.isEmpty) { - return const Center(child: Text('Nenhum nutricionista encontrado.')); - } else { - var nutricionistas = snapshot.data!; - return ListView.builder( - itemCount: nutricionistas.length, - itemBuilder: (context, index) { - return NutricionistaItem(nutricionista: nutricionistas[index]); + backgroundColor: Color(0xFFF5F5F5), + appBar: AppBar( + title: Text('Nutricionistas'), + backgroundColor: Color(0xFF31BAC2), + elevation: 0, + ), + body: Column( + children: [ + _buildSearchBar(), + Expanded( + child: FutureBuilder>( + future: _nutricionistas, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))); + } else if (snapshot.hasError) { + return _buildErrorWidget(snapshot.error.toString()); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return _buildEmptyWidget(); + } else { + nutricionistas = snapshot.data!; + if (nutricionistasFiltrados.isEmpty) { + nutricionistasFiltrados = nutricionistas; + } + return _buildNutricionistasList(); + } }, - ); - } - }, + ), + ), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: _carregarNutricionistas, + child: Icon(Icons.refresh), + backgroundColor: Color(0xFF31BAC2), + ), + ); + } + + Widget _buildSearchBar() { + return Container( + padding: EdgeInsets.all(16), + color: Color(0xFF31BAC2), + child: TextField( + controller: searchController, + onChanged: _filtrarNutricionistas, + decoration: InputDecoration( + hintText: 'Pesquisar por nome ou especialidade...', + prefixIcon: Icon(Icons.search, color: Color(0xFF31BAC2)), + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30), + borderSide: BorderSide.none, + ), + ), + ), + ); + } + + Widget _buildNutricionistasList() { + return ListView.builder( + itemCount: nutricionistasFiltrados.length, + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + child: NutricionistaItem(nutricionista: nutricionistasFiltrados[index]), + ), + ); + }, + ); + } + + Widget _buildErrorWidget(String error) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.error_outline, size: 60, color: Colors.red), + SizedBox(height: 16), + Text( + 'Erro ao carregar nutricionistas', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text( + error, + style: TextStyle(color: Colors.grey[600]), + textAlign: TextAlign.center, + ), + ], + ), + ); + } + + Widget _buildEmptyWidget() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.person_off, size: 60, color: Color(0xFF31BAC2)), + SizedBox(height: 16), + Text( + 'Nenhum nutricionista encontrado', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ], ), ); } } + From 1f15818b072210ff32340193263e6265366c9333 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 23 Dec 2024 15:10:28 -0300 Subject: [PATCH 04/47] f --- healthway_app/ios/Flutter/flutter_export_environment.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/healthway_app/ios/Flutter/flutter_export_environment.sh b/healthway_app/ios/Flutter/flutter_export_environment.sh index 9f63276..91c916d 100755 --- a/healthway_app/ios/Flutter/flutter_export_environment.sh +++ b/healthway_app/ios/Flutter/flutter_export_environment.sh @@ -1,13 +1,13 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/Users/lemuelcavalcante/Documents/development/flutter" -export "FLUTTER_APPLICATION_PATH=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app" +export "FLUTTER_ROOT=/opt/flutter" +export "FLUTTER_APPLICATION_PATH=/home/kaua/AndroidStudioProjects/Healthway/healthway_app" export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app/lib/main.dart" +export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=true" export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app/.dart_tool/package_config.json" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" From 796fea53bedd2f2d2f66ac1a665065aca603e1fb Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 23 Dec 2024 16:08:27 -0300 Subject: [PATCH 05/47] melhorando as telas de login e cadastro --- .../geral_screens/apresentationScreen.dart | 4 +- .../lib/geral_screens/loginScreen.dart | 278 ++++++----- healthway_app/lib/main.dart | 2 +- .../lib/screens_patient/signupScreen.dart | 445 +++++++++++------- 4 files changed, 446 insertions(+), 283 deletions(-) diff --git a/healthway_app/lib/geral_screens/apresentationScreen.dart b/healthway_app/lib/geral_screens/apresentationScreen.dart index a3684b7..cf84014 100644 --- a/healthway_app/lib/geral_screens/apresentationScreen.dart +++ b/healthway_app/lib/geral_screens/apresentationScreen.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:healthway_app/geral_screens/loginScreen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; import 'dart:async'; import 'package:healthway_app/screens_patient//dashboardScreen.dart'; +import 'package:healthway_app/screens_patient/signupScreen.dart'; class PresentationScreen extends StatefulWidget { const PresentationScreen({super.key}); @@ -36,7 +38,7 @@ class _PresentationScreenState extends State // Navegar para a próxima tela após a animação Timer(Duration(seconds: 3), () { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => PatientDashboardScreen()), + MaterialPageRoute(builder: (_) => LoginScreen()), ); }); } diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index ea37628..5bd71f8 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -4,145 +4,183 @@ class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override - State createState() => _LoginScreenState(); + _LoginScreenState createState() => _LoginScreenState(); } class _LoginScreenState extends State { final _formKey = GlobalKey(); final _emailController = TextEditingController(); - final _passwordController = TextEditingController(); + final _senhaController = TextEditingController(); bool _obscurePassword = true; - @override - void dispose() { - _emailController.dispose(); - _passwordController.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Color(0xFFE6F7F8), // Tom muito claro de azul appBar: AppBar( - title: const Text('Login'), - backgroundColor: const Color(0xFF31BAC2), + title: Text('Login', style: TextStyle(fontWeight: FontWeight.bold)), + backgroundColor: Color(0xFF31BAC2), elevation: 0, ), - body: SafeArea( - child: SingleChildScrollView( - padding: const EdgeInsets.all(16.0), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: 48), - Icon( - Icons.account_circle, - size: 100, - color: Color(0xFF31BAC2), + body: SingleChildScrollView( + child: Column( + children: [ + Container( + height: 200, + decoration: BoxDecoration( + color: Color(0xFF31BAC2), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(30), + bottomRight: Radius.circular(30), ), - const SizedBox(height: 48), - TextFormField( - controller: _emailController, - decoration: InputDecoration( - labelText: 'Email', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - prefixIcon: Icon(Icons.email, color: Color(0xFF31BAC2)), - ), - keyboardType: TextInputType.emailAddress, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Por favor, insira seu email'; - } - if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$') - .hasMatch(value)) { - return 'Por favor, insira um email válido'; - } - return null; - }, - ), - const SizedBox(height: 16), - TextFormField( - controller: _passwordController, - decoration: InputDecoration( - labelText: 'Senha', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), - suffixIcon: IconButton( - icon: Icon( - _obscurePassword - ? Icons.visibility - : Icons.visibility_off, - color: Color(0xFF31BAC2), - ), - onPressed: () { - setState(() { - _obscurePassword = !_obscurePassword; - }); - }, - ), - ), - obscureText: _obscurePassword, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Por favor, insira sua senha'; - } - return null; - }, - ), - const SizedBox(height: 24), - ElevatedButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - // Implementar lógica de login aqui - print('Email: ${_emailController.text}'); - print('Senha: ${_passwordController.text}'); - // Navegar para a tela principal após o login bem-sucedido - Navigator.pushReplacementNamed(context, '/dashboard'); - } - }, - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF31BAC2), - padding: const EdgeInsets.symmetric(vertical: 16), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - child: const Text( - 'Entrar', - style: TextStyle(fontSize: 18), - ), - ), - const SizedBox(height: 16), - TextButton( - onPressed: () { - Navigator.pushNamed(context, '/signUp'); - }, - child: const Text( - 'Não tem uma conta? Cadastre-se', - style: TextStyle(color: Color(0xFF31BAC2)), - ), - ), - const SizedBox(height: 16), - TextButton( - onPressed: () { - // Implementar lógica de recuperação de senha - }, - child: const Text( - 'Esqueceu sua senha?', - style: TextStyle(color: Color(0xFF31BAC2)), - ), + ), + child: Center( + child: Icon(Icons.lock_open, size: 100, color: Colors.white), + ), + ), + Padding( + padding: EdgeInsets.all(20.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildTextField(_emailController, 'E-mail', Icons.email, keyboardType: TextInputType.emailAddress), + SizedBox(height: 20), + _buildPasswordField(), + SizedBox(height: 20), + _buildForgotPasswordButton(), + SizedBox(height: 30), + _buildLoginButton(), + SizedBox(height: 20), + _buildRegisterButton(), + ], ), - ], + ), ), + ], + ), + ), + ); + } + + Widget _buildTextField(TextEditingController controller, String label, IconData icon, {TextInputType? keyboardType}) { + return TextFormField( + controller: controller, + decoration: InputDecoration( + labelText: label, + prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16), + keyboardType: keyboardType, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, preencha este campo'; + } + return null; + }, + ); + } + + Widget _buildPasswordField() { + return TextFormField( + controller: _senhaController, + obscureText: _obscurePassword, + decoration: InputDecoration( + labelText: 'Senha', + prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), + suffixIcon: IconButton( + icon: Icon( + _obscurePassword ? Icons.visibility : Icons.visibility_off, + color: Color(0xFF31BAC2), ), + onPressed: () { + setState(() { + _obscurePassword = !_obscurePassword; + }); + }, ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, ), + style: TextStyle(fontSize: 16), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, insira sua senha'; + } + return null; + }, ); } + + Widget _buildForgotPasswordButton() { + return Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: () { + // TODO: Implementar lógica para recuperação de senha + }, + child: Text( + 'Esqueceu a senha?', + style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + ), + ), + ); + } + + Widget _buildLoginButton() { + return ElevatedButton( + child: Text('Entrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + onPressed: _submitForm, + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), + padding: EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + ); + } + + Widget _buildRegisterButton() { + return TextButton( + onPressed: () { + // TODO: Navegar para a tela de cadastro + }, + child: Text( + 'Não tem uma conta? Cadastre-se', + style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + ), + ); + } + + void _submitForm() { + if (_formKey.currentState!.validate()) { + // TODO: Implementar lógica de autenticação + print('Form is valid. Submitting...'); + // Você normalmente chamaria um método de serviço aqui para autenticar o usuário + } + } + + @override + void dispose() { + _emailController.dispose(); + _senhaController.dispose(); + super.dispose(); + } } + diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index e250f58..1e2662c 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -38,7 +38,7 @@ class MyApp extends StatelessWidget { routes: { '/': (context) => PresentationScreen(), '/home': (context) => PatientDashboardScreen(), - '/signUp': (context) => SignUpScreen(), + '/signUpPatient': (context) => CadastroPacienteScreen(), '/login': (context) => LoginScreen(), '/chat': (context) => ChatScreen(), '/health': (context) => DietManagementScreen(), diff --git a/healthway_app/lib/screens_patient/signupScreen.dart b/healthway_app/lib/screens_patient/signupScreen.dart index c6c4fe4..d6c2c6f 100644 --- a/healthway_app/lib/screens_patient/signupScreen.dart +++ b/healthway_app/lib/screens_patient/signupScreen.dart @@ -1,189 +1,312 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; -class SignUpScreen extends StatefulWidget { - const SignUpScreen({super.key}); - +class CadastroPacienteScreen extends StatefulWidget { @override - State createState() => _SignUpScreenState(); + _CadastroPacienteScreenState createState() => _CadastroPacienteScreenState(); } -class _SignUpScreenState extends State { +class _CadastroPacienteScreenState extends State { final _formKey = GlobalKey(); - final _nameController = TextEditingController(); + final _nomeController = TextEditingController(); final _emailController = TextEditingController(); - final _passwordController = TextEditingController(); - DateTime? _selectedDate; + final _cpfController = TextEditingController(); + final _dataNascimentoController = TextEditingController(); + final _alturaController = TextEditingController(); + final _pesoController = TextEditingController(); + final _circunferenciaAbdominalController = TextEditingController(); + final _gorduraCorporalController = TextEditingController(); + final _massaMuscularController = TextEditingController(); + final _alergiasController = TextEditingController(); + final _preferenciasController = TextEditingController(); + final _senhaController = TextEditingController(); + final _confirmarSenhaController = TextEditingController(); - @override - void dispose() { - _nameController.dispose(); - _emailController.dispose(); - _passwordController.dispose(); - super.dispose(); - } - - void _selectDate(BuildContext context) async { - final DateTime? picked = await showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(1900), - lastDate: DateTime.now(), - builder: (context, child) { - return Theme( - data: Theme.of(context).copyWith( - colorScheme: ColorScheme.light( - primary: Color(0xFF31BAC2), - onPrimary: Colors.white, - onSurface: Colors.black, - ), - ), - child: child!, - ); - }, - ); - if (picked != null && picked != _selectedDate) { - setState(() { - _selectedDate = picked; - }); - } - } + String? _sexo; + DateTime? _dataNascimento; @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Color(0xFFE6F7F8), // Tom muito claro de azul appBar: AppBar( - title: const Text('Cadastro'), - backgroundColor: const Color(0xFF31BAC2), + title: Text('Cadastro de Paciente', style: TextStyle(fontWeight: FontWeight.bold)), + backgroundColor: Color(0xFF31BAC2), elevation: 0, ), - body: SafeArea( - child: SingleChildScrollView( - padding: const EdgeInsets.all(16.0), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: 24), - TextFormField( - controller: _nameController, - decoration: InputDecoration( - labelText: 'Nome', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - prefixIcon: Icon(Icons.person, color: Color(0xFF31BAC2)), - ), - validator: (value) { - if (value == null || value.isEmpty) { - return 'Por favor, insira seu nome'; - } - return null; - }, - ), - const SizedBox(height: 16), - TextFormField( - controller: _emailController, - decoration: InputDecoration( - labelText: 'Email', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - prefixIcon: Icon(Icons.email, color: Color(0xFF31BAC2)), - ), - keyboardType: TextInputType.emailAddress, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Por favor, insira seu email'; - } - if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$') - .hasMatch(value)) { - return 'Por favor, insira um email válido'; - } - return null; - }, - ), - const SizedBox(height: 16), - TextFormField( - controller: _passwordController, - decoration: InputDecoration( - labelText: 'Senha', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), - ), - obscureText: true, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Por favor, insira uma senha'; - } - if (value.length < 6) { - return 'A senha deve ter pelo menos 6 caracteres'; - } - return null; - }, + body: SingleChildScrollView( + child: Column( + children: [ + Container( + height: 150, + decoration: BoxDecoration( + color: Color(0xFF31BAC2), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(30), + bottomRight: Radius.circular(30), ), - const SizedBox(height: 16), - InkWell( - onTap: () => _selectDate(context), - child: InputDecorator( - decoration: InputDecoration( - labelText: 'Data de Nascimento', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), + ), + child: Center( + child: Icon(Icons.person_add, size: 80, color: Colors.white), + ), + ), + Padding( + padding: EdgeInsets.all(20.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildTextField(_nomeController, 'Nome completo', Icons.person), + _buildTextField(_emailController, 'E-mail', Icons.email, keyboardType: TextInputType.emailAddress), + _buildTextField(_cpfController, 'CPF', Icons.badge, inputFormatters: [FilteringTextInputFormatter.digitsOnly]), + _buildDateField(), + _buildDropdownField(), + _buildMeasurementFields(), + _buildTextField(_alergiasController, 'Alergias', Icons.warning), + _buildTextField(_preferenciasController, 'Preferências Alimentares', Icons.restaurant), + _buildPasswordFields(), + SizedBox(height: 20), + ElevatedButton( + onPressed: _submitForm, + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), + padding: EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), ), - prefixIcon: - Icon(Icons.calendar_today, color: Color(0xFF31BAC2)), + child: Text('Cadastrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ), - child: Text( - _selectedDate == null - ? 'Selecione sua data de nascimento' - : DateFormat('dd/MM/yyyy').format(_selectedDate!), - ), - ), - ), - const SizedBox(height: 24), - ElevatedButton( - onPressed: () { - if (_formKey.currentState!.validate() && - _selectedDate != null) { - // Implementar lógica de cadastro aqui - print('Nome: ${_nameController.text}'); - print('Email: ${_emailController.text}'); - print('Senha: ${_passwordController.text}'); - print( - 'Data de Nascimento: ${DateFormat('dd/MM/yyyy').format(_selectedDate!)}'); - } - }, - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF31BAC2), - padding: const EdgeInsets.symmetric(vertical: 16), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - child: const Text( - 'Cadastrar', - style: TextStyle(fontSize: 18), - ), + ], ), - const SizedBox(height: 16), - TextButton( - onPressed: () { - Navigator.pushNamed(context, '/login'); - }, - child: const Text( - 'Já tem uma conta? Faça login', - style: TextStyle(color: Color(0xFF31BAC2)), - ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildTextField(TextEditingController controller, String label, IconData icon, {bool obscureText = false, TextInputType? keyboardType, List? inputFormatters}) { + return Padding( + padding: EdgeInsets.only(bottom: 20.0), + child: TextFormField( + controller: controller, + decoration: InputDecoration( + labelText: label, + prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16), + obscureText: obscureText, + keyboardType: keyboardType, + inputFormatters: inputFormatters, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, preencha este campo'; + } + return null; + }, + ), + ); + } + + Widget _buildDateField() { + return Padding( + padding: EdgeInsets.only(bottom: 20.0), + child: TextFormField( + controller: _dataNascimentoController, + decoration: InputDecoration( + labelText: 'Data de Nascimento', + prefixIcon: Icon(Icons.calendar_today, color: Color(0xFF31BAC2)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16), + readOnly: true, + onTap: () async { + final pickedDate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(1900), + lastDate: DateTime.now(), + builder: (context, child) { + return Theme( + data: ThemeData.light().copyWith( + primaryColor: Color(0xFF31BAC2), + hintColor: Color(0xFF31BAC2), + colorScheme: ColorScheme.light(primary: Color(0xFF31BAC2)), + buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary), ), + child: child!, + ); + }, + ); + if (pickedDate != null) { + setState(() { + _dataNascimento = pickedDate; + _dataNascimentoController.text = DateFormat('dd/MM/yyyy').format(pickedDate); + }); + } + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, selecione a data de nascimento'; + } + return null; + }, + ), + ); + } + + Widget _buildDropdownField() { + return Padding( + padding: EdgeInsets.only(bottom: 20.0), + child: DropdownButtonFormField( + value: _sexo, + decoration: InputDecoration( + labelText: 'Sexo', + prefixIcon: Icon(Icons.wc, color: Color(0xFF31BAC2)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16, color: Colors.black), + items: ['Masculino', 'Feminino', 'Outro'] + .map((label) => DropdownMenuItem( + child: Text(label), + value: label, + )) + .toList(), + onChanged: (value) { + setState(() { + _sexo = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, selecione o sexo'; + } + return null; + }, + ), + ); + } + + Widget _buildMeasurementFields() { + return Card( + elevation: 4, + color: Color(0xFFF0FAFB), // Tom muito claro de azul + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Medidas Corporais', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + ), + SizedBox(height: 16), + Row( + children: [ + Expanded(child: _buildMeasurementField(_alturaController, 'Altura (cm)', Icons.height)), + SizedBox(width: 16), + Expanded(child: _buildMeasurementField(_pesoController, 'Peso (kg)', Icons.fitness_center)), ], ), - ), + SizedBox(height: 16), + _buildMeasurementField(_circunferenciaAbdominalController, 'Circunferência Abdominal (cm)', Icons.straighten), + SizedBox(height: 16), + Row( + children: [ + Expanded(child: _buildMeasurementField(_gorduraCorporalController, 'Gordura Corporal (%)', Icons.percent)), + SizedBox(width: 16), + Expanded(child: _buildMeasurementField(_massaMuscularController, 'Massa Muscular (kg)', Icons.fitness_center)), + ], + ), + ], ), ), ); } + + Widget _buildMeasurementField(TextEditingController controller, String label, IconData icon) { + return TextFormField( + controller: controller, + decoration: InputDecoration( + labelText: label, + prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide(color: Color(0xFF31BAC2)), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide(color: Color(0xFF31BAC2), width: 2), + ), + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + ), + keyboardType: TextInputType.number, + style: TextStyle(fontSize: 16), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Preencha este campo'; + } + return null; + }, + ); + } + + Widget _buildPasswordFields() { + return Card( + elevation: 4, + color: Color(0xFFF0FAFB), // Tom muito claro de azul + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Segurança', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + ), + SizedBox(height: 16), + _buildTextField(_senhaController, 'Senha', Icons.lock, obscureText: true), + _buildTextField(_confirmarSenhaController, 'Confirmar Senha', Icons.lock, obscureText: true), + ], + ), + ), + ); + } + + void _submitForm() { + if (_formKey.currentState!.validate()) { + // TODO: Implement form submission logic + print('Form is valid. Submitting...'); + // You would typically call a service method here to save the patient data + } + } } + From 1808092531c06ac9a224a5f4e9428e4e91bea34a Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Tue, 24 Dec 2024 10:40:19 -0300 Subject: [PATCH 06/47] aprimorando telas de login e cadastro --- .../plugins/GeneratedPluginRegistrant.java | 10 + .../ios/Runner/GeneratedPluginRegistrant.m | 7 + .../geral_screens/apresentationScreen.dart | 3 +- healthway_app/lib/main.dart | 2 + healthway_app/lib/models/paciente.dart | 105 ++++++ .../signUpNutritionist.dart | 301 ++++++++++++++++++ .../lib/screens_patient/signupScreen.dart | 137 +++++++- .../lib/services/nutricionista_services.dart | 34 +- .../lib/services/paciente_services.dart | 67 ++++ .../flutter/generated_plugin_registrant.cc | 4 + .../linux/flutter/generated_plugins.cmake | 1 + .../Flutter/GeneratedPluginRegistrant.swift | 2 + healthway_app/pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + .../windows/flutter/generated_plugins.cmake | 1 + 15 files changed, 660 insertions(+), 18 deletions(-) create mode 100644 healthway_app/lib/models/paciente.dart create mode 100644 healthway_app/lib/screens_nutricionist/signUpNutritionist.dart create mode 100644 healthway_app/lib/services/paciente_services.dart diff --git a/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 539ab02..ec061d9 100644 --- a/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -15,5 +15,15 @@ public final class GeneratedPluginRegistrant { private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin flutter_plugin_android_lifecycle, io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin", e); + } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.imagepicker.ImagePickerPlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin image_picker_android, io.flutter.plugins.imagepicker.ImagePickerPlugin", e); + } } } diff --git a/healthway_app/ios/Runner/GeneratedPluginRegistrant.m b/healthway_app/ios/Runner/GeneratedPluginRegistrant.m index efe65ec..ed39389 100644 --- a/healthway_app/ios/Runner/GeneratedPluginRegistrant.m +++ b/healthway_app/ios/Runner/GeneratedPluginRegistrant.m @@ -6,9 +6,16 @@ #import "GeneratedPluginRegistrant.h" +#if __has_include() +#import +#else +@import image_picker_ios; +#endif + @implementation GeneratedPluginRegistrant + (void)registerWithRegistry:(NSObject*)registry { + [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]]; } @end diff --git a/healthway_app/lib/geral_screens/apresentationScreen.dart b/healthway_app/lib/geral_screens/apresentationScreen.dart index cf84014..87864a1 100644 --- a/healthway_app/lib/geral_screens/apresentationScreen.dart +++ b/healthway_app/lib/geral_screens/apresentationScreen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/loginScreen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; +import 'package:healthway_app/screens_nutricionist/signUpNutritionist.dart'; import 'dart:async'; import 'package:healthway_app/screens_patient//dashboardScreen.dart'; @@ -38,7 +39,7 @@ class _PresentationScreenState extends State // Navegar para a próxima tela após a animação Timer(Duration(seconds: 3), () { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => LoginScreen()), + MaterialPageRoute(builder: (_) => CadastroPacienteScreen()), ); }); } diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 1e2662c..63649ed 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens//apresentationScreen.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; +import 'package:healthway_app/screens_nutricionist/signUpNutritionist.dart'; import 'package:healthway_app/screens_patient/dashboardScreen.dart'; import 'package:healthway_app/screens_patient/dietScreen.dart'; import 'package:healthway_app/screens_patient/healthScreen.dart'; @@ -49,6 +50,7 @@ class MyApp extends StatelessWidget { '/profile': (context) => PatientProfileScreen(), '/notifications': (context) => NotificationScreen(), '/settings': (context) => SettingsScreen(), + '/signUpNutricionista': (context) => CadastroNutricionistaScreen(), }, ); } diff --git a/healthway_app/lib/models/paciente.dart b/healthway_app/lib/models/paciente.dart new file mode 100644 index 0000000..d2192bb --- /dev/null +++ b/healthway_app/lib/models/paciente.dart @@ -0,0 +1,105 @@ +class Paciente { + final String? id; + final String nome; + final String email; + final String cpf; + final String dataNascimento; + final String sexo; + final double altura; + final double peso; + final double circunferenciaAbdominal; + final double gorduraCorporal; + final double massaMuscular; + final String alergias; + final String preferencias; + + Paciente({ + this.id, + required this.nome, + required this.email, + required this.cpf, + required this.dataNascimento, + required this.sexo, + required this.altura, + required this.peso, + required this.circunferenciaAbdominal, + required this.gorduraCorporal, + required this.massaMuscular, + required this.alergias, + required this.preferencias, + }); + + factory Paciente.fromJson(Map json) { + return Paciente( + id: json['id'], + nome: json['nome'], + email: json['email'], + cpf: json['cpf'], + dataNascimento: json['dataNascimento'], + sexo: json['sexo'], + altura: json['altura'].toDouble(), + peso: json['peso'].toDouble(), + circunferenciaAbdominal: json['circunferenciaAbdominal'].toDouble(), + gorduraCorporal: json['gorduraCorporal'].toDouble(), + massaMuscular: json['massaMuscular'].toDouble(), + alergias: json['alergias'], + preferencias: json['preferencias'], + ); + } + + Map toJson() { + return { + 'id': id, + 'nome': nome, + 'email': email, + 'cpf': cpf, + 'dataNascimento': dataNascimento, + 'sexo': sexo, + 'altura': altura, + 'peso': peso, + 'circunferenciaAbdominal': circunferenciaAbdominal, + 'gorduraCorporal': gorduraCorporal, + 'massaMuscular': massaMuscular, + 'alergias': alergias, + 'preferencias': preferencias, + }; + } + + Paciente copyWith({ + String? id, + String? nome, + String? email, + String? cpf, + String? dataNascimento, + String? sexo, + double? altura, + double? peso, + double? circunferenciaAbdominal, + double? gorduraCorporal, + double? massaMuscular, + String? alergias, + String? preferencias, + }) { + return Paciente( + id: id ?? this.id, + nome: nome ?? this.nome, + email: email ?? this.email, + cpf: cpf ?? this.cpf, + dataNascimento: dataNascimento ?? this.dataNascimento, + sexo: sexo ?? this.sexo, + altura: altura ?? this.altura, + peso: peso ?? this.peso, + circunferenciaAbdominal: circunferenciaAbdominal ?? this.circunferenciaAbdominal, + gorduraCorporal: gorduraCorporal ?? this.gorduraCorporal, + massaMuscular: massaMuscular ?? this.massaMuscular, + alergias: alergias ?? this.alergias, + preferencias: preferencias ?? this.preferencias, + ); + } + + @override + String toString() { + return 'Paciente(id: $id, nome: $nome, email: $email, cpf: $cpf, dataNascimento: $dataNascimento, sexo: $sexo, altura: $altura, peso: $peso, circunferenciaAbdominal: $circunferenciaAbdominal, gorduraCorporal: $gorduraCorporal, massaMuscular: $massaMuscular, alergias: $alergias, preferencias: $preferencias)'; + } +} + diff --git a/healthway_app/lib/screens_nutricionist/signUpNutritionist.dart b/healthway_app/lib/screens_nutricionist/signUpNutritionist.dart new file mode 100644 index 0000000..f6dceb1 --- /dev/null +++ b/healthway_app/lib/screens_nutricionist/signUpNutritionist.dart @@ -0,0 +1,301 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:image_picker/image_picker.dart'; +import 'dart:io'; +import '../services/nutricionista_services.dart'; + +class CadastroNutricionistaScreen extends StatefulWidget { + const CadastroNutricionistaScreen({super.key}); + + @override + _CadastroNutricionistaScreenState createState() => _CadastroNutricionistaScreenState(); +} + +class _CadastroNutricionistaScreenState extends State { + final _formKey = GlobalKey(); + final _nomeController = TextEditingController(); + final _emailController = TextEditingController(); + final _cpfController = TextEditingController(); + final _crnController = TextEditingController(); + final _especialidadeController = TextEditingController(); + final _senhaController = TextEditingController(); + final _confirmarSenhaController = TextEditingController(); + + File? _fotoPerfil; + File? _fotoDocumento; + + final NutricionistaService _nutricionistaService = NutricionistaService(); + + bool _isLoading = false; + bool _obscurePassword = true; + bool _obscureConfirmPassword = true; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color(0xFFE6F7F8), + appBar: AppBar( + title: Text('Cadastro de Nutricionista', style: TextStyle(fontWeight: FontWeight.bold)), + backgroundColor: Color(0xFF31BAC2), + elevation: 0, + ), + body: SingleChildScrollView( + child: Column( + children: [ + Container( + height: 150, + decoration: BoxDecoration( + color: Color(0xFF31BAC2), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(30), + bottomRight: Radius.circular(30), + ), + ), + child: Center( + child: Icon(Icons.person_add, size: 80, color: Colors.white), + ), + ), + Padding( + padding: EdgeInsets.all(20.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildTextField(_nomeController, 'Nome completo', Icons.person), + _buildTextField(_emailController, 'E-mail', Icons.email, keyboardType: TextInputType.emailAddress), + _buildTextField(_cpfController, 'CPF', Icons.badge, inputFormatters: [FilteringTextInputFormatter.digitsOnly]), + _buildTextField(_crnController, 'CRN', Icons.card_membership), + _buildTextField(_especialidadeController, 'Especialidade', Icons.star), + SizedBox(height: 20), + _buildImageUploadField('Foto de Perfil', _fotoPerfil, _pickProfileImage), + SizedBox(height: 20), + _buildImageUploadField('Foto do Documento', _fotoDocumento, _pickDocumentImage), + SizedBox(height: 20), + _buildPasswordFields(), + SizedBox(height: 30), + ElevatedButton( + onPressed: _isLoading ? null : _submitForm, + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), + padding: EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + child: _isLoading + ? CircularProgressIndicator(color: Colors.white) + : Text('Cadastrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildTextField(TextEditingController controller, String label, IconData icon, {TextInputType? keyboardType, List? inputFormatters}) { + return Padding( + padding: EdgeInsets.only(bottom: 20.0), + child: TextFormField( + controller: controller, + decoration: InputDecoration( + labelText: label, + prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16), + keyboardType: keyboardType, + inputFormatters: inputFormatters, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, preencha este campo'; + } + return null; + }, + ), + ); + } + + Widget _buildImageUploadField(String label, File? image, Function() onTap) { + return GestureDetector( + onTap: onTap, + child: Container( + height: 150, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + border: Border.all(color: Color(0xFF31BAC2), width: 2), + ), + child: image == null + ? Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.add_a_photo, size: 50, color: Color(0xFF31BAC2)), + SizedBox(height: 10), + Text(label, style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold)), + ], + ) + : ClipRRect( + borderRadius: BorderRadius.circular(13), + child: Image.file(image, fit: BoxFit.cover), + ), + ), + ); + } + + Widget _buildPasswordFields() { + return Card( + elevation: 4, + color: Color(0xFFF0FAFB), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Segurança', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + ), + SizedBox(height: 16), + _buildPasswordField(_senhaController, 'Senha', _obscurePassword, () { + setState(() { + _obscurePassword = !_obscurePassword; + }); + }), + SizedBox(height: 16), + _buildPasswordField(_confirmarSenhaController, 'Confirmar Senha', _obscureConfirmPassword, () { + setState(() { + _obscureConfirmPassword = !_obscureConfirmPassword; + }); + }), + ], + ), + ), + ); + } + + Widget _buildPasswordField(TextEditingController controller, String label, bool obscureText, Function() onTap) { + return TextFormField( + controller: controller, + obscureText: obscureText, + decoration: InputDecoration( + labelText: label, + prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), + suffixIcon: IconButton( + icon: Icon( + obscureText ? Icons.visibility : Icons.visibility_off, + color: Color(0xFF31BAC2), + ), + onPressed: onTap, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, insira uma senha'; + } + return null; + }, + ); + } + + Future _pickProfileImage() async { + final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery); + if (pickedFile != null) { + setState(() { + _fotoPerfil = File(pickedFile.path); + }); + } + } + + Future _pickDocumentImage() async { + final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery); + if (pickedFile != null) { + setState(() { + _fotoDocumento = File(pickedFile.path); + }); + } + } + + Future _submitForm() async { + if (_formKey.currentState!.validate()) { + if (_fotoPerfil == null || _fotoDocumento == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Por favor, selecione as fotos de perfil e documento')), + ); + return; + } + + if (_senhaController.text != _confirmarSenhaController.text) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('As senhas não coincidem')), + ); + return; + } + + setState(() { + _isLoading = true; + }); + + try { + await _nutricionistaService.cadastrarNutricionista( + nome: _nomeController.text, + email: _emailController.text, + cpf: _cpfController.text, + crn: _crnController.text, + especialidade: _especialidadeController.text, + fotoPerfil: _fotoPerfil!, + fotoDocumento: _fotoDocumento!, + senha: _senhaController.text, + ); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Nutricionista cadastrado com sucesso!')), + ); + + Navigator.of(context).pop(); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Erro ao cadastrar nutricionista: ${e.toString()}')), + ); + } finally { + setState(() { + _isLoading = false; + }); + } + } + } + + @override + void dispose() { + _nomeController.dispose(); + _emailController.dispose(); + _cpfController.dispose(); + _crnController.dispose(); + _especialidadeController.dispose(); + _senhaController.dispose(); + _confirmarSenhaController.dispose(); + super.dispose(); + } +} + diff --git a/healthway_app/lib/screens_patient/signupScreen.dart b/healthway_app/lib/screens_patient/signupScreen.dart index d6c2c6f..8c0b649 100644 --- a/healthway_app/lib/screens_patient/signupScreen.dart +++ b/healthway_app/lib/screens_patient/signupScreen.dart @@ -1,8 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; +import '../services/paciente_services.dart'; class CadastroPacienteScreen extends StatefulWidget { + const CadastroPacienteScreen({super.key}); + @override _CadastroPacienteScreenState createState() => _CadastroPacienteScreenState(); } @@ -26,10 +29,16 @@ class _CadastroPacienteScreenState extends State { String? _sexo; DateTime? _dataNascimento; + final PacienteService _pacienteService = PacienteService(); + + bool _isLoading = false; + bool _obscurePassword = true; + bool _obscureConfirmPassword = true; + @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFE6F7F8), // Tom muito claro de azul + backgroundColor: Color(0xFFE6F7F8), appBar: AppBar( title: Text('Cadastro de Paciente', style: TextStyle(fontWeight: FontWeight.bold)), backgroundColor: Color(0xFF31BAC2), @@ -67,9 +76,9 @@ class _CadastroPacienteScreenState extends State { _buildTextField(_alergiasController, 'Alergias', Icons.warning), _buildTextField(_preferenciasController, 'Preferências Alimentares', Icons.restaurant), _buildPasswordFields(), - SizedBox(height: 20), + SizedBox(height: 30), ElevatedButton( - onPressed: _submitForm, + onPressed: _isLoading ? null : _submitForm, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(vertical: 16), @@ -77,7 +86,9 @@ class _CadastroPacienteScreenState extends State { borderRadius: BorderRadius.circular(30), ), ), - child: Text('Cadastrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + child: _isLoading + ? CircularProgressIndicator(color: Colors.white) + : Text('Cadastrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ), ], ), @@ -89,7 +100,7 @@ class _CadastroPacienteScreenState extends State { ); } - Widget _buildTextField(TextEditingController controller, String label, IconData icon, {bool obscureText = false, TextInputType? keyboardType, List? inputFormatters}) { + Widget _buildTextField(TextEditingController controller, String label, IconData icon, {TextInputType? keyboardType, List? inputFormatters}) { return Padding( padding: EdgeInsets.only(bottom: 20.0), child: TextFormField( @@ -107,7 +118,6 @@ class _CadastroPacienteScreenState extends State { floatingLabelBehavior: FloatingLabelBehavior.always, ), style: TextStyle(fontSize: 16), - obscureText: obscureText, keyboardType: keyboardType, inputFormatters: inputFormatters, validator: (value) { @@ -216,7 +226,7 @@ class _CadastroPacienteScreenState extends State { Widget _buildMeasurementFields() { return Card( elevation: 4, - color: Color(0xFFF0FAFB), // Tom muito claro de azul + color: Color(0xFFF0FAFB), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), child: Padding( padding: EdgeInsets.all(16), @@ -281,7 +291,7 @@ class _CadastroPacienteScreenState extends State { Widget _buildPasswordFields() { return Card( elevation: 4, - color: Color(0xFFF0FAFB), // Tom muito claro de azul + color: Color(0xFFF0FAFB), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), child: Padding( padding: EdgeInsets.all(16), @@ -293,20 +303,119 @@ class _CadastroPacienteScreenState extends State { style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), ), SizedBox(height: 16), - _buildTextField(_senhaController, 'Senha', Icons.lock, obscureText: true), - _buildTextField(_confirmarSenhaController, 'Confirmar Senha', Icons.lock, obscureText: true), + _buildPasswordField(_senhaController, 'Senha', _obscurePassword, () { + setState(() { + _obscurePassword = !_obscurePassword; + }); + }), + SizedBox(height: 16), + _buildPasswordField(_confirmarSenhaController, 'Confirmar Senha', _obscureConfirmPassword, () { + setState(() { + _obscureConfirmPassword = !_obscureConfirmPassword; + }); + }), ], ), ), ); } - void _submitForm() { + Widget _buildPasswordField(TextEditingController controller, String label, bool obscureText, Function() onTap) { + return TextFormField( + controller: controller, + obscureText: obscureText, + decoration: InputDecoration( + labelText: label, + prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), + suffixIcon: IconButton( + icon: Icon( + obscureText ? Icons.visibility : Icons.visibility_off, + color: Color(0xFF31BAC2), + ), + onPressed: onTap, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: Color(0xFF31BAC2)), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, insira uma senha'; + } + return null; + }, + ); + } + + Future _submitForm() async { if (_formKey.currentState!.validate()) { - // TODO: Implement form submission logic - print('Form is valid. Submitting...'); - // You would typically call a service method here to save the patient data + if (_senhaController.text != _confirmarSenhaController.text) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('As senhas não coincidem')), + ); + return; + } + + setState(() { + _isLoading = true; + }); + + try { + await _pacienteService.cadastrarPaciente( + nome: _nomeController.text, + email: _emailController.text, + cpf: _cpfController.text, + dataNascimento: _dataNascimentoController.text, + sexo: _sexo!, + altura: double.parse(_alturaController.text), + peso: double.parse(_pesoController.text), + circunferenciaAbdominal: double.parse(_circunferenciaAbdominalController.text), + gorduraCorporal: double.parse(_gorduraCorporalController.text), + massaMuscular: double.parse(_massaMuscularController.text), + alergias: _alergiasController.text, + preferencias: _preferenciasController.text, + senha: _senhaController.text, + ); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Paciente cadastrado com sucesso!')), + ); + + Navigator.of(context).pop(); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Erro ao cadastrar paciente: ${e.toString()}')), + ); + } finally { + setState(() { + _isLoading = false; + }); + } } } + + @override + void dispose() { + _nomeController.dispose(); + _emailController.dispose(); + _cpfController.dispose(); + _dataNascimentoController.dispose(); + _alturaController.dispose(); + _pesoController.dispose(); + _circunferenciaAbdominalController.dispose(); + _gorduraCorporalController.dispose(); + _massaMuscularController.dispose(); + _alergiasController.dispose(); + _preferenciasController.dispose(); + _senhaController.dispose(); + _confirmarSenhaController.dispose(); + super.dispose(); + } } diff --git a/healthway_app/lib/services/nutricionista_services.dart b/healthway_app/lib/services/nutricionista_services.dart index a43fef6..a74a5bd 100644 --- a/healthway_app/lib/services/nutricionista_services.dart +++ b/healthway_app/lib/services/nutricionista_services.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:http/http.dart' as http; import '../models/nutricionista.dart'; +import 'dart:io'; class NutricionistaService { static const String apiUrl = 'http://localhost:3000/api/nutricionistas'; @@ -10,14 +11,11 @@ class NutricionistaService { if (response.statusCode == 200) { try { - // Decodifica o corpo da resposta List data = json.decode(response.body); - // Verifica se os dados não são nulos e se são uma lista if (data != null && data is List) { return data.map((json) => Nutricionista.fromJson(json)).toList(); } else { - // Caso os dados sejam nulos ou não sejam uma lista throw Exception('Dados não encontrados ou formato inválido'); } } catch (e) { @@ -27,4 +25,34 @@ class NutricionistaService { throw Exception('Falha ao carregar nutricionistas'); } } + + Future cadastrarNutricionista({ + required String nome, + required String email, + required String cpf, + required String crn, + required String especialidade, + required File fotoPerfil, + required File fotoDocumento, + required String senha, + }) async { + var uri = Uri.parse('$apiUrl'); + var request = http.MultipartRequest('POST', uri); + + request.fields['nome'] = nome; + request.fields['email'] = email; + request.fields['cpf'] = cpf; + request.fields['crn'] = crn; + request.fields['especialidade'] = especialidade; + request.fields['senha'] = senha; + + request.files.add(await http.MultipartFile.fromPath('foto_perfil', fotoPerfil.path)); + request.files.add(await http.MultipartFile.fromPath('foto_documento', fotoDocumento.path)); + + var response = await request.send(); + if (response.statusCode != 201) { + throw Exception('Falha ao cadastrar nutricionista'); + } + } } + diff --git a/healthway_app/lib/services/paciente_services.dart b/healthway_app/lib/services/paciente_services.dart new file mode 100644 index 0000000..d656b38 --- /dev/null +++ b/healthway_app/lib/services/paciente_services.dart @@ -0,0 +1,67 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import '../models/paciente.dart'; +import 'dart:io'; + +class PacienteService { + static const String apiUrl = 'http://localhost:3000/api/pacientes'; + + Future> fetchPacientes() async { + final response = await http.get(Uri.parse(apiUrl)); + + if (response.statusCode == 200) { + try { + List data = json.decode(response.body); + + if (data != null && data is List) { + return data.map((json) => Paciente.fromJson(json)).toList(); + } else { + throw Exception('Dados não encontrados ou formato inválido'); + } + } catch (e) { + throw Exception('Erro ao parsear o JSON: $e'); + } + } else { + throw Exception('Falha ao carregar pacientes'); + } + } + + Future cadastrarPaciente({ + required String nome, + required String email, + required String cpf, + required String dataNascimento, + required String sexo, + required double altura, + required double peso, + required double circunferenciaAbdominal, + required double gorduraCorporal, + required double massaMuscular, + required String alergias, + required String preferencias, + required String senha, + }) async { + var uri = Uri.parse(apiUrl); + var request = http.MultipartRequest('POST', uri); + + request.fields['nome'] = nome; + request.fields['email'] = email; + request.fields['cpf'] = cpf; + request.fields['dataNascimento'] = dataNascimento; + request.fields['sexo'] = sexo; + request.fields['altura'] = altura.toString(); + request.fields['peso'] = peso.toString(); + request.fields['circunferenciaAbdominal'] = circunferenciaAbdominal.toString(); + request.fields['gorduraCorporal'] = gorduraCorporal.toString(); + request.fields['massaMuscular'] = massaMuscular.toString(); + request.fields['alergias'] = alergias; + request.fields['preferencias'] = preferencias; + request.fields['senha'] = senha; + + var response = await request.send(); + if (response.statusCode != 201) { + throw Exception('Falha ao cadastrar paciente'); + } + } +} + diff --git a/healthway_app/linux/flutter/generated_plugin_registrant.cc b/healthway_app/linux/flutter/generated_plugin_registrant.cc index e71a16d..64a0ece 100644 --- a/healthway_app/linux/flutter/generated_plugin_registrant.cc +++ b/healthway_app/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); + file_selector_plugin_register_with_registrar(file_selector_linux_registrar); } diff --git a/healthway_app/linux/flutter/generated_plugins.cmake b/healthway_app/linux/flutter/generated_plugins.cmake index 2e1de87..2db3c22 100644 --- a/healthway_app/linux/flutter/generated_plugins.cmake +++ b/healthway_app/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + file_selector_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift b/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817..14b5f7c 100644 --- a/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,8 @@ import FlutterMacOS import Foundation +import file_selector_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) } diff --git a/healthway_app/pubspec.yaml b/healthway_app/pubspec.yaml index 0756baf..853ce56 100644 --- a/healthway_app/pubspec.yaml +++ b/healthway_app/pubspec.yaml @@ -32,6 +32,7 @@ dependencies: sdk: flutter http: ^1.2.2 intl: ^0.17.0 + image_picker: ^0.8.7+5 # The following adds the Cupertino Icons font to your application. diff --git a/healthway_app/windows/flutter/generated_plugin_registrant.cc b/healthway_app/windows/flutter/generated_plugin_registrant.cc index 8b6d468..77ab7a0 100644 --- a/healthway_app/windows/flutter/generated_plugin_registrant.cc +++ b/healthway_app/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); } diff --git a/healthway_app/windows/flutter/generated_plugins.cmake b/healthway_app/windows/flutter/generated_plugins.cmake index b93c4c3..a423a02 100644 --- a/healthway_app/windows/flutter/generated_plugins.cmake +++ b/healthway_app/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + file_selector_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST From 63ce620291b099591ed39549cf0dbe29ba2cacb7 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 6 Jan 2025 09:09:31 -0300 Subject: [PATCH 07/47] resolvendo problemas --- .../geral_screens/apresentationScreen.dart | 3 ++- .../lib/geral_screens/loginScreen.dart | 25 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/healthway_app/lib/geral_screens/apresentationScreen.dart b/healthway_app/lib/geral_screens/apresentationScreen.dart index 87864a1..0163b30 100644 --- a/healthway_app/lib/geral_screens/apresentationScreen.dart +++ b/healthway_app/lib/geral_screens/apresentationScreen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/loginScreen.dart'; +import 'package:healthway_app/screens/dashboardScreen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; import 'package:healthway_app/screens_nutricionist/signUpNutritionist.dart'; import 'dart:async'; @@ -39,7 +40,7 @@ class _PresentationScreenState extends State // Navegar para a próxima tela após a animação Timer(Duration(seconds: 3), () { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => CadastroPacienteScreen()), + MaterialPageRoute(builder: (_) => DashboardScreen(onThemeChanged: (bool value) { },)), ); }); } diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index 5bd71f8..979a454 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:healthway_app/screens_patient/signupScreen.dart'; +import 'package:healthway_app/screens_nutricionist/signUpNutritionist.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @@ -53,7 +55,8 @@ class _LoginScreenState extends State { SizedBox(height: 30), _buildLoginButton(), SizedBox(height: 20), - _buildRegisterButton(), + _buildPatientButton(), + _buildNutricionistButton(), ], ), ), @@ -144,7 +147,6 @@ class _LoginScreenState extends State { Widget _buildLoginButton() { return ElevatedButton( - child: Text('Entrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), onPressed: _submitForm, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), @@ -153,16 +155,29 @@ class _LoginScreenState extends State { borderRadius: BorderRadius.circular(30), ), ), + child: Text('Entrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + ); + } + + Widget _buildPatientButton() { + return TextButton( + onPressed: () { + MaterialPageRoute(builder: (_) => CadastroPacienteScreen()); + }, + child: Text( + 'Sou paciente', + style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + ), ); } - Widget _buildRegisterButton() { + Widget _buildNutricionistButton() { return TextButton( onPressed: () { - // TODO: Navegar para a tela de cadastro + MaterialPageRoute(builder: (_) => CadastroNutricionistaScreen()); }, child: Text( - 'Não tem uma conta? Cadastre-se', + 'Sou nutricionista', style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), ), ); From 4f9df25389d16681f5eaad49d2ca3317a6fc60f5 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Wed, 8 Jan 2025 21:55:48 -0300 Subject: [PATCH 08/47] adicionando telas ao nutricionista --- .../geral_screens/apresentationScreen.dart | 2 +- .../nutricionistas_details_screen.dart | 194 ++++++++-- healthway_app/lib/main.dart | 8 +- .../nutritionist_dashboard.dart | 364 +++++++++++------- .../nutritionist_profile.dart | 273 +++++++++++++ .../screens_nutricionist/schedule_screen.dart | 198 ++++++++++ .../lib/screens_patient/dashboardScreen.dart | 2 +- .../lib/screens_patient/dietScreen.dart | 148 ++++++- .../lib/screens_patient/profileScreen.dart | 232 +++++++++-- healthway_app/lib/widgets/rating_stars.dart | 31 ++ healthway_app/lib/widgets/review_card.dart | 53 +++ healthway_app/pubspec.yaml | 3 +- 12 files changed, 1288 insertions(+), 220 deletions(-) create mode 100644 healthway_app/lib/screens_nutricionist/nutritionist_profile.dart create mode 100644 healthway_app/lib/screens_nutricionist/schedule_screen.dart create mode 100644 healthway_app/lib/widgets/rating_stars.dart create mode 100644 healthway_app/lib/widgets/review_card.dart diff --git a/healthway_app/lib/geral_screens/apresentationScreen.dart b/healthway_app/lib/geral_screens/apresentationScreen.dart index a3684b7..8c5c65f 100644 --- a/healthway_app/lib/geral_screens/apresentationScreen.dart +++ b/healthway_app/lib/geral_screens/apresentationScreen.dart @@ -36,7 +36,7 @@ class _PresentationScreenState extends State // Navegar para a próxima tela após a animação Timer(Duration(seconds: 3), () { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => PatientDashboardScreen()), + MaterialPageRoute(builder: (_) => NutritionistDashboardScreen()), ); }); } diff --git a/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart b/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart index 4a4cc26..aed4e75 100644 --- a/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart +++ b/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart @@ -1,53 +1,195 @@ import 'package:flutter/material.dart'; -import 'rating_stars.dart'; - -class ReviewCard extends StatelessWidget { - final String authorName; - final double rating; - final String comment; - final String date; - - const ReviewCard({ - Key? key, - required this.authorName, - required this.rating, - required this.comment, - required this.date, - }) : super(key: key); +import '../models/nutricionista.dart'; +import '../widgets/rating_stars.dart'; +import '../widgets/review_card.dart'; + +class NutricionistaDetailScreen extends StatelessWidget { + final Nutricionista nutricionista; + + const NutricionistaDetailScreen({super.key, required this.nutricionista}); @override Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color(0xFFF5F5F5), + body: CustomScrollView( + slivers: [ + _buildSliverAppBar(), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildInfoCard(), + SizedBox(height: 16), + _buildAboutSection(), + SizedBox(height: 16), + _buildReviewsSection(), + ], + ), + ), + ), + ], + ), + floatingActionButton: FloatingActionButton.extended( + onPressed: () { + // TODO: Implement appointment scheduling + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Funcionalidade de agendamento em desenvolvimento')), + ); + }, + icon: Icon(Icons.calendar_today), + label: Text('Agendar Consulta'), + backgroundColor: Color(0xFF31BAC2), + ), + ); + } + + Widget _buildSliverAppBar() { + return SliverAppBar( + expandedHeight: 200.0, + floating: false, + pinned: true, + flexibleSpace: FlexibleSpaceBar( + title: Text(nutricionista.nome), + background: Image.network( + nutricionista.fotoPerfil ?? 'https://www.w3schools.com/w3images/avatar2.png', + fit: BoxFit.cover, + ), + ), + backgroundColor: Color(0xFF31BAC2), + ); + } + + Widget _buildInfoCard() { return Card( - margin: EdgeInsets.symmetric(vertical: 8), + elevation: 4, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: Padding( - padding: const EdgeInsets.all(12.0), + padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + nutricionista.nome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text( + nutricionista.especialidade, + style: TextStyle(fontSize: 18, color: Colors.grey[600]), + ), + SizedBox(height: 16), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Icon(Icons.star, color: Colors.amber), + SizedBox(width: 4), Text( - authorName, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + '${nutricionista.avaliacao.toStringAsFixed(1)}', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), + SizedBox(width: 16), + Icon(Icons.person, color: Color(0xFF31BAC2)), + SizedBox(width: 4), Text( - date, - style: TextStyle(color: Colors.grey[600], fontSize: 14), + '${nutricionista.numeroClientes} clientes', + style: TextStyle(fontSize: 16), ), ], ), - SizedBox(height: 4), - RatingStars(rating: rating, size: 18), + SizedBox(height: 16), + _buildInfoRow(Icons.email, nutricionista.email), + SizedBox(height: 8), + _buildInfoRow(Icons.badge, 'CRN: ${nutricionista.crn}'), + ], + ), + ), + ); + } + + Widget _buildInfoRow(IconData icon, String text) { + return Row( + children: [ + Icon(icon, color: Color(0xFF31BAC2), size: 20), + SizedBox(width: 8), + Expanded( + child: Text( + text, + style: TextStyle(fontSize: 16), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ); + } + + Widget _buildAboutSection() { + return Card( + elevation: 4, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Sobre', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), SizedBox(height: 8), Text( - comment, - style: TextStyle(fontSize: 14), + nutricionista.sobre ?? 'Informações sobre o nutricionista não disponíveis.', + style: TextStyle(fontSize: 16), ), ], ), ), ); } + + Widget _buildReviewsSection() { + return Card( + elevation: 4, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Avaliações', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + SizedBox(height: 16), + RatingStars(rating: nutricionista.avaliacao), + SizedBox(height: 16), + // Aqui você pode adicionar uma lista de ReviewCard widgets + // representando as avaliações reais dos clientes + ReviewCard( + authorName: 'Maria Silva', + rating: 5, + comment: 'Excelente profissional! Muito atencioso e competente.', + date: '10/05/2023', + ), + ReviewCard( + authorName: 'João Santos', + rating: 4, + comment: 'Ótimo atendimento e resultados satisfatórios.', + date: '05/05/2023', + ), + // Adicione mais ReviewCards conforme necessário + ], + ), + ), + ); + } +} + +extension on Nutricionista { + get avaliacao => 5.0; + get sobre => "Sou um nutricionista muito bom"; + + get numeroClientes => 12; } diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 08af9cc..b7c1411 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -2,6 +2,9 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens//apresentationScreen.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; +import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; +import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; +import 'package:healthway_app/screens_nutricionist/schedule_screen.dart'; import 'package:healthway_app/screens_patient/dashboardScreen.dart'; import 'package:healthway_app/screens_patient/dietScreen.dart'; import 'package:healthway_app/screens_patient/healthScreen.dart'; @@ -41,7 +44,7 @@ class MyApp extends StatelessWidget { '/signUp': (context) => CadastroPacienteScreen(), '/login': (context) => LoginScreen(), '/chat': (context) => ChatScreen(), - '/health': (context) => DietManagementScreen(), + '/health': (context) => PlanoAlimentarScreen(pacienteId: '',), '/alimentos': (context) => AlimentosScreen(), '/nutricionistas': (context) => NutricionistasScreen(), '/menu': (context) => MenuScreen(), @@ -49,6 +52,9 @@ class MyApp extends StatelessWidget { '/profile': (context) => PatientProfileScreen(), '/notifications': (context) => NotificationScreen(), '/settings': (context) => SettingsScreen(), + '/patientList': (context) => PatientListScreen(), + '/nutritionistProfile': (context) => NutritionistProfileScreen(), + '/schedule': (context) => ScheduleScreen(), }, ); } diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart index d19a2eb..a776dca 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; class NutritionistDashboardScreen extends StatelessWidget { - const NutritionistDashboardScreen({Key? key}) : super(key: key); + const NutritionistDashboardScreen({super.key}); @override Widget build(BuildContext context) { @@ -13,19 +13,19 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildHeader(), - _buildQuickAccess(), - _buildAppointments(), - _buildPatientUpdates(), + _buildHeader(context), + _buildQuickAccess(context), + _buildAppointments(context), + _buildPatientUpdates(context), ], ), ), ), - bottomNavigationBar: _buildBottomNavigationBar(), + bottomNavigationBar: _buildBottomNavigationBar(context), ); } - Widget _buildHeader() { + Widget _buildHeader(BuildContext context) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( @@ -62,13 +62,18 @@ class NutritionistDashboardScreen extends StatelessWidget { ), ], ), - CircleAvatar( - radius: 30, - backgroundColor: Colors.white, - child: Icon( - Icons.person, - size: 35, - color: Color(0xFF31BAC2), + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/nutritionistProfile'); + }, + child: CircleAvatar( + radius: 30, + backgroundColor: Colors.white, + child: Icon( + Icons.person, + size: 35, + color: Color(0xFF31BAC2), + ), ), ), ], @@ -117,7 +122,7 @@ class NutritionistDashboardScreen extends StatelessWidget { ); } - Widget _buildQuickAccess() { + Widget _buildQuickAccess(BuildContext context) { return Padding( padding: const EdgeInsets.all(20), child: Column( @@ -135,10 +140,10 @@ class NutritionistDashboardScreen extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - _buildQuickAccessItem(Icons.people, 'Pacientes', '/patient_list'), - _buildQuickAccessItem(Icons.calendar_today, 'Agenda', '/schedule'), - _buildQuickAccessItem(Icons.restaurant_menu, 'Planos', '/meal_plans'), - _buildQuickAccessItem(Icons.message, 'Mensagens', '/messages'), + _buildQuickAccessItem(context, Icons.people, 'Pacientes', '/patientList'), + _buildQuickAccessItem(context, Icons.calendar_today, 'Agenda', '/schedule'), + _buildQuickAccessItem(context, Icons.restaurant_menu, 'Planos', '/meal_plans'), + _buildQuickAccessItem(context, Icons.message, 'Mensagens', '/chat'), ], ), ], @@ -146,10 +151,10 @@ class NutritionistDashboardScreen extends StatelessWidget { ); } - Widget _buildQuickAccessItem(IconData icon, String label, String route) { + Widget _buildQuickAccessItem(BuildContext context, IconData icon, String label, String route) { return GestureDetector( onTap: () { - // Navegação para a rota especificada + Navigator.pushNamed(context, route); }, child: Column( children: [ @@ -178,178 +183,222 @@ class NutritionistDashboardScreen extends StatelessWidget { ); } - Widget _buildAppointments() { + Widget _buildAppointments(BuildContext context) { return Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - 'Próximas Consultas', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Próximas Consultas', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + TextButton( + onPressed: () { + Navigator.pushNamed(context, '/appointments'); + }, + child: Text( + 'Ver todas', + style: TextStyle( + color: Color(0xFF31BAC2), + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), SizedBox(height: 15), - _buildAppointmentItem('Maria Oliveira', '14:00', 'Consulta de Rotina'), - _buildAppointmentItem('João Silva', '15:30', 'Avaliação Nutricional'), - _buildAppointmentItem('Ana Santos', '17:00', 'Revisão de Dieta'), + _buildAppointmentItem(context, 'Maria Oliveira', '14:00', 'Consulta de Rotina'), + _buildAppointmentItem(context, 'João Silva', '15:30', 'Avaliação Nutricional'), + _buildAppointmentItem(context, 'Ana Santos', '17:00', 'Revisão de Dieta'), ], ), ); } - Widget _buildAppointmentItem(String name, String time, String type) { - return Container( - margin: EdgeInsets.only(bottom: 10), - padding: EdgeInsets.all(15), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 1, - blurRadius: 5, - offset: Offset(0, 3), - ), - ], - ), - child: Row( - children: [ - Container( - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Color(0xFF31BAC2).withOpacity(0.1), - borderRadius: BorderRadius.circular(10), + Widget _buildAppointmentItem(BuildContext context, String name, String time, String type) { + return GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/appointment_details', arguments: {'name': name, 'time': time, 'type': type}); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10), + padding: EdgeInsets.all(15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 5, + offset: Offset(0, 3), ), - child: Icon( - Icons.calendar_today, - color: Color(0xFF31BAC2), + ], + ), + child: Row( + children: [ + Container( + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: Color(0xFF31BAC2).withOpacity(0.1), + borderRadius: BorderRadius.circular(10), + ), + child: Icon( + Icons.calendar_today, + color: Color(0xFF31BAC2), + ), ), - ), - SizedBox(width: 15), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - name, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, + SizedBox(width: 15), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), ), - ), - SizedBox(height: 5), - Text( - type, - style: TextStyle( - color: Colors.grey[600], - fontSize: 14, + SizedBox(height: 5), + Text( + type, + style: TextStyle( + color: Colors.grey[600], + fontSize: 14, + ), ), - ), - ], + ], + ), ), - ), - Text( - time, - style: TextStyle( - fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2), + Text( + time, + style: TextStyle( + fontWeight: FontWeight.bold, + color: Color(0xFF31BAC2), + ), ), - ), - ], + ], + ), ), ); } - Widget _buildPatientUpdates() { + Widget _buildPatientUpdates(BuildContext context) { return Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - 'Atualizações de Pacientes', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Atualizações de Pacientes', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + TextButton( + onPressed: () { + Navigator.pushNamed(context, '/patient_updates'); + }, + child: Text( + 'Ver todas', + style: TextStyle( + color: Color(0xFF31BAC2), + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), SizedBox(height: 15), - _buildPatientUpdateItem('Carlos Mendes', 'Atingiu meta de peso', '2h atrás'), - _buildPatientUpdateItem('Fernanda Lima', 'Novo registro de refeição', '4h atrás'), - _buildPatientUpdateItem('Ricardo Souza', 'Solicitou alteração na dieta', '1d atrás'), + _buildPatientUpdateItem(context, 'Carlos Mendes', 'Atingiu meta de peso', '2h atrás'), + _buildPatientUpdateItem(context, 'Fernanda Lima', 'Novo registro de refeição', '4h atrás'), + _buildPatientUpdateItem(context, 'Ricardo Souza', 'Solicitou alteração na dieta', '1d atrás'), ], ), ); } - Widget _buildPatientUpdateItem(String name, String update, String time) { - return Container( - margin: EdgeInsets.only(bottom: 10), - padding: EdgeInsets.all(15), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 1, - blurRadius: 5, - offset: Offset(0, 3), - ), - ], - ), - child: Row( - children: [ - CircleAvatar( - backgroundColor: Color(0xFF31BAC2).withOpacity(0.1), - child: Text( - name[0], - style: TextStyle( - color: Color(0xFF31BAC2), - fontWeight: FontWeight.bold, + Widget _buildPatientUpdateItem(BuildContext context, String name, String update, String time) { + return GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/patient_details', arguments: {'name': name}); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10), + padding: EdgeInsets.all(15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: Row( + children: [ + CircleAvatar( + backgroundColor: Color(0xFF31BAC2).withOpacity(0.1), + child: Text( + name[0], + style: TextStyle( + color: Color(0xFF31BAC2), + fontWeight: FontWeight.bold, + ), ), ), - ), - SizedBox(width: 15), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - name, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, + SizedBox(width: 15), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), ), - ), - SizedBox(height: 5), - Text( - update, - style: TextStyle( - color: Colors.grey[600], - fontSize: 14, + SizedBox(height: 5), + Text( + update, + style: TextStyle( + color: Colors.grey[600], + fontSize: 14, + ), ), - ), - ], + ], + ), ), - ), - Text( - time, - style: TextStyle( - color: Colors.grey[400], - fontSize: 12, + Text( + time, + style: TextStyle( + color: Colors.grey[400], + fontSize: 12, + ), ), - ), - ], + ], + ), ), ); } - Widget _buildBottomNavigationBar() { + Widget _buildBottomNavigationBar(BuildContext context) { return Container( decoration: BoxDecoration( color: Colors.white, @@ -370,6 +419,23 @@ class NutritionistDashboardScreen extends StatelessWidget { showSelectedLabels: true, showUnselectedLabels: true, type: BottomNavigationBarType.fixed, + currentIndex: 0, + onTap: (index) { + switch (index) { + case 0: + // Already on home screen + break; + case 1: + Navigator.pushNamed(context, '/patientList'); + break; + case 2: + Navigator.pushNamed(context, '/schedule'); + break; + case 3: + Navigator.pushNamed(context, '/chat'); + break; + } + }, items: [ BottomNavigationBarItem( icon: Icon(Icons.home), diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart new file mode 100644 index 0000000..7b07721 --- /dev/null +++ b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart @@ -0,0 +1,273 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class NutritionistProfileScreen extends StatefulWidget { + const NutritionistProfileScreen({super.key}); + + @override + _NutritionistProfileScreenState createState() => _NutritionistProfileScreenState(); +} + +class _NutritionistProfileScreenState extends State { + bool _isEditing = false; + final _formKey = GlobalKey(); + + // Mock data - replace with actual data fetching in a real app + String nome = 'Dr. Silva'; + String email = 'dr.silva@email.com'; + String cpf = '123.456.789-00'; + String crn = 'CRN-1 12345'; + String especialidade = 'Nutrição Esportiva'; + String fotoPerfil = 'https://example.com/dr_silva_profile.jpg'; + String fotoDocumento = 'https://example.com/dr_silva_document.jpg'; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF5F5F5), + appBar: AppBar( + title: const Text('Meu Perfil'), + backgroundColor: const Color(0xFF31BAC2), + elevation: 0, + actions: [ + IconButton( + icon: Icon(_isEditing ? Icons.close : Icons.edit), + onPressed: () { + setState(() { + if (_isEditing) { + // Discard changes + _isEditing = false; + } else { + _isEditing = true; + } + }); + }, + ), + ], + ), + body: SafeArea( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildProfileHeader(), + SizedBox(height: 24), + _buildInfoSection(), + SizedBox(height: 24), + _buildActionButtons(), + SizedBox(height: 24), + _buildDocumentSection(), + ], + ), + ), + ), + ), + floatingActionButton: _isEditing + ? FloatingActionButton( + onPressed: _saveChanges, + backgroundColor: Color(0xFF31BAC2), + child: Icon(Icons.save), + ) + : null, + ); + } + + Widget _buildProfileHeader() { + return Center( + child: Column( + children: [ + Stack( + alignment: Alignment.bottomRight, + children: [ + CircleAvatar( + radius: 60, + backgroundColor: Color(0xFF31BAC2), + backgroundImage: NetworkImage(fotoPerfil), + child: fotoPerfil.isEmpty + ? Text( + nome.isNotEmpty ? nome[0].toUpperCase() : '?', + style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white), + ) + : null, + ), + if (!_isEditing) + Container( + decoration: BoxDecoration( + color: Color(0xFF31BAC2), + shape: BoxShape.circle, + ), + child: IconButton( + icon: Icon(Icons.camera_alt, color: Colors.white), + onPressed: () { + // Implement image picking functionality + }, + ), + ), + ], + ), + SizedBox(height: 16), + _isEditing + ? TextFormField( + initialValue: nome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => nome = value, + ) + : Text( + nome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + _isEditing + ? TextFormField( + initialValue: email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => email = value, + ) + : Text( + email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + ), + ], + ), + ); + } + + Widget _buildInfoSection() { + return Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + _buildInfoRow('CPF', cpf, (value) => cpf = value), + _buildInfoRow('CRN', crn, (value) => crn = value), + _buildInfoRow('Especialidade', especialidade, (value) => especialidade = value), + ], + ), + ), + ); + } + + Widget _buildInfoRow(String label, String value, Function(String) onChanged) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(label, style: TextStyle(fontSize: 16, color: Colors.grey[600])), + _isEditing && onChanged != null + ? SizedBox( + width: 200, + child: TextFormField( + initialValue: value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + textAlign: TextAlign.right, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: onChanged, + ), + ) + : Text(value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + ], + ), + ); + } + + Widget _buildActionButtons() { + return Column( + children: [ + ElevatedButton( + onPressed: () { + // Navigate to detailed edit profile screen + }, + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xFF31BAC2), + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + ), + child: Text('Editar Perfil Detalhado'), + ), + SizedBox(height: 12), + OutlinedButton( + onPressed: () { + // Navigate to change password screen + }, + style: OutlinedButton.styleFrom( + foregroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + side: BorderSide(color: Color(0xFF31BAC2)), + ), + child: Text('Alterar Senha'), + ), + ], + ); + } + + Widget _buildDocumentSection() { + return Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Documento', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox(height: 16), + Center( + child: GestureDetector( + onTap: () { + // Implement document image viewing or updating functionality + }, + child: Container( + width: 200, + height: 150, + decoration: BoxDecoration( + border: Border.all(color: Color(0xFF31BAC2)), + borderRadius: BorderRadius.circular(10), + image: DecorationImage( + image: NetworkImage(fotoDocumento), + fit: BoxFit.cover, + ), + ), + child: fotoDocumento.isEmpty + ? Icon(Icons.add_a_photo, size: 50, color: Color(0xFF31BAC2)) + : null, + ), + ), + ), + ], + ), + ), + ); + } + + void _saveChanges() { + if (_formKey.currentState!.validate()) { + // Save the changes + setState(() { + _isEditing = false; + }); + // Show a snackbar to confirm changes + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Perfil atualizado com sucesso!')), + ); + } + } +} + diff --git a/healthway_app/lib/screens_nutricionist/schedule_screen.dart b/healthway_app/lib/screens_nutricionist/schedule_screen.dart new file mode 100644 index 0000000..db9ba68 --- /dev/null +++ b/healthway_app/lib/screens_nutricionist/schedule_screen.dart @@ -0,0 +1,198 @@ +import 'package:flutter/material.dart'; +import 'package:table_calendar/table_calendar.dart'; +import 'package:intl/intl.dart'; + +class ScheduleScreen extends StatefulWidget { + const ScheduleScreen({super.key}); + + @override + _ScheduleScreenState createState() => _ScheduleScreenState(); +} + +class _ScheduleScreenState extends State { + CalendarFormat _calendarFormat = CalendarFormat.week; + DateTime _focusedDay = DateTime.now(); + DateTime? _selectedDay; + Map> _appointments = {}; + + @override + void initState() { + super.initState(); + _selectedDay = _focusedDay; + // Mock data - replace with actual data fetching + _appointments = { + DateTime.now().subtract(Duration(days: 1)): [ + Appointment("Maria Oliveira", "Consulta de Rotina", "14:00"), + Appointment("João Silva", "Avaliação Nutricional", "16:30"), + ], + DateTime.now(): [ + Appointment("Ana Santos", "Revisão de Dieta", "10:00"), + Appointment("Carlos Mendes", "Primeira Consulta", "15:00"), + ], + DateTime.now().add(Duration(days: 1)): [ + Appointment("Fernanda Lima", "Acompanhamento", "11:30"), + Appointment("Ricardo Souza", "Consulta de Rotina", "14:00"), + ], + }; + } + + List _getAppointmentsForDay(DateTime day) { + return _appointments[day] ?? []; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF5F5F5), + appBar: AppBar( + title: Text('Agenda', style: TextStyle(fontWeight: FontWeight.bold)), + backgroundColor: const Color(0xFF31BAC2), + elevation: 0, + ), + body: Column( + children: [ + _buildCalendar(), + Expanded(child: _buildAppointmentList()), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: _addAppointment, + backgroundColor: const Color(0xFF31BAC2), + child: Icon(Icons.add), + ), + ); + } + + Widget _buildCalendar() { + return TableCalendar( + firstDay: DateTime.utc(2023, 1, 1), + lastDay: DateTime.utc(2030, 12, 31), + focusedDay: _focusedDay, + calendarFormat: _calendarFormat, + selectedDayPredicate: (day) { + return isSameDay(_selectedDay, day); + }, + onFormatChanged: (format) { + if (_calendarFormat != format) { + setState(() { + _calendarFormat = format; + }); + } + }, + onPageChanged: (focusedDay) { + _focusedDay = focusedDay; + }, + eventLoader: _getAppointmentsForDay, + calendarStyle: CalendarStyle( + selectedDecoration: BoxDecoration( + color: const Color(0xFF31BAC2), + shape: BoxShape.circle, + ), + todayDecoration: BoxDecoration( + color: const Color(0xFF31BAC2).withOpacity(0.5), + shape: BoxShape.circle, + ), + markerDecoration: BoxDecoration( + color: const Color(0xFF31BAC2), + shape: BoxShape.circle, + ), + ), + headerStyle: HeaderStyle( + formatButtonVisible: false, + titleCentered: true, + titleTextStyle: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + ); + } + + Widget _buildAppointmentList() { + final appointments = _getAppointmentsForDay(_selectedDay!); + return ListView.builder( + itemCount: appointments.length, + itemBuilder: (context, index) { + final appointment = appointments[index]; + return Card( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: ListTile( + leading: CircleAvatar( + backgroundColor: const Color(0xFF31BAC2), + child: Text( + appointment.patientName[0], + style: TextStyle(color: Colors.white), + ), + ), + title: Text(appointment.patientName), + subtitle: Text(appointment.type), + trailing: Text( + appointment.time, + style: TextStyle( + fontWeight: FontWeight.bold, + color: const Color(0xFF31BAC2), + ), + ), + onTap: () => _viewAppointmentDetails(appointment), + ), + ); + }, + ); + } + + void _addAppointment() { + // TODO: Implement add appointment functionality + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Adicionar Consulta'), + content: Text('Funcionalidade de adicionar consulta a ser implementada.'), + actions: [ + TextButton( + child: Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + + void _viewAppointmentDetails(Appointment appointment) { + // TODO: Implement view appointment details functionality + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Detalhes da Consulta'), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text('Paciente: ${appointment.patientName}'), + Text('Tipo: ${appointment.type}'), + Text('Horário: ${appointment.time}'), + ], + ), + actions: [ + TextButton( + child: Text('Fechar'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } +} + +class Appointment { + final String patientName; + final String type; + final String time; + + Appointment(this.patientName, this.type, this.time); +} + diff --git a/healthway_app/lib/screens_patient/dashboardScreen.dart b/healthway_app/lib/screens_patient/dashboardScreen.dart index 52b3408..bdde3e4 100644 --- a/healthway_app/lib/screens_patient/dashboardScreen.dart +++ b/healthway_app/lib/screens_patient/dashboardScreen.dart @@ -341,7 +341,7 @@ Widget _buildQuickAccessItem(BuildContext context, IconData icon, String label, // Já estamos na tela inicial, então não faça nada break; case 1: - Navigator.pushNamed(context, '/diet'); + Navigator.pushNamed(context, '/health'); break; case 2: Navigator.pushNamed(context, '/progress'); diff --git a/healthway_app/lib/screens_patient/dietScreen.dart b/healthway_app/lib/screens_patient/dietScreen.dart index 7735aae..7a2f3fb 100644 --- a/healthway_app/lib/screens_patient/dietScreen.dart +++ b/healthway_app/lib/screens_patient/dietScreen.dart @@ -1,15 +1,155 @@ import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class PlanoAlimentarScreen extends StatefulWidget { + final String pacienteId; + + const PlanoAlimentarScreen({Key? key, required this.pacienteId}) : super(key: key); + + @override + _PlanoAlimentarScreenState createState() => _PlanoAlimentarScreenState(); +} + +class _PlanoAlimentarScreenState extends State { + List planosAlimentares = []; + bool isLoading = true; + + @override + void initState() { + super.initState(); + _carregarPlanosAlimentares(); + } + + Future _carregarPlanosAlimentares() async { + // Simular uma chamada de API + await Future.delayed(Duration(seconds: 2)); + setState(() { + planosAlimentares = [ + PlanoAlimentar( + consulta: 'Consulta 1', + dtInicio: DateTime.now(), + dtFim: DateTime.now().add(Duration(days: 30)), + refeicoes: [ + Refeicao('Café da Manhã', ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), + Refeicao('Almoço', ['150g de frango grelhado', '1 xícara de arroz integral', 'Salada verde']), + Refeicao('Jantar', ['150g de peixe assado', '1 batata doce média', 'Legumes no vapor']), + ], + paciente: widget.pacienteId, + ), + ]; + isLoading = false; + }); + } -class DietScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Color(0xFFF5F5F5), appBar: AppBar( - title: Text('Plano de Dieta'), + title: Text('Plano Alimentar', style: TextStyle(fontWeight: FontWeight.bold)), + backgroundColor: Color(0xFF31BAC2), + elevation: 0, + ), + body: isLoading + ? Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))) + : planosAlimentares.isEmpty + ? _buildEmptyState() + : _buildPlanoAlimentarList(), + floatingActionButton: FloatingActionButton( + onPressed: () { + // TODO: Implementar a criação de um novo plano alimentar + }, + child: Icon(Icons.add), + backgroundColor: Color(0xFF31BAC2), ), - body: Center( - child: Text('Aqui está o seu plano de dieta!'), + ); + } + + Widget _buildEmptyState() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.no_meals, size: 80, color: Color(0xFF31BAC2)), + SizedBox(height: 16), + Text( + 'Nenhum plano alimentar encontrado', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text( + 'Clique no botão + para adicionar um novo plano', + style: TextStyle(color: Colors.grey[600]), + ), + ], + ), + ); + } + + Widget _buildPlanoAlimentarList() { + return ListView.builder( + itemCount: planosAlimentares.length, + itemBuilder: (context, index) { + final plano = planosAlimentares[index]; + return Card( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: ExpansionTile( + title: Text( + plano.consulta, + style: TextStyle(fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + ), + subtitle: Text( + '${DateFormat('dd/MM/yyyy').format(plano.dtInicio)} - ${DateFormat('dd/MM/yyyy').format(plano.dtFim)}', + style: TextStyle(color: Colors.grey[600]), + ), + children: plano.refeicoes.map((refeicao) => _buildRefeicaoItem(refeicao)).toList(), + ), + ); + }, + ); + } + + Widget _buildRefeicaoItem(Refeicao refeicao) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + refeicao.nome, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + SizedBox(height: 4), + ...refeicao.alimentos.map((alimento) => Padding( + padding: const EdgeInsets.only(left: 16, top: 2), + child: Text('• $alimento'), + )), + ], ), ); } } + +class PlanoAlimentar { + final String consulta; + final DateTime dtInicio; + final DateTime dtFim; + final List refeicoes; + final String paciente; + + PlanoAlimentar({ + required this.consulta, + required this.dtInicio, + required this.dtFim, + required this.refeicoes, + required this.paciente, + }); +} + +class Refeicao { + final String nome; + final List alimentos; + + Refeicao(this.nome, this.alimentos); +} + diff --git a/healthway_app/lib/screens_patient/profileScreen.dart b/healthway_app/lib/screens_patient/profileScreen.dart index 2d5697a..42b2094 100644 --- a/healthway_app/lib/screens_patient/profileScreen.dart +++ b/healthway_app/lib/screens_patient/profileScreen.dart @@ -1,8 +1,26 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:intl/intl.dart'; -class PatientProfileScreen extends StatelessWidget { +class PatientProfileScreen extends StatefulWidget { const PatientProfileScreen({Key? key}) : super(key: key); + @override + _PatientProfileScreenState createState() => _PatientProfileScreenState(); +} + +class _PatientProfileScreenState extends State { + bool _isEditing = false; + final _formKey = GlobalKey(); + + // Mock data - replace with actual data fetching in a real app + String name = 'João Silva'; + String email = 'joao.silva@email.com'; + int age = 35; + double height = 1.75; + double weight = 70.0; + String objective = 'Manutenção de peso'; + @override Widget build(BuildContext context) { return Scaffold( @@ -11,24 +29,51 @@ class PatientProfileScreen extends StatelessWidget { title: const Text('Meu Perfil'), backgroundColor: const Color(0xFF31BAC2), elevation: 0, + actions: [ + IconButton( + icon: Icon(_isEditing ? Icons.close : Icons.edit), + onPressed: () { + setState(() { + if (_isEditing) { + // Discard changes + _isEditing = false; + } else { + _isEditing = true; + } + }); + }, + ), + ], ), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildProfileHeader(), - SizedBox(height: 24), - _buildInfoSection(), - SizedBox(height: 24), - _buildActionButtons(), - SizedBox(height: 24), - _buildHealthMetrics(), - ], + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildProfileHeader(), + SizedBox(height: 24), + _buildInfoSection(), + SizedBox(height: 24), + _buildActionButtons(), + SizedBox(height: 24), + _buildHealthMetrics(), + SizedBox(height: 24), + _buildProgressChart(), + ], + ), ), ), ), + floatingActionButton: _isEditing + ? FloatingActionButton( + onPressed: _saveChanges, + backgroundColor: Color(0xFF31BAC2), + child: Icon(Icons.save), + ) + : null, ); } @@ -36,23 +81,61 @@ class PatientProfileScreen extends StatelessWidget { return Center( child: Column( children: [ - CircleAvatar( - radius: 60, - backgroundColor: Color(0xFF31BAC2), - child: Icon( - Icons.person, - size: 60, - color: Colors.white, - ), + Stack( + alignment: Alignment.bottomRight, + children: [ + CircleAvatar( + radius: 60, + backgroundColor: Color(0xFF31BAC2), + backgroundImage: NetworkImage('https://example.com/profile_image.jpg'), + child: Text( + name.isNotEmpty ? name[0].toUpperCase() : '?', + style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white), + ), + ), + if (!_isEditing) + Container( + decoration: BoxDecoration( + color: Color(0xFF31BAC2), + shape: BoxShape.circle, + ), + child: IconButton( + icon: Icon(Icons.camera_alt, color: Colors.white), + onPressed: () { + // Implement image picking functionality + }, + ), + ), + ], ), SizedBox(height: 16), - Text( - 'João Silva', + _isEditing + ? TextFormField( + initialValue: name, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => name = value, + ) + : Text( + name, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), SizedBox(height: 8), - Text( - 'joao.silva@email.com', + _isEditing + ? TextFormField( + initialValue: email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => email = value, + ) + : Text( + email, style: TextStyle(fontSize: 16, color: Colors.grey[600]), ), ], @@ -67,25 +150,39 @@ class PatientProfileScreen extends StatelessWidget { padding: const EdgeInsets.all(16.0), child: Column( children: [ - _buildInfoRow('Idade', '35 anos'), - _buildInfoRow('Altura', '1.75 m'), - _buildInfoRow('Peso', '70 kg'), - _buildInfoRow('IMC', '22.9 (Normal)'), - _buildInfoRow('Objetivo', 'Manutenção de peso'), + _buildInfoRow('Idade', '$age anos', (value) => age = int.parse(value)), + _buildInfoRow('Altura', '${height.toStringAsFixed(2)} m', (value) => height = double.parse(value)), + _buildInfoRow('Peso', '${weight.toStringAsFixed(1)} kg', (value) => weight = double.parse(value)), + _buildInfoRow('IMC', '${_calculateBMI().toStringAsFixed(1)} (${_getBMICategory()})', null), + _buildInfoRow('Objetivo', objective, (value) => objective = value), ], ), ), ); } - Widget _buildInfoRow(String label, String value) { + Widget _buildInfoRow(String label, String value, Function(String)? onChanged) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: TextStyle(fontSize: 16, color: Colors.grey[600])), - Text(value, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + _isEditing && onChanged != null + ? SizedBox( + width: 120, + child: TextFormField( + initialValue: value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + textAlign: TextAlign.right, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: onChanged, + ), + ) + : Text(value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ], ), ); @@ -96,26 +193,27 @@ class PatientProfileScreen extends StatelessWidget { children: [ ElevatedButton( onPressed: () { - // Editar perfil + // Navigate to detailed edit profile screen }, style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), ), - child: Text('Editar Perfil'), + child: Text('Editar Perfil Detalhado'), ), SizedBox(height: 12), OutlinedButton( onPressed: () { - // Alterar senha + // Navigate to change password screen }, - child: Text('Alterar Senha'), style: OutlinedButton.styleFrom( - foregroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), + foregroundColor: Color(0xFF31BAC2), + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), side: BorderSide(color: Color(0xFF31BAC2)), ), + child: Text('Alterar Senha'), ), ], ); @@ -151,10 +249,70 @@ class PatientProfileScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: TextStyle(fontSize: 16)), - Text(value, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2))), + Text(value, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xFF31BAC2))), ], ), ); } + + Widget _buildProgressChart() { + return Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Progresso de Peso', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox(height: 16), + Container( + height: 200, + child: _buildWeightChart(), + ), + ], + ), + ), + ); + } + + Widget _buildWeightChart() { + // This is a placeholder for the chart + // You should implement an actual chart using a charting library + return Center( + child: Text('Gráfico de Progresso de Peso'), + ); + } + + void _saveChanges() { + if (_formKey.currentState!.validate()) { + // Save the changes + setState(() { + _isEditing = false; + }); + // Show a snackbar to confirm changes + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Perfil atualizado com sucesso!')), + ); + } + } + + double _calculateBMI() { + return weight / (height * height); + } + + String _getBMICategory() { + double bmi = _calculateBMI(); + if (bmi < 18.5) return 'Abaixo do peso'; + if (bmi < 25) return 'Normal'; + if (bmi < 30) return 'Sobrepeso'; + return 'Obeso'; + } } diff --git a/healthway_app/lib/widgets/rating_stars.dart b/healthway_app/lib/widgets/rating_stars.dart new file mode 100644 index 0000000..b7ff497 --- /dev/null +++ b/healthway_app/lib/widgets/rating_stars.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +class RatingStars extends StatelessWidget { + final double rating; + final double size; + final Color color; + + const RatingStars({ + super.key, + required this.rating, + this.size = 24, + this.color = Colors.amber, + }); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: List.generate(5, (index) { + if (index < rating.floor()) { + return Icon(Icons.star, size: size, color: color); + } else if (index < rating.ceil() && rating % 1 != 0) { + return Icon(Icons.star_half, size: size, color: color); + } else { + return Icon(Icons.star_border, size: size, color: color); + } + }), + ); + } +} + diff --git a/healthway_app/lib/widgets/review_card.dart b/healthway_app/lib/widgets/review_card.dart new file mode 100644 index 0000000..3a3277b --- /dev/null +++ b/healthway_app/lib/widgets/review_card.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'rating_stars.dart'; + +class ReviewCard extends StatelessWidget { + final String authorName; + final double rating; + final String comment; + final String date; + + const ReviewCard({ + super.key, + required this.authorName, + required this.rating, + required this.comment, + required this.date, + }); + + @override + Widget build(BuildContext context) { + return Card( + margin: EdgeInsets.symmetric(vertical: 8), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + authorName, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + Text( + date, + style: TextStyle(color: Colors.grey[600], fontSize: 14), + ), + ], + ), + SizedBox(height: 4), + RatingStars(rating: rating, size: 18), + SizedBox(height: 8), + Text( + comment, + style: TextStyle(fontSize: 14), + ), + ], + ), + ), + ); + } +} + diff --git a/healthway_app/pubspec.yaml b/healthway_app/pubspec.yaml index 853ce56..9215c46 100644 --- a/healthway_app/pubspec.yaml +++ b/healthway_app/pubspec.yaml @@ -31,8 +31,9 @@ dependencies: flutter: sdk: flutter http: ^1.2.2 - intl: ^0.17.0 image_picker: ^0.8.7+5 + table_calendar: ^3.0.9 + intl: ^0.18.0 # The following adds the Cupertino Icons font to your application. From bc5632234ec1749ec3c2f9eb66a7712dad30b10e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kau=C3=A3=20Marques?= Date: Thu, 9 Jan 2025 16:26:20 -0300 Subject: [PATCH 09/47] Fazendo as telas de login e deixando funcionais --- .../plugins/GeneratedPluginRegistrant.java | 15 +++ .../ios/Flutter/flutter_export_environment.sh | 4 +- .../ios/Runner/GeneratedPluginRegistrant.m | 21 ++++ .../lib/geral_screens/forgot_screen.dart | 0 .../lib/geral_screens/presentationScreen.dart | 6 +- .../meal_plan_screen.dart | 46 +++++--- .../nutritionist_profile.dart | 107 ++++++++++-------- healthway_app/lib/services/auth_service.dart | 52 +++++++++ .../Flutter/GeneratedPluginRegistrant.swift | 6 + healthway_app/pubspec.yaml | 2 + .../flutter/generated_plugin_registrant.cc | 9 ++ .../windows/flutter/generated_plugins.cmake | 3 + 12 files changed, 199 insertions(+), 72 deletions(-) create mode 100644 healthway_app/lib/geral_screens/forgot_screen.dart create mode 100644 healthway_app/lib/services/auth_service.dart diff --git a/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index ec061d9..f6a3c39 100644 --- a/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -15,6 +15,21 @@ public final class GeneratedPluginRegistrant { private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin cloud_firestore, io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin", e); + } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin firebase_auth, io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin", e); + } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e); + } try { flutterEngine.getPlugins().add(new io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin()); } catch (Exception e) { diff --git a/healthway_app/ios/Flutter/flutter_export_environment.sh b/healthway_app/ios/Flutter/flutter_export_environment.sh index 91c916d..770f09b 100755 --- a/healthway_app/ios/Flutter/flutter_export_environment.sh +++ b/healthway_app/ios/Flutter/flutter_export_environment.sh @@ -1,7 +1,7 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/opt/flutter" -export "FLUTTER_APPLICATION_PATH=/home/kaua/AndroidStudioProjects/Healthway/healthway_app" +export "FLUTTER_ROOT=/home/kaua/flutter" +export "FLUTTER_APPLICATION_PATH=/home/kaua/VSCode/Healthway/healthway_app" export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" diff --git a/healthway_app/ios/Runner/GeneratedPluginRegistrant.m b/healthway_app/ios/Runner/GeneratedPluginRegistrant.m index ed39389..4c3a2fb 100644 --- a/healthway_app/ios/Runner/GeneratedPluginRegistrant.m +++ b/healthway_app/ios/Runner/GeneratedPluginRegistrant.m @@ -6,6 +6,24 @@ #import "GeneratedPluginRegistrant.h" +#if __has_include() +#import +#else +@import cloud_firestore; +#endif + +#if __has_include() +#import +#else +@import firebase_auth; +#endif + +#if __has_include() +#import +#else +@import firebase_core; +#endif + #if __has_include() #import #else @@ -15,6 +33,9 @@ @implementation GeneratedPluginRegistrant + (void)registerWithRegistry:(NSObject*)registry { + [FLTFirebaseFirestorePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseFirestorePlugin"]]; + [FLTFirebaseAuthPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseAuthPlugin"]]; + [FLTFirebaseCorePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTFirebaseCorePlugin"]]; [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]]; } diff --git a/healthway_app/lib/geral_screens/forgot_screen.dart b/healthway_app/lib/geral_screens/forgot_screen.dart new file mode 100644 index 0000000..e69de29 diff --git a/healthway_app/lib/geral_screens/presentationScreen.dart b/healthway_app/lib/geral_screens/presentationScreen.dart index 8c5c65f..a44cd29 100644 --- a/healthway_app/lib/geral_screens/presentationScreen.dart +++ b/healthway_app/lib/geral_screens/presentationScreen.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; +import 'package:healthway_app/geral_screens/loginScreen.dart'; import 'dart:async'; -import 'package:healthway_app/screens_patient//dashboardScreen.dart'; - class PresentationScreen extends StatefulWidget { const PresentationScreen({super.key}); @@ -36,7 +34,7 @@ class _PresentationScreenState extends State // Navegar para a próxima tela após a animação Timer(Duration(seconds: 3), () { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => NutritionistDashboardScreen()), + MaterialPageRoute(builder: (_) => LoginScreen()), ); }); } diff --git a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart index 4959a89..92ee121 100644 --- a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart +++ b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart @@ -18,11 +18,22 @@ class MealPlanScreen extends StatelessWidget { child: ListView( padding: const EdgeInsets.all(16.0), children: [ - _buildMealCard('Café da Manhã', ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), - _buildMealCard('Lanche da Manhã', ['1 iogurte natural', '1 punhado de castanhas']), - _buildMealCard('Almoço', ['150g de frango grelhado', '1 xícara de arroz integral', 'Salada verde']), - _buildMealCard('Lanche da Tarde', ['1 banana', '1 colher de sopa de pasta de amendoim']), - _buildMealCard('Jantar', ['150g de peixe assado', '1 batata doce média', 'Legumes no vapor']), + _buildMealCard('Café da Manhã', + ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), + _buildMealCard('Lanche da Manhã', + ['1 iogurte natural', '1 punhado de castanhas']), + _buildMealCard('Almoço', [ + '150g de frango grelhado', + '1 xícara de arroz integral', + 'Salada verde' + ]), + _buildMealCard('Lanche da Tarde', + ['1 banana', '1 colher de sopa de pasta de amendoim']), + _buildMealCard('Jantar', [ + '150g de peixe assado', + '1 batata doce média', + 'Legumes no vapor' + ]), SizedBox(height: 16), ElevatedButton( onPressed: () { @@ -57,23 +68,26 @@ class MealPlanScreen extends StatelessWidget { children: [ Text( mealName, - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Color(0xFF31BAC2)), ), SizedBox(height: 8), ...foods.map((food) => Padding( - padding: const EdgeInsets.only(bottom: 4), - child: Row( - children: [ - Icon(Icons.fiber_manual_record, size: 8, color: Color(0xFF31BAC2)), - SizedBox(width: 8), - Text(food, style: TextStyle(fontSize: 16)), - ], - ), - )).toList(), + padding: const EdgeInsets.only(bottom: 4), + child: Row( + children: [ + Icon(Icons.fiber_manual_record, + size: 8, color: Color(0xFF31BAC2)), + SizedBox(width: 8), + Text(food, style: TextStyle(fontSize: 16)), + ], + ), + )), ], ), ), ); } } - diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart index 7b07721..4b7cc11 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; class NutritionistProfileScreen extends StatefulWidget { const NutritionistProfileScreen({super.key}); @override - _NutritionistProfileScreenState createState() => _NutritionistProfileScreenState(); + _NutritionistProfileScreenState createState() => + _NutritionistProfileScreenState(); } class _NutritionistProfileScreenState extends State { @@ -67,10 +67,10 @@ class _NutritionistProfileScreenState extends State { ), floatingActionButton: _isEditing ? FloatingActionButton( - onPressed: _saveChanges, - backgroundColor: Color(0xFF31BAC2), - child: Icon(Icons.save), - ) + onPressed: _saveChanges, + backgroundColor: Color(0xFF31BAC2), + child: Icon(Icons.save), + ) : null, ); } @@ -88,9 +88,12 @@ class _NutritionistProfileScreenState extends State { backgroundImage: NetworkImage(fotoPerfil), child: fotoPerfil.isEmpty ? Text( - nome.isNotEmpty ? nome[0].toUpperCase() : '?', - style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white), - ) + nome.isNotEmpty ? nome[0].toUpperCase() : '?', + style: TextStyle( + fontSize: 40, + fontWeight: FontWeight.bold, + color: Colors.white), + ) : null, ), if (!_isEditing) @@ -111,33 +114,33 @@ class _NutritionistProfileScreenState extends State { SizedBox(height: 16), _isEditing ? TextFormField( - initialValue: nome, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - textAlign: TextAlign.center, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: (value) => nome = value, - ) + initialValue: nome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => nome = value, + ) : Text( - nome, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), + nome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), SizedBox(height: 8), _isEditing ? TextFormField( - initialValue: email, - style: TextStyle(fontSize: 16, color: Colors.grey[600]), - textAlign: TextAlign.center, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: (value) => email = value, - ) + initialValue: email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => email = value, + ) : Text( - email, - style: TextStyle(fontSize: 16, color: Colors.grey[600]), - ), + email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + ), ], ), ); @@ -152,7 +155,8 @@ class _NutritionistProfileScreenState extends State { children: [ _buildInfoRow('CPF', cpf, (value) => cpf = value), _buildInfoRow('CRN', crn, (value) => crn = value), - _buildInfoRow('Especialidade', especialidade, (value) => especialidade = value), + _buildInfoRow('Especialidade', especialidade, + (value) => especialidade = value), ], ), ), @@ -166,21 +170,21 @@ class _NutritionistProfileScreenState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: TextStyle(fontSize: 16, color: Colors.grey[600])), - _isEditing && onChanged != null + _isEditing ? SizedBox( - width: 200, - child: TextFormField( - initialValue: value, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), - textAlign: TextAlign.right, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: onChanged, - ), - ) + width: 200, + child: TextFormField( + initialValue: value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + textAlign: TextAlign.right, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: onChanged, + ), + ) : Text(value, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ], ), ); @@ -196,7 +200,8 @@ class _NutritionistProfileScreenState extends State { style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), ), child: Text('Editar Perfil Detalhado'), ), @@ -206,8 +211,10 @@ class _NutritionistProfileScreenState extends State { // Navigate to change password screen }, style: OutlinedButton.styleFrom( - foregroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + foregroundColor: Color(0xFF31BAC2), + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), side: BorderSide(color: Color(0xFF31BAC2)), ), child: Text('Alterar Senha'), @@ -246,7 +253,8 @@ class _NutritionistProfileScreenState extends State { ), ), child: fotoDocumento.isEmpty - ? Icon(Icons.add_a_photo, size: 50, color: Color(0xFF31BAC2)) + ? Icon(Icons.add_a_photo, + size: 50, color: Color(0xFF31BAC2)) : null, ), ), @@ -270,4 +278,3 @@ class _NutritionistProfileScreenState extends State { } } } - diff --git a/healthway_app/lib/services/auth_service.dart b/healthway_app/lib/services/auth_service.dart new file mode 100644 index 0000000..a908d18 --- /dev/null +++ b/healthway_app/lib/services/auth_service.dart @@ -0,0 +1,52 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; + +enum UserType { patient, nutritionist } + +class AuthService { + static final FirebaseAuth _auth = FirebaseAuth.instance; + static final FirebaseFirestore _firestore = FirebaseFirestore.instance; + + static Future signIn(String email, String password) async { + try { + UserCredential result = await _auth.signInWithEmailAndPassword( + email: email, + password: password, + ); + User? user = result.user; + + if (user != null) { + // Check if the user is a patient or nutritionist + DocumentSnapshot patientDoc = + await _firestore.collection('paciente').doc(user.uid).get(); + if (patientDoc.exists) { + return UserType.patient; + } + + DocumentSnapshot nutritionistDoc = + await _firestore.collection('nutricionista').doc(user.uid).get(); + if (nutritionistDoc.exists) { + return UserType.nutritionist; + } + + // If user is neither patient nor nutritionist, sign out and throw an error + await _auth.signOut(); + throw Exception( + 'Usuário não encontrado como paciente ou nutricionista'); + } + + throw Exception('Falha ao fazer login'); + } catch (e) { + print(e.toString()); + throw Exception('Falha ao fazer login: ${e.toString()}'); + } + } + + static Future signOut() async { + await _auth.signOut(); + } + + static Future resetPassword(String email) async { + await _auth.sendPasswordResetEmail(email: email); + } +} diff --git a/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift b/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift index 14b5f7c..0235908 100644 --- a/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,8 +5,14 @@ import FlutterMacOS import Foundation +import cloud_firestore import file_selector_macos +import firebase_auth +import firebase_core func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) } diff --git a/healthway_app/pubspec.yaml b/healthway_app/pubspec.yaml index 9215c46..8fb7393 100644 --- a/healthway_app/pubspec.yaml +++ b/healthway_app/pubspec.yaml @@ -39,6 +39,8 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 + firebase_auth: ^5.4.0 + cloud_firestore: ^5.6.1 dev_dependencies: flutter_test: diff --git a/healthway_app/windows/flutter/generated_plugin_registrant.cc b/healthway_app/windows/flutter/generated_plugin_registrant.cc index 77ab7a0..4a46c81 100644 --- a/healthway_app/windows/flutter/generated_plugin_registrant.cc +++ b/healthway_app/windows/flutter/generated_plugin_registrant.cc @@ -6,9 +6,18 @@ #include "generated_plugin_registrant.h" +#include #include +#include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + CloudFirestorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); + FirebaseAuthPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); } diff --git a/healthway_app/windows/flutter/generated_plugins.cmake b/healthway_app/windows/flutter/generated_plugins.cmake index a423a02..e0beee3 100644 --- a/healthway_app/windows/flutter/generated_plugins.cmake +++ b/healthway_app/windows/flutter/generated_plugins.cmake @@ -3,7 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST + cloud_firestore file_selector_windows + firebase_auth + firebase_core ) list(APPEND FLUTTER_FFI_PLUGIN_LIST From 7e89af8134d80762169c2318dd4d4285d305c225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kau=C3=A3=20Marques?= Date: Thu, 9 Jan 2025 17:06:51 -0300 Subject: [PATCH 10/47] resolvendo problemas --- .../lib/geral_screens/loginScreen.dart | 110 ++++++++++-------- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index 979a454..8f06fa7 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:healthway_app/geral_screens/forgot_screen.dart'; +import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; +import 'package:healthway_app/screens_patient/dashboardScreen.dart'; import 'package:healthway_app/screens_patient/signupScreen.dart'; -import 'package:healthway_app/screens_nutricionist/signUpNutritionist.dart'; +import 'package:healthway_app/services/auth_service.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @@ -12,13 +15,14 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { final _formKey = GlobalKey(); final _emailController = TextEditingController(); - final _senhaController = TextEditingController(); + final _passwordController = TextEditingController(); bool _obscurePassword = true; + bool _isLoading = false; @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFE6F7F8), // Tom muito claro de azul + backgroundColor: Color(0xFFE6F7F8), appBar: AppBar( title: Text('Login', style: TextStyle(fontWeight: FontWeight.bold)), backgroundColor: Color(0xFF31BAC2), @@ -47,7 +51,8 @@ class _LoginScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildTextField(_emailController, 'E-mail', Icons.email, keyboardType: TextInputType.emailAddress), + _buildTextField(_emailController, 'E-mail', Icons.email, + keyboardType: TextInputType.emailAddress), SizedBox(height: 20), _buildPasswordField(), SizedBox(height: 20), @@ -55,8 +60,7 @@ class _LoginScreenState extends State { SizedBox(height: 30), _buildLoginButton(), SizedBox(height: 20), - _buildPatientButton(), - _buildNutricionistButton(), + _buildSignUpButton(), ], ), ), @@ -67,7 +71,9 @@ class _LoginScreenState extends State { ); } - Widget _buildTextField(TextEditingController controller, String label, IconData icon, {TextInputType? keyboardType}) { + Widget _buildTextField( + TextEditingController controller, String label, IconData icon, + {TextInputType? keyboardType}) { return TextFormField( controller: controller, decoration: InputDecoration( @@ -95,7 +101,7 @@ class _LoginScreenState extends State { Widget _buildPasswordField() { return TextFormField( - controller: _senhaController, + controller: _passwordController, obscureText: _obscurePassword, decoration: InputDecoration( labelText: 'Senha', @@ -130,72 +136,82 @@ class _LoginScreenState extends State { ); } - Widget _buildForgotPasswordButton() { - return Align( - alignment: Alignment.centerRight, - child: TextButton( - onPressed: () { - // TODO: Implementar lógica para recuperação de senha - }, - child: Text( - 'Esqueceu a senha?', - style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), - ), - ), - ); - } - Widget _buildLoginButton() { return ElevatedButton( - onPressed: _submitForm, + onPressed: _isLoading ? null : _submitForm, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), + foregroundColor: Colors.white, + backgroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), ), - child: Text('Entrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), - ); - } - - Widget _buildPatientButton() { - return TextButton( - onPressed: () { - MaterialPageRoute(builder: (_) => CadastroPacienteScreen()); - }, - child: Text( - 'Sou paciente', - style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), - ), + child: _isLoading + ? CircularProgressIndicator(color: Colors.white) + : Text('Entrar', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ); } - Widget _buildNutricionistButton() { + Widget _buildSignUpButton() { return TextButton( onPressed: () { - MaterialPageRoute(builder: (_) => CadastroNutricionistaScreen()); + Navigator.push( + context, + MaterialPageRoute(builder: (context) => CadastroPacienteScreen()), + ); }, child: Text( - 'Sou nutricionista', + 'Não tem uma conta? Cadastre-se', style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), ), ); } - void _submitForm() { + void _submitForm() async { if (_formKey.currentState!.validate()) { - // TODO: Implementar lógica de autenticação - print('Form is valid. Submitting...'); - // Você normalmente chamaria um método de serviço aqui para autenticar o usuário + setState(() { + _isLoading = true; + }); + + try { + final userType = await AuthService.signIn( + _emailController.text, + _passwordController.text, + ); + + setState(() { + _isLoading = false; + }); + + if (userType == UserType.patient) { + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => PatientDashboardScreen()), + ); + } else if (userType == UserType.nutritionist) { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => NutritionistDashboardScreen()), + ); + } + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Erro ao fazer login: ${e.toString()}')), + ); + } } } @override void dispose() { _emailController.dispose(); - _senhaController.dispose(); + _passwordController.dispose(); super.dispose(); } } - From 31145050aa5d05229d6496445a2bda3320e6c6f9 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Sun, 12 Jan 2025 10:06:50 -0300 Subject: [PATCH 11/47] a --- healthway_app/lib/geral_screens/loginScreen.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index 8f06fa7..f0ec7fb 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -215,3 +215,13 @@ class _LoginScreenState extends State { super.dispose(); } } + +_buildForgotPasswordButton() { + return TextButton( + onPressed: () { }, + child: Text( + 'Esqueceu sua senha?', + style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + ), + ); +} From e611a34261837007be79e60a93e14dd31a70e66d Mon Sep 17 00:00:00 2001 From: lucasherlon Date: Thu, 16 Jan 2025 08:26:16 -0300 Subject: [PATCH 12/47] feat: criando endpoint getAlimentosByCategoria #64 --- backend/controllers/alimentoController.js | 28 ++++- backend/package-lock.json | 141 +--------------------- 2 files changed, 28 insertions(+), 141 deletions(-) diff --git a/backend/controllers/alimentoController.js b/backend/controllers/alimentoController.js index 5d90b79..413b906 100644 --- a/backend/controllers/alimentoController.js +++ b/backend/controllers/alimentoController.js @@ -35,7 +35,7 @@ const alimentoController = { res.status(500).json({ error: error.message }); } }, - + //Obter um alimento pelo ID async getById(req, res){ try { @@ -74,7 +74,31 @@ const alimentoController = { } catch (error) { res.status(500).json({ error: error.message }); } - } + }, + + async getByCategory(req, res) { + try { + const { nome } = req.params; + + const startAt = nome; + const endAt = nome + '\uf8ff'; + + const snapshot = await db.collection('alimentos') + .orderBy('Categoria') + .startAt(startAt) + .endAt(endAt) + .get(); + + if (snapshot.empty) { + return res.status(404).json({ message: 'Nenhum alimento encontrado nessa categoria.' }); + } + + const alimentos = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + res.status(200).json(alimentos); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, }; module.exports = alimentoController; diff --git a/backend/package-lock.json b/backend/package-lock.json index 1c4c6dd..e4a7bde 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1703,8 +1703,6 @@ "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "license": "MIT", -<<<<<<< Updated upstream -======= "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -1826,144 +1824,9 @@ } }, "node_modules/backend": { - "version": "1.0.0", - "resolved": "file:", - "license": "ISC", ->>>>>>> Stashed changes - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, -<<<<<<< Updated upstream - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", - "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/backend": { - "version": "1.0.0", - "resolved": "file:", - "license": "ISC", - "dependencies": { - "backend": "file:", - "dotenv": "^16.4.5", - "express": "^4.21.1", - "firebase-admin": "^13.0.0" - } + "resolved": "", + "link": true }, -======= ->>>>>>> Stashed changes "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", From 96f091a9337cee7ebee82710763d13cc80dd9a8a Mon Sep 17 00:00:00 2001 From: LEMUEL CAVALCANTE Date: Thu, 16 Jan 2025 09:41:54 -0300 Subject: [PATCH 13/47] integracao e estilizacao da tela de alimentos --- healthway_app/ios/Flutter/Debug.xcconfig | 1 + healthway_app/ios/Flutter/Release.xcconfig | 1 + .../ios/Flutter/flutter_export_environment.sh | 8 +- healthway_app/ios/Podfile | 44 ++++++ healthway_app/ios/Podfile.lock | 22 +++ .../ios/Runner.xcodeproj/project.pbxproj | 112 +++++++++++++++ .../contents.xcworkspacedata | 3 + .../lib/geral_screens/alimentos_screen.dart | 20 +-- healthway_app/lib/main.dart | 2 + healthway_app/lib/models/alimento.dart | 81 ++++++++--- .../nutritionist_dashboard.dart | 2 +- .../lib/services/alimento_services.dart | 37 ++--- healthway_app/lib/widgets/alimento_item.dart | 133 +++++++++++------- .../macos/Flutter/Flutter-Debug.xcconfig | 1 + .../macos/Flutter/Flutter-Release.xcconfig | 1 + healthway_app/macos/Podfile | 43 ++++++ 16 files changed, 401 insertions(+), 110 deletions(-) create mode 100644 healthway_app/ios/Podfile create mode 100644 healthway_app/ios/Podfile.lock create mode 100644 healthway_app/macos/Podfile diff --git a/healthway_app/ios/Flutter/Debug.xcconfig b/healthway_app/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/healthway_app/ios/Flutter/Debug.xcconfig +++ b/healthway_app/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/healthway_app/ios/Flutter/Release.xcconfig b/healthway_app/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/healthway_app/ios/Flutter/Release.xcconfig +++ b/healthway_app/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/healthway_app/ios/Flutter/flutter_export_environment.sh b/healthway_app/ios/Flutter/flutter_export_environment.sh index 91c916d..9f63276 100755 --- a/healthway_app/ios/Flutter/flutter_export_environment.sh +++ b/healthway_app/ios/Flutter/flutter_export_environment.sh @@ -1,13 +1,13 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/opt/flutter" -export "FLUTTER_APPLICATION_PATH=/home/kaua/AndroidStudioProjects/Healthway/healthway_app" +export "FLUTTER_ROOT=/Users/lemuelcavalcante/Documents/development/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app" export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_TARGET=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app/lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=true" export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=.dart_tool/package_config.json" +export "PACKAGE_CONFIG=/Users/lemuelcavalcante/Documents/engenharia2/Healthway/healthway_app/.dart_tool/package_config.json" diff --git a/healthway_app/ios/Podfile b/healthway_app/ios/Podfile new file mode 100644 index 0000000..d97f17e --- /dev/null +++ b/healthway_app/ios/Podfile @@ -0,0 +1,44 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '12.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/healthway_app/ios/Podfile.lock b/healthway_app/ios/Podfile.lock new file mode 100644 index 0000000..c7be6e0 --- /dev/null +++ b/healthway_app/ios/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - Flutter (1.0.0) + - image_picker_ios (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + image_picker_ios: + :path: ".symlinks/plugins/image_picker_ios/ios" + +SPEC CHECKSUMS: + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 + +PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 + +COCOAPODS: 1.15.2 diff --git a/healthway_app/ios/Runner.xcodeproj/project.pbxproj b/healthway_app/ios/Runner.xcodeproj/project.pbxproj index 8645f75..455e023 100644 --- a/healthway_app/ios/Runner.xcodeproj/project.pbxproj +++ b/healthway_app/ios/Runner.xcodeproj/project.pbxproj @@ -11,9 +11,11 @@ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 8A896C6F34CEA5B3F1AF1547 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF74FA70F4800FD0CA06786D /* Pods_RunnerTests.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + E274567C7BBB479B2C69C96D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 304AEE3071F61786454BA8E0 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -42,12 +44,16 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2630F51167F9BFA2AD8E8AB6 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 2A0552A13A003D376D9E22B8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 304AEE3071F61786454BA8E0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9065F4484FADA14F9F4029CD /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -55,19 +61,55 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DFA0F05E491EBF421843DFE7 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + EF74FA70F4800FD0CA06786D /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F07D98ECE89B04072F1C31CD /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + F2B393BD2F3FD6C39388BEC2 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 27D2106E7B7874E299080376 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8A896C6F34CEA5B3F1AF1547 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E274567C7BBB479B2C69C96D /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0D2B2E9BC32BE0B401DFAD58 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 304AEE3071F61786454BA8E0 /* Pods_Runner.framework */, + EF74FA70F4800FD0CA06786D /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 0FC1C04FFCBF27C438DD23C1 /* Pods */ = { + isa = PBXGroup; + children = ( + F2B393BD2F3FD6C39388BEC2 /* Pods-Runner.debug.xcconfig */, + 2A0552A13A003D376D9E22B8 /* Pods-Runner.release.xcconfig */, + DFA0F05E491EBF421843DFE7 /* Pods-Runner.profile.xcconfig */, + 9065F4484FADA14F9F4029CD /* Pods-RunnerTests.debug.xcconfig */, + 2630F51167F9BFA2AD8E8AB6 /* Pods-RunnerTests.release.xcconfig */, + F07D98ECE89B04072F1C31CD /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 331C8082294A63A400263BE5 /* RunnerTests */ = { isa = PBXGroup; children = ( @@ -94,6 +136,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + 0FC1C04FFCBF27C438DD23C1 /* Pods */, + 0D2B2E9BC32BE0B401DFAD58 /* Frameworks */, ); sourceTree = ""; }; @@ -128,8 +172,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 50AD71150355A6D709627D6F /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + 27D2106E7B7874E299080376 /* Frameworks */, ); buildRules = ( ); @@ -145,12 +191,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 49092B28E62835C5CE4E7B88 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 0197F33779076244AEC73E16 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -222,6 +270,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 0197F33779076244AEC73E16 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -238,6 +303,50 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 49092B28E62835C5CE4E7B88 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 50AD71150355A6D709627D6F /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -378,6 +487,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9065F4484FADA14F9F4029CD /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -395,6 +505,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 2630F51167F9BFA2AD8E8AB6 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -410,6 +521,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F07D98ECE89B04072F1C31CD /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; diff --git a/healthway_app/ios/Runner.xcworkspace/contents.xcworkspacedata b/healthway_app/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/healthway_app/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/healthway_app/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/healthway_app/lib/geral_screens/alimentos_screen.dart b/healthway_app/lib/geral_screens/alimentos_screen.dart index 28ae52b..1fd7f80 100644 --- a/healthway_app/lib/geral_screens/alimentos_screen.dart +++ b/healthway_app/lib/geral_screens/alimentos_screen.dart @@ -30,10 +30,11 @@ class _AlimentosScreenState extends State { void _filtrarAlimentos(String query) { setState(() { - alimentosFiltrados = alimentos - .where((alimento) => - alimento.nome.toLowerCase().contains(query.toLowerCase())) - .toList(); + alimentosFiltrados = alimentos.where((alimento) { + final descricaoMatch = alimento.descricao.toLowerCase().contains(query.toLowerCase()); + final categoriaMatch = alimento.categoria.toLowerCase().contains(query.toLowerCase()); + return descricaoMatch || categoriaMatch; + }).toList(); }); } @@ -44,7 +45,9 @@ class _AlimentosScreenState extends State { appBar: AppBar( title: Text('Alimentos'), backgroundColor: Color(0xFF31BAC2), - elevation: 0, + elevation: 5, + // Remover o arredondamento da parte superior do AppBar + shape: null, ), body: Column( children: [ @@ -107,10 +110,12 @@ class _AlimentosScreenState extends State { return Padding( padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Card( - elevation: 2, + elevation: 6, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15), + borderRadius: BorderRadius.circular(20), ), + shadowColor: Colors.black.withOpacity(0.2), + color: Colors.transparent, // Garantir que o fundo do card seja transparente child: AlimentoItem(alimento: alimentosFiltrados[index]), ), ); @@ -156,4 +161,3 @@ class _AlimentosScreenState extends State { ); } } - diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 1f15300..3489325 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/presentationScreen.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; +import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; import 'package:healthway_app/screens_nutricionist/schedule_screen.dart'; @@ -55,6 +56,7 @@ class MyApp extends StatelessWidget { '/patientList': (context) => PatientListScreen(), '/nutritionistProfile': (context) => NutritionistProfileScreen(), '/schedule': (context) => ScheduleScreen(), + '/meal_plans': (context) => MealPlanScreen(patientName: '',), }, ); } diff --git a/healthway_app/lib/models/alimento.dart b/healthway_app/lib/models/alimento.dart index dd33c3c..894c1e2 100644 --- a/healthway_app/lib/models/alimento.dart +++ b/healthway_app/lib/models/alimento.dart @@ -1,34 +1,73 @@ class Alimento { final String id; - final double calorias; - final double carboidratos; - final double proteinas; - final String nome; - final double gordura; - final double peso; - final String porcao; + final String categoria; + final String descricao; + final double umidade; + final double energiaKcal; + final double energiaKj; + final double proteina; + final double lipideos; + final double colesterol; + final double carboidrato; + final double fibraAlimentar; + final double cinzas; + final double calcio; + final double magnesio; + final double manganes; + final double fosforo; + final double ferro; + final double sodio; + final double potassio; + final double cobre; + final double zinco; Alimento({ required this.id, - required this.calorias, - required this.carboidratos, - required this.proteinas, - required this.nome, - required this.gordura, - required this.peso, - required this.porcao, + required this.categoria, + required this.descricao, + required this.umidade, + required this.energiaKcal, + required this.energiaKj, + required this.proteina, + required this.lipideos, + required this.colesterol, + required this.carboidrato, + required this.fibraAlimentar, + required this.cinzas, + required this.calcio, + required this.magnesio, + required this.manganes, + required this.fosforo, + required this.ferro, + required this.sodio, + required this.potassio, + required this.cobre, + required this.zinco, }); factory Alimento.fromJson(Map json) { return Alimento( id: json['id'] ?? '', - calorias: json['calorias']?.toDouble() ?? 0.0, - carboidratos: json['carboidratos']?.toDouble() ?? 0.0, - proteinas: json['proteinas']?.toDouble() ?? 0.0, - nome: json['nome'] ?? '', - gordura: json['gordura']?.toDouble() ?? 0.0, - peso: json['peso']?.toDouble() ?? 0.0, - porcao: json['porcao'] ?? '', + categoria: json['Categoria'] ?? '', + descricao: json['Descrição dos alimentos'] ?? '', + umidade: double.tryParse(json['Umidade (%)']?.toString() ?? '0') ?? 0, + energiaKcal: double.tryParse(json['Energia (Kcal)']?.toString() ?? '0') ?? 0, + energiaKj: double.tryParse(json['Energia (KJ)']?.toString() ?? '0') ?? 0, + proteina: double.tryParse(json['Proteína (g)']?.toString() ?? '0') ?? 0, + lipideos: double.tryParse(json['Lipídeos (g)']?.toString() ?? '0') ?? 0, + colesterol: double.tryParse(json['Colesterol (mg)']?.toString() ?? '0') ?? 0, + carboidrato: double.tryParse(json['Carboidrato (g)']?.toString() ?? '0') ?? 0, + fibraAlimentar: double.tryParse(json['Fibra Alimentar (g)']?.toString() ?? '0') ?? 0, + cinzas: double.tryParse(json['Cinzas (g)']?.toString() ?? '0') ?? 0, + calcio: double.tryParse(json['Cálcio (mg)']?.toString() ?? '0') ?? 0, + magnesio: double.tryParse(json['Magnésio (mg)']?.toString() ?? '0') ?? 0, + manganes: double.tryParse(json['Manganês (mg)']?.toString() ?? '0') ?? 0, + fosforo: double.tryParse(json['Fósforo (mg)']?.toString() ?? '0') ?? 0, + ferro: double.tryParse(json['Ferro (mg)']?.toString() ?? '0') ?? 0, + sodio: double.tryParse(json['Sódio (mg)']?.toString() ?? '0') ?? 0, + potassio: double.tryParse(json['Potássio (mg)']?.toString() ?? '0') ?? 0, + cobre: double.tryParse(json['Cobre (mg)']?.toString() ?? '0') ?? 0, + zinco: double.tryParse(json['Zinco (mg)']?.toString() ?? '0') ?? 0, ); } } diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart index a776dca..5eaf390 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart @@ -143,7 +143,7 @@ class NutritionistDashboardScreen extends StatelessWidget { _buildQuickAccessItem(context, Icons.people, 'Pacientes', '/patientList'), _buildQuickAccessItem(context, Icons.calendar_today, 'Agenda', '/schedule'), _buildQuickAccessItem(context, Icons.restaurant_menu, 'Planos', '/meal_plans'), - _buildQuickAccessItem(context, Icons.message, 'Mensagens', '/chat'), + _buildQuickAccessItem(context, Icons.food_bank_outlined, 'Alimentos', '/alimentos'), ], ), ], diff --git a/healthway_app/lib/services/alimento_services.dart b/healthway_app/lib/services/alimento_services.dart index 5982f11..c3bf657 100644 --- a/healthway_app/lib/services/alimento_services.dart +++ b/healthway_app/lib/services/alimento_services.dart @@ -3,33 +3,20 @@ import 'package:http/http.dart' as http; import '../models/alimento.dart'; class AlimentoService { - static const String apiUrl = 'http://localhost:3000/api/alimentos'; - Future> fetchAlimentos() async { - try { - final response = await http.get(Uri.parse(apiUrl)); - - if (response.statusCode == 200) { - // Decodifica o corpo da resposta para obter a lista de alimentos - List data = json.decode(response.body); + // Fazendo a requisição HTTP para o endpoint da API + final response = await http.get(Uri.parse('http://localhost:3000/api/alimentos')); - // Converte os dados em objetos Alimento, tratando valores nulos - return data - .map((json) { - try { - return Alimento.fromJson(json); - } catch (e) { - print('Erro ao parse JSON: $e'); - return null; // Retorna null caso haja erro na conversão - } - }) - .whereType() - .toList(); // Ignora objetos null - } else { - throw Exception('Falha ao carregar alimentos'); - } - } catch (e) { - throw Exception('Falha ao carregar alimentos: $e'); + // Verificando o status da resposta + if (response.statusCode == 200) { + // Se a requisição for bem-sucedida, parseia o JSON + final List jsonData = json.decode(response.body); + + // Mapeia os dados JSON para objetos Alimento + return jsonData.map((item) => Alimento.fromJson(item)).toList(); + } else { + // Em caso de erro, lança uma exceção + throw Exception('Falha ao carregar os alimentos'); } } } diff --git a/healthway_app/lib/widgets/alimento_item.dart b/healthway_app/lib/widgets/alimento_item.dart index d811a7c..dfa04fe 100644 --- a/healthway_app/lib/widgets/alimento_item.dart +++ b/healthway_app/lib/widgets/alimento_item.dart @@ -4,62 +4,93 @@ import '../models/alimento.dart'; class AlimentoItem extends StatelessWidget { final Alimento alimento; - AlimentoItem({required this.alimento}); + const AlimentoItem({Key? key, required this.alimento}) : super(key: key); @override Widget build(BuildContext context) { - return Card( - margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), - child: ListTile( - contentPadding: EdgeInsets.all(16.0), - leading: Icon(Icons.food_bank), // Ícone do alimento - title: Text( - alimento.nome, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18.0), - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Porção: ${alimento.porcao}'), - Text('Peso: ${alimento.peso}g'), - Text('Calorias: ${alimento.calorias} kcal'), - Text('Carboidratos: ${alimento.carboidratos}g'), - Text('Proteínas: ${alimento.proteinas}g'), - Text('Gordura: ${alimento.gordura}g'), - ], - ), - isThreeLine: true, // Permite que o conteúdo ocupe 3 linhas - onTap: () { - // Ação quando o item é tocado, por exemplo, abrir detalhes - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: Text(alimento.nome), - content: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text('Porção: ${alimento.porcao}'), - Text('Peso: ${alimento.peso}g'), - Text('Calorias: ${alimento.calorias} kcal'), - Text('Carboidratos: ${alimento.carboidratos}g'), - Text('Proteínas: ${alimento.proteinas}g'), - Text('Gordura: ${alimento.gordura}g'), - ], - ), - actions: [ - TextButton( - child: Text('Fechar'), - onPressed: () { - Navigator.of(context).pop(); - }, + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + elevation: 3, + shadowColor: Colors.black.withOpacity(0.1), // Sombra suave + color: Colors.white, // Cor de fundo do card + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Título com nome e categoria do alimento + Row( + children: [ + Icon(Icons.fastfood, color: Color(0xFF31BAC2)), // Ícone de comida + const SizedBox(width: 8), + Expanded( + child: Text( + alimento.descricao, + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black87), + ), ), ], - ); - }, - ); - }, + ), + const SizedBox(height: 8), + Text( + 'Categoria: ${alimento.categoria}', + style: TextStyle(color: Colors.grey[700]), // Cor mais suave para a categoria + ), + const Divider(), // Linha separadora + + // Informações nutricionais + _buildNutritionalInfo(), + ], + ), + ), + ), + ); + } + + // Função que constrói a listagem das informações nutricionais + Widget _buildNutritionalInfo() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Informações Nutricionais:', + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + const SizedBox(height: 8), + _buildNutritionalItem('Calorias', alimento.energiaKcal, 'Kcal'), + _buildNutritionalItem('Carboidrato', alimento.carboidrato, 'g'), + _buildNutritionalItem('Proteína', alimento.proteina, 'g'), + _buildNutritionalItem('Lipídeos', alimento.lipideos, 'g'), + _buildNutritionalItem('Fibra Alimentar', alimento.fibraAlimentar, 'g'), + if (alimento.colesterol != null) + _buildNutritionalItem('Colesterol', alimento.colesterol, 'mg'), + _buildNutritionalItem('Cálcio', alimento.calcio, 'mg'), + _buildNutritionalItem('Ferro', alimento.ferro, 'mg'), + _buildNutritionalItem('Potássio', alimento.potassio, 'mg'), + _buildNutritionalItem('Magnésio', alimento.magnesio, 'mg'), + _buildNutritionalItem('Zinco', alimento.zinco, 'mg'), + const Divider(), + _buildNutritionalItem('Umidade', alimento.umidade, '%'), + _buildNutritionalItem('Cinzas', alimento.cinzas, 'g'), + ], + ); + } + + // Função auxiliar para exibir cada item nutricional de forma compacta + Widget _buildNutritionalItem(String label, double? value, String unit) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(label, style: TextStyle(color: Colors.grey[800], fontSize: 14)), + Text( + value != null ? '$value $unit' : 'N/A', + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + ), + ], ), ); } diff --git a/healthway_app/macos/Flutter/Flutter-Debug.xcconfig b/healthway_app/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b..4b81f9b 100644 --- a/healthway_app/macos/Flutter/Flutter-Debug.xcconfig +++ b/healthway_app/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/healthway_app/macos/Flutter/Flutter-Release.xcconfig b/healthway_app/macos/Flutter/Flutter-Release.xcconfig index c2efd0b..5caa9d1 100644 --- a/healthway_app/macos/Flutter/Flutter-Release.xcconfig +++ b/healthway_app/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/healthway_app/macos/Podfile b/healthway_app/macos/Podfile new file mode 100644 index 0000000..c795730 --- /dev/null +++ b/healthway_app/macos/Podfile @@ -0,0 +1,43 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end From 8268ed1389b05d840fbd75e8c7f703d0d2e26351 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Fri, 17 Jan 2025 16:11:26 -0300 Subject: [PATCH 14/47] =?UTF-8?q?implementando=20Facade=20para=20os=20serv?= =?UTF-8?q?i=C3=A7os=20do=20front=20#65?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementa a classe ServicesFacade para centralizar os serviços de nutricionista, paciente e alimento. Faz algumas alterações em classes relacionadas. --- .../lib/geral_screens/loginScreen.dart | 21 ++-- healthway_app/lib/main.dart | 16 +-- healthway_app/lib/models/nutricionista.dart | 40 +++++-- healthway_app/lib/models/paciente.dart | 9 +- ...itionist.dart => signup_nutritionist.dart} | 107 +++++++++++------- ...Screen.dart => signup_patient_screen.dart} | 106 +++++++++++------ .../lib/services/nutricionista_services.dart | 39 +++---- .../lib/services/paciente_services.dart | 51 +++------ .../lib/services/services_facade.dart | 37 ++++++ 9 files changed, 270 insertions(+), 156 deletions(-) rename healthway_app/lib/screens_nutricionist/{signUpNutritionist.dart => signup_nutritionist.dart} (72%) rename healthway_app/lib/screens_patient/{signupScreen.dart => signup_patient_screen.dart} (78%) create mode 100644 healthway_app/lib/services/services_facade.dart diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index 979a454..5694861 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:healthway_app/screens_patient/signupScreen.dart'; -import 'package:healthway_app/screens_nutricionist/signUpNutritionist.dart'; +import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; +import 'package:healthway_app/screens_nutricionist/signup_nutritionist.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @@ -47,7 +47,8 @@ class _LoginScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildTextField(_emailController, 'E-mail', Icons.email, keyboardType: TextInputType.emailAddress), + _buildTextField(_emailController, 'E-mail', Icons.email, + keyboardType: TextInputType.emailAddress), SizedBox(height: 20), _buildPasswordField(), SizedBox(height: 20), @@ -67,7 +68,9 @@ class _LoginScreenState extends State { ); } - Widget _buildTextField(TextEditingController controller, String label, IconData icon, {TextInputType? keyboardType}) { + Widget _buildTextField( + TextEditingController controller, String label, IconData icon, + {TextInputType? keyboardType}) { return TextFormField( controller: controller, decoration: InputDecoration( @@ -139,7 +142,8 @@ class _LoginScreenState extends State { }, child: Text( 'Esqueceu a senha?', - style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + style: + TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), ), ), ); @@ -149,13 +153,15 @@ class _LoginScreenState extends State { return ElevatedButton( onPressed: _submitForm, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), + foregroundColor: Colors.white, + backgroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), ), - child: Text('Entrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + child: Text('Entrar', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ); } @@ -198,4 +204,3 @@ class _LoginScreenState extends State { super.dispose(); } } - diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 3489325..ec3dc82 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -1,20 +1,18 @@ import 'package:flutter/material.dart'; -import 'package:healthway_app/geral_screens/presentationScreen.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; +import 'package:healthway_app/geral_screens/loginScreen.dart'; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; +import 'package:healthway_app/geral_screens/presentationScreen.dart'; import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; import 'package:healthway_app/screens_nutricionist/schedule_screen.dart'; import 'package:healthway_app/screens_patient/dashboardScreen.dart'; import 'package:healthway_app/screens_patient/dietScreen.dart'; -import 'package:healthway_app/geral_screens/loginScreen.dart'; import 'package:healthway_app/screens_patient/notificationScreen.dart'; import 'package:healthway_app/screens_patient/profileScreen.dart'; import 'package:healthway_app/screens_patient/setingsScreen.dart'; -import 'package:healthway_app/screens_patient/signupScreen.dart'; - -import 'geral_screens/presentationScreen.dart'; +import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; void main() { runApp(MyApp()); @@ -46,7 +44,9 @@ class MyApp extends StatelessWidget { '/signUp': (context) => CadastroPacienteScreen(), '/login': (context) => LoginScreen(), '/chat': (context) => ChatScreen(), - '/health': (context) => PlanoAlimentarScreen(pacienteId: '',), + '/health': (context) => PlanoAlimentarScreen( + pacienteId: '', + ), '/alimentos': (context) => AlimentosScreen(), '/nutricionistas': (context) => NutricionistasScreen(), '/menu': (context) => MenuScreen(), @@ -56,7 +56,9 @@ class MyApp extends StatelessWidget { '/patientList': (context) => PatientListScreen(), '/nutritionistProfile': (context) => NutritionistProfileScreen(), '/schedule': (context) => ScheduleScreen(), - '/meal_plans': (context) => MealPlanScreen(patientName: '',), + '/meal_plans': (context) => MealPlanScreen( + patientName: '', + ), }, ); } diff --git a/healthway_app/lib/models/nutricionista.dart b/healthway_app/lib/models/nutricionista.dart index e20dd08..328b4fe 100644 --- a/healthway_app/lib/models/nutricionista.dart +++ b/healthway_app/lib/models/nutricionista.dart @@ -1,31 +1,51 @@ class Nutricionista { - final String id; + final String? id; final String cpf; final String crn; final String nome; final String especialidade; final String email; + final String senha; final String? fotoPerfil; + final String? fotoDocumento; Nutricionista({ - required this.id, + this.id, required this.cpf, required this.crn, required this.nome, required this.especialidade, required this.email, - required this.fotoPerfil, + required this.senha, + this.fotoPerfil, + this.fotoDocumento, }); factory Nutricionista.fromJson(Map json) { return Nutricionista( - id: json['id'] ?? '', - cpf: json['cpf'] ?? '', - crn: json['crn'] ?? '', - nome: json['nome'] ?? '', - especialidade: json['especialidade'] ?? '', - email: json['email'] ?? '', - fotoPerfil: json['foto_perfil'] ?? '', + id: json['id'], + cpf: json['cpf'], + crn: json['crn'], + nome: json['nome'], + especialidade: json['especialidade'], + email: json['email'], + senha: json['senha'], + fotoPerfil: json['foto_perfil'], + fotoDocumento: json['foto_documento'], ); } + + Map toJson() { + return { + 'id': id, + 'cpf': cpf, + 'crn': crn, + 'nome': nome, + 'especialidade': especialidade, + 'email': email, + 'senha': senha, + 'foto_perfil': fotoPerfil, + 'foto_documento': fotoDocumento, + }; + } } diff --git a/healthway_app/lib/models/paciente.dart b/healthway_app/lib/models/paciente.dart index d2192bb..de7164d 100644 --- a/healthway_app/lib/models/paciente.dart +++ b/healthway_app/lib/models/paciente.dart @@ -12,6 +12,7 @@ class Paciente { final double massaMuscular; final String alergias; final String preferencias; + final String senha; Paciente({ this.id, @@ -27,6 +28,7 @@ class Paciente { required this.massaMuscular, required this.alergias, required this.preferencias, + required this.senha, }); factory Paciente.fromJson(Map json) { @@ -44,6 +46,7 @@ class Paciente { massaMuscular: json['massaMuscular'].toDouble(), alergias: json['alergias'], preferencias: json['preferencias'], + senha: json['senha'], ); } @@ -79,6 +82,7 @@ class Paciente { double? massaMuscular, String? alergias, String? preferencias, + String? senha, }) { return Paciente( id: id ?? this.id, @@ -89,11 +93,13 @@ class Paciente { sexo: sexo ?? this.sexo, altura: altura ?? this.altura, peso: peso ?? this.peso, - circunferenciaAbdominal: circunferenciaAbdominal ?? this.circunferenciaAbdominal, + circunferenciaAbdominal: + circunferenciaAbdominal ?? this.circunferenciaAbdominal, gorduraCorporal: gorduraCorporal ?? this.gorduraCorporal, massaMuscular: massaMuscular ?? this.massaMuscular, alergias: alergias ?? this.alergias, preferencias: preferencias ?? this.preferencias, + senha: senha ?? this.senha, ); } @@ -102,4 +108,3 @@ class Paciente { return 'Paciente(id: $id, nome: $nome, email: $email, cpf: $cpf, dataNascimento: $dataNascimento, sexo: $sexo, altura: $altura, peso: $peso, circunferenciaAbdominal: $circunferenciaAbdominal, gorduraCorporal: $gorduraCorporal, massaMuscular: $massaMuscular, alergias: $alergias, preferencias: $preferencias)'; } } - diff --git a/healthway_app/lib/screens_nutricionist/signUpNutritionist.dart b/healthway_app/lib/screens_nutricionist/signup_nutritionist.dart similarity index 72% rename from healthway_app/lib/screens_nutricionist/signUpNutritionist.dart rename to healthway_app/lib/screens_nutricionist/signup_nutritionist.dart index f6dceb1..93b64f1 100644 --- a/healthway_app/lib/screens_nutricionist/signUpNutritionist.dart +++ b/healthway_app/lib/screens_nutricionist/signup_nutritionist.dart @@ -1,17 +1,20 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:healthway_app/models/nutricionista.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; -import '../services/nutricionista_services.dart'; +import 'package:healthway_app/services/services_facade.dart'; class CadastroNutricionistaScreen extends StatefulWidget { const CadastroNutricionistaScreen({super.key}); @override - _CadastroNutricionistaScreenState createState() => _CadastroNutricionistaScreenState(); + State createState() => + _CadastroNutricionistaScreenState(); } -class _CadastroNutricionistaScreenState extends State { +class _CadastroNutricionistaScreenState + extends State { final _formKey = GlobalKey(); final _nomeController = TextEditingController(); final _emailController = TextEditingController(); @@ -24,7 +27,7 @@ class _CadastroNutricionistaScreenState extends State? inputFormatters}) { + Widget _buildTextField( + TextEditingController controller, String label, IconData icon, + {TextInputType? keyboardType, + List? inputFormatters}) { return Padding( padding: EdgeInsets.only(bottom: 20.0), child: TextFormField( @@ -139,17 +158,20 @@ class _CadastroNutricionistaScreenState extends State _pickProfileImage() async { - final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery); + final pickedFile = + await ImagePicker().pickImage(source: ImageSource.gallery); if (pickedFile != null) { setState(() { _fotoPerfil = File(pickedFile.path); @@ -229,7 +258,8 @@ class _CadastroNutricionistaScreenState extends State _pickDocumentImage() async { - final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery); + final pickedFile = + await ImagePicker().pickImage(source: ImageSource.gallery); if (pickedFile != null) { setState(() { _fotoDocumento = File(pickedFile.path); @@ -241,7 +271,9 @@ class _CadastroNutricionistaScreenState extends State _CadastroPacienteScreenState(); + State createState() => _CadastroPacienteScreenState(); } class _CadastroPacienteScreenState extends State { @@ -27,9 +28,9 @@ class _CadastroPacienteScreenState extends State { final _confirmarSenhaController = TextEditingController(); String? _sexo; - DateTime? _dataNascimento; - final PacienteService _pacienteService = PacienteService(); + // final PacienteService _pacienteService = PacienteService(); + final ServicesFacade _servicesFacade = ServicesFacade(); bool _isLoading = false; bool _obscurePassword = true; @@ -40,7 +41,8 @@ class _CadastroPacienteScreenState extends State { return Scaffold( backgroundColor: Color(0xFFE6F7F8), appBar: AppBar( - title: Text('Cadastro de Paciente', style: TextStyle(fontWeight: FontWeight.bold)), + title: Text('Cadastro de Paciente', + style: TextStyle(fontWeight: FontWeight.bold)), backgroundColor: Color(0xFF31BAC2), elevation: 0, ), @@ -67,20 +69,28 @@ class _CadastroPacienteScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildTextField(_nomeController, 'Nome completo', Icons.person), - _buildTextField(_emailController, 'E-mail', Icons.email, keyboardType: TextInputType.emailAddress), - _buildTextField(_cpfController, 'CPF', Icons.badge, inputFormatters: [FilteringTextInputFormatter.digitsOnly]), + _buildTextField( + _nomeController, 'Nome completo', Icons.person), + _buildTextField(_emailController, 'E-mail', Icons.email, + keyboardType: TextInputType.emailAddress), + _buildTextField(_cpfController, 'CPF', Icons.badge, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ]), _buildDateField(), _buildDropdownField(), _buildMeasurementFields(), - _buildTextField(_alergiasController, 'Alergias', Icons.warning), - _buildTextField(_preferenciasController, 'Preferências Alimentares', Icons.restaurant), + _buildTextField( + _alergiasController, 'Alergias', Icons.warning), + _buildTextField(_preferenciasController, + 'Preferências Alimentares', Icons.restaurant), _buildPasswordFields(), SizedBox(height: 30), ElevatedButton( onPressed: _isLoading ? null : _submitForm, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, backgroundColor: Color(0xFF31BAC2), + foregroundColor: Colors.white, + backgroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), @@ -88,7 +98,9 @@ class _CadastroPacienteScreenState extends State { ), child: _isLoading ? CircularProgressIndicator(color: Colors.white) - : Text('Cadastrar', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + : Text('Cadastrar', + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), ), ], ), @@ -100,7 +112,10 @@ class _CadastroPacienteScreenState extends State { ); } - Widget _buildTextField(TextEditingController controller, String label, IconData icon, {TextInputType? keyboardType, List? inputFormatters}) { + Widget _buildTextField( + TextEditingController controller, String label, IconData icon, + {TextInputType? keyboardType, + List? inputFormatters}) { return Padding( padding: EdgeInsets.only(bottom: 20.0), child: TextFormField( @@ -161,7 +176,8 @@ class _CadastroPacienteScreenState extends State { primaryColor: Color(0xFF31BAC2), hintColor: Color(0xFF31BAC2), colorScheme: ColorScheme.light(primary: Color(0xFF31BAC2)), - buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary), + buttonTheme: + ButtonThemeData(textTheme: ButtonTextTheme.primary), ), child: child!, ); @@ -169,8 +185,8 @@ class _CadastroPacienteScreenState extends State { ); if (pickedDate != null) { setState(() { - _dataNascimento = pickedDate; - _dataNascimentoController.text = DateFormat('dd/MM/yyyy').format(pickedDate); + _dataNascimentoController.text = + DateFormat('dd/MM/yyyy').format(pickedDate); }); } }, @@ -204,9 +220,9 @@ class _CadastroPacienteScreenState extends State { style: TextStyle(fontSize: 16, color: Colors.black), items: ['Masculino', 'Feminino', 'Outro'] .map((label) => DropdownMenuItem( - child: Text(label), - value: label, - )) + value: label, + child: Text(label), + )) .toList(), onChanged: (value) { setState(() { @@ -235,24 +251,36 @@ class _CadastroPacienteScreenState extends State { children: [ Text( 'Medidas Corporais', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Color(0xFF31BAC2)), ), SizedBox(height: 16), Row( children: [ - Expanded(child: _buildMeasurementField(_alturaController, 'Altura (cm)', Icons.height)), + Expanded( + child: _buildMeasurementField( + _alturaController, 'Altura (cm)', Icons.height)), SizedBox(width: 16), - Expanded(child: _buildMeasurementField(_pesoController, 'Peso (kg)', Icons.fitness_center)), + Expanded( + child: _buildMeasurementField( + _pesoController, 'Peso (kg)', Icons.fitness_center)), ], ), SizedBox(height: 16), - _buildMeasurementField(_circunferenciaAbdominalController, 'Circunferência Abdominal (cm)', Icons.straighten), + _buildMeasurementField(_circunferenciaAbdominalController, + 'Circunferência Abdominal (cm)', Icons.straighten), SizedBox(height: 16), Row( children: [ - Expanded(child: _buildMeasurementField(_gorduraCorporalController, 'Gordura Corporal (%)', Icons.percent)), + Expanded( + child: _buildMeasurementField(_gorduraCorporalController, + 'Gordura Corporal (%)', Icons.percent)), SizedBox(width: 16), - Expanded(child: _buildMeasurementField(_massaMuscularController, 'Massa Muscular (kg)', Icons.fitness_center)), + Expanded( + child: _buildMeasurementField(_massaMuscularController, + 'Massa Muscular (kg)', Icons.fitness_center)), ], ), ], @@ -261,7 +289,8 @@ class _CadastroPacienteScreenState extends State { ); } - Widget _buildMeasurementField(TextEditingController controller, String label, IconData icon) { + Widget _buildMeasurementField( + TextEditingController controller, String label, IconData icon) { return TextFormField( controller: controller, decoration: InputDecoration( @@ -300,16 +329,21 @@ class _CadastroPacienteScreenState extends State { children: [ Text( 'Segurança', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Color(0xFF31BAC2)), ), SizedBox(height: 16), - _buildPasswordField(_senhaController, 'Senha', _obscurePassword, () { + _buildPasswordField(_senhaController, 'Senha', _obscurePassword, + () { setState(() { _obscurePassword = !_obscurePassword; }); }), SizedBox(height: 16), - _buildPasswordField(_confirmarSenhaController, 'Confirmar Senha', _obscureConfirmPassword, () { + _buildPasswordField(_confirmarSenhaController, 'Confirmar Senha', + _obscureConfirmPassword, () { setState(() { _obscureConfirmPassword = !_obscureConfirmPassword; }); @@ -320,7 +354,8 @@ class _CadastroPacienteScreenState extends State { ); } - Widget _buildPasswordField(TextEditingController controller, String label, bool obscureText, Function() onTap) { + Widget _buildPasswordField(TextEditingController controller, String label, + bool obscureText, Function() onTap) { return TextFormField( controller: controller, obscureText: obscureText, @@ -367,7 +402,7 @@ class _CadastroPacienteScreenState extends State { }); try { - await _pacienteService.cadastrarPaciente( + await _servicesFacade.cadastrar(Paciente( nome: _nomeController.text, email: _emailController.text, cpf: _cpfController.text, @@ -375,13 +410,14 @@ class _CadastroPacienteScreenState extends State { sexo: _sexo!, altura: double.parse(_alturaController.text), peso: double.parse(_pesoController.text), - circunferenciaAbdominal: double.parse(_circunferenciaAbdominalController.text), + circunferenciaAbdominal: + double.parse(_circunferenciaAbdominalController.text), gorduraCorporal: double.parse(_gorduraCorporalController.text), massaMuscular: double.parse(_massaMuscularController.text), alergias: _alergiasController.text, preferencias: _preferenciasController.text, senha: _senhaController.text, - ); + )); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Paciente cadastrado com sucesso!')), @@ -390,7 +426,8 @@ class _CadastroPacienteScreenState extends State { Navigator.of(context).pop(); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Erro ao cadastrar paciente: ${e.toString()}')), + SnackBar( + content: Text('Erro ao cadastrar paciente: ${e.toString()}')), ); } finally { setState(() { @@ -418,4 +455,3 @@ class _CadastroPacienteScreenState extends State { super.dispose(); } } - diff --git a/healthway_app/lib/services/nutricionista_services.dart b/healthway_app/lib/services/nutricionista_services.dart index a74a5bd..06498a9 100644 --- a/healthway_app/lib/services/nutricionista_services.dart +++ b/healthway_app/lib/services/nutricionista_services.dart @@ -1,7 +1,8 @@ import 'dart:convert'; + import 'package:http/http.dart' as http; + import '../models/nutricionista.dart'; -import 'dart:io'; class NutricionistaService { static const String apiUrl = 'http://localhost:3000/api/nutricionistas'; @@ -11,9 +12,9 @@ class NutricionistaService { if (response.statusCode == 200) { try { - List data = json.decode(response.body); + List? data = json.decode(response.body); - if (data != null && data is List) { + if (data != null) { return data.map((json) => Nutricionista.fromJson(json)).toList(); } else { throw Exception('Dados não encontrados ou formato inválido'); @@ -26,28 +27,21 @@ class NutricionistaService { } } - Future cadastrarNutricionista({ - required String nome, - required String email, - required String cpf, - required String crn, - required String especialidade, - required File fotoPerfil, - required File fotoDocumento, - required String senha, - }) async { - var uri = Uri.parse('$apiUrl'); + Future cadastrarNutricionista(Nutricionista nutricionista) async { + var uri = Uri.parse(apiUrl); var request = http.MultipartRequest('POST', uri); - request.fields['nome'] = nome; - request.fields['email'] = email; - request.fields['cpf'] = cpf; - request.fields['crn'] = crn; - request.fields['especialidade'] = especialidade; - request.fields['senha'] = senha; + request.fields['nome'] = nutricionista.nome; + request.fields['email'] = nutricionista.email; + request.fields['cpf'] = nutricionista.cpf; + request.fields['crn'] = nutricionista.crn; + request.fields['especialidade'] = nutricionista.especialidade; + request.fields['senha'] = nutricionista.senha; - request.files.add(await http.MultipartFile.fromPath('foto_perfil', fotoPerfil.path)); - request.files.add(await http.MultipartFile.fromPath('foto_documento', fotoDocumento.path)); + // request.files + // .add(await http.MultipartFile.fromPath('foto_perfil', fotoPerfil.path)); + // request.files.add(await http.MultipartFile.fromPath( + // 'foto_documento', fotoDocumento.path)); var response = await request.send(); if (response.statusCode != 201) { @@ -55,4 +49,3 @@ class NutricionistaService { } } } - diff --git a/healthway_app/lib/services/paciente_services.dart b/healthway_app/lib/services/paciente_services.dart index d656b38..d1320ea 100644 --- a/healthway_app/lib/services/paciente_services.dart +++ b/healthway_app/lib/services/paciente_services.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:http/http.dart' as http; -import '../models/paciente.dart'; -import 'dart:io'; +import 'package:healthway_app/models/paciente.dart'; class PacienteService { static const String apiUrl = 'http://localhost:3000/api/pacientes'; @@ -11,9 +10,9 @@ class PacienteService { if (response.statusCode == 200) { try { - List data = json.decode(response.body); + List? data = json.decode(response.body); - if (data != null && data is List) { + if (data != null) { return data.map((json) => Paciente.fromJson(json)).toList(); } else { throw Exception('Dados não encontrados ou formato inválido'); @@ -26,37 +25,24 @@ class PacienteService { } } - Future cadastrarPaciente({ - required String nome, - required String email, - required String cpf, - required String dataNascimento, - required String sexo, - required double altura, - required double peso, - required double circunferenciaAbdominal, - required double gorduraCorporal, - required double massaMuscular, - required String alergias, - required String preferencias, - required String senha, - }) async { + Future cadastrarPaciente(Paciente paciente) async { var uri = Uri.parse(apiUrl); var request = http.MultipartRequest('POST', uri); - request.fields['nome'] = nome; - request.fields['email'] = email; - request.fields['cpf'] = cpf; - request.fields['dataNascimento'] = dataNascimento; - request.fields['sexo'] = sexo; - request.fields['altura'] = altura.toString(); - request.fields['peso'] = peso.toString(); - request.fields['circunferenciaAbdominal'] = circunferenciaAbdominal.toString(); - request.fields['gorduraCorporal'] = gorduraCorporal.toString(); - request.fields['massaMuscular'] = massaMuscular.toString(); - request.fields['alergias'] = alergias; - request.fields['preferencias'] = preferencias; - request.fields['senha'] = senha; + request.fields['nome'] = paciente.nome; + request.fields['email'] = paciente.email; + request.fields['cpf'] = paciente.cpf; + request.fields['dataNascimento'] = paciente.dataNascimento; + request.fields['sexo'] = paciente.sexo; + request.fields['altura'] = paciente.altura.toString(); + request.fields['peso'] = paciente.peso.toString(); + request.fields['circunferenciaAbdominal'] = + paciente.circunferenciaAbdominal.toString(); + request.fields['gorduraCorporal'] = paciente.gorduraCorporal.toString(); + request.fields['massaMuscular'] = paciente.massaMuscular.toString(); + request.fields['alergias'] = paciente.alergias; + request.fields['preferencias'] = paciente.preferencias; + request.fields['senha'] = paciente.senha; var response = await request.send(); if (response.statusCode != 201) { @@ -64,4 +50,3 @@ class PacienteService { } } } - diff --git a/healthway_app/lib/services/services_facade.dart b/healthway_app/lib/services/services_facade.dart new file mode 100644 index 0000000..afaa46e --- /dev/null +++ b/healthway_app/lib/services/services_facade.dart @@ -0,0 +1,37 @@ +import '../models/alimento.dart'; +import '../models/nutricionista.dart'; +import '../models/paciente.dart'; +import 'alimento_services.dart'; +import 'nutricionista_services.dart'; +import 'paciente_services.dart'; + +class ServicesFacade { + final AlimentoService _alimentoService = AlimentoService(); + final NutricionistaService _nutricionistaService = NutricionistaService(); + final PacienteService _pacienteService = PacienteService(); + + // Métodos para AlimentoService + Future> obterAlimentos() async { + return await _alimentoService.fetchAlimentos(); + } + + // Métodos para NutricionistaService + Future> obterNutricionistas() async { + return await _nutricionistaService.fetchNutricionistas(); + } + + // Métodos para PacienteService + Future> obterPacientes() async { + return await _pacienteService.fetchPacientes(); + } + + Future cadastrar(dynamic entity) async { + if (entity is Nutricionista) { + await _nutricionistaService.cadastrarNutricionista(entity); + } else if (entity is Paciente) { + await _pacienteService.cadastrarPaciente(entity); + } else { + throw Exception('Tipo de entidade desconhecido'); + } + } +} From 9042a73d795cf6fec9295699e0f7fe788a017f6f Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Sat, 18 Jan 2025 17:25:52 -0300 Subject: [PATCH 15/47] fiz a listagem de pacientes e a tela de chat --- .../lib/controllers/chat_controller.dart | 35 ++++ .../lib/geral_screens/chat_screen.dart | 68 +++++++ .../lib/geral_screens/presentationScreen.dart | 5 +- healthway_app/lib/main.dart | 17 +- healthway_app/lib/models/message_model.dart | 36 ++++ .../patient_list_screen.dart | 182 +++++++++++++----- healthway_app/lib/services/chat_services.dart | 30 +++ .../lib/widgets/chat_input_field.dart | 91 +++++++++ .../lib/widgets/chat_message_bubble.dart | 74 +++++++ healthway_app/lib/widgets/paciente_item.dart | 103 ++++++++++ healthway_app/pubspec.yaml | 2 + 11 files changed, 580 insertions(+), 63 deletions(-) create mode 100644 healthway_app/lib/controllers/chat_controller.dart create mode 100644 healthway_app/lib/geral_screens/chat_screen.dart create mode 100644 healthway_app/lib/models/message_model.dart create mode 100644 healthway_app/lib/services/chat_services.dart create mode 100644 healthway_app/lib/widgets/chat_input_field.dart create mode 100644 healthway_app/lib/widgets/chat_message_bubble.dart create mode 100644 healthway_app/lib/widgets/paciente_item.dart diff --git a/healthway_app/lib/controllers/chat_controller.dart b/healthway_app/lib/controllers/chat_controller.dart new file mode 100644 index 0000000..020ad41 --- /dev/null +++ b/healthway_app/lib/controllers/chat_controller.dart @@ -0,0 +1,35 @@ +import 'package:get/get.dart'; +import '../models/message_model.dart'; +import '../services/chat_services.dart'; + +class ChatController extends GetxController { + final ChatService _chatService = ChatService(); + final RxList messages = [].obs; + + @override + void onInit() { + super.onInit(); + _loadMessages(); + } + + Future _loadMessages() async { + try { + final loadedMessages = await _chatService.getMessages(); + messages.assignAll(loadedMessages); + } catch (e) { + print('Error loading messages: $e'); + // TODO: Handle error (e.g., show a snackbar) + } + } + + Future sendMessage(String text) async { + try { + final newMessage = await _chatService.sendMessage(text); + messages.insert(0, newMessage); + } catch (e) { + print('Error sending message: $e'); + // TODO: Handle error (e.g., show a snackbar) + } + } +} + diff --git a/healthway_app/lib/geral_screens/chat_screen.dart b/healthway_app/lib/geral_screens/chat_screen.dart new file mode 100644 index 0000000..4f9d1be --- /dev/null +++ b/healthway_app/lib/geral_screens/chat_screen.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../controllers/chat_controller.dart'; +import '../models/message_model.dart'; +import '../widgets/chat_message_bubble.dart'; +import '../widgets/chat_input_field.dart'; + +class ChatScreen extends StatelessWidget { + final ChatController chatController = Get.put(ChatController()); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Row( + children: [ + CircleAvatar( + backgroundColor: Color(0xFF31BAC2), + child: Icon(Icons.person, color: Colors.white), + radius: 20, + ), + SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Nutricionista', style: TextStyle(fontSize: 16, color: Colors.white)), + Text('Online', style: TextStyle(fontSize: 12, color: Colors.white70)), + ], + ), + ], + ), + backgroundColor: Color(0xFF31BAC2), + actions: [ + IconButton(icon: Icon(Icons.video_call), onPressed: () {}), + IconButton(icon: Icon(Icons.call), onPressed: () {}), + IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), + ], + ), + body: Container( + decoration: BoxDecoration( + color: Colors.white, + ), + child: Column( + children: [ + Expanded( + child: Obx(() { + return ListView.builder( + reverse: true, + itemCount: chatController.messages.length, + itemBuilder: (context, index) { + final message = chatController.messages[index]; + return ChatMessageBubble(message: message); + }, + ); + }), + ), + ChatInputField( + onSendMessage: (String text) { + chatController.sendMessage(text); + }, + ), + ], + ), + ), + ); + } +} + diff --git a/healthway_app/lib/geral_screens/presentationScreen.dart b/healthway_app/lib/geral_screens/presentationScreen.dart index a44cd29..74df0f4 100644 --- a/healthway_app/lib/geral_screens/presentationScreen.dart +++ b/healthway_app/lib/geral_screens/presentationScreen.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/loginScreen.dart'; +import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; import 'dart:async'; +import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; + class PresentationScreen extends StatefulWidget { const PresentationScreen({super.key}); @@ -34,7 +37,7 @@ class _PresentationScreenState extends State // Navegar para a próxima tela após a animação Timer(Duration(seconds: 3), () { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => LoginScreen()), + MaterialPageRoute(builder: (_) => NutritionistDashboardScreen()), ); }); } diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 1f15300..2186595 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -12,7 +12,9 @@ import 'package:healthway_app/screens_patient/notificationScreen.dart'; import 'package:healthway_app/screens_patient/profileScreen.dart'; import 'package:healthway_app/screens_patient/setingsScreen.dart'; import 'package:healthway_app/screens_patient/signupScreen.dart'; +import 'package:healthway_app/widgets/paciente_item.dart'; +import 'geral_screens/chat_screen.dart'; import 'geral_screens/presentationScreen.dart'; void main() { @@ -52,7 +54,7 @@ class MyApp extends StatelessWidget { '/profile': (context) => PatientProfileScreen(), '/notifications': (context) => NotificationScreen(), '/settings': (context) => SettingsScreen(), - '/patientList': (context) => PatientListScreen(), + '/patientList': (context) => PacientesScreen(), '/nutritionistProfile': (context) => NutritionistProfileScreen(), '/schedule': (context) => ScheduleScreen(), }, @@ -73,19 +75,6 @@ class HomeScreen extends StatelessWidget { } } -class ChatScreen extends StatelessWidget { - const ChatScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text('Chat')), - bottomNavigationBar: CustomBottomNavigationBar(), - body: Center(child: Text('Tela de Chat')), - ); - } -} - class MenuScreen extends StatelessWidget { const MenuScreen({super.key}); diff --git a/healthway_app/lib/models/message_model.dart b/healthway_app/lib/models/message_model.dart new file mode 100644 index 0000000..0900fd9 --- /dev/null +++ b/healthway_app/lib/models/message_model.dart @@ -0,0 +1,36 @@ +class Message { + final String id; + final String senderId; + final String senderName; + final String text; + final DateTime timestamp; + + Message({ + required this.id, + required this.senderId, + required this.senderName, + required this.text, + required this.timestamp, + }); + + factory Message.fromJson(Map json) { + return Message( + id: json['id'], + senderId: json['senderId'], + senderName: json['senderName'], + text: json['text'], + timestamp: DateTime.parse(json['timestamp']), + ); + } + + Map toJson() { + return { + 'id': id, + 'senderId': senderId, + 'senderName': senderName, + 'text': text, + 'timestamp': timestamp.toIso8601String(), + }; + } +} + diff --git a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart index 92b9a02..10453ea 100644 --- a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart +++ b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart @@ -1,73 +1,159 @@ import 'package:flutter/material.dart'; +import '../models/paciente.dart'; +import '../services/paciente_services.dart'; +import '../widgets/paciente_item.dart'; -class PatientListScreen extends StatelessWidget { - const PatientListScreen({super.key}); +class PacientesScreen extends StatefulWidget { + const PacientesScreen({super.key}); + + @override + _PacientesScreenState createState() => _PacientesScreenState(); +} + +class _PacientesScreenState extends State { + late Future> _pacientes; + List pacientes = []; + List pacientesFiltrados = []; + TextEditingController searchController = TextEditingController(); + + @override + void initState() { + super.initState(); + _carregarPacientes(); + } + + void _carregarPacientes() { + setState(() { + _pacientes = PacienteService().fetchPacientes(); + }); + } + + void _filtrarPacientes(String query) { + setState(() { + pacientesFiltrados = pacientes + .where((paciente) => + paciente.nome.toLowerCase().contains(query.toLowerCase()) || + paciente.email.toLowerCase().contains(query.toLowerCase())) + .toList(); + }); + } @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: Color(0xFFF5F5F5), appBar: AppBar( - title: const Text('Meus Pacientes'), - backgroundColor: const Color(0xFF31BAC2), + title: Text('Pacientes'), + backgroundColor: Color(0xFF31BAC2), elevation: 0, ), - body: SafeArea( - child: ListView.builder( - itemCount: 10, // Exemplo com 10 pacientes - itemBuilder: (context, index) { - return _buildPatientItem('Paciente ${index + 1}', 'Última consulta: ${10 - index}d atrás'); - }, - ), + body: Column( + children: [ + _buildSearchBar(), + Expanded( + child: FutureBuilder>( + future: _pacientes, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))); + } else if (snapshot.hasError) { + return _buildErrorWidget(snapshot.error.toString()); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return _buildEmptyWidget(); + } else { + pacientes = snapshot.data!; + if (pacientesFiltrados.isEmpty) { + pacientesFiltrados = pacientes; + } + return _buildPacientesList(); + } + }, + ), + ), + ], ), floatingActionButton: FloatingActionButton( - onPressed: () { - // Adicionar novo paciente - }, + onPressed: _carregarPacientes, backgroundColor: Color(0xFF31BAC2), - child: Icon(Icons.add), + child: Icon(Icons.refresh), ), ); } - Widget _buildPatientItem(String name, String lastConsultation) { + Widget _buildSearchBar() { return Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 1, - blurRadius: 5, - offset: Offset(0, 3), + padding: EdgeInsets.all(16), + color: Color(0xFF31BAC2), + child: TextField( + controller: searchController, + onChanged: _filtrarPacientes, + decoration: InputDecoration( + hintText: 'Pesquisar por nome ou email...', + prefixIcon: Icon(Icons.search, color: Color(0xFF31BAC2)), + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30), + borderSide: BorderSide.none, + ), + ), + ), + ); + } + + Widget _buildPacientesList() { + return ListView.builder( + itemCount: pacientesFiltrados.length, + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + child: PacienteItem(paciente: pacientesFiltrados[index]), + ), + ); + }, + ); + } + + Widget _buildErrorWidget(String error) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.error_outline, size: 60, color: Colors.red), + SizedBox(height: 16), + Text( + 'Erro ao carregar pacientes', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text( + error, + style: TextStyle(color: Colors.grey[600]), + textAlign: TextAlign.center, ), ], ), - child: ListTile( - contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), - leading: CircleAvatar( - backgroundColor: Color(0xFF31BAC2), - child: Text( - name[0], - style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold), + ); + } + + Widget _buildEmptyWidget() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.person_off, size: 60, color: Color(0xFF31BAC2)), + SizedBox(height: 16), + Text( + 'Nenhum paciente encontrado', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), - ), - title: Text( - name, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), - ), - subtitle: Text( - lastConsultation, - style: TextStyle(color: Colors.grey[600], fontSize: 14), - ), - trailing: Icon(Icons.chevron_right, color: Color(0xFF31BAC2)), - onTap: () { - // Navegar para os detalhes do paciente - }, + ], ), ); } } - diff --git a/healthway_app/lib/services/chat_services.dart b/healthway_app/lib/services/chat_services.dart new file mode 100644 index 0000000..dd7aa27 --- /dev/null +++ b/healthway_app/lib/services/chat_services.dart @@ -0,0 +1,30 @@ +import '../models/message_model.dart'; +import 'package:uuid/uuid.dart'; + +class ChatService { + final List _messages = []; + final _uuid = Uuid(); + + Future> getMessages() async { + // Simulating API call delay + await Future.delayed(Duration(seconds: 1)); + return _messages; + } + + Future sendMessage(String text) async { + // Simulating API call delay + await Future.delayed(Duration(milliseconds: 500)); + + final newMessage = Message( + id: _uuid.v4(), + senderId: 'currentUser', // Replace with actual user ID + senderName: 'You', // Replace with actual user name + text: text, + timestamp: DateTime.now(), + ); + + _messages.insert(0, newMessage); + return newMessage; + } +} + diff --git a/healthway_app/lib/widgets/chat_input_field.dart b/healthway_app/lib/widgets/chat_input_field.dart new file mode 100644 index 0000000..b7b02c8 --- /dev/null +++ b/healthway_app/lib/widgets/chat_input_field.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; + +class ChatInputField extends StatefulWidget { + final Function(String) onSendMessage; + + const ChatInputField({super.key, required this.onSendMessage}); + + @override + _ChatInputFieldState createState() => _ChatInputFieldState(); +} + +class _ChatInputFieldState extends State { + final TextEditingController _textController = TextEditingController(); + bool _isComposing = false; + + void _handleSubmitted(String text) { + widget.onSendMessage(text); + setState(() { + _isComposing = false; + }); + _textController.clear(); + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + offset: Offset(0, -2), + blurRadius: 4, + color: Colors.black.withOpacity(0.1), + ), + ], + ), + child: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0), + child: Row( + children: [ + IconButton( + icon: Icon(Icons.emoji_emotions_outlined, color: Color(0xFF31BAC2)), + onPressed: () { + // TODO: Implement emoji picker + }, + ), + Expanded( + child: TextField( + controller: _textController, + onChanged: (text) { + setState(() { + _isComposing = text.isNotEmpty; + }); + }, + onSubmitted: _isComposing ? _handleSubmitted : null, + decoration: InputDecoration( + hintText: 'Digite uma mensagem...', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(25.0), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.grey[100], + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + ), + style: TextStyle(color: Colors.black87, fontSize: 16), + ), + ), + IconButton( + icon: Icon(Icons.attach_file, color: Color(0xFF31BAC2)), + onPressed: () { + // TODO: Implement file attachment + }, + ), + IconButton( + icon: Icon(_isComposing ? Icons.send : Icons.mic, color: Color(0xFF31BAC2)), + onPressed: _isComposing + ? () => _handleSubmitted(_textController.text) + : () { + // TODO: Implement voice recording + }, + ), + ], + ), + ), + ), + ); + } +} + diff --git a/healthway_app/lib/widgets/chat_message_bubble.dart b/healthway_app/lib/widgets/chat_message_bubble.dart new file mode 100644 index 0000000..126427b --- /dev/null +++ b/healthway_app/lib/widgets/chat_message_bubble.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import '../models/message_model.dart'; + +class ChatMessageBubble extends StatelessWidget { + final Message message; + + const ChatMessageBubble({Key? key, required this.message}) : super(key: key); + + @override + Widget build(BuildContext context) { + final isMe = message.senderId == 'currentUser'; // Replace with actual user ID check + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + child: Row( + mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start, + children: [ + if (!isMe) SizedBox(width: 40), + Flexible( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10), + decoration: BoxDecoration( + color: isMe ? Color(0xFF31BAC2).withOpacity(0.2) : Colors.grey[200], + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + spreadRadius: 1, + blurRadius: 1, + offset: Offset(0, 1), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + message.text, + style: TextStyle( + color: Colors.black87, + fontSize: 16, + ), + ), + SizedBox(height: 4), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + DateFormat('HH:mm').format(message.timestamp), + style: TextStyle( + color: Colors.black54, + fontSize: 12, + ), + ), + if (isMe) SizedBox(width: 4), + if (isMe) Icon( + Icons.done_all, + size: 16, + color: Color(0xFF31BAC2), + ), + ], + ), + ], + ), + ), + ), + if (isMe) SizedBox(width: 40), + ], + ), + ); + } +} + diff --git a/healthway_app/lib/widgets/paciente_item.dart b/healthway_app/lib/widgets/paciente_item.dart new file mode 100644 index 0000000..3ebf096 --- /dev/null +++ b/healthway_app/lib/widgets/paciente_item.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import '../models/paciente.dart'; + +class PacienteItem extends StatelessWidget { + final Paciente paciente; + + const PacienteItem({Key? key, required this.paciente}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ListTile( + contentPadding: EdgeInsets.all(16), + leading: CircleAvatar( + backgroundColor: Colors.grey[300], + child: Icon( + Icons.person, + color: Colors.grey[700], + ), + ), + title: Text( + paciente.nome, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 4), + Text('Email: ${paciente.email}'), + Text('CPF: ${paciente.cpf}'), + ], + ), + trailing: Icon( + Icons.chevron_right, + color: Colors.grey[700], + ), + onTap: () { + // Ação ao clicar no item (Exemplo: abrir detalhes do paciente) + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PacienteDetalhesScreen(paciente: paciente), + ), + ); + }, + ); + } +} + +class PacienteDetalhesScreen extends StatelessWidget { + final Paciente paciente; + + const PacienteDetalhesScreen({Key? key, required this.paciente}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Detalhes do Paciente'), + backgroundColor: Color(0xFF31BAC2), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + paciente.nome, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 16), + Text('Email: ${paciente.email}'), + Text('CPF: ${paciente.cpf}'), + Text('Data de Nascimento: ${paciente.dataNascimento}'), + Text('Sexo: ${paciente.sexo}'), + Text('Altura: ${paciente.altura} m'), + Text('Peso: ${paciente.peso} kg'), + Text('Circunferência Abdominal: ${paciente.circunferenciaAbdominal} cm'), + Text('Gordura Corporal: ${paciente.gorduraCorporal}%'), + Text('Massa Muscular: ${paciente.massaMuscular} kg'), + SizedBox(height: 16), + Text( + 'Alergias:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + Text(paciente.alergias), + SizedBox(height: 16), + Text( + 'Preferências:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + Text(paciente.preferencias), + ], + ), + ), + ); + } +} diff --git a/healthway_app/pubspec.yaml b/healthway_app/pubspec.yaml index 8fb7393..3a08f42 100644 --- a/healthway_app/pubspec.yaml +++ b/healthway_app/pubspec.yaml @@ -34,6 +34,8 @@ dependencies: image_picker: ^0.8.7+5 table_calendar: ^3.0.9 intl: ^0.18.0 + get: ^4.6.5 + uuid: ^3.0.7 # The following adds the Cupertino Icons font to your application. From 8ccd65862a255f49c14527f1ba58a66195e4b9ce Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Sat, 18 Jan 2025 17:33:33 -0300 Subject: [PATCH 16/47] Resolvendo conflitos --- backend/model/Paciente.js | 110 +++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/backend/model/Paciente.js b/backend/model/Paciente.js index 21e2f9b..9f0d73a 100644 --- a/backend/model/Paciente.js +++ b/backend/model/Paciente.js @@ -1,41 +1,79 @@ class Paciente { - constructor(alergias, altura, cpf, data_nascimento, email, foto_perfil, nome, peso, sexo, - circunferencia_abdominal, gordura_corporal, massa_muscular, preferencias, senha) { - this.alergias = alergias; - this.altura = altura; - this.cpf = cpf; - this.data_nascimento = data_nascimento; - this.email = email; - this.foto_perfil = foto_perfil; - this.nome = nome; - this.peso = peso; - this.sexo = sexo; - this.circunferencia_abdominal = circunferencia_abdominal; - this.gordura_corporal = gordura_corporal; - this.massa_muscular = massa_muscular; - this.preferencias = preferencias; - this.senha = senha; + constructor({ + id = null, + alergias = [], + altura = 0, + cpf = "", + data_nascimento = new Date(), + email = "", + foto_perfil = null, + nome = "", + peso = 0, + sexo = "", + circunferencia_abdominal = 0, + gordura_corporal = 0, + massa_muscular = 0, + preferencias = {}, + senha = "", + }) { + this.id = id; // String (opcional) + this.alergias = alergias; // Lista de Strings + this.altura = altura; // Número (double) + this.cpf = cpf; // String + this.data_nascimento = new Date(data_nascimento); // Date + this.email = email; // String + this.foto_perfil = foto_perfil; // String (opcional) + this.nome = nome; // String + this.peso = peso; // Número (double) + this.sexo = sexo; // String + this.circunferencia_abdominal = circunferencia_abdominal; // Número (double) + this.gordura_corporal = gordura_corporal; // Número (double) + this.massa_muscular = massa_muscular; // Número (double) + this.preferencias = preferencias; // Objeto (Map) + this.senha = senha; // String + } - } + // Método estático para criar um objeto Paciente a partir de JSON + static fromJson(json) { + return new Paciente({ + id: json.id || null, + alergias: Array.isArray(json.alergias) ? json.alergias : [], + altura: parseFloat(json.altura || 0), + cpf: json.cpf || "", + data_nascimento: json.data_nascimento || new Date(), + email: json.email || "", + foto_perfil: json.foto_perfil || null, + nome: json.nome || "", + peso: parseFloat(json.peso || 0), + sexo: json.sexo || "", + circunferencia_abdominal: parseFloat(json.circunferencia_abdominal || 0), + gordura_corporal: parseFloat(json.gordura_corporal || 0), + massa_muscular: parseFloat(json.massa_muscular || 0), + preferencias: json.preferencias || {}, + senha: json.senha || "", + }); + } - toFirestore() { - return { - alergias: this.alergias, - altura: this.altura, - cpf: this.cpf, - data_nascimento: this.data_nascimento, - email: this.email, - foto_perfil: this.foto_perfil, - nome: this.nome, - peso: this.peso, - sexo: this.sexo, - circunferencia_abdominal: this.circunferencia_abdominal, - gordura_corporal: this.gordura_corporal, - massa_muscular: this.massa_muscular, - preferencias: this.preferencias, - senha: this.senha - }; - } + // Método para converter um objeto Paciente para JSON + toJson() { + return { + id: this.id, + alergias: this.alergias, + altura: this.altura, + cpf: this.cpf, + data_nascimento: this.data_nascimento.toISOString(), + email: this.email, + foto_perfil: this.foto_perfil, + nome: this.nome, + peso: this.peso, + sexo: this.sexo, + circunferencia_abdominal: this.circunferencia_abdominal, + gordura_corporal: this.gordura_corporal, + massa_muscular: this.massa_muscular, + preferencias: this.preferencias, + senha: this.senha, + }; } +} - module.exports = Paciente; +module.exports = Paciente; // Exporta a classe para uso em outros módulos From 42f060eab2942a18c7fa625ae2112b7e5a95282d Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sat, 18 Jan 2025 22:57:51 -0300 Subject: [PATCH 17/47] preparando telas de cadastro, login e perfil --- .../controllers/nutricionistaController.js | 16 + backend/controllers/pacienteController.js | 16 + backend/routes/nutricionistaRoutes.js | 1 + backend/routes/pacienteRoutes.js | 1 + healthway_app/lib/constants.dart | 5 + .../lib/geral_screens/loginScreen.dart | 117 ++++-- ...onScreen.dart => presentation_screen.dart} | 9 +- healthway_app/lib/main.dart | 33 +- healthway_app/lib/models/paciente.dart | 10 +- ...art => nutritionist_dashboard_screen.dart} | 49 ++- ...t.dart => signup_nutritionist_screen.dart} | 0 ...een.dart => patient_dashboard_screen.dart} | 9 +- .../patient_profile_screen.dart | 351 ++++++++++++++++++ .../lib/screens_patient/profileScreen.dart | 318 ---------------- .../signup_patient_screen.dart | 12 +- .../lib/services/nutricionista_services.dart | 22 ++ .../lib/services/paciente_services.dart | 56 ++- .../lib/services/services_facade.dart | 44 +++ healthway_app/test/dashboard_screen_test.dart | 7 +- 19 files changed, 691 insertions(+), 385 deletions(-) create mode 100644 healthway_app/lib/constants.dart rename healthway_app/lib/geral_screens/{presentationScreen.dart => presentation_screen.dart} (81%) rename healthway_app/lib/screens_nutricionist/{nutritionist_dashboard.dart => nutritionist_dashboard_screen.dart} (87%) rename healthway_app/lib/screens_nutricionist/{signup_nutritionist.dart => signup_nutritionist_screen.dart} (100%) rename healthway_app/lib/screens_patient/{dashboardScreen.dart => patient_dashboard_screen.dart} (97%) create mode 100644 healthway_app/lib/screens_patient/patient_profile_screen.dart delete mode 100644 healthway_app/lib/screens_patient/profileScreen.dart diff --git a/backend/controllers/nutricionistaController.js b/backend/controllers/nutricionistaController.js index 50e8391..6603b9a 100644 --- a/backend/controllers/nutricionistaController.js +++ b/backend/controllers/nutricionistaController.js @@ -40,6 +40,22 @@ const nutricionistaController = { } }, + async getByEmailAndPassword(req, res) { + try { + const { email, senha } = req.body; + const snapshot = await db.collection('nutricionista').where('email', '==', email).where('senha', '==', senha).get(); + const paciente = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + + if (paciente.length === 0) { + return res.status(404).json({ error: 'Nutricionista não encontrado.' }); + } + + res.status(200).json(paciente[0]); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}, + // Atualizar um nutricionista async update(req, res) { try { diff --git a/backend/controllers/pacienteController.js b/backend/controllers/pacienteController.js index 79fbf2f..e704e9b 100644 --- a/backend/controllers/pacienteController.js +++ b/backend/controllers/pacienteController.js @@ -40,6 +40,22 @@ const pacienteController = { } }, + async getByEmailAndPassword(req, res) { + try { + const { email, senha } = req.body; + const snapshot = await db.collection('paciente').where('email', '==', email).where('senha', '==', senha).get(); + const paciente = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + + if (paciente.length === 0) { + return res.status(404).json({ error: 'Paciente não encontrado.' }); + } + + res.status(200).json(paciente[0]); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + // Atualizar um paciente async update(req, res) { try { diff --git a/backend/routes/nutricionistaRoutes.js b/backend/routes/nutricionistaRoutes.js index 78f6621..1579b98 100644 --- a/backend/routes/nutricionistaRoutes.js +++ b/backend/routes/nutricionistaRoutes.js @@ -6,6 +6,7 @@ const nutricionistaController = require('../controllers/nutricionistaController' router.post('/', nutricionistaController.create); router.get('/', nutricionistaController.getAll); router.get('/:id', nutricionistaController.getById); +router.post('/login', nutricionistaController.getByEmailAndPassword); router.put('/:id', nutricionistaController.update); router.delete('/:id', nutricionistaController.delete); router.get('/specialty/:specialty', nutricionistaController.getBySpecialty); diff --git a/backend/routes/pacienteRoutes.js b/backend/routes/pacienteRoutes.js index cadbeef..c0c5502 100644 --- a/backend/routes/pacienteRoutes.js +++ b/backend/routes/pacienteRoutes.js @@ -6,6 +6,7 @@ const pacienteController = require('../controllers/pacienteController'); router.post('/', pacienteController.create); router.get('/', pacienteController.getAll); router.get('/:id', pacienteController.getById); +router.post('/login', pacienteController.getByEmailAndPassword); router.put('/:id', pacienteController.update); router.delete('/:id', pacienteController.delete); diff --git a/healthway_app/lib/constants.dart b/healthway_app/lib/constants.dart new file mode 100644 index 0000000..f24a835 --- /dev/null +++ b/healthway_app/lib/constants.dart @@ -0,0 +1,5 @@ +import 'package:flutter/material.dart'; + +const kPrimaryColor = Color(0xFF31BAC2); +const kSecondaryColor = Color(0xFFE6F7F8); +const kTextColor = Color.fromARGB(255, 13, 56, 58); diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index 5694861..8932a49 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -1,12 +1,14 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:flutter/material.dart'; -import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; -import 'package:healthway_app/screens_nutricionist/signup_nutritionist.dart'; +import 'package:healthway_app/constants.dart'; +import 'package:healthway_app/services/services_facade.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override - _LoginScreenState createState() => _LoginScreenState(); + State createState() => _LoginScreenState(); } class _LoginScreenState extends State { @@ -14,14 +16,17 @@ class _LoginScreenState extends State { final _emailController = TextEditingController(); final _senhaController = TextEditingController(); bool _obscurePassword = true; + String _userType = 'Paciente'; + final ServicesFacade _servicesFacade = ServicesFacade(); @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFE6F7F8), // Tom muito claro de azul + backgroundColor: kSecondaryColor, appBar: AppBar( - title: Text('Login', style: TextStyle(fontWeight: FontWeight.bold)), - backgroundColor: Color(0xFF31BAC2), + title: Text('Login', + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white)), + backgroundColor: kPrimaryColor, elevation: 0, ), body: SingleChildScrollView( @@ -30,7 +35,7 @@ class _LoginScreenState extends State { Container( height: 200, decoration: BoxDecoration( - color: Color(0xFF31BAC2), + color: kPrimaryColor, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), @@ -52,6 +57,8 @@ class _LoginScreenState extends State { SizedBox(height: 20), _buildPasswordField(), SizedBox(height: 20), + _buildUserTypeDropdown(), + SizedBox(height: 20), _buildForgotPasswordButton(), SizedBox(height: 30), _buildLoginButton(), @@ -75,17 +82,18 @@ class _LoginScreenState extends State { controller: controller, decoration: InputDecoration( labelText: label, - prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + prefixIcon: Icon(icon, color: kPrimaryColor), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), - style: TextStyle(fontSize: 16), + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.w600, color: kTextColor), keyboardType: keyboardType, validator: (value) { if (value == null || value.isEmpty) { @@ -102,11 +110,11 @@ class _LoginScreenState extends State { obscureText: _obscurePassword, decoration: InputDecoration( labelText: 'Senha', - prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.lock, color: kPrimaryColor), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility : Icons.visibility_off, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), onPressed: () { setState(() { @@ -120,10 +128,11 @@ class _LoginScreenState extends State { ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), - style: TextStyle(fontSize: 16), + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.w600, color: kTextColor), validator: (value) { if (value == null || value.isEmpty) { return 'Por favor, insira sua senha'; @@ -133,6 +142,38 @@ class _LoginScreenState extends State { ); } + Widget _buildUserTypeDropdown() { + return DropdownButtonFormField( + value: _userType, + decoration: InputDecoration( + labelText: 'Tipo de Usuário', + prefixIcon: Icon(Icons.person, color: kPrimaryColor), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: kPrimaryColor), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + dropdownColor: Colors.white, + items: ['Paciente', 'Nutricionista'] + .map((value) => DropdownMenuItem( + value: value, + child: Text(value), + )) + .toList(), + onChanged: (value) { + setState(() { + _userType = value!; + }); + }, + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.w600, color: kTextColor), + ); + } + Widget _buildForgotPasswordButton() { return Align( alignment: Alignment.centerRight, @@ -142,8 +183,7 @@ class _LoginScreenState extends State { }, child: Text( 'Esqueceu a senha?', - style: - TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + style: TextStyle(color: kPrimaryColor, fontWeight: FontWeight.bold), ), ), ); @@ -154,7 +194,7 @@ class _LoginScreenState extends State { onPressed: _submitForm, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), @@ -168,11 +208,11 @@ class _LoginScreenState extends State { Widget _buildPatientButton() { return TextButton( onPressed: () { - MaterialPageRoute(builder: (_) => CadastroPacienteScreen()); + Navigator.pushNamed(context, '/signup_patient'); }, child: Text( 'Sou paciente', - style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + style: TextStyle(color: kPrimaryColor, fontWeight: FontWeight.bold), ), ); } @@ -180,20 +220,47 @@ class _LoginScreenState extends State { Widget _buildNutricionistButton() { return TextButton( onPressed: () { - MaterialPageRoute(builder: (_) => CadastroNutricionistaScreen()); + Navigator.pushNamed(context, '/signup_nutritionist'); }, child: Text( 'Sou nutricionista', - style: TextStyle(color: Color(0xFF31BAC2), fontWeight: FontWeight.bold), + style: TextStyle(color: kPrimaryColor, fontWeight: FontWeight.bold), ), ); } - void _submitForm() { + Future _submitForm() async { if (_formKey.currentState!.validate()) { - // TODO: Implementar lógica de autenticação - print('Form is valid. Submitting...'); - // Você normalmente chamaria um método de serviço aqui para autenticar o usuário + String email = _emailController.text; + String senha = _senhaController.text; + String userType = _userType; + + // Call the login service + _servicesFacade + .login(email: email, senha: senha, userType: userType) + .then((userData) { + if (userData != null) { + if (_userType == 'Paciente') { + Navigator.pushReplacementNamed(context, '/home_patient', + arguments: userData); + } else if (_userType == 'Nutricionista') { + Navigator.pushReplacementNamed(context, '/home_nutritionist', + arguments: userData); + } + } else { + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Falha no login. Verifique suas credenciais.')), + ); + } + }).catchError((error) { + // Handle any errors that occur during login + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ocorreu um erro. Tente novamente mais tarde.')), + ); + }); } } diff --git a/healthway_app/lib/geral_screens/presentationScreen.dart b/healthway_app/lib/geral_screens/presentation_screen.dart similarity index 81% rename from healthway_app/lib/geral_screens/presentationScreen.dart rename to healthway_app/lib/geral_screens/presentation_screen.dart index 8c5c65f..bfd48ad 100644 --- a/healthway_app/lib/geral_screens/presentationScreen.dart +++ b/healthway_app/lib/geral_screens/presentation_screen.dart @@ -1,14 +1,13 @@ -import 'package:flutter/material.dart'; -import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; import 'dart:async'; -import 'package:healthway_app/screens_patient//dashboardScreen.dart'; +import 'package:flutter/material.dart'; +import 'package:healthway_app/geral_screens/loginScreen.dart'; class PresentationScreen extends StatefulWidget { const PresentationScreen({super.key}); @override - _PresentationScreenState createState() => _PresentationScreenState(); + State createState() => _PresentationScreenState(); } class _PresentationScreenState extends State @@ -36,7 +35,7 @@ class _PresentationScreenState extends State // Navegar para a próxima tela após a animação Timer(Duration(seconds: 3), () { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (_) => NutritionistDashboardScreen()), + MaterialPageRoute(builder: (_) => LoginScreen()), ); }); } diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index ec3dc82..8bc47b4 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -2,15 +2,17 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; import 'package:healthway_app/geral_screens/loginScreen.dart'; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; -import 'package:healthway_app/geral_screens/presentationScreen.dart'; +import 'package:healthway_app/geral_screens/presentation_screen.dart'; import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; +import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard_screen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; import 'package:healthway_app/screens_nutricionist/schedule_screen.dart'; -import 'package:healthway_app/screens_patient/dashboardScreen.dart'; +import 'package:healthway_app/screens_nutricionist/signup_nutritionist_screen.dart'; +import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; import 'package:healthway_app/screens_patient/dietScreen.dart'; import 'package:healthway_app/screens_patient/notificationScreen.dart'; -import 'package:healthway_app/screens_patient/profileScreen.dart'; +import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; import 'package:healthway_app/screens_patient/setingsScreen.dart'; import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; @@ -40,8 +42,8 @@ class MyApp extends StatelessWidget { initialRoute: '/', routes: { '/': (context) => PresentationScreen(), - '/home': (context) => PatientDashboardScreen(), - '/signUp': (context) => CadastroPacienteScreen(), + '/signup_patient': (context) => CadastroPacienteScreen(), + '/signup_nutritionist': (context) => CadastroNutricionistaScreen(), '/login': (context) => LoginScreen(), '/chat': (context) => ChatScreen(), '/health': (context) => PlanoAlimentarScreen( @@ -50,7 +52,6 @@ class MyApp extends StatelessWidget { '/alimentos': (context) => AlimentosScreen(), '/nutricionistas': (context) => NutricionistasScreen(), '/menu': (context) => MenuScreen(), - '/profile': (context) => PatientProfileScreen(), '/notifications': (context) => NotificationScreen(), '/settings': (context) => SettingsScreen(), '/patientList': (context) => PatientListScreen(), @@ -60,6 +61,26 @@ class MyApp extends StatelessWidget { patientName: '', ), }, + onGenerateRoute: (settings) { + switch (settings.name) { + case '/home_patient': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => PatientDashboardScreen(userData: args), + ); + case '/home_nutritionist': + return MaterialPageRoute( + builder: (context) => NutritionistDashboardScreen(), + ); + case '/patient_profile': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => PatientProfileScreen(userData: args), + ); + default: + return null; + } + }, ); } } diff --git a/healthway_app/lib/models/paciente.dart b/healthway_app/lib/models/paciente.dart index de7164d..ed6d02a 100644 --- a/healthway_app/lib/models/paciente.dart +++ b/healthway_app/lib/models/paciente.dart @@ -3,7 +3,7 @@ class Paciente { final String nome; final String email; final String cpf; - final String dataNascimento; + final Map dataNascimento; final String sexo; final double altura; final double peso; @@ -37,7 +37,7 @@ class Paciente { nome: json['nome'], email: json['email'], cpf: json['cpf'], - dataNascimento: json['dataNascimento'], + dataNascimento: Map.from(json['dt_nascimento']), sexo: json['sexo'], altura: json['altura'].toDouble(), peso: json['peso'].toDouble(), @@ -56,7 +56,7 @@ class Paciente { 'nome': nome, 'email': email, 'cpf': cpf, - 'dataNascimento': dataNascimento, + 'dt_nascimento': dataNascimento, 'sexo': sexo, 'altura': altura, 'peso': peso, @@ -73,7 +73,7 @@ class Paciente { String? nome, String? email, String? cpf, - String? dataNascimento, + Map? dataNascimento, String? sexo, double? altura, double? peso, @@ -105,6 +105,6 @@ class Paciente { @override String toString() { - return 'Paciente(id: $id, nome: $nome, email: $email, cpf: $cpf, dataNascimento: $dataNascimento, sexo: $sexo, altura: $altura, peso: $peso, circunferenciaAbdominal: $circunferenciaAbdominal, gorduraCorporal: $gorduraCorporal, massaMuscular: $massaMuscular, alergias: $alergias, preferencias: $preferencias)'; + return 'Paciente(id: $id, nome: $nome, email: $email, cpf: $cpf, dt_nascimento: $dataNascimento, sexo: $sexo, altura: $altura, peso: $peso, circunferenciaAbdominal: $circunferenciaAbdominal, gorduraCorporal: $gorduraCorporal, massaMuscular: $massaMuscular, alergias: $alergias, preferencias: $preferencias)'; } } diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart similarity index 87% rename from healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart rename to healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index 5eaf390..afb208a 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; class NutritionistDashboardScreen extends StatelessWidget { const NutritionistDashboardScreen({super.key}); @@ -140,10 +139,14 @@ class NutritionistDashboardScreen extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - _buildQuickAccessItem(context, Icons.people, 'Pacientes', '/patientList'), - _buildQuickAccessItem(context, Icons.calendar_today, 'Agenda', '/schedule'), - _buildQuickAccessItem(context, Icons.restaurant_menu, 'Planos', '/meal_plans'), - _buildQuickAccessItem(context, Icons.food_bank_outlined, 'Alimentos', '/alimentos'), + _buildQuickAccessItem( + context, Icons.people, 'Pacientes', '/patientList'), + _buildQuickAccessItem( + context, Icons.calendar_today, 'Agenda', '/schedule'), + _buildQuickAccessItem( + context, Icons.restaurant_menu, 'Planos', '/meal_plans'), + _buildQuickAccessItem( + context, Icons.food_bank_outlined, 'Alimentos', '/alimentos'), ], ), ], @@ -151,7 +154,8 @@ class NutritionistDashboardScreen extends StatelessWidget { ); } - Widget _buildQuickAccessItem(BuildContext context, IconData icon, String label, String route) { + Widget _buildQuickAccessItem( + BuildContext context, IconData icon, String label, String route) { return GestureDetector( onTap: () { Navigator.pushNamed(context, route); @@ -214,18 +218,23 @@ class NutritionistDashboardScreen extends StatelessWidget { ], ), SizedBox(height: 15), - _buildAppointmentItem(context, 'Maria Oliveira', '14:00', 'Consulta de Rotina'), - _buildAppointmentItem(context, 'João Silva', '15:30', 'Avaliação Nutricional'), - _buildAppointmentItem(context, 'Ana Santos', '17:00', 'Revisão de Dieta'), + _buildAppointmentItem( + context, 'Maria Oliveira', '14:00', 'Consulta de Rotina'), + _buildAppointmentItem( + context, 'João Silva', '15:30', 'Avaliação Nutricional'), + _buildAppointmentItem( + context, 'Ana Santos', '17:00', 'Revisão de Dieta'), ], ), ); } - Widget _buildAppointmentItem(BuildContext context, String name, String time, String type) { + Widget _buildAppointmentItem( + BuildContext context, String name, String time, String type) { return GestureDetector( onTap: () { - Navigator.pushNamed(context, '/appointment_details', arguments: {'name': name, 'time': time, 'type': type}); + Navigator.pushNamed(context, '/appointment_details', + arguments: {'name': name, 'time': time, 'type': type}); }, child: Container( margin: EdgeInsets.only(bottom: 10), @@ -322,18 +331,23 @@ class NutritionistDashboardScreen extends StatelessWidget { ], ), SizedBox(height: 15), - _buildPatientUpdateItem(context, 'Carlos Mendes', 'Atingiu meta de peso', '2h atrás'), - _buildPatientUpdateItem(context, 'Fernanda Lima', 'Novo registro de refeição', '4h atrás'), - _buildPatientUpdateItem(context, 'Ricardo Souza', 'Solicitou alteração na dieta', '1d atrás'), + _buildPatientUpdateItem( + context, 'Carlos Mendes', 'Atingiu meta de peso', '2h atrás'), + _buildPatientUpdateItem(context, 'Fernanda Lima', + 'Novo registro de refeição', '4h atrás'), + _buildPatientUpdateItem(context, 'Ricardo Souza', + 'Solicitou alteração na dieta', '1d atrás'), ], ), ); } - Widget _buildPatientUpdateItem(BuildContext context, String name, String update, String time) { + Widget _buildPatientUpdateItem( + BuildContext context, String name, String update, String time) { return GestureDetector( onTap: () { - Navigator.pushNamed(context, '/patient_details', arguments: {'name': name}); + Navigator.pushNamed(context, '/patient_details', + arguments: {'name': name}); }, child: Container( margin: EdgeInsets.only(bottom: 10), @@ -423,7 +437,7 @@ class NutritionistDashboardScreen extends StatelessWidget { onTap: (index) { switch (index) { case 0: - // Already on home screen + // Already on home screen break; case 1: Navigator.pushNamed(context, '/patientList'); @@ -458,4 +472,3 @@ class NutritionistDashboardScreen extends StatelessWidget { ); } } - diff --git a/healthway_app/lib/screens_nutricionist/signup_nutritionist.dart b/healthway_app/lib/screens_nutricionist/signup_nutritionist_screen.dart similarity index 100% rename from healthway_app/lib/screens_nutricionist/signup_nutritionist.dart rename to healthway_app/lib/screens_nutricionist/signup_nutritionist_screen.dart diff --git a/healthway_app/lib/screens_patient/dashboardScreen.dart b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart similarity index 97% rename from healthway_app/lib/screens_patient/dashboardScreen.dart rename to healthway_app/lib/screens_patient/patient_dashboard_screen.dart index 8159088..af7c25a 100644 --- a/healthway_app/lib/screens_patient/dashboardScreen.dart +++ b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; class PatientDashboardScreen extends StatelessWidget { - const PatientDashboardScreen({super.key}); + final Map userData; + + const PatientDashboardScreen({super.key, required this.userData}); @override Widget build(BuildContext context) { @@ -44,7 +46,7 @@ class PatientDashboardScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'Olá, João', + userData['nome'], style: TextStyle( color: Colors.white, fontSize: 24, @@ -347,7 +349,8 @@ class PatientDashboardScreen extends StatelessWidget { Navigator.pushNamed(context, '/progress'); break; case 3: - Navigator.pushNamed(context, '/profile'); + Navigator.pushNamed(context, '/patient_profile', + arguments: userData); break; } }, diff --git a/healthway_app/lib/screens_patient/patient_profile_screen.dart b/healthway_app/lib/screens_patient/patient_profile_screen.dart new file mode 100644 index 0000000..61bf4e9 --- /dev/null +++ b/healthway_app/lib/screens_patient/patient_profile_screen.dart @@ -0,0 +1,351 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:healthway_app/models/paciente.dart'; +import 'package:healthway_app/services/services_facade.dart'; + +class PatientProfileScreen extends StatefulWidget { + final Map userData; + const PatientProfileScreen({super.key, required this.userData}); + + @override + State createState() => _PatientProfileScreenState(); +} + +class _PatientProfileScreenState extends State { + bool _isEditing = false; + bool _edited = false; + final _formKey = GlobalKey(); + static final ServicesFacade _servicesFacade = ServicesFacade(); + + late String name; + late String email; + late int age; + late double altura; + late double peso; + late double circunferenciaAbdominal; + late double massaMuscular; + late double gorduraCorporal; + late List preferencias; + late List alergias; + + @override + void initState() { + super.initState(); + preferencias = List.from(widget.userData['preferencias']); + alergias = List.from(widget.userData['alergias']); + name = widget.userData['nome']; + email = widget.userData['email']; + var birthDate = widget.userData['dt_nascimento']; + age = DateTime.now() + .difference(DateTime.fromMillisecondsSinceEpoch( + birthDate['_seconds'] * 1000 + + birthDate['_nanoseconds'] ~/ 1000000)) + .inDays ~/ + 365; + altura = widget.userData['altura'].toDouble(); + peso = widget.userData['peso'].toDouble(); + circunferenciaAbdominal = + widget.userData['circunferencia_abdominal'].toDouble(); + massaMuscular = widget.userData['massa_muscular'].toDouble(); + gorduraCorporal = widget.userData['gordura_corporal'].toDouble(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF5F5F5), + appBar: AppBar( + title: const Text('Meu Perfil'), + backgroundColor: const Color(0xFF31BAC2), + elevation: 0, + actions: [ + IconButton( + icon: Icon(_isEditing ? Icons.close : Icons.edit), + onPressed: () { + setState(() { + _isEditing = !_isEditing; + }); + }, + ), + ], + ), + body: SafeArea( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildProfileHeader(), + SizedBox(height: 24), + _buildInfoSection(), + SizedBox(height: 24), + _buildAlergiasSection(), + SizedBox(height: 24), + _buildPreferenciasSection(), + ], + ), + ), + ), + ), + floatingActionButton: _edited + ? FloatingActionButton( + onPressed: _saveChanges, + backgroundColor: Color(0xFF31BAC2), + child: Icon(Icons.save), + ) + : null, + ); + } + + Widget _buildProfileHeader() { + return Center( + child: Column( + children: [ + Stack( + alignment: Alignment.bottomRight, + children: [ + CircleAvatar( + radius: 60, + backgroundColor: Color(0xFF31BAC2), + backgroundImage: + NetworkImage('https://example.com/profile_image.jpg'), + child: Text( + name.isNotEmpty ? name[0].toUpperCase() : '?', + style: TextStyle( + fontSize: 40, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + ), + if (!_isEditing) + Container( + decoration: BoxDecoration( + color: Color(0xFF31BAC2), + shape: BoxShape.circle, + ), + child: IconButton( + icon: Icon(Icons.camera_alt, color: Colors.white), + onPressed: () { + // Implement image picking functionality + }, + ), + ), + ], + ), + SizedBox(height: 16), + Text( + name, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text( + email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + ), + ], + ), + ); + } + + Widget _buildInfoSection() { + return Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + _buildInfoRow('Idade', '$age anos', null), + _buildInfoRow('Altura', altura.toStringAsFixed(1), (value) { + if (value.isNotEmpty) { + _edited = true; + altura = double.parse(value); + } + }), + _buildInfoRow('Peso', peso.toStringAsFixed(1), (value) { + if (value.isNotEmpty) { + _edited = true; + peso = double.parse(value); + } + }), + _buildInfoRow( + 'IMC', + '${_calculateBMI().toStringAsFixed(1)} (${_getBMICategory()})', + null), + _buildInfoRow('Circunferência Abdominal', + circunferenciaAbdominal.toStringAsFixed(1), (value) { + if (value.isNotEmpty) { + _edited = true; + circunferenciaAbdominal = double.parse(value); + } + }), + _buildInfoRow('Massa Muscular', massaMuscular.toStringAsFixed(1), + (value) { + if (value.isNotEmpty) { + _edited = true; + massaMuscular = double.parse(value); + } + }), + _buildInfoRow( + 'Gordura Corporal', gorduraCorporal.toStringAsFixed(1), + (value) { + if (value.isNotEmpty) { + _edited = true; + gorduraCorporal = double.parse(value); + } + }), + ], + ), + ), + ); + } + + Widget _buildInfoRow( + String label, String value, Function(String)? onChanged) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(label, style: TextStyle(fontSize: 16, color: Colors.grey[600])), + _isEditing && onChanged != null + ? SizedBox( + width: 120, + child: TextFormField( + initialValue: value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + textAlign: TextAlign.right, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + keyboardType: + TextInputType.numberWithOptions(decimal: true), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d*')), + ], + onChanged: onChanged, + ), + ) + : Text(value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + ], + ), + ); + } + + Widget _buildAlergiasSection() { + return Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Text('Alergias', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + ...alergias.map((alergia) => ListTile( + title: Text(alergia), + trailing: _isEditing + ? IconButton( + icon: Icon(Icons.delete), + onPressed: () { + setState(() { + _edited = true; + alergias.remove(alergia); + }); + }, + ) + : null, + )), + if (_isEditing) + TextField( + decoration: InputDecoration(labelText: 'Adicionar Alergia'), + onSubmitted: (value) { + if (value.isNotEmpty) { + setState(() { + _edited = true; + alergias.add(value); + }); + } + }, + ), + ], + ), + ), + ); + } + + Widget _buildPreferenciasSection() { + return Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Text('Preferências', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + ...preferencias.map((preferencia) => ListTile( + title: Text(preferencia), + trailing: _isEditing + ? IconButton( + icon: Icon(Icons.delete), + onPressed: () { + setState(() { + _edited = true; + preferencias.remove(preferencia); + }); + }, + ) + : null, + )), + if (_isEditing) + TextField( + decoration: InputDecoration(labelText: 'Adicionar Preferência'), + onSubmitted: (value) { + if (value.isNotEmpty) { + setState(() { + _edited = true; + preferencias.add(value); + }); + } + }, + ), + ], + ), + ), + ); + } + + void _saveChanges() { + if (_formKey.currentState!.validate()) { + // Save the changes + setState(() { + _edited = false; + }); + widget.userData['altura'] = altura; + widget.userData['peso'] = peso; + widget.userData['circunferencia_abdominal'] = circunferenciaAbdominal; + widget.userData['massa_muscular'] = massaMuscular; + widget.userData['gordura_corporal'] = gorduraCorporal; + widget.userData['preferencias'] = preferencias; + widget.userData['alergias'] = alergias; + _servicesFacade.atualizar(Paciente.fromJson(widget.userData)); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Perfil atualizado com sucesso!')), + ); + } + } + + double _calculateBMI() { + var altura = this.altura / 100; + return peso / (altura * altura); + } + + String _getBMICategory() { + double bmi = _calculateBMI(); + if (bmi < 18.5) return 'Abaixo do peso'; + if (bmi < 25) return 'Normal'; + if (bmi < 30) return 'Sobrepeso'; + return 'Obeso'; + } +} diff --git a/healthway_app/lib/screens_patient/profileScreen.dart b/healthway_app/lib/screens_patient/profileScreen.dart deleted file mode 100644 index 42b2094..0000000 --- a/healthway_app/lib/screens_patient/profileScreen.dart +++ /dev/null @@ -1,318 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:intl/intl.dart'; - -class PatientProfileScreen extends StatefulWidget { - const PatientProfileScreen({Key? key}) : super(key: key); - - @override - _PatientProfileScreenState createState() => _PatientProfileScreenState(); -} - -class _PatientProfileScreenState extends State { - bool _isEditing = false; - final _formKey = GlobalKey(); - - // Mock data - replace with actual data fetching in a real app - String name = 'João Silva'; - String email = 'joao.silva@email.com'; - int age = 35; - double height = 1.75; - double weight = 70.0; - String objective = 'Manutenção de peso'; - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), - appBar: AppBar( - title: const Text('Meu Perfil'), - backgroundColor: const Color(0xFF31BAC2), - elevation: 0, - actions: [ - IconButton( - icon: Icon(_isEditing ? Icons.close : Icons.edit), - onPressed: () { - setState(() { - if (_isEditing) { - // Discard changes - _isEditing = false; - } else { - _isEditing = true; - } - }); - }, - ), - ], - ), - body: SafeArea( - child: SingleChildScrollView( - padding: const EdgeInsets.all(16.0), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildProfileHeader(), - SizedBox(height: 24), - _buildInfoSection(), - SizedBox(height: 24), - _buildActionButtons(), - SizedBox(height: 24), - _buildHealthMetrics(), - SizedBox(height: 24), - _buildProgressChart(), - ], - ), - ), - ), - ), - floatingActionButton: _isEditing - ? FloatingActionButton( - onPressed: _saveChanges, - backgroundColor: Color(0xFF31BAC2), - child: Icon(Icons.save), - ) - : null, - ); - } - - Widget _buildProfileHeader() { - return Center( - child: Column( - children: [ - Stack( - alignment: Alignment.bottomRight, - children: [ - CircleAvatar( - radius: 60, - backgroundColor: Color(0xFF31BAC2), - backgroundImage: NetworkImage('https://example.com/profile_image.jpg'), - child: Text( - name.isNotEmpty ? name[0].toUpperCase() : '?', - style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white), - ), - ), - if (!_isEditing) - Container( - decoration: BoxDecoration( - color: Color(0xFF31BAC2), - shape: BoxShape.circle, - ), - child: IconButton( - icon: Icon(Icons.camera_alt, color: Colors.white), - onPressed: () { - // Implement image picking functionality - }, - ), - ), - ], - ), - SizedBox(height: 16), - _isEditing - ? TextFormField( - initialValue: name, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - textAlign: TextAlign.center, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: (value) => name = value, - ) - : Text( - name, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - _isEditing - ? TextFormField( - initialValue: email, - style: TextStyle(fontSize: 16, color: Colors.grey[600]), - textAlign: TextAlign.center, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: (value) => email = value, - ) - : Text( - email, - style: TextStyle(fontSize: 16, color: Colors.grey[600]), - ), - ], - ), - ); - } - - Widget _buildInfoSection() { - return Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - _buildInfoRow('Idade', '$age anos', (value) => age = int.parse(value)), - _buildInfoRow('Altura', '${height.toStringAsFixed(2)} m', (value) => height = double.parse(value)), - _buildInfoRow('Peso', '${weight.toStringAsFixed(1)} kg', (value) => weight = double.parse(value)), - _buildInfoRow('IMC', '${_calculateBMI().toStringAsFixed(1)} (${_getBMICategory()})', null), - _buildInfoRow('Objetivo', objective, (value) => objective = value), - ], - ), - ), - ); - } - - Widget _buildInfoRow(String label, String value, Function(String)? onChanged) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(label, style: TextStyle(fontSize: 16, color: Colors.grey[600])), - _isEditing && onChanged != null - ? SizedBox( - width: 120, - child: TextFormField( - initialValue: value, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), - textAlign: TextAlign.right, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: onChanged, - ), - ) - : Text(value, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), - ], - ), - ); - } - - Widget _buildActionButtons() { - return Column( - children: [ - ElevatedButton( - onPressed: () { - // Navigate to detailed edit profile screen - }, - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF31BAC2), - padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), - ), - child: Text('Editar Perfil Detalhado'), - ), - SizedBox(height: 12), - OutlinedButton( - onPressed: () { - // Navigate to change password screen - }, - style: OutlinedButton.styleFrom( - foregroundColor: Color(0xFF31BAC2), - padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), - side: BorderSide(color: Color(0xFF31BAC2)), - ), - child: Text('Alterar Senha'), - ), - ], - ); - } - - Widget _buildHealthMetrics() { - return Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Métricas de Saúde', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - SizedBox(height: 16), - _buildMetricItem('Pressão Arterial', '120/80 mmHg'), - _buildMetricItem('Glicemia em Jejum', '90 mg/dL'), - _buildMetricItem('Colesterol Total', '180 mg/dL'), - _buildMetricItem('Triglicerídeos', '150 mg/dL'), - ], - ), - ), - ); - } - - Widget _buildMetricItem(String label, String value) { - return Padding( - padding: const EdgeInsets.only(bottom: 12.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(label, style: TextStyle(fontSize: 16)), - Text(value, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2))), - ], - ), - ); - } - - Widget _buildProgressChart() { - return Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Progresso de Peso', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - SizedBox(height: 16), - Container( - height: 200, - child: _buildWeightChart(), - ), - ], - ), - ), - ); - } - - Widget _buildWeightChart() { - // This is a placeholder for the chart - // You should implement an actual chart using a charting library - return Center( - child: Text('Gráfico de Progresso de Peso'), - ); - } - - void _saveChanges() { - if (_formKey.currentState!.validate()) { - // Save the changes - setState(() { - _isEditing = false; - }); - // Show a snackbar to confirm changes - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Perfil atualizado com sucesso!')), - ); - } - } - - double _calculateBMI() { - return weight / (height * height); - } - - String _getBMICategory() { - double bmi = _calculateBMI(); - if (bmi < 18.5) return 'Abaixo do peso'; - if (bmi < 25) return 'Normal'; - if (bmi < 30) return 'Sobrepeso'; - return 'Obeso'; - } -} - diff --git a/healthway_app/lib/screens_patient/signup_patient_screen.dart b/healthway_app/lib/screens_patient/signup_patient_screen.dart index 54a6eb2..de2ed27 100644 --- a/healthway_app/lib/screens_patient/signup_patient_screen.dart +++ b/healthway_app/lib/screens_patient/signup_patient_screen.dart @@ -402,11 +402,21 @@ class _CadastroPacienteScreenState extends State { }); try { + final dataNascimento = + DateFormat('dd/MM/yyyy').parse(_dataNascimentoController.text); + final dataNascimentoEmSegundos = + dataNascimento.millisecondsSinceEpoch ~/ 1000; + final dataNascimentoEmNanosegundos = + dataNascimento.microsecondsSinceEpoch * 1000; + final dataNascimentoMap = { + '_seconds': dataNascimentoEmSegundos, + '_nanoseconds': dataNascimentoEmNanosegundos, + }; await _servicesFacade.cadastrar(Paciente( nome: _nomeController.text, email: _emailController.text, cpf: _cpfController.text, - dataNascimento: _dataNascimentoController.text, + dataNascimento: dataNascimentoMap, sexo: _sexo!, altura: double.parse(_alturaController.text), peso: double.parse(_pesoController.text), diff --git a/healthway_app/lib/services/nutricionista_services.dart b/healthway_app/lib/services/nutricionista_services.dart index 06498a9..7e4d771 100644 --- a/healthway_app/lib/services/nutricionista_services.dart +++ b/healthway_app/lib/services/nutricionista_services.dart @@ -48,4 +48,26 @@ class NutricionistaService { throw Exception('Falha ao cadastrar nutricionista'); } } + + Future atualizarNutricionista(Nutricionista nutricionista) async { + var uri = Uri.parse('$apiUrl/${nutricionista.id}'); + var request = http.MultipartRequest('PUT', uri); + + request.fields['nome'] = nutricionista.nome; + request.fields['email'] = nutricionista.email; + request.fields['cpf'] = nutricionista.cpf; + request.fields['crn'] = nutricionista.crn; + request.fields['especialidade'] = nutricionista.especialidade; + request.fields['senha'] = nutricionista.senha; + + // request.files + // .add(await http.MultipartFile.fromPath('foto_perfil', fotoPerfil.path)); + // request.files.add(await http.MultipartFile.fromPath( + // 'foto_documento', fotoDocumento.path)); + + var response = await request.send(); + if (response.statusCode != 200) { + throw Exception('Falha ao atualizar nutricionista'); + } + } } diff --git a/healthway_app/lib/services/paciente_services.dart b/healthway_app/lib/services/paciente_services.dart index d1320ea..68c717f 100644 --- a/healthway_app/lib/services/paciente_services.dart +++ b/healthway_app/lib/services/paciente_services.dart @@ -25,6 +25,20 @@ class PacienteService { } } + Future fetchPacienteById(String id) async { + final response = await http.get(Uri.parse('$apiUrl/$id')); + + if (response.statusCode == 200) { + try { + return Paciente.fromJson(json.decode(response.body)); + } catch (e) { + throw Exception('Erro ao parsear o JSON: $e'); + } + } else { + throw Exception('Falha ao carregar paciente'); + } + } + Future cadastrarPaciente(Paciente paciente) async { var uri = Uri.parse(apiUrl); var request = http.MultipartRequest('POST', uri); @@ -32,7 +46,7 @@ class PacienteService { request.fields['nome'] = paciente.nome; request.fields['email'] = paciente.email; request.fields['cpf'] = paciente.cpf; - request.fields['dataNascimento'] = paciente.dataNascimento; + request.fields['dataNascimento'] = paciente.dataNascimento.toString(); request.fields['sexo'] = paciente.sexo; request.fields['altura'] = paciente.altura.toString(); request.fields['peso'] = paciente.peso.toString(); @@ -49,4 +63,44 @@ class PacienteService { throw Exception('Falha ao cadastrar paciente'); } } + + Future login({required String email, required String senha}) async { + var uri = Uri.parse('$apiUrl/login'); + var request = http.MultipartRequest('POST', uri); + + request.fields['email'] = email; + request.fields['senha'] = senha; + + var response = await request.send(); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } + + Future atualizarPaciente(Paciente paciente) async { + var uri = Uri.parse('$apiUrl/${paciente.id}'); + var request = http.MultipartRequest('PUT', uri); + + request.fields['nome'] = paciente.nome; + request.fields['email'] = paciente.email; + request.fields['cpf'] = paciente.cpf; + request.fields['dataNascimento'] = paciente.dataNascimento.toString(); + request.fields['sexo'] = paciente.sexo; + request.fields['altura'] = paciente.altura.toString(); + request.fields['peso'] = paciente.peso.toString(); + request.fields['circunferenciaAbdominal'] = + paciente.circunferenciaAbdominal.toString(); + request.fields['gorduraCorporal'] = paciente.gorduraCorporal.toString(); + request.fields['massaMuscular'] = paciente.massaMuscular.toString(); + request.fields['alergias'] = paciente.alergias; + request.fields['preferencias'] = paciente.preferencias; + request.fields['senha'] = paciente.senha; + + var response = await request.send(); + if (response.statusCode != 200) { + throw Exception('Falha ao atualizar paciente'); + } + } } diff --git a/healthway_app/lib/services/services_facade.dart b/healthway_app/lib/services/services_facade.dart index afaa46e..06bf655 100644 --- a/healthway_app/lib/services/services_facade.dart +++ b/healthway_app/lib/services/services_facade.dart @@ -4,8 +4,13 @@ import '../models/paciente.dart'; import 'alimento_services.dart'; import 'nutricionista_services.dart'; import 'paciente_services.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert'; class ServicesFacade { + static const String apiUrl = 'http://localhost:3000/api'; + static const String pacienteUrl = '$apiUrl/pacientes'; + static const String nutricionistaUrl = '$apiUrl/nutricionistas'; final AlimentoService _alimentoService = AlimentoService(); final NutricionistaService _nutricionistaService = NutricionistaService(); final PacienteService _pacienteService = PacienteService(); @@ -25,6 +30,10 @@ class ServicesFacade { return await _pacienteService.fetchPacientes(); } + Future obterPacientePorId(String id) async { + return await _pacienteService.fetchPacienteById(id); + } + Future cadastrar(dynamic entity) async { if (entity is Nutricionista) { await _nutricionistaService.cadastrarNutricionista(entity); @@ -34,4 +43,39 @@ class ServicesFacade { throw Exception('Tipo de entidade desconhecido'); } } + + Future atualizar(dynamic entity) async { + if (entity is Nutricionista) { + await _nutricionistaService.atualizarNutricionista(entity); + } else if (entity is Paciente) { + await _pacienteService.atualizarPaciente(entity); + } else { + throw Exception('Tipo de entidade desconhecido'); + } + } + + Future login( + {required String email, + required String senha, + required String userType}) async { + Uri uri; + if (userType == 'Nutricionista') { + uri = Uri.parse('$nutricionistaUrl/login'); + } else if (userType == 'Paciente') { + uri = Uri.parse('$pacienteUrl/login'); + } else { + throw Exception('Tipo de usuário desconhecido'); + } + var request = http.Request('POST', uri) + ..headers['Content-Type'] = 'application/json' + ..body = json.encode({'email': email, 'senha': senha}); + var response = await request.send(); + if (response.statusCode == 200) { + var responseBody = await response.stream.bytesToString(); + var responseJson = json.decode(responseBody); + return responseJson; + } else { + return null; + } + } } diff --git a/healthway_app/test/dashboard_screen_test.dart b/healthway_app/test/dashboard_screen_test.dart index 220edce..99a04c1 100644 --- a/healthway_app/test/dashboard_screen_test.dart +++ b/healthway_app/test/dashboard_screen_test.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:healthway_app/screens_patient/dashboardScreen.dart'; +import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; void main() { - testWidgets('PatientDashboardScreen displays correctly', (WidgetTester tester) async { + testWidgets('PatientDashboardScreen displays correctly', + (WidgetTester tester) async { // Build the PatientDashboardScreen widget. await tester.pumpWidget(MaterialApp(home: PatientDashboardScreen())); @@ -22,4 +23,4 @@ void main() { // Add more specific tests for the widgets inside the Column as needed. }); -} \ No newline at end of file +} From e6518cc0bcad5f32c64d5f34c6335b6fc57f6e78 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sun, 19 Jan 2025 01:25:11 -0300 Subject: [PATCH 18/47] integra telas de login e do paciente #77 #78 #79 --- backend/controllers/pacienteController.js | 3 +- backend/model/Paciente.js | 23 ++- .../lib/controllers/chat_controller.dart | 35 ++++ .../lib/geral_screens/chat_screen.dart | 69 +++++++ .../lib/geral_screens/loginScreen.dart | 17 +- healthway_app/lib/main.dart | 67 ++----- healthway_app/lib/models/message_model.dart | 36 ++++ healthway_app/lib/models/paciente.dart | 32 +-- .../meal_plan_screen.dart | 52 +++-- .../nutritionist_profile.dart | 111 ++++++----- .../patient_list_screen.dart | 184 +++++++++++++----- .../screens_nutricionist/schedule_screen.dart | 5 +- .../lib/screens_patient/dietScreen.dart | 40 ++-- .../patient_dashboard_screen.dart | 36 ++-- .../patient_profile_screen.dart | 47 +++-- .../signup_patient_screen.dart | 14 +- healthway_app/lib/services/chat_services.dart | 29 +++ .../lib/services/paciente_services.dart | 49 ++--- .../lib/services/services_facade.dart | 12 +- .../lib/widgets/chat_input_field.dart | 91 +++++++++ .../lib/widgets/chat_message_bubble.dart | 74 +++++++ healthway_app/lib/widgets/paciente_item.dart | 115 +++++++++++ healthway_app/pubspec.yaml | 2 + 23 files changed, 861 insertions(+), 282 deletions(-) create mode 100644 healthway_app/lib/controllers/chat_controller.dart create mode 100644 healthway_app/lib/geral_screens/chat_screen.dart create mode 100644 healthway_app/lib/models/message_model.dart create mode 100644 healthway_app/lib/services/chat_services.dart create mode 100644 healthway_app/lib/widgets/chat_input_field.dart create mode 100644 healthway_app/lib/widgets/chat_message_bubble.dart create mode 100644 healthway_app/lib/widgets/paciente_item.dart diff --git a/backend/controllers/pacienteController.js b/backend/controllers/pacienteController.js index e704e9b..c451944 100644 --- a/backend/controllers/pacienteController.js +++ b/backend/controllers/pacienteController.js @@ -60,7 +60,8 @@ const pacienteController = { async update(req, res) { try { const { id } = req.params; - const paciente = new Paciente(req.body); + const paciente = new Paciente(); + paciente.fromJson(req.body); await db.collection('paciente').doc(id).update(paciente.toFirestore()); res.status(200).json({ message: 'Paciente atualizado com sucesso!' }); diff --git a/backend/model/Paciente.js b/backend/model/Paciente.js index 21e2f9b..2e1314f 100644 --- a/backend/model/Paciente.js +++ b/backend/model/Paciente.js @@ -1,10 +1,10 @@ class Paciente { - constructor(alergias, altura, cpf, data_nascimento, email, foto_perfil, nome, peso, sexo, + constructor(alergias, altura, cpf, data_nascimento, email, foto_perfil = '', nome, peso, sexo, circunferencia_abdominal, gordura_corporal, massa_muscular, preferencias, senha) { this.alergias = alergias; this.altura = altura; this.cpf = cpf; - this.data_nascimento = data_nascimento; + this.dt_nascimento = data_nascimento; this.email = email; this.foto_perfil = foto_perfil; this.nome = nome; @@ -23,7 +23,7 @@ class Paciente { alergias: this.alergias, altura: this.altura, cpf: this.cpf, - data_nascimento: this.data_nascimento, + dt_nascimento: this.dt_nascimento, email: this.email, foto_perfil: this.foto_perfil, nome: this.nome, @@ -36,6 +36,23 @@ class Paciente { senha: this.senha }; } + + fromJson(json) { + this.alergias = json.alergias || ''; + this.altura = json.altura || 0; + this.cpf = json.cpf || ''; + this.dt_nascimento = json.dt_nascimento || ''; + this.email = json.email || ''; + this.foto_perfil = json.foto_perfil || ''; + this.nome = json.nome || ''; + this.peso = parseFloat(json.peso) || 0; + this.sexo = json.sexo || ''; + this.circunferencia_abdominal = parseFloat(json.circunferencia_abdominal) || 0; + this.gordura_corporal = parseFloat(json.gordura_corporal) || 0; + this.massa_muscular = parseFloat(json.massa_muscular) || 0; + this.preferencias = json.preferencias || ''; + this.senha = json.senha || ''; + } } module.exports = Paciente; diff --git a/healthway_app/lib/controllers/chat_controller.dart b/healthway_app/lib/controllers/chat_controller.dart new file mode 100644 index 0000000..020ad41 --- /dev/null +++ b/healthway_app/lib/controllers/chat_controller.dart @@ -0,0 +1,35 @@ +import 'package:get/get.dart'; +import '../models/message_model.dart'; +import '../services/chat_services.dart'; + +class ChatController extends GetxController { + final ChatService _chatService = ChatService(); + final RxList messages = [].obs; + + @override + void onInit() { + super.onInit(); + _loadMessages(); + } + + Future _loadMessages() async { + try { + final loadedMessages = await _chatService.getMessages(); + messages.assignAll(loadedMessages); + } catch (e) { + print('Error loading messages: $e'); + // TODO: Handle error (e.g., show a snackbar) + } + } + + Future sendMessage(String text) async { + try { + final newMessage = await _chatService.sendMessage(text); + messages.insert(0, newMessage); + } catch (e) { + print('Error sending message: $e'); + // TODO: Handle error (e.g., show a snackbar) + } + } +} + diff --git a/healthway_app/lib/geral_screens/chat_screen.dart b/healthway_app/lib/geral_screens/chat_screen.dart new file mode 100644 index 0000000..058d865 --- /dev/null +++ b/healthway_app/lib/geral_screens/chat_screen.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../controllers/chat_controller.dart'; +import '../widgets/chat_input_field.dart'; +import '../widgets/chat_message_bubble.dart'; + +class ChatScreen extends StatelessWidget { + final ChatController chatController = Get.put(ChatController()); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Row( + children: [ + CircleAvatar( + backgroundColor: Color(0xFF31BAC2), + child: Icon(Icons.person, color: Colors.white), + radius: 20, + ), + SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Nutricionista', + style: TextStyle(fontSize: 16, color: Colors.white)), + Text('Online', + style: TextStyle(fontSize: 12, color: Colors.white70)), + ], + ), + ], + ), + backgroundColor: Color(0xFF31BAC2), + actions: [ + IconButton(icon: Icon(Icons.video_call), onPressed: () {}), + IconButton(icon: Icon(Icons.call), onPressed: () {}), + IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), + ], + ), + body: Container( + decoration: BoxDecoration( + color: Colors.white, + ), + child: Column( + children: [ + Expanded( + child: Obx(() { + return ListView.builder( + reverse: true, + itemCount: chatController.messages.length, + itemBuilder: (context, index) { + final message = chatController.messages[index]; + return ChatMessageBubble(message: message); + }, + ); + }), + ), + ChatInputField( + onSendMessage: (String text) { + chatController.sendMessage(text); + }, + ), + ], + ), + ), + ); + } +} diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index 8932a49..a4d0334 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -16,6 +16,7 @@ class _LoginScreenState extends State { final _emailController = TextEditingController(); final _senhaController = TextEditingController(); bool _obscurePassword = true; + bool _isLoading = false; String _userType = 'Paciente'; final ServicesFacade _servicesFacade = ServicesFacade(); @@ -191,7 +192,7 @@ class _LoginScreenState extends State { Widget _buildLoginButton() { return ElevatedButton( - onPressed: _submitForm, + onPressed: _isLoading ? null : _submitForm, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: kPrimaryColor, @@ -211,7 +212,7 @@ class _LoginScreenState extends State { Navigator.pushNamed(context, '/signup_patient'); }, child: Text( - 'Sou paciente', + 'Cadastrar como paciente', style: TextStyle(color: kPrimaryColor, fontWeight: FontWeight.bold), ), ); @@ -223,7 +224,7 @@ class _LoginScreenState extends State { Navigator.pushNamed(context, '/signup_nutritionist'); }, child: Text( - 'Sou nutricionista', + 'Cadastrar como nutricionista', style: TextStyle(color: kPrimaryColor, fontWeight: FontWeight.bold), ), ); @@ -231,6 +232,9 @@ class _LoginScreenState extends State { Future _submitForm() async { if (_formKey.currentState!.validate()) { + setState(() { + _isLoading = true; + }); String email = _emailController.text; String senha = _senhaController.text; String userType = _userType; @@ -255,10 +259,11 @@ class _LoginScreenState extends State { ); } }).catchError((error) { - // Handle any errors that occur during login + setState(() { + _isLoading = false; + }); ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Ocorreu um erro. Tente novamente mais tarde.')), + SnackBar(content: Text('Erro ao fazer login: ${error.toString()}')), ); }); } diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 8bc47b4..5ffc300 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; +import 'package:healthway_app/geral_screens/chat_screen.dart'; import 'package:healthway_app/geral_screens/loginScreen.dart'; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; import 'package:healthway_app/geral_screens/presentation_screen.dart'; @@ -9,9 +10,8 @@ import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; import 'package:healthway_app/screens_nutricionist/schedule_screen.dart'; import 'package:healthway_app/screens_nutricionist/signup_nutritionist_screen.dart'; -import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; -import 'package:healthway_app/screens_patient/dietScreen.dart'; import 'package:healthway_app/screens_patient/notificationScreen.dart'; +import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; import 'package:healthway_app/screens_patient/setingsScreen.dart'; import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; @@ -46,20 +46,16 @@ class MyApp extends StatelessWidget { '/signup_nutritionist': (context) => CadastroNutricionistaScreen(), '/login': (context) => LoginScreen(), '/chat': (context) => ChatScreen(), - '/health': (context) => PlanoAlimentarScreen( - pacienteId: '', - ), + // '/historic': (context) => PlanoAlimentarScreen( + // pacienteId: '', + // ), + '/alimentos': (context) => AlimentosScreen(), '/nutricionistas': (context) => NutricionistasScreen(), - '/menu': (context) => MenuScreen(), '/notifications': (context) => NotificationScreen(), '/settings': (context) => SettingsScreen(), - '/patientList': (context) => PatientListScreen(), - '/nutritionistProfile': (context) => NutritionistProfileScreen(), + '/patientList': (context) => PacientesScreen(), '/schedule': (context) => ScheduleScreen(), - '/meal_plans': (context) => MealPlanScreen( - patientName: '', - ), }, onGenerateRoute: (settings) { switch (settings.name) { @@ -77,6 +73,16 @@ class MyApp extends StatelessWidget { return MaterialPageRoute( builder: (context) => PatientProfileScreen(userData: args), ); + case '/nutritionist_profile': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => NutritionistProfileScreen(userData: args), + ); + case '/meal_plan': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => MealPlanScreen(patientData: args), + ); default: return null; } @@ -85,45 +91,6 @@ class MyApp extends StatelessWidget { } } -class HomeScreen extends StatelessWidget { - const HomeScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text('Home')), - bottomNavigationBar: CustomBottomNavigationBar(), - body: Center(child: Text('Tela Inicial')), - ); - } -} - -class ChatScreen extends StatelessWidget { - const ChatScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text('Chat')), - bottomNavigationBar: CustomBottomNavigationBar(), - body: Center(child: Text('Tela de Chat')), - ); - } -} - -class MenuScreen extends StatelessWidget { - const MenuScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text('Menu')), - bottomNavigationBar: CustomBottomNavigationBar(), - body: Center(child: Text('Tela de Menu')), - ); - } -} - class CustomBottomNavigationBar extends StatelessWidget { const CustomBottomNavigationBar({super.key}); diff --git a/healthway_app/lib/models/message_model.dart b/healthway_app/lib/models/message_model.dart new file mode 100644 index 0000000..0900fd9 --- /dev/null +++ b/healthway_app/lib/models/message_model.dart @@ -0,0 +1,36 @@ +class Message { + final String id; + final String senderId; + final String senderName; + final String text; + final DateTime timestamp; + + Message({ + required this.id, + required this.senderId, + required this.senderName, + required this.text, + required this.timestamp, + }); + + factory Message.fromJson(Map json) { + return Message( + id: json['id'], + senderId: json['senderId'], + senderName: json['senderName'], + text: json['text'], + timestamp: DateTime.parse(json['timestamp']), + ); + } + + Map toJson() { + return { + 'id': id, + 'senderId': senderId, + 'senderName': senderName, + 'text': text, + 'timestamp': timestamp.toIso8601String(), + }; + } +} + diff --git a/healthway_app/lib/models/paciente.dart b/healthway_app/lib/models/paciente.dart index ed6d02a..f90f0fe 100644 --- a/healthway_app/lib/models/paciente.dart +++ b/healthway_app/lib/models/paciente.dart @@ -3,15 +3,15 @@ class Paciente { final String nome; final String email; final String cpf; - final Map dataNascimento; + final String dataNascimento; final String sexo; final double altura; final double peso; final double circunferenciaAbdominal; final double gorduraCorporal; final double massaMuscular; - final String alergias; - final String preferencias; + final List alergias; + final List preferencias; final String senha; Paciente({ @@ -37,15 +37,15 @@ class Paciente { nome: json['nome'], email: json['email'], cpf: json['cpf'], - dataNascimento: Map.from(json['dt_nascimento']), + dataNascimento: json['dt_nascimento'], sexo: json['sexo'], altura: json['altura'].toDouble(), peso: json['peso'].toDouble(), - circunferenciaAbdominal: json['circunferenciaAbdominal'].toDouble(), - gorduraCorporal: json['gorduraCorporal'].toDouble(), - massaMuscular: json['massaMuscular'].toDouble(), - alergias: json['alergias'], - preferencias: json['preferencias'], + circunferenciaAbdominal: json['circunferencia_abdominal'].toDouble(), + gorduraCorporal: json['gordura_corporal'].toDouble(), + massaMuscular: json['massa_muscular'].toDouble(), + alergias: List.from(json['alergias']), + preferencias: List.from(json['preferencias']), senha: json['senha'], ); } @@ -60,9 +60,9 @@ class Paciente { 'sexo': sexo, 'altura': altura, 'peso': peso, - 'circunferenciaAbdominal': circunferenciaAbdominal, - 'gorduraCorporal': gorduraCorporal, - 'massaMuscular': massaMuscular, + 'circunferencia_abdominal': circunferenciaAbdominal, + 'gordura_corporal': gorduraCorporal, + 'massa_muscular': massaMuscular, 'alergias': alergias, 'preferencias': preferencias, }; @@ -73,15 +73,15 @@ class Paciente { String? nome, String? email, String? cpf, - Map? dataNascimento, + String? dataNascimento, String? sexo, double? altura, double? peso, double? circunferenciaAbdominal, double? gorduraCorporal, double? massaMuscular, - String? alergias, - String? preferencias, + List? alergias, + List? preferencias, String? senha, }) { return Paciente( @@ -105,6 +105,6 @@ class Paciente { @override String toString() { - return 'Paciente(id: $id, nome: $nome, email: $email, cpf: $cpf, dt_nascimento: $dataNascimento, sexo: $sexo, altura: $altura, peso: $peso, circunferenciaAbdominal: $circunferenciaAbdominal, gorduraCorporal: $gorduraCorporal, massaMuscular: $massaMuscular, alergias: $alergias, preferencias: $preferencias)'; + return 'Paciente(id: $id, nome: $nome, email: $email, cpf: $cpf, dataNascimento: $dataNascimento, sexo: $sexo, altura: $altura, peso: $peso, circunferenciaAbdominal: $circunferenciaAbdominal, gorduraCorporal: $gorduraCorporal, massaMuscular: $massaMuscular, alergias: $alergias, preferencias: $preferencias)'; } } diff --git a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart index 4959a89..019bab8 100644 --- a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart +++ b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; class MealPlanScreen extends StatelessWidget { - final String patientName; + final Map patientData; - const MealPlanScreen({super.key, required this.patientName}); + const MealPlanScreen({super.key, required this.patientData}); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F5F5), appBar: AppBar( - title: Text('Plano Alimentar - $patientName'), + title: Text('Plano Alimentar - ${patientData['nome']}'), backgroundColor: const Color(0xFF31BAC2), elevation: 0, ), @@ -18,11 +18,22 @@ class MealPlanScreen extends StatelessWidget { child: ListView( padding: const EdgeInsets.all(16.0), children: [ - _buildMealCard('Café da Manhã', ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), - _buildMealCard('Lanche da Manhã', ['1 iogurte natural', '1 punhado de castanhas']), - _buildMealCard('Almoço', ['150g de frango grelhado', '1 xícara de arroz integral', 'Salada verde']), - _buildMealCard('Lanche da Tarde', ['1 banana', '1 colher de sopa de pasta de amendoim']), - _buildMealCard('Jantar', ['150g de peixe assado', '1 batata doce média', 'Legumes no vapor']), + _buildMealCard('Café da Manhã', + ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), + _buildMealCard('Lanche da Manhã', + ['1 iogurte natural', '1 punhado de castanhas']), + _buildMealCard('Almoço', [ + '150g de frango grelhado', + '1 xícara de arroz integral', + 'Salada verde' + ]), + _buildMealCard('Lanche da Tarde', + ['1 banana', '1 colher de sopa de pasta de amendoim']), + _buildMealCard('Jantar', [ + '150g de peixe assado', + '1 batata doce média', + 'Legumes no vapor' + ]), SizedBox(height: 16), ElevatedButton( onPressed: () { @@ -57,23 +68,26 @@ class MealPlanScreen extends StatelessWidget { children: [ Text( mealName, - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Color(0xFF31BAC2)), ), SizedBox(height: 8), ...foods.map((food) => Padding( - padding: const EdgeInsets.only(bottom: 4), - child: Row( - children: [ - Icon(Icons.fiber_manual_record, size: 8, color: Color(0xFF31BAC2)), - SizedBox(width: 8), - Text(food, style: TextStyle(fontSize: 16)), - ], - ), - )).toList(), + padding: const EdgeInsets.only(bottom: 4), + child: Row( + children: [ + Icon(Icons.fiber_manual_record, + size: 8, color: Color(0xFF31BAC2)), + SizedBox(width: 8), + Text(food, style: TextStyle(fontSize: 16)), + ], + ), + )), ], ), ), ); } } - diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart index 7b07721..86be1cd 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart @@ -1,11 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; class NutritionistProfileScreen extends StatefulWidget { - const NutritionistProfileScreen({super.key}); + final Object userData; + + const NutritionistProfileScreen({super.key, required this.userData}); @override - _NutritionistProfileScreenState createState() => _NutritionistProfileScreenState(); + State createState() => + _NutritionistProfileScreenState(); } class _NutritionistProfileScreenState extends State { @@ -67,10 +69,10 @@ class _NutritionistProfileScreenState extends State { ), floatingActionButton: _isEditing ? FloatingActionButton( - onPressed: _saveChanges, - backgroundColor: Color(0xFF31BAC2), - child: Icon(Icons.save), - ) + onPressed: _saveChanges, + backgroundColor: Color(0xFF31BAC2), + child: Icon(Icons.save), + ) : null, ); } @@ -88,9 +90,12 @@ class _NutritionistProfileScreenState extends State { backgroundImage: NetworkImage(fotoPerfil), child: fotoPerfil.isEmpty ? Text( - nome.isNotEmpty ? nome[0].toUpperCase() : '?', - style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white), - ) + nome.isNotEmpty ? nome[0].toUpperCase() : '?', + style: TextStyle( + fontSize: 40, + fontWeight: FontWeight.bold, + color: Colors.white), + ) : null, ), if (!_isEditing) @@ -111,33 +116,33 @@ class _NutritionistProfileScreenState extends State { SizedBox(height: 16), _isEditing ? TextFormField( - initialValue: nome, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - textAlign: TextAlign.center, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: (value) => nome = value, - ) + initialValue: nome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => nome = value, + ) : Text( - nome, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), + nome, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), SizedBox(height: 8), _isEditing ? TextFormField( - initialValue: email, - style: TextStyle(fontSize: 16, color: Colors.grey[600]), - textAlign: TextAlign.center, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: (value) => email = value, - ) + initialValue: email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + textAlign: TextAlign.center, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: (value) => email = value, + ) : Text( - email, - style: TextStyle(fontSize: 16, color: Colors.grey[600]), - ), + email, + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + ), ], ), ); @@ -152,7 +157,8 @@ class _NutritionistProfileScreenState extends State { children: [ _buildInfoRow('CPF', cpf, (value) => cpf = value), _buildInfoRow('CRN', crn, (value) => crn = value), - _buildInfoRow('Especialidade', especialidade, (value) => especialidade = value), + _buildInfoRow('Especialidade', especialidade, + (value) => especialidade = value), ], ), ), @@ -166,21 +172,21 @@ class _NutritionistProfileScreenState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: TextStyle(fontSize: 16, color: Colors.grey[600])), - _isEditing && onChanged != null + _isEditing ? SizedBox( - width: 200, - child: TextFormField( - initialValue: value, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), - textAlign: TextAlign.right, - decoration: InputDecoration( - border: UnderlineInputBorder(), - ), - onChanged: onChanged, - ), - ) + width: 200, + child: TextFormField( + initialValue: value, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + textAlign: TextAlign.right, + decoration: InputDecoration( + border: UnderlineInputBorder(), + ), + onChanged: onChanged, + ), + ) : Text(value, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ], ), ); @@ -196,7 +202,8 @@ class _NutritionistProfileScreenState extends State { style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), ), child: Text('Editar Perfil Detalhado'), ), @@ -206,8 +213,10 @@ class _NutritionistProfileScreenState extends State { // Navigate to change password screen }, style: OutlinedButton.styleFrom( - foregroundColor: Color(0xFF31BAC2), padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + foregroundColor: Color(0xFF31BAC2), + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), side: BorderSide(color: Color(0xFF31BAC2)), ), child: Text('Alterar Senha'), @@ -246,7 +255,8 @@ class _NutritionistProfileScreenState extends State { ), ), child: fotoDocumento.isEmpty - ? Icon(Icons.add_a_photo, size: 50, color: Color(0xFF31BAC2)) + ? Icon(Icons.add_a_photo, + size: 50, color: Color(0xFF31BAC2)) : null, ), ), @@ -270,4 +280,3 @@ class _NutritionistProfileScreenState extends State { } } } - diff --git a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart index 92b9a02..0ac6408 100644 --- a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart +++ b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart @@ -1,73 +1,161 @@ import 'package:flutter/material.dart'; +import '../models/paciente.dart'; +import '../services/paciente_services.dart'; +import '../widgets/paciente_item.dart'; -class PatientListScreen extends StatelessWidget { - const PatientListScreen({super.key}); +class PacientesScreen extends StatefulWidget { + const PacientesScreen({super.key}); + + @override + _PacientesScreenState createState() => _PacientesScreenState(); +} + +class _PacientesScreenState extends State { + late Future> _pacientes; + List pacientes = []; + List pacientesFiltrados = []; + TextEditingController searchController = TextEditingController(); + + @override + void initState() { + super.initState(); + _carregarPacientes(); + } + + void _carregarPacientes() { + setState(() { + _pacientes = PacienteService().fetchPacientes(); + }); + } + + void _filtrarPacientes(String query) { + setState(() { + pacientesFiltrados = pacientes + .where((paciente) => + paciente.nome.toLowerCase().contains(query.toLowerCase()) || + paciente.email.toLowerCase().contains(query.toLowerCase())) + .toList(); + }); + } @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: Color(0xFFF5F5F5), appBar: AppBar( - title: const Text('Meus Pacientes'), - backgroundColor: const Color(0xFF31BAC2), + title: Text('Pacientes'), + backgroundColor: Color(0xFF31BAC2), elevation: 0, ), - body: SafeArea( - child: ListView.builder( - itemCount: 10, // Exemplo com 10 pacientes - itemBuilder: (context, index) { - return _buildPatientItem('Paciente ${index + 1}', 'Última consulta: ${10 - index}d atrás'); - }, - ), + body: Column( + children: [ + _buildSearchBar(), + Expanded( + child: FutureBuilder>( + future: _pacientes, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center( + child: + CircularProgressIndicator(color: Color(0xFF31BAC2))); + } else if (snapshot.hasError) { + return _buildErrorWidget(snapshot.error.toString()); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return _buildEmptyWidget(); + } else { + pacientes = snapshot.data!; + if (pacientesFiltrados.isEmpty) { + pacientesFiltrados = pacientes; + } + return _buildPacientesList(); + } + }, + ), + ), + ], ), floatingActionButton: FloatingActionButton( - onPressed: () { - // Adicionar novo paciente - }, + onPressed: _carregarPacientes, backgroundColor: Color(0xFF31BAC2), - child: Icon(Icons.add), + child: Icon(Icons.refresh), ), ); } - Widget _buildPatientItem(String name, String lastConsultation) { + Widget _buildSearchBar() { return Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 1, - blurRadius: 5, - offset: Offset(0, 3), + padding: EdgeInsets.all(16), + color: Color(0xFF31BAC2), + child: TextField( + controller: searchController, + onChanged: _filtrarPacientes, + decoration: InputDecoration( + hintText: 'Pesquisar por nome ou email...', + prefixIcon: Icon(Icons.search, color: Color(0xFF31BAC2)), + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30), + borderSide: BorderSide.none, + ), + ), + ), + ); + } + + Widget _buildPacientesList() { + return ListView.builder( + itemCount: pacientesFiltrados.length, + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + child: PacienteItem(paciente: pacientesFiltrados[index]), + ), + ); + }, + ); + } + + Widget _buildErrorWidget(String error) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.error_outline, size: 60, color: Colors.red), + SizedBox(height: 16), + Text( + 'Erro ao carregar pacientes', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text( + error, + style: TextStyle(color: Colors.grey[600]), + textAlign: TextAlign.center, ), ], ), - child: ListTile( - contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), - leading: CircleAvatar( - backgroundColor: Color(0xFF31BAC2), - child: Text( - name[0], - style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold), + ); + } + + Widget _buildEmptyWidget() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.person_off, size: 60, color: Color(0xFF31BAC2)), + SizedBox(height: 16), + Text( + 'Nenhum paciente encontrado', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), - ), - title: Text( - name, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), - ), - subtitle: Text( - lastConsultation, - style: TextStyle(color: Colors.grey[600], fontSize: 14), - ), - trailing: Icon(Icons.chevron_right, color: Color(0xFF31BAC2)), - onTap: () { - // Navegar para os detalhes do paciente - }, + ], ), ); } } - diff --git a/healthway_app/lib/screens_nutricionist/schedule_screen.dart b/healthway_app/lib/screens_nutricionist/schedule_screen.dart index db9ba68..68c11a9 100644 --- a/healthway_app/lib/screens_nutricionist/schedule_screen.dart +++ b/healthway_app/lib/screens_nutricionist/schedule_screen.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:table_calendar/table_calendar.dart'; -import 'package:intl/intl.dart'; class ScheduleScreen extends StatefulWidget { const ScheduleScreen({super.key}); @@ -144,7 +143,8 @@ class _ScheduleScreenState extends State { builder: (BuildContext context) { return AlertDialog( title: Text('Adicionar Consulta'), - content: Text('Funcionalidade de adicionar consulta a ser implementada.'), + content: + Text('Funcionalidade de adicionar consulta a ser implementada.'), actions: [ TextButton( child: Text('OK'), @@ -195,4 +195,3 @@ class Appointment { Appointment(this.patientName, this.type, this.time); } - diff --git a/healthway_app/lib/screens_patient/dietScreen.dart b/healthway_app/lib/screens_patient/dietScreen.dart index 7a2f3fb..5459ba2 100644 --- a/healthway_app/lib/screens_patient/dietScreen.dart +++ b/healthway_app/lib/screens_patient/dietScreen.dart @@ -4,10 +4,10 @@ import 'package:intl/intl.dart'; class PlanoAlimentarScreen extends StatefulWidget { final String pacienteId; - const PlanoAlimentarScreen({Key? key, required this.pacienteId}) : super(key: key); + const PlanoAlimentarScreen({super.key, required this.pacienteId}); @override - _PlanoAlimentarScreenState createState() => _PlanoAlimentarScreenState(); + State createState() => _PlanoAlimentarScreenState(); } class _PlanoAlimentarScreenState extends State { @@ -30,9 +30,18 @@ class _PlanoAlimentarScreenState extends State { dtInicio: DateTime.now(), dtFim: DateTime.now().add(Duration(days: 30)), refeicoes: [ - Refeicao('Café da Manhã', ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), - Refeicao('Almoço', ['150g de frango grelhado', '1 xícara de arroz integral', 'Salada verde']), - Refeicao('Jantar', ['150g de peixe assado', '1 batata doce média', 'Legumes no vapor']), + Refeicao('Café da Manhã', + ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), + Refeicao('Almoço', [ + '150g de frango grelhado', + '1 xícara de arroz integral', + 'Salada verde' + ]), + Refeicao('Jantar', [ + '150g de peixe assado', + '1 batata doce média', + 'Legumes no vapor' + ]), ], paciente: widget.pacienteId, ), @@ -46,15 +55,16 @@ class _PlanoAlimentarScreenState extends State { return Scaffold( backgroundColor: Color(0xFFF5F5F5), appBar: AppBar( - title: Text('Plano Alimentar', style: TextStyle(fontWeight: FontWeight.bold)), + title: Text('Plano Alimentar', + style: TextStyle(fontWeight: FontWeight.bold)), backgroundColor: Color(0xFF31BAC2), elevation: 0, ), body: isLoading ? Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))) : planosAlimentares.isEmpty - ? _buildEmptyState() - : _buildPlanoAlimentarList(), + ? _buildEmptyState() + : _buildPlanoAlimentarList(), floatingActionButton: FloatingActionButton( onPressed: () { // TODO: Implementar a criação de um novo plano alimentar @@ -96,13 +106,16 @@ class _PlanoAlimentarScreenState extends State { child: ExpansionTile( title: Text( plano.consulta, - style: TextStyle(fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + style: TextStyle( + fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), ), subtitle: Text( '${DateFormat('dd/MM/yyyy').format(plano.dtInicio)} - ${DateFormat('dd/MM/yyyy').format(plano.dtFim)}', style: TextStyle(color: Colors.grey[600]), ), - children: plano.refeicoes.map((refeicao) => _buildRefeicaoItem(refeicao)).toList(), + children: plano.refeicoes + .map((refeicao) => _buildRefeicaoItem(refeicao)) + .toList(), ), ); }, @@ -121,9 +134,9 @@ class _PlanoAlimentarScreenState extends State { ), SizedBox(height: 4), ...refeicao.alimentos.map((alimento) => Padding( - padding: const EdgeInsets.only(left: 16, top: 2), - child: Text('• $alimento'), - )), + padding: const EdgeInsets.only(left: 16, top: 2), + child: Text('• $alimento'), + )), ], ), ); @@ -152,4 +165,3 @@ class Refeicao { Refeicao(this.nome, this.alimentos); } - diff --git a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart index af7c25a..227a1bf 100644 --- a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart +++ b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart @@ -84,9 +84,13 @@ class PatientDashboardScreen extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - _buildStatItem('IMC', '22.5'), - _buildStatItem('Peso', '70 kg'), - _buildStatItem('Altura', '1.75 m'), + _buildStatItem( + 'IMC', + _calculateBMI(userData['altura'], userData['peso']) + .toStringAsFixed(1), + ), + _buildStatItem('Peso', '${userData['peso'].toInt()} kg'), + _buildStatItem('Altura', '${userData['altura'].toInt()} cm'), ], ), ), @@ -136,13 +140,14 @@ class PatientDashboardScreen extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + _buildQuickAccessItem(context, Icons.restaurant_menu, 'Dieta', + '/meal_plan', userData), + _buildQuickAccessItem(context, Icons.people, 'Nutricionistas', + '/nutricionistas', null), _buildQuickAccessItem( - context, Icons.restaurant_menu, 'Dieta', '/diet'), - _buildQuickAccessItem( - context, Icons.people, 'Nutricionistas', '/nutricionistas'), + context, Icons.insert_chart, 'Progresso', '/progress', null), _buildQuickAccessItem( - context, Icons.insert_chart, 'Progresso', '/progress'), - _buildQuickAccessItem(context, Icons.message, 'Chat', '/chat'), + context, Icons.message, 'Chat', '/chat', null), ], ), ], @@ -150,12 +155,12 @@ class PatientDashboardScreen extends StatelessWidget { ); } - Widget _buildQuickAccessItem( - BuildContext context, IconData icon, String label, String route) { + Widget _buildQuickAccessItem(BuildContext context, IconData icon, + String label, String route, Object? args) { return GestureDetector( onTap: () { - Navigator.pushNamed( - context, route); // Aqui você agora tem acesso ao 'context' + Navigator.pushNamed(context, route, + arguments: args); // Aqui você agora tem acesso ao 'context' }, child: Column( children: [ @@ -343,7 +348,7 @@ class PatientDashboardScreen extends StatelessWidget { // Já estamos na tela inicial, então não faça nada break; case 1: - Navigator.pushNamed(context, '/health'); + Navigator.pushNamed(context, '/meal_plan', arguments: userData); break; case 2: Navigator.pushNamed(context, '/progress'); @@ -357,4 +362,9 @@ class PatientDashboardScreen extends StatelessWidget { ), ); } + + double _calculateBMI(alturaM, peso) { + var alturaCm = alturaM / 100; + return peso / (alturaCm * alturaCm); + } } diff --git a/healthway_app/lib/screens_patient/patient_profile_screen.dart b/healthway_app/lib/screens_patient/patient_profile_screen.dart index 61bf4e9..93b0ffc 100644 --- a/healthway_app/lib/screens_patient/patient_profile_screen.dart +++ b/healthway_app/lib/screens_patient/patient_profile_screen.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:healthway_app/models/paciente.dart'; import 'package:healthway_app/services/services_facade.dart'; +import 'package:intl/intl.dart'; class PatientProfileScreen extends StatefulWidget { final Map userData; @@ -36,12 +37,9 @@ class _PatientProfileScreenState extends State { name = widget.userData['nome']; email = widget.userData['email']; var birthDate = widget.userData['dt_nascimento']; - age = DateTime.now() - .difference(DateTime.fromMillisecondsSinceEpoch( - birthDate['_seconds'] * 1000 + - birthDate['_nanoseconds'] ~/ 1000000)) - .inDays ~/ - 365; + var ageDuration = + DateTime.now().difference(DateFormat('dd/MM/yyyy').parse(birthDate)); + age = ageDuration.inDays ~/ 365; altura = widget.userData['altura'].toDouble(); peso = widget.userData['peso'].toDouble(); circunferenciaAbdominal = @@ -318,21 +316,28 @@ class _PatientProfileScreenState extends State { void _saveChanges() { if (_formKey.currentState!.validate()) { - // Save the changes - setState(() { - _edited = false; - }); - widget.userData['altura'] = altura; - widget.userData['peso'] = peso; - widget.userData['circunferencia_abdominal'] = circunferenciaAbdominal; - widget.userData['massa_muscular'] = massaMuscular; - widget.userData['gordura_corporal'] = gorduraCorporal; - widget.userData['preferencias'] = preferencias; - widget.userData['alergias'] = alergias; - _servicesFacade.atualizar(Paciente.fromJson(widget.userData)); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Perfil atualizado com sucesso!')), - ); + try { + // Save the changes + setState(() { + _edited = false; + }); + widget.userData['altura'] = altura.toDouble(); + widget.userData['peso'] = peso.toDouble(); + widget.userData['circunferencia_abdominal'] = + circunferenciaAbdominal.toDouble(); + widget.userData['massa_muscular'] = massaMuscular.toDouble(); + widget.userData['gordura_corporal'] = gorduraCorporal.toDouble(); + widget.userData['preferencias'] = preferencias; + widget.userData['alergias'] = alergias; + _servicesFacade.atualizar(Paciente.fromJson(widget.userData)); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Perfil atualizado com sucesso')), + ); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Erro ao atualizar perfil: $e')), + ); + } } } diff --git a/healthway_app/lib/screens_patient/signup_patient_screen.dart b/healthway_app/lib/screens_patient/signup_patient_screen.dart index de2ed27..014a498 100644 --- a/healthway_app/lib/screens_patient/signup_patient_screen.dart +++ b/healthway_app/lib/screens_patient/signup_patient_screen.dart @@ -404,19 +404,11 @@ class _CadastroPacienteScreenState extends State { try { final dataNascimento = DateFormat('dd/MM/yyyy').parse(_dataNascimentoController.text); - final dataNascimentoEmSegundos = - dataNascimento.millisecondsSinceEpoch ~/ 1000; - final dataNascimentoEmNanosegundos = - dataNascimento.microsecondsSinceEpoch * 1000; - final dataNascimentoMap = { - '_seconds': dataNascimentoEmSegundos, - '_nanoseconds': dataNascimentoEmNanosegundos, - }; await _servicesFacade.cadastrar(Paciente( nome: _nomeController.text, email: _emailController.text, cpf: _cpfController.text, - dataNascimento: dataNascimentoMap, + dataNascimento: DateFormat('dd/MM/yyyy').format(dataNascimento), sexo: _sexo!, altura: double.parse(_alturaController.text), peso: double.parse(_pesoController.text), @@ -424,8 +416,8 @@ class _CadastroPacienteScreenState extends State { double.parse(_circunferenciaAbdominalController.text), gorduraCorporal: double.parse(_gorduraCorporalController.text), massaMuscular: double.parse(_massaMuscularController.text), - alergias: _alergiasController.text, - preferencias: _preferenciasController.text, + alergias: [], + preferencias: [], senha: _senhaController.text, )); diff --git a/healthway_app/lib/services/chat_services.dart b/healthway_app/lib/services/chat_services.dart new file mode 100644 index 0000000..7fc58bb --- /dev/null +++ b/healthway_app/lib/services/chat_services.dart @@ -0,0 +1,29 @@ +import '../models/message_model.dart'; +import 'package:uuid/uuid.dart'; + +class ChatService { + final List _messages = []; + final _uuid = Uuid(); + + Future> getMessages() async { + // Simulating API call delay + await Future.delayed(Duration(seconds: 1)); + return _messages; + } + + Future sendMessage(String text) async { + // Simulating API call delay + await Future.delayed(Duration(milliseconds: 500)); + + final newMessage = Message( + id: _uuid.v4(), + senderId: 'currentUser', // Replace with actual user ID + senderName: 'You', // Replace with actual user name + text: text, + timestamp: DateTime.now(), + ); + + _messages.insert(0, newMessage); + return newMessage; + } +} diff --git a/healthway_app/lib/services/paciente_services.dart b/healthway_app/lib/services/paciente_services.dart index 68c717f..e7f4f8a 100644 --- a/healthway_app/lib/services/paciente_services.dart +++ b/healthway_app/lib/services/paciente_services.dart @@ -46,16 +46,16 @@ class PacienteService { request.fields['nome'] = paciente.nome; request.fields['email'] = paciente.email; request.fields['cpf'] = paciente.cpf; - request.fields['dataNascimento'] = paciente.dataNascimento.toString(); + request.fields['dt_nascimento'] = paciente.dataNascimento.toString(); request.fields['sexo'] = paciente.sexo; request.fields['altura'] = paciente.altura.toString(); request.fields['peso'] = paciente.peso.toString(); - request.fields['circunferenciaAbdominal'] = + request.fields['circunferencia_abdominal'] = paciente.circunferenciaAbdominal.toString(); - request.fields['gorduraCorporal'] = paciente.gorduraCorporal.toString(); - request.fields['massaMuscular'] = paciente.massaMuscular.toString(); - request.fields['alergias'] = paciente.alergias; - request.fields['preferencias'] = paciente.preferencias; + request.fields['gordura_corporal'] = paciente.gorduraCorporal.toString(); + request.fields['massa_muscular'] = paciente.massaMuscular.toString(); + request.fields['alergias'] = paciente.alergias.toString(); + request.fields['preferencias'] = paciente.preferencias.toString(); request.fields['senha'] = paciente.senha; var response = await request.send(); @@ -81,24 +81,25 @@ class PacienteService { Future atualizarPaciente(Paciente paciente) async { var uri = Uri.parse('$apiUrl/${paciente.id}'); - var request = http.MultipartRequest('PUT', uri); - - request.fields['nome'] = paciente.nome; - request.fields['email'] = paciente.email; - request.fields['cpf'] = paciente.cpf; - request.fields['dataNascimento'] = paciente.dataNascimento.toString(); - request.fields['sexo'] = paciente.sexo; - request.fields['altura'] = paciente.altura.toString(); - request.fields['peso'] = paciente.peso.toString(); - request.fields['circunferenciaAbdominal'] = - paciente.circunferenciaAbdominal.toString(); - request.fields['gorduraCorporal'] = paciente.gorduraCorporal.toString(); - request.fields['massaMuscular'] = paciente.massaMuscular.toString(); - request.fields['alergias'] = paciente.alergias; - request.fields['preferencias'] = paciente.preferencias; - request.fields['senha'] = paciente.senha; - - var response = await request.send(); + var response = await http.put( + uri, + headers: {'Content-Type': 'application/json'}, + body: jsonEncode({ + 'nome': paciente.nome, + 'email': paciente.email, + 'cpf': paciente.cpf, + 'dt_nascimento': paciente.dataNascimento.toString(), + 'sexo': paciente.sexo, + 'altura': paciente.altura.toString(), + 'peso': paciente.peso.toString(), + 'circunferencia_abdominal': paciente.circunferenciaAbdominal.toString(), + 'gordura_corporal': paciente.gorduraCorporal.toString(), + 'massa_muscular': paciente.massaMuscular.toString(), + 'alergias': paciente.alergias, + 'preferencias': paciente.preferencias, + 'senha': paciente.senha, + }), + ); if (response.statusCode != 200) { throw Exception('Falha ao atualizar paciente'); } diff --git a/healthway_app/lib/services/services_facade.dart b/healthway_app/lib/services/services_facade.dart index 06bf655..4157698 100644 --- a/healthway_app/lib/services/services_facade.dart +++ b/healthway_app/lib/services/services_facade.dart @@ -46,9 +46,17 @@ class ServicesFacade { Future atualizar(dynamic entity) async { if (entity is Nutricionista) { - await _nutricionistaService.atualizarNutricionista(entity); + try { + await _nutricionistaService.atualizarNutricionista(entity); + } catch (e) { + throw Exception('Erro ao atualizar Nutricionista: $e'); + } } else if (entity is Paciente) { - await _pacienteService.atualizarPaciente(entity); + try { + await _pacienteService.atualizarPaciente(entity); + } catch (e) { + throw Exception('Erro ao atualizar Paciente: $e'); + } } else { throw Exception('Tipo de entidade desconhecido'); } diff --git a/healthway_app/lib/widgets/chat_input_field.dart b/healthway_app/lib/widgets/chat_input_field.dart new file mode 100644 index 0000000..b7b02c8 --- /dev/null +++ b/healthway_app/lib/widgets/chat_input_field.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; + +class ChatInputField extends StatefulWidget { + final Function(String) onSendMessage; + + const ChatInputField({super.key, required this.onSendMessage}); + + @override + _ChatInputFieldState createState() => _ChatInputFieldState(); +} + +class _ChatInputFieldState extends State { + final TextEditingController _textController = TextEditingController(); + bool _isComposing = false; + + void _handleSubmitted(String text) { + widget.onSendMessage(text); + setState(() { + _isComposing = false; + }); + _textController.clear(); + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + offset: Offset(0, -2), + blurRadius: 4, + color: Colors.black.withOpacity(0.1), + ), + ], + ), + child: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0), + child: Row( + children: [ + IconButton( + icon: Icon(Icons.emoji_emotions_outlined, color: Color(0xFF31BAC2)), + onPressed: () { + // TODO: Implement emoji picker + }, + ), + Expanded( + child: TextField( + controller: _textController, + onChanged: (text) { + setState(() { + _isComposing = text.isNotEmpty; + }); + }, + onSubmitted: _isComposing ? _handleSubmitted : null, + decoration: InputDecoration( + hintText: 'Digite uma mensagem...', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(25.0), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.grey[100], + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + ), + style: TextStyle(color: Colors.black87, fontSize: 16), + ), + ), + IconButton( + icon: Icon(Icons.attach_file, color: Color(0xFF31BAC2)), + onPressed: () { + // TODO: Implement file attachment + }, + ), + IconButton( + icon: Icon(_isComposing ? Icons.send : Icons.mic, color: Color(0xFF31BAC2)), + onPressed: _isComposing + ? () => _handleSubmitted(_textController.text) + : () { + // TODO: Implement voice recording + }, + ), + ], + ), + ), + ), + ); + } +} + diff --git a/healthway_app/lib/widgets/chat_message_bubble.dart b/healthway_app/lib/widgets/chat_message_bubble.dart new file mode 100644 index 0000000..126427b --- /dev/null +++ b/healthway_app/lib/widgets/chat_message_bubble.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import '../models/message_model.dart'; + +class ChatMessageBubble extends StatelessWidget { + final Message message; + + const ChatMessageBubble({Key? key, required this.message}) : super(key: key); + + @override + Widget build(BuildContext context) { + final isMe = message.senderId == 'currentUser'; // Replace with actual user ID check + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + child: Row( + mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start, + children: [ + if (!isMe) SizedBox(width: 40), + Flexible( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10), + decoration: BoxDecoration( + color: isMe ? Color(0xFF31BAC2).withOpacity(0.2) : Colors.grey[200], + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + spreadRadius: 1, + blurRadius: 1, + offset: Offset(0, 1), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + message.text, + style: TextStyle( + color: Colors.black87, + fontSize: 16, + ), + ), + SizedBox(height: 4), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + DateFormat('HH:mm').format(message.timestamp), + style: TextStyle( + color: Colors.black54, + fontSize: 12, + ), + ), + if (isMe) SizedBox(width: 4), + if (isMe) Icon( + Icons.done_all, + size: 16, + color: Color(0xFF31BAC2), + ), + ], + ), + ], + ), + ), + ), + if (isMe) SizedBox(width: 40), + ], + ), + ); + } +} + diff --git a/healthway_app/lib/widgets/paciente_item.dart b/healthway_app/lib/widgets/paciente_item.dart new file mode 100644 index 0000000..d9b8444 --- /dev/null +++ b/healthway_app/lib/widgets/paciente_item.dart @@ -0,0 +1,115 @@ +import 'package:flutter/material.dart'; +import '../models/paciente.dart'; + +class PacienteItem extends StatelessWidget { + final Paciente paciente; + + const PacienteItem({Key? key, required this.paciente}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ListTile( + contentPadding: EdgeInsets.all(16), + leading: CircleAvatar( + backgroundColor: Colors.grey[300], + child: Icon( + Icons.person, + color: Colors.grey[700], + ), + ), + title: Text( + paciente.nome, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 4), + Text('Email: ${paciente.email}'), + Text('CPF: ${paciente.cpf}'), + ], + ), + trailing: Icon( + Icons.chevron_right, + color: Colors.grey[700], + ), + onTap: () { + // Ação ao clicar no item (Exemplo: abrir detalhes do paciente) + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PacienteDetalhesScreen(paciente: paciente), + ), + ); + }, + ); + } +} + +class PacienteDetalhesScreen extends StatelessWidget { + final Paciente paciente; + + const PacienteDetalhesScreen({Key? key, required this.paciente}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Detalhes do Paciente'), + backgroundColor: Color(0xFF31BAC2), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + paciente.nome, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 16), + Text('Email: ${paciente.email}'), + Text('CPF: ${paciente.cpf}'), + Text('Data de Nascimento: ${paciente.dataNascimento}'), + Text('Sexo: ${paciente.sexo}'), + Text('Altura: ${paciente.altura} m'), + Text('Peso: ${paciente.peso} kg'), + Text( + 'Circunferência Abdominal: ${paciente.circunferenciaAbdominal} cm'), + Text('Gordura Corporal: ${paciente.gorduraCorporal}%'), + Text('Massa Muscular: ${paciente.massaMuscular} kg'), + SizedBox(height: 16), + Text( + 'Alergias:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: paciente.alergias + .map((alergia) => Text('- $alergia')) + .toList(), + ), + SizedBox(height: 16), + Text( + 'Preferências:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: paciente.preferencias + .map((preferencia) => Text('- $preferencia')) + .toList(), + ), + ], + ), + ), + ); + } +} diff --git a/healthway_app/pubspec.yaml b/healthway_app/pubspec.yaml index 9215c46..6bb8557 100644 --- a/healthway_app/pubspec.yaml +++ b/healthway_app/pubspec.yaml @@ -39,6 +39,8 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 + uuid: ^4.5.1 + get: ^4.6.6 dev_dependencies: flutter_test: From 0501137940e4ccab9ec5e128727466da4a8fddd1 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sun, 19 Jan 2025 15:19:11 -0300 Subject: [PATCH 19/47] adiciona testes para getByEmailAndPassword #80 --- .../nutricionistaController.test.js | 50 +++++++++++++++++++ .../controllers/pacienteController.test.js | 50 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/backend/tests/controllers/nutricionistaController.test.js b/backend/tests/controllers/nutricionistaController.test.js index a5ac475..bae62f3 100644 --- a/backend/tests/controllers/nutricionistaController.test.js +++ b/backend/tests/controllers/nutricionistaController.test.js @@ -320,4 +320,54 @@ describe('nutricionistaController', () => { expect(res.json).toHaveBeenCalledWith({ error: 'Erro ao buscar nutricionistas.' }); }); }); + + describe('getByEmailAndPassword', () => { + test('deve retornar um nutricionista pelo email e senha', async () => { + const mockData = { id: '1', nome: 'Nutricionista 1', email: 'test@example.com', senha: '123456' }; + db.get.mockResolvedValueOnce({ + docs: [{ id: mockData.id, data: () => mockData }], + }); + + const req = { body: { email: 'test@example.com', senha: '123456' } }; + const res = { + status: jest.fn().mockReturnThis(), + json: jest.fn(), + }; + + await nutricionistaController.getByEmailAndPassword(req, res); + + expect(res.status).toHaveBeenCalledWith(200); + expect(res.json).toHaveBeenCalledWith(mockData); + }); + + test('deve retornar um erro ao não achar nenhum nutricionista com o email e senha', async () => { + db.get.mockResolvedValueOnce({ docs: [] }); + + const req = { body: { email: 'test@example.com', senha: '123456' } }; + const res = { + status: jest.fn().mockReturnThis(), + json: jest.fn(), + }; + + await nutricionistaController.getByEmailAndPassword(req, res); + + expect(res.status).toHaveBeenCalledWith(404); + expect(res.json).toHaveBeenCalledWith({ error: 'Nutricionista não encontrado.' }); + }); + + test('deve retornar um erro ao buscar nutricionista pelo email e senha', async () => { + db.get.mockRejectedValueOnce(new Error('Erro ao buscar nutricionista.')); + + const req = { body: { email: 'test@example.com', senha: '123456' } }; + const res = { + status: jest.fn().mockReturnThis(), + json: jest.fn(), + }; + + await nutricionistaController.getByEmailAndPassword(req, res); + + expect(res.status).toHaveBeenCalledWith(500); + expect(res.json).toHaveBeenCalledWith({ error: 'Erro ao buscar nutricionista.' }); + }); + }); }); \ No newline at end of file diff --git a/backend/tests/controllers/pacienteController.test.js b/backend/tests/controllers/pacienteController.test.js index 5e9028b..e2cc8d9 100644 --- a/backend/tests/controllers/pacienteController.test.js +++ b/backend/tests/controllers/pacienteController.test.js @@ -204,4 +204,54 @@ describe('pacienteController', () => { expect(res.json).toHaveBeenCalledWith({ error: 'Erro ao excluir paciente.' }); }); }); + + describe('getByEmailAndPassword', () => { + test('deve retornar um paciente pelo email e senha', async () => { + const mockData = { id: '1', nome: 'João', email: 'joao@example.com', senha: '123456' }; + db.get.mockResolvedValueOnce({ + docs: [{ id: mockData.id, data: () => mockData }], + }); + + const req = { body: { email: 'joao@example.com', senha: '123456' } }; + const res = { + status: jest.fn().mockReturnThis(), + json: jest.fn(), + }; + + await pacienteController.getByEmailAndPassword(req, res); + + expect(res.status).toHaveBeenCalledWith(200); + expect(res.json).toHaveBeenCalledWith(mockData); + }); + + test('deve retornar um erro ao não achar nenhum paciente com o email e senha', async () => { + db.get.mockResolvedValueOnce({ docs: [] }); + + const req = { body: { email: 'joao@example.com', senha: '123456' } }; + const res = { + status: jest.fn().mockReturnThis(), + json: jest.fn(), + }; + + await pacienteController.getByEmailAndPassword(req, res); + + expect(res.status).toHaveBeenCalledWith(404); + expect(res.json).toHaveBeenCalledWith({ error: 'Paciente não encontrado.' }); + }); + + test('deve retornar um erro ao buscar um paciente pelo email e senha', async () => { + db.get.mockRejectedValueOnce(new Error('Erro ao buscar paciente.')); + + const req = { body: { email: 'joao@example.com', senha: '123456' } }; + const res = { + status: jest.fn().mockReturnThis(), + json: jest.fn(), + }; + + await pacienteController.getByEmailAndPassword(req, res); + + expect(res.status).toHaveBeenCalledWith(500); + expect(res.json).toHaveBeenCalledWith({ error: 'Erro ao buscar paciente.' }); + }); + }); }); \ No newline at end of file From fa0e5d2f7c894115d193dd434f8915a713aa1f79 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sun, 19 Jan 2025 15:26:01 -0300 Subject: [PATCH 20/47] criando testes para o dashboard do paciente #81 --- healthway_app/lib/widgets/alimento_item.dart | 22 +++--- healthway_app/test/dashboard_screen_test.dart | 26 ------- .../test/patient_dashboard_screen_test.dart | 78 +++++++++++++++++++ 3 files changed, 91 insertions(+), 35 deletions(-) delete mode 100644 healthway_app/test/dashboard_screen_test.dart create mode 100644 healthway_app/test/patient_dashboard_screen_test.dart diff --git a/healthway_app/lib/widgets/alimento_item.dart b/healthway_app/lib/widgets/alimento_item.dart index dfa04fe..832b207 100644 --- a/healthway_app/lib/widgets/alimento_item.dart +++ b/healthway_app/lib/widgets/alimento_item.dart @@ -4,7 +4,7 @@ import '../models/alimento.dart'; class AlimentoItem extends StatelessWidget { final Alimento alimento; - const AlimentoItem({Key? key, required this.alimento}) : super(key: key); + const AlimentoItem({super.key, required this.alimento}); @override Widget build(BuildContext context) { @@ -13,8 +13,8 @@ class AlimentoItem extends StatelessWidget { child: Card( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), elevation: 3, - shadowColor: Colors.black.withOpacity(0.1), // Sombra suave - color: Colors.white, // Cor de fundo do card + shadowColor: Colors.black.withOpacity(0.1), // Sombra suave + color: Colors.white, // Cor de fundo do card child: Padding( padding: const EdgeInsets.all(16.0), child: Column( @@ -23,12 +23,16 @@ class AlimentoItem extends StatelessWidget { // Título com nome e categoria do alimento Row( children: [ - Icon(Icons.fastfood, color: Color(0xFF31BAC2)), // Ícone de comida + Icon(Icons.fastfood, + color: Color(0xFF31BAC2)), // Ícone de comida const SizedBox(width: 8), Expanded( child: Text( alimento.descricao, - style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black87), + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.black87), ), ), ], @@ -36,10 +40,11 @@ class AlimentoItem extends StatelessWidget { const SizedBox(height: 8), Text( 'Categoria: ${alimento.categoria}', - style: TextStyle(color: Colors.grey[700]), // Cor mais suave para a categoria + style: TextStyle( + color: Colors.grey[700]), // Cor mais suave para a categoria ), const Divider(), // Linha separadora - + // Informações nutricionais _buildNutritionalInfo(), ], @@ -64,8 +69,7 @@ class AlimentoItem extends StatelessWidget { _buildNutritionalItem('Proteína', alimento.proteina, 'g'), _buildNutritionalItem('Lipídeos', alimento.lipideos, 'g'), _buildNutritionalItem('Fibra Alimentar', alimento.fibraAlimentar, 'g'), - if (alimento.colesterol != null) - _buildNutritionalItem('Colesterol', alimento.colesterol, 'mg'), + _buildNutritionalItem('Colesterol', alimento.colesterol, 'mg'), _buildNutritionalItem('Cálcio', alimento.calcio, 'mg'), _buildNutritionalItem('Ferro', alimento.ferro, 'mg'), _buildNutritionalItem('Potássio', alimento.potassio, 'mg'), diff --git a/healthway_app/test/dashboard_screen_test.dart b/healthway_app/test/dashboard_screen_test.dart deleted file mode 100644 index 99a04c1..0000000 --- a/healthway_app/test/dashboard_screen_test.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; - -void main() { - testWidgets('PatientDashboardScreen displays correctly', - (WidgetTester tester) async { - // Build the PatientDashboardScreen widget. - await tester.pumpWidget(MaterialApp(home: PatientDashboardScreen())); - - // Verify if the background color is correct. - final scaffold = tester.widget(find.byType(Scaffold)); - expect(scaffold.backgroundColor, const Color(0xFFF5F5F5)); - - // Verify if the SafeArea widget is present. - expect(find.byType(SafeArea), findsOneWidget); - - // Verify if the SingleChildScrollView widget is present. - expect(find.byType(SingleChildScrollView), findsOneWidget); - - // Verify if the Column widget is present. - //expect(find.byType(Column), findsOneWidget); - - // Add more specific tests for the widgets inside the Column as needed. - }); -} diff --git a/healthway_app/test/patient_dashboard_screen_test.dart b/healthway_app/test/patient_dashboard_screen_test.dart new file mode 100644 index 0000000..f1d9a60 --- /dev/null +++ b/healthway_app/test/patient_dashboard_screen_test.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; + +void main() { + final Map mockUserData = { + 'nome': 'John Doe', + 'altura': 180, + 'peso': 75, + }; + + testWidgets('PatientDashboardScreen displays user data correctly', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientDashboardScreen(userData: mockUserData), + )); + + expect(find.text('John Doe'), findsOneWidget); + expect(find.text('Vamos cuidar da sua saúde hoje!'), findsOneWidget); + expect(find.text('IMC'), findsOneWidget); + expect(find.text('Peso'), findsOneWidget); + expect(find.text('Altura'), findsOneWidget); + }); + + testWidgets('PatientDashboardScreen navigates to meal plan on tap', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientDashboardScreen(userData: mockUserData), + )); + + await tester.tap(find.text('Dieta')); + await tester.pumpAndSettle(); + + expect(find.byType(PatientDashboardScreen), findsNothing); + }); + + testWidgets('PatientDashboardScreen displays next appointment', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientDashboardScreen(userData: mockUserData), + )); + + expect(find.text('Próxima Consulta'), findsOneWidget); + expect(find.text('Dr. Silva - Nutricionista'), findsOneWidget); + expect(find.text('15 Mai\n14:00'), findsOneWidget); + }); + + testWidgets('PatientDashboardScreen displays daily progress', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientDashboardScreen(userData: mockUserData), + )); + + expect(find.text('Progresso Diário'), findsOneWidget); + expect(find.text('Calorias'), findsOneWidget); + expect(find.text('Água'), findsOneWidget); + expect(find.text('Passos'), findsOneWidget); + }); + + testWidgets('PatientDashboardScreen bottom navigation works', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientDashboardScreen(userData: mockUserData), + )); + + await tester.tap(find.text('Dieta')); + await tester.pumpAndSettle(); + expect(find.byType(PatientDashboardScreen), findsNothing); + + await tester.tap(find.text('Progresso')); + await tester.pumpAndSettle(); + expect(find.byType(PatientDashboardScreen), findsNothing); + + await tester.tap(find.text('Perfil')); + await tester.pumpAndSettle(); + expect(find.byType(PatientDashboardScreen), findsNothing); + }); +} From 79b856f18eabbd0c44ab1f828a0658c03e3ee1f4 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sun, 19 Jan 2025 18:07:35 -0300 Subject: [PATCH 21/47] corrigindo testes do dashboard e melhorando aparencia #80 --- healthway_app/lib/constants.dart | 3 +- .../lib/geral_screens/alimentos_screen.dart | 25 ++- .../lib/geral_screens/chat_screen.dart | 8 +- .../lib/geral_screens/loginScreen.dart | 2 +- .../nutricionistas_details_screen.dart | 29 ++- .../geral_screens/nutricionistas_screen.dart | 37 ++-- .../geral_screens/presentation_screen.dart | 3 +- healthway_app/lib/main.dart | 13 +- .../meal_plan_screen.dart | 12 +- .../nutritionist_dashboard_screen.dart | 29 +-- .../nutritionist_profile.dart | 22 +- .../patient_list_screen.dart | 16 +- .../screens_nutricionist/schedule_screen.dart | 17 +- .../signup_nutritionist_screen.dart | 28 +-- .../lib/screens_patient/dietScreen.dart | 15 +- .../lib/screens_patient/healthScreen.dart | 19 +- .../screens_patient/notificationScreen.dart | 13 +- .../patient_dashboard_screen.dart | 195 ++++++++++-------- .../patient_profile_screen.dart | 66 ++++-- .../lib/screens_patient/setingsScreen.dart | 11 +- .../signup_patient_screen.dart | 45 ++-- healthway_app/lib/widgets/alimento_item.dart | 4 +- .../lib/widgets/chat_input_field.dart | 16 +- .../lib/widgets/chat_message_bubble.dart | 21 +- .../lib/widgets/nutricionista_item.dart | 15 +- healthway_app/lib/widgets/paciente_item.dart | 3 +- .../test/patient_dashboard_screen_test.dart | 52 ++++- 27 files changed, 427 insertions(+), 292 deletions(-) diff --git a/healthway_app/lib/constants.dart b/healthway_app/lib/constants.dart index f24a835..be84566 100644 --- a/healthway_app/lib/constants.dart +++ b/healthway_app/lib/constants.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; const kPrimaryColor = Color(0xFF31BAC2); -const kSecondaryColor = Color(0xFFE6F7F8); +const kAccentColor = Color(0xFFE6F7F8); +const kBackgroundColor = Color(0xFFF5F5F5); const kTextColor = Color.fromARGB(255, 13, 56, 58); diff --git a/healthway_app/lib/geral_screens/alimentos_screen.dart b/healthway_app/lib/geral_screens/alimentos_screen.dart index 1fd7f80..fdfbc5f 100644 --- a/healthway_app/lib/geral_screens/alimentos_screen.dart +++ b/healthway_app/lib/geral_screens/alimentos_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:healthway_app/constants.dart'; import '../services/alimento_services.dart'; import '../models/alimento.dart'; import '../widgets/alimento_item.dart'; @@ -31,8 +32,10 @@ class _AlimentosScreenState extends State { void _filtrarAlimentos(String query) { setState(() { alimentosFiltrados = alimentos.where((alimento) { - final descricaoMatch = alimento.descricao.toLowerCase().contains(query.toLowerCase()); - final categoriaMatch = alimento.categoria.toLowerCase().contains(query.toLowerCase()); + final descricaoMatch = + alimento.descricao.toLowerCase().contains(query.toLowerCase()); + final categoriaMatch = + alimento.categoria.toLowerCase().contains(query.toLowerCase()); return descricaoMatch || categoriaMatch; }).toList(); }); @@ -41,10 +44,10 @@ class _AlimentosScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Alimentos'), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 5, // Remover o arredondamento da parte superior do AppBar shape: null, @@ -57,7 +60,8 @@ class _AlimentosScreenState extends State { future: futureAlimentos, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { - return Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))); + return Center( + child: CircularProgressIndicator(color: kPrimaryColor)); } else if (snapshot.hasError) { return _buildErrorWidget(snapshot.error.toString()); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { @@ -77,7 +81,7 @@ class _AlimentosScreenState extends State { floatingActionButton: FloatingActionButton( onPressed: _carregarAlimentos, child: Icon(Icons.refresh), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, ), ); } @@ -85,13 +89,13 @@ class _AlimentosScreenState extends State { Widget _buildSearchBar() { return Container( padding: EdgeInsets.all(16), - color: Color(0xFF31BAC2), + color: kPrimaryColor, child: TextField( controller: searchController, onChanged: _filtrarAlimentos, decoration: InputDecoration( hintText: 'Pesquisar alimentos...', - prefixIcon: Icon(Icons.search, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.search, color: kPrimaryColor), filled: true, fillColor: Colors.white, border: OutlineInputBorder( @@ -115,7 +119,8 @@ class _AlimentosScreenState extends State { borderRadius: BorderRadius.circular(20), ), shadowColor: Colors.black.withOpacity(0.2), - color: Colors.transparent, // Garantir que o fundo do card seja transparente + color: Colors + .transparent, // Garantir que o fundo do card seja transparente child: AlimentoItem(alimento: alimentosFiltrados[index]), ), ); @@ -150,7 +155,7 @@ class _AlimentosScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.no_food, size: 60, color: Color(0xFF31BAC2)), + Icon(Icons.no_food, size: 60, color: kPrimaryColor), SizedBox(height: 16), Text( 'Nenhum alimento encontrado', diff --git a/healthway_app/lib/geral_screens/chat_screen.dart b/healthway_app/lib/geral_screens/chat_screen.dart index 058d865..00354e4 100644 --- a/healthway_app/lib/geral_screens/chat_screen.dart +++ b/healthway_app/lib/geral_screens/chat_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -12,12 +13,13 @@ class ChatScreen extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( + foregroundColor: Colors.white, title: Row( children: [ CircleAvatar( - backgroundColor: Color(0xFF31BAC2), - child: Icon(Icons.person, color: Colors.white), + backgroundColor: kPrimaryColor, radius: 20, + child: Icon(Icons.person, color: Colors.white), ), SizedBox(width: 10), Column( @@ -31,7 +33,7 @@ class ChatScreen extends StatelessWidget { ), ], ), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, actions: [ IconButton(icon: Icon(Icons.video_call), onPressed: () {}), IconButton(icon: Icon(Icons.call), onPressed: () {}), diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index a4d0334..cd4dfbb 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -23,7 +23,7 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: kSecondaryColor, + backgroundColor: kAccentColor, appBar: AppBar( title: Text('Login', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white)), diff --git a/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart b/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart index aed4e75..5e801e6 100644 --- a/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart +++ b/healthway_app/lib/geral_screens/nutricionistas_details_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import '../models/nutricionista.dart'; import '../widgets/rating_stars.dart'; @@ -11,7 +12,7 @@ class NutricionistaDetailScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, body: CustomScrollView( slivers: [ _buildSliverAppBar(), @@ -36,12 +37,15 @@ class NutricionistaDetailScreen extends StatelessWidget { onPressed: () { // TODO: Implement appointment scheduling ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Funcionalidade de agendamento em desenvolvimento')), + SnackBar( + content: + Text('Funcionalidade de agendamento em desenvolvimento')), ); }, icon: Icon(Icons.calendar_today), label: Text('Agendar Consulta'), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, ), ); } @@ -52,13 +56,13 @@ class NutricionistaDetailScreen extends StatelessWidget { floating: false, pinned: true, flexibleSpace: FlexibleSpaceBar( - title: Text(nutricionista.nome), + title: Text(nutricionista.nome, style: TextStyle(color: Colors.white)), background: Image.network( - nutricionista.fotoPerfil ?? 'https://www.w3schools.com/w3images/avatar2.png', + 'https://www.w3schools.com/w3images/avatar2.png', fit: BoxFit.cover, ), ), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, ); } @@ -73,7 +77,10 @@ class NutricionistaDetailScreen extends StatelessWidget { children: [ Text( nutricionista.nome, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), ), SizedBox(height: 8), Text( @@ -90,7 +97,7 @@ class NutricionistaDetailScreen extends StatelessWidget { style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), SizedBox(width: 16), - Icon(Icons.person, color: Color(0xFF31BAC2)), + Icon(Icons.person, color: kPrimaryColor), SizedBox(width: 4), Text( '${nutricionista.numeroClientes} clientes', @@ -111,7 +118,7 @@ class NutricionistaDetailScreen extends StatelessWidget { Widget _buildInfoRow(IconData icon, String text) { return Row( children: [ - Icon(icon, color: Color(0xFF31BAC2), size: 20), + Icon(icon, color: kPrimaryColor, size: 20), SizedBox(width: 8), Expanded( child: Text( @@ -139,7 +146,8 @@ class NutricionistaDetailScreen extends StatelessWidget { ), SizedBox(height: 8), Text( - nutricionista.sobre ?? 'Informações sobre o nutricionista não disponíveis.', + nutricionista.sobre ?? + 'Informações sobre o nutricionista não disponíveis.', style: TextStyle(fontSize: 16), ), ], @@ -192,4 +200,3 @@ extension on Nutricionista { get numeroClientes => 12; } - diff --git a/healthway_app/lib/geral_screens/nutricionistas_screen.dart b/healthway_app/lib/geral_screens/nutricionistas_screen.dart index fc593e8..173bf58 100644 --- a/healthway_app/lib/geral_screens/nutricionistas_screen.dart +++ b/healthway_app/lib/geral_screens/nutricionistas_screen.dart @@ -1,11 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:healthway_app/constants.dart'; +import 'package:healthway_app/services/services_facade.dart'; + import '../models/nutricionista.dart'; -import '../services/nutricionista_services.dart'; import '../widgets/nutricionista_item.dart'; class NutricionistasScreen extends StatefulWidget { + const NutricionistasScreen({super.key}); + @override - _NutricionistasScreenState createState() => _NutricionistasScreenState(); + State createState() => _NutricionistasScreenState(); } class _NutricionistasScreenState extends State { @@ -22,7 +26,7 @@ class _NutricionistasScreenState extends State { void _carregarNutricionistas() { setState(() { - _nutricionistas = NutricionistaService().fetchNutricionistas(); + _nutricionistas = ServicesFacade().obterNutricionistas(); }); } @@ -30,8 +34,10 @@ class _NutricionistasScreenState extends State { setState(() { nutricionistasFiltrados = nutricionistas .where((nutricionista) => - nutricionista.nome.toLowerCase().contains(query.toLowerCase()) || - nutricionista.especialidade.toLowerCase().contains(query.toLowerCase())) + nutricionista.nome.toLowerCase().contains(query.toLowerCase()) || + nutricionista.especialidade + .toLowerCase() + .contains(query.toLowerCase())) .toList(); }); } @@ -39,10 +45,11 @@ class _NutricionistasScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Nutricionistas'), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, elevation: 0, ), body: Column( @@ -53,7 +60,8 @@ class _NutricionistasScreenState extends State { future: _nutricionistas, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { - return Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))); + return Center( + child: CircularProgressIndicator(color: kPrimaryColor)); } else if (snapshot.hasError) { return _buildErrorWidget(snapshot.error.toString()); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { @@ -72,8 +80,9 @@ class _NutricionistasScreenState extends State { ), floatingActionButton: FloatingActionButton( onPressed: _carregarNutricionistas, + backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, child: Icon(Icons.refresh), - backgroundColor: Color(0xFF31BAC2), ), ); } @@ -81,13 +90,13 @@ class _NutricionistasScreenState extends State { Widget _buildSearchBar() { return Container( padding: EdgeInsets.all(16), - color: Color(0xFF31BAC2), + color: kPrimaryColor, child: TextField( controller: searchController, onChanged: _filtrarNutricionistas, decoration: InputDecoration( hintText: 'Pesquisar por nome ou especialidade...', - prefixIcon: Icon(Icons.search, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.search, color: kPrimaryColor), filled: true, fillColor: Colors.white, border: OutlineInputBorder( @@ -110,7 +119,8 @@ class _NutricionistasScreenState extends State { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), - child: NutricionistaItem(nutricionista: nutricionistasFiltrados[index]), + child: NutricionistaItem( + nutricionista: nutricionistasFiltrados[index]), ), ); }, @@ -144,7 +154,7 @@ class _NutricionistasScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.person_off, size: 60, color: Color(0xFF31BAC2)), + Icon(Icons.person_off, size: 60, color: kPrimaryColor), SizedBox(height: 16), Text( 'Nenhum nutricionista encontrado', @@ -155,4 +165,3 @@ class _NutricionistasScreenState extends State { ); } } - diff --git a/healthway_app/lib/geral_screens/presentation_screen.dart b/healthway_app/lib/geral_screens/presentation_screen.dart index bfd48ad..7fc67e8 100644 --- a/healthway_app/lib/geral_screens/presentation_screen.dart +++ b/healthway_app/lib/geral_screens/presentation_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'dart:async'; import 'package:flutter/material.dart'; @@ -49,7 +50,7 @@ class _PresentationScreenState extends State @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, body: Center( child: FadeTransition( opacity: _animation, diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 5ffc300..1a60736 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; import 'package:healthway_app/geral_screens/chat_screen.dart'; @@ -29,13 +30,19 @@ class MyApp extends StatelessWidget { title: 'Health Dashboard', theme: ThemeData( brightness: Brightness.light, - primaryColor: const Color(0xFF4CAF50), + primaryColor: kPrimaryColor, scaffoldBackgroundColor: Colors.white, + textSelectionTheme: TextSelectionThemeData( + cursorColor: kPrimaryColor, // Define a cor do cursor + ), ), darkTheme: ThemeData( brightness: Brightness.dark, - primaryColor: const Color(0xFF4CAF50), + primaryColor: kPrimaryColor, scaffoldBackgroundColor: Colors.black, + textSelectionTheme: TextSelectionThemeData( + cursorColor: kPrimaryColor, // Define a cor do cursor + ), ), themeMode: ThemeMode.system, // Alterna automaticamente entre claro e escuro @@ -97,7 +104,7 @@ class CustomBottomNavigationBar extends StatelessWidget { @override Widget build(BuildContext context) { return BottomNavigationBar( - selectedItemColor: Color(0xFF31BAC2), + selectedItemColor: kPrimaryColor, unselectedItemColor: Colors.grey, type: BottomNavigationBarType.fixed, items: const [ diff --git a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart index 019bab8..9574b2c 100644 --- a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart +++ b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class MealPlanScreen extends StatelessWidget { @@ -8,10 +9,11 @@ class MealPlanScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Plano Alimentar - ${patientData['nome']}'), - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, elevation: 0, ), body: SafeArea( @@ -40,7 +42,7 @@ class MealPlanScreen extends StatelessWidget { // Editar plano alimentar }, style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), @@ -71,7 +73,7 @@ class MealPlanScreen extends StatelessWidget { style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2)), + color: kPrimaryColor), ), SizedBox(height: 8), ...foods.map((food) => Padding( @@ -79,7 +81,7 @@ class MealPlanScreen extends StatelessWidget { child: Row( children: [ Icon(Icons.fiber_manual_record, - size: 8, color: Color(0xFF31BAC2)), + size: 8, color: kPrimaryColor), SizedBox(width: 8), Text(food, style: TextStyle(fontSize: 16)), ], diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index afb208a..2835719 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class NutritionistDashboardScreen extends StatelessWidget { @@ -6,7 +7,7 @@ class NutritionistDashboardScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, body: SafeArea( child: SingleChildScrollView( child: Column( @@ -28,7 +29,7 @@ class NutritionistDashboardScreen extends StatelessWidget { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( - color: const Color(0xFF31BAC2), + color: kPrimaryColor, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), @@ -71,7 +72,7 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Icon( Icons.person, size: 35, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), ), @@ -106,7 +107,7 @@ class NutritionistDashboardScreen extends StatelessWidget { style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), SizedBox(height: 5), @@ -165,12 +166,12 @@ class NutritionistDashboardScreen extends StatelessWidget { Container( padding: EdgeInsets.all(15), decoration: BoxDecoration( - color: Color(0xFF31BAC2).withOpacity(0.1), + color: kPrimaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(15), ), child: Icon( icon, - color: Color(0xFF31BAC2), + color: kPrimaryColor, size: 30, ), ), @@ -210,7 +211,7 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Text( 'Ver todas', style: TextStyle( - color: Color(0xFF31BAC2), + color: kPrimaryColor, fontWeight: FontWeight.bold, ), ), @@ -256,12 +257,12 @@ class NutritionistDashboardScreen extends StatelessWidget { Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( - color: Color(0xFF31BAC2).withOpacity(0.1), + color: kPrimaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(10), ), child: Icon( Icons.calendar_today, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), SizedBox(width: 15), @@ -291,7 +292,7 @@ class NutritionistDashboardScreen extends StatelessWidget { time, style: TextStyle( fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), ], @@ -323,7 +324,7 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Text( 'Ver todas', style: TextStyle( - color: Color(0xFF31BAC2), + color: kPrimaryColor, fontWeight: FontWeight.bold, ), ), @@ -367,11 +368,11 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Row( children: [ CircleAvatar( - backgroundColor: Color(0xFF31BAC2).withOpacity(0.1), + backgroundColor: kPrimaryColor.withOpacity(0.1), child: Text( name[0], style: TextStyle( - color: Color(0xFF31BAC2), + color: kPrimaryColor, fontWeight: FontWeight.bold, ), ), @@ -428,7 +429,7 @@ class NutritionistDashboardScreen extends StatelessWidget { child: BottomNavigationBar( backgroundColor: Colors.transparent, elevation: 0, - selectedItemColor: Color(0xFF31BAC2), + selectedItemColor: kPrimaryColor, unselectedItemColor: Colors.grey, showSelectedLabels: true, showUnselectedLabels: true, diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart index 86be1cd..7d6f24d 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class NutritionistProfileScreen extends StatefulWidget { @@ -26,10 +27,10 @@ class _NutritionistProfileScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: const Text('Meu Perfil'), - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, actions: [ IconButton( @@ -70,7 +71,7 @@ class _NutritionistProfileScreenState extends State { floatingActionButton: _isEditing ? FloatingActionButton( onPressed: _saveChanges, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, child: Icon(Icons.save), ) : null, @@ -86,7 +87,7 @@ class _NutritionistProfileScreenState extends State { children: [ CircleAvatar( radius: 60, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, backgroundImage: NetworkImage(fotoPerfil), child: fotoPerfil.isEmpty ? Text( @@ -101,7 +102,7 @@ class _NutritionistProfileScreenState extends State { if (!_isEditing) Container( decoration: BoxDecoration( - color: Color(0xFF31BAC2), + color: kPrimaryColor, shape: BoxShape.circle, ), child: IconButton( @@ -200,7 +201,7 @@ class _NutritionistProfileScreenState extends State { // Navigate to detailed edit profile screen }, style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), @@ -213,11 +214,11 @@ class _NutritionistProfileScreenState extends State { // Navigate to change password screen }, style: OutlinedButton.styleFrom( - foregroundColor: Color(0xFF31BAC2), + foregroundColor: kPrimaryColor, padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), - side: BorderSide(color: Color(0xFF31BAC2)), + side: BorderSide(color: kPrimaryColor), ), child: Text('Alterar Senha'), ), @@ -247,7 +248,7 @@ class _NutritionistProfileScreenState extends State { width: 200, height: 150, decoration: BoxDecoration( - border: Border.all(color: Color(0xFF31BAC2)), + border: Border.all(color: kPrimaryColor), borderRadius: BorderRadius.circular(10), image: DecorationImage( image: NetworkImage(fotoDocumento), @@ -255,8 +256,7 @@ class _NutritionistProfileScreenState extends State { ), ), child: fotoDocumento.isEmpty - ? Icon(Icons.add_a_photo, - size: 50, color: Color(0xFF31BAC2)) + ? Icon(Icons.add_a_photo, size: 50, color: kPrimaryColor) : null, ), ), diff --git a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart index 0ac6408..d74b22c 100644 --- a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart +++ b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import '../models/paciente.dart'; import '../services/paciente_services.dart'; @@ -41,10 +42,10 @@ class _PacientesScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Pacientes'), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: Column( @@ -56,8 +57,7 @@ class _PacientesScreenState extends State { builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center( - child: - CircularProgressIndicator(color: Color(0xFF31BAC2))); + child: CircularProgressIndicator(color: kPrimaryColor)); } else if (snapshot.hasError) { return _buildErrorWidget(snapshot.error.toString()); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { @@ -76,7 +76,7 @@ class _PacientesScreenState extends State { ), floatingActionButton: FloatingActionButton( onPressed: _carregarPacientes, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, child: Icon(Icons.refresh), ), ); @@ -85,13 +85,13 @@ class _PacientesScreenState extends State { Widget _buildSearchBar() { return Container( padding: EdgeInsets.all(16), - color: Color(0xFF31BAC2), + color: kPrimaryColor, child: TextField( controller: searchController, onChanged: _filtrarPacientes, decoration: InputDecoration( hintText: 'Pesquisar por nome ou email...', - prefixIcon: Icon(Icons.search, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.search, color: kPrimaryColor), filled: true, fillColor: Colors.white, border: OutlineInputBorder( @@ -148,7 +148,7 @@ class _PacientesScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.person_off, size: 60, color: Color(0xFF31BAC2)), + Icon(Icons.person_off, size: 60, color: kPrimaryColor), SizedBox(height: 16), Text( 'Nenhum paciente encontrado', diff --git a/healthway_app/lib/screens_nutricionist/schedule_screen.dart b/healthway_app/lib/screens_nutricionist/schedule_screen.dart index 68c11a9..c948bda 100644 --- a/healthway_app/lib/screens_nutricionist/schedule_screen.dart +++ b/healthway_app/lib/screens_nutricionist/schedule_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:table_calendar/table_calendar.dart'; @@ -42,10 +43,10 @@ class _ScheduleScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Agenda', style: TextStyle(fontWeight: FontWeight.bold)), - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: Column( @@ -56,7 +57,7 @@ class _ScheduleScreenState extends State { ), floatingActionButton: FloatingActionButton( onPressed: _addAppointment, - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, child: Icon(Icons.add), ), ); @@ -84,15 +85,15 @@ class _ScheduleScreenState extends State { eventLoader: _getAppointmentsForDay, calendarStyle: CalendarStyle( selectedDecoration: BoxDecoration( - color: const Color(0xFF31BAC2), + color: kPrimaryColor, shape: BoxShape.circle, ), todayDecoration: BoxDecoration( - color: const Color(0xFF31BAC2).withOpacity(0.5), + color: kPrimaryColor.withOpacity(0.5), shape: BoxShape.circle, ), markerDecoration: BoxDecoration( - color: const Color(0xFF31BAC2), + color: kPrimaryColor, shape: BoxShape.circle, ), ), @@ -114,7 +115,7 @@ class _ScheduleScreenState extends State { margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: ListTile( leading: CircleAvatar( - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, child: Text( appointment.patientName[0], style: TextStyle(color: Colors.white), @@ -126,7 +127,7 @@ class _ScheduleScreenState extends State { appointment.time, style: TextStyle( fontWeight: FontWeight.bold, - color: const Color(0xFF31BAC2), + color: kPrimaryColor, ), ), onTap: () => _viewAppointmentDetails(appointment), diff --git a/healthway_app/lib/screens_nutricionist/signup_nutritionist_screen.dart b/healthway_app/lib/screens_nutricionist/signup_nutritionist_screen.dart index 93b64f1..583c2d4 100644 --- a/healthway_app/lib/screens_nutricionist/signup_nutritionist_screen.dart +++ b/healthway_app/lib/screens_nutricionist/signup_nutritionist_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:healthway_app/models/nutricionista.dart'; @@ -36,11 +37,11 @@ class _CadastroNutricionistaScreenState @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFE6F7F8), + backgroundColor: kAccentColor, appBar: AppBar( title: Text('Cadastro de Nutricionista', style: TextStyle(fontWeight: FontWeight.bold)), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: SingleChildScrollView( @@ -49,7 +50,7 @@ class _CadastroNutricionistaScreenState Container( height: 150, decoration: BoxDecoration( - color: Color(0xFF31BAC2), + color: kPrimaryColor, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), @@ -91,7 +92,7 @@ class _CadastroNutricionistaScreenState onPressed: _isLoading ? null : _submitForm, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), @@ -123,14 +124,14 @@ class _CadastroNutricionistaScreenState controller: controller, decoration: InputDecoration( labelText: label, - prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + prefixIcon: Icon(icon, color: kPrimaryColor), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), style: TextStyle(fontSize: 16), @@ -154,18 +155,17 @@ class _CadastroNutricionistaScreenState decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), - border: Border.all(color: Color(0xFF31BAC2), width: 2), + border: Border.all(color: kPrimaryColor, width: 2), ), child: image == null ? Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.add_a_photo, size: 50, color: Color(0xFF31BAC2)), + Icon(Icons.add_a_photo, size: 50, color: kPrimaryColor), SizedBox(height: 10), Text(label, style: TextStyle( - color: Color(0xFF31BAC2), - fontWeight: FontWeight.bold)), + color: kPrimaryColor, fontWeight: FontWeight.bold)), ], ) : ClipRRect( @@ -191,7 +191,7 @@ class _CadastroNutricionistaScreenState style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2)), + color: kPrimaryColor), ), SizedBox(height: 16), _buildPasswordField(_senhaController, 'Senha', _obscurePassword, @@ -220,11 +220,11 @@ class _CadastroNutricionistaScreenState obscureText: obscureText, decoration: InputDecoration( labelText: label, - prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.lock, color: kPrimaryColor), suffixIcon: IconButton( icon: Icon( obscureText ? Icons.visibility : Icons.visibility_off, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), onPressed: onTap, ), @@ -234,7 +234,7 @@ class _CadastroNutricionistaScreenState ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), style: TextStyle(fontSize: 16), diff --git a/healthway_app/lib/screens_patient/dietScreen.dart b/healthway_app/lib/screens_patient/dietScreen.dart index 5459ba2..d6e183d 100644 --- a/healthway_app/lib/screens_patient/dietScreen.dart +++ b/healthway_app/lib/screens_patient/dietScreen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -53,15 +54,15 @@ class _PlanoAlimentarScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Plano Alimentar', style: TextStyle(fontWeight: FontWeight.bold)), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: isLoading - ? Center(child: CircularProgressIndicator(color: Color(0xFF31BAC2))) + ? Center(child: CircularProgressIndicator(color: kPrimaryColor)) : planosAlimentares.isEmpty ? _buildEmptyState() : _buildPlanoAlimentarList(), @@ -70,7 +71,7 @@ class _PlanoAlimentarScreenState extends State { // TODO: Implementar a criação de um novo plano alimentar }, child: Icon(Icons.add), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, ), ); } @@ -80,7 +81,7 @@ class _PlanoAlimentarScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.no_meals, size: 80, color: Color(0xFF31BAC2)), + Icon(Icons.no_meals, size: 80, color: kPrimaryColor), SizedBox(height: 16), Text( 'Nenhum plano alimentar encontrado', @@ -106,8 +107,8 @@ class _PlanoAlimentarScreenState extends State { child: ExpansionTile( title: Text( plano.consulta, - style: TextStyle( - fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + style: + TextStyle(fontWeight: FontWeight.bold, color: kPrimaryColor), ), subtitle: Text( '${DateFormat('dd/MM/yyyy').format(plano.dtInicio)} - ${DateFormat('dd/MM/yyyy').format(plano.dtFim)}', diff --git a/healthway_app/lib/screens_patient/healthScreen.dart b/healthway_app/lib/screens_patient/healthScreen.dart index 3922b95..014a271 100644 --- a/healthway_app/lib/screens_patient/healthScreen.dart +++ b/healthway_app/lib/screens_patient/healthScreen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class DietManagementScreen extends StatelessWidget { @@ -6,10 +7,10 @@ class DietManagementScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: const Text('Gerenciamento de Dieta'), - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: SafeArea( @@ -33,7 +34,7 @@ class DietManagementScreen extends StatelessWidget { onPressed: () { // Adicionar refeição }, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, child: Icon(Icons.add), ), ); @@ -114,15 +115,14 @@ class DietManagementScreen extends StatelessWidget { child: ListTile( contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), leading: CircleAvatar( - backgroundColor: Color(0xFF31BAC2).withOpacity(0.1), - child: Icon(Icons.restaurant, color: Color(0xFF31BAC2)), + backgroundColor: kPrimaryColor.withOpacity(0.1), + child: Icon(Icons.restaurant, color: kPrimaryColor), ), title: Text(mealName, style: TextStyle(fontWeight: FontWeight.bold)), subtitle: Text(time), trailing: Text( calories, - style: - TextStyle(fontWeight: FontWeight.bold, color: Color(0xFF31BAC2)), + style: TextStyle(fontWeight: FontWeight.bold, color: kPrimaryColor), ), onTap: () { // Abrir detalhes da refeição @@ -150,8 +150,7 @@ class DietManagementScreen extends StatelessWidget { child: LinearProgressIndicator( value: 0.6, backgroundColor: Colors.grey[300], - valueColor: - AlwaysStoppedAnimation(Color(0xFF31BAC2)), + valueColor: AlwaysStoppedAnimation(kPrimaryColor), ), ), SizedBox(width: 16), @@ -203,7 +202,7 @@ class DietManagementScreen extends StatelessWidget { child: LinearProgressIndicator( value: progress, backgroundColor: Colors.grey[300], - valueColor: AlwaysStoppedAnimation(Color(0xFF31BAC2)), + valueColor: AlwaysStoppedAnimation(kPrimaryColor), ), ), SizedBox(width: 16), diff --git a/healthway_app/lib/screens_patient/notificationScreen.dart b/healthway_app/lib/screens_patient/notificationScreen.dart index 58f1532..59a6869 100644 --- a/healthway_app/lib/screens_patient/notificationScreen.dart +++ b/healthway_app/lib/screens_patient/notificationScreen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class NotificationScreen extends StatelessWidget { @@ -6,10 +7,10 @@ class NotificationScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: const Text('Notificações'), - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: SafeArea( @@ -52,15 +53,16 @@ class NotificationScreen extends StatelessWidget { ); } - Widget _buildNotificationItem(String title, String description, String time, IconData icon) { + Widget _buildNotificationItem( + String title, String description, String time, IconData icon) { return Card( margin: EdgeInsets.only(bottom: 16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), child: ListTile( contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), leading: CircleAvatar( - backgroundColor: Color(0xFF31BAC2).withOpacity(0.1), - child: Icon(icon, color: Color(0xFF31BAC2)), + backgroundColor: kPrimaryColor.withOpacity(0.1), + child: Icon(icon, color: kPrimaryColor), ), title: Text( title, @@ -85,4 +87,3 @@ class NotificationScreen extends StatelessWidget { ); } } - diff --git a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart index 227a1bf..8e2ac32 100644 --- a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart +++ b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class PatientDashboardScreen extends StatelessWidget { @@ -8,13 +9,13 @@ class PatientDashboardScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, body: SafeArea( child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildHeader(), + _buildHeader(context), _buildQuickAccess(context), _buildNextAppointment(), _buildDailyProgress(), @@ -22,15 +23,16 @@ class PatientDashboardScreen extends StatelessWidget { ), ), ), - bottomNavigationBar: _buildBottomNavigationBar(context), + // bottomNavigationBar: _buildBottomNavigationBar(context), ); } - Widget _buildHeader() { + Widget _buildHeader(context) { + String name = userData['nome']; return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( - color: const Color(0xFF31BAC2), + color: kPrimaryColor, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), @@ -63,13 +65,22 @@ class PatientDashboardScreen extends StatelessWidget { ), ], ), - CircleAvatar( - radius: 30, - backgroundColor: Colors.white, - child: Icon( - Icons.person, - size: 35, - color: Color(0xFF31BAC2), + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/patient_profile', + arguments: userData); + }, + child: CircleAvatar( + radius: 30, + backgroundColor: Colors.white, + child: Text( + name.isNotEmpty ? name[0].toUpperCase() : '?', + style: TextStyle( + fontSize: 24, + backgroundColor: Colors.white, + fontWeight: FontWeight.bold, + color: kPrimaryColor), + ), ), ), ], @@ -107,7 +118,7 @@ class PatientDashboardScreen extends StatelessWidget { style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), SizedBox(height: 5), @@ -131,7 +142,7 @@ class PatientDashboardScreen extends StatelessWidget { Text( 'Acesso Rápido', style: TextStyle( - color: Colors.black, + color: kTextColor, fontSize: 18, fontWeight: FontWeight.bold, ), @@ -141,13 +152,13 @@ class PatientDashboardScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildQuickAccessItem(context, Icons.restaurant_menu, 'Dieta', - '/meal_plan', userData), + '/meal_plan', 'dashboard_dieta', userData), _buildQuickAccessItem(context, Icons.people, 'Nutricionistas', - '/nutricionistas', null), - _buildQuickAccessItem( - context, Icons.insert_chart, 'Progresso', '/progress', null), - _buildQuickAccessItem( - context, Icons.message, 'Chat', '/chat', null), + '/nutricionistas', 'dashboard_nutricionistas', null), + // _buildQuickAccessItem( + // context, Icons.insert_chart, 'Progresso', '/progress', 'dashboard_', null), + _buildQuickAccessItem(context, Icons.message, 'Chat', '/chat', + 'dashboard_chat', null), ], ), ], @@ -156,23 +167,24 @@ class PatientDashboardScreen extends StatelessWidget { } Widget _buildQuickAccessItem(BuildContext context, IconData icon, - String label, String route, Object? args) { + String label, String route, String key, Object? args) { return GestureDetector( onTap: () { Navigator.pushNamed(context, route, arguments: args); // Aqui você agora tem acesso ao 'context' }, + key: Key(key), child: Column( children: [ Container( padding: EdgeInsets.all(15), decoration: BoxDecoration( - color: Color(0xFF31BAC2).withOpacity(0.1), + color: kPrimaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(15), ), child: Icon( icon, - color: Color(0xFF31BAC2), + color: kPrimaryColor, size: 30, ), ), @@ -211,12 +223,12 @@ class PatientDashboardScreen extends StatelessWidget { Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( - color: Color(0xFF31BAC2).withOpacity(0.1), + color: kPrimaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(10), ), child: Icon( Icons.calendar_today, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), SizedBox(width: 15), @@ -227,7 +239,7 @@ class PatientDashboardScreen extends StatelessWidget { Text( 'Próxima Consulta', style: TextStyle( - color: Colors.black, + color: kTextColor, fontWeight: FontWeight.bold, fontSize: 16, ), @@ -236,7 +248,7 @@ class PatientDashboardScreen extends StatelessWidget { Text( 'Dr. Silva - Nutricionista', style: TextStyle( - color: Colors.black, + color: kTextColor, fontSize: 14, ), ), @@ -248,7 +260,7 @@ class PatientDashboardScreen extends StatelessWidget { textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), ], @@ -266,7 +278,7 @@ class PatientDashboardScreen extends StatelessWidget { Text( 'Progresso Diário', style: TextStyle( - color: Colors.black, + color: kTextColor, fontSize: 18, fontWeight: FontWeight.bold, ), @@ -297,71 +309,76 @@ class PatientDashboardScreen extends StatelessWidget { LinearProgressIndicator( value: progress, backgroundColor: Colors.grey[300], - valueColor: AlwaysStoppedAnimation(Color(0xFF31BAC2)), + valueColor: AlwaysStoppedAnimation(kPrimaryColor), ), ], ); } - Widget _buildBottomNavigationBar(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.3), - spreadRadius: 1, - blurRadius: 5, - offset: Offset(0, -3), - ), - ], - ), - child: BottomNavigationBar( - backgroundColor: Colors.transparent, - elevation: 0, - selectedItemColor: Color(0xFF31BAC2), - unselectedItemColor: Colors.grey, - showSelectedLabels: true, - showUnselectedLabels: true, - type: BottomNavigationBarType.fixed, - items: [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: 'Início', - ), - BottomNavigationBarItem( - icon: Icon(Icons.restaurant_menu), - label: 'Dieta', - ), - BottomNavigationBarItem( - icon: Icon(Icons.insert_chart), - label: 'Progresso', - ), - BottomNavigationBarItem( - icon: Icon(Icons.person), - label: 'Perfil', - ), - ], - onTap: (index) { - switch (index) { - case 0: - // Já estamos na tela inicial, então não faça nada - break; - case 1: - Navigator.pushNamed(context, '/meal_plan', arguments: userData); - break; - case 2: - Navigator.pushNamed(context, '/progress'); - break; - case 3: - Navigator.pushNamed(context, '/patient_profile', - arguments: userData); - break; - } - }, - ), - ); - } + // Widget _buildBottomNavigationBar(BuildContext context) { + // return Container( + // decoration: BoxDecoration( + // color: Colors.white, + // boxShadow: [ + // BoxShadow( + // color: Colors.grey.withValues(alpha: 0.3), + // spreadRadius: 1, + // blurRadius: 5, + // offset: Offset(0, -3), + // ), + // ], + // ), + // child: BottomNavigationBar( + // backgroundColor: Colors.transparent, + // elevation: 0, + // selectedItemColor: kPrimaryColor, + // unselectedItemColor: Colors.grey, + // showSelectedLabels: true, + // showUnselectedLabels: true, + // type: BottomNavigationBarType.fixed, + // items: [ + // BottomNavigationBarItem( + // icon: Icon(Icons.home), + // label: 'Início', + // key: Key('bottom_nav_inicio'), + // ), + // BottomNavigationBarItem( + // icon: Icon(Icons.restaurant_menu), + // label: 'Dieta', + // key: Key('bottom_nav_dieta'), + // ), + // // BottomNavigationBarItem( + // // icon: Icon(Icons.insert_chart), + // // label: 'Progresso', + // // key: Key('bottom_nav_progresso'), + // // ), + // BottomNavigationBarItem( + // icon: Icon(Icons.person), + // label: 'Perfil', + // key: Key('bottom_nav_perfil'), + // ), + // ], + // onTap: (index) { + // switch (index) { + // case 0: + // // Já estamos na tela inicial, então não faça nada + // break; + // case 1: + // Navigator.pushNamed(context, '/meal_plan', arguments: userData); + // break; + // // case 2: + // // Navigator.pushNamed(context, '/progress'); + // // break; + // // case 3: + // case 2: + // Navigator.pushNamed(context, '/patient_profile', + // arguments: userData); + // break; + // } + // }, + // ), + // ); + // } double _calculateBMI(alturaM, peso) { var alturaCm = alturaM / 100; diff --git a/healthway_app/lib/screens_patient/patient_profile_screen.dart b/healthway_app/lib/screens_patient/patient_profile_screen.dart index 93b0ffc..ebc88e0 100644 --- a/healthway_app/lib/screens_patient/patient_profile_screen.dart +++ b/healthway_app/lib/screens_patient/patient_profile_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:healthway_app/models/paciente.dart'; @@ -18,9 +19,9 @@ class _PatientProfileScreenState extends State { final _formKey = GlobalKey(); static final ServicesFacade _servicesFacade = ServicesFacade(); - late String name; + late String nome; late String email; - late int age; + late int idade; late double altura; late double peso; late double circunferenciaAbdominal; @@ -34,12 +35,12 @@ class _PatientProfileScreenState extends State { super.initState(); preferencias = List.from(widget.userData['preferencias']); alergias = List.from(widget.userData['alergias']); - name = widget.userData['nome']; + nome = widget.userData['nome']; email = widget.userData['email']; var birthDate = widget.userData['dt_nascimento']; var ageDuration = DateTime.now().difference(DateFormat('dd/MM/yyyy').parse(birthDate)); - age = ageDuration.inDays ~/ 365; + idade = ageDuration.inDays ~/ 365; altura = widget.userData['altura'].toDouble(); peso = widget.userData['peso'].toDouble(); circunferenciaAbdominal = @@ -51,10 +52,11 @@ class _PatientProfileScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: kBackgroundColor, appBar: AppBar( title: const Text('Meu Perfil'), - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, elevation: 0, actions: [ IconButton( @@ -90,7 +92,7 @@ class _PatientProfileScreenState extends State { floatingActionButton: _edited ? FloatingActionButton( onPressed: _saveChanges, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, child: Icon(Icons.save), ) : null, @@ -106,11 +108,9 @@ class _PatientProfileScreenState extends State { children: [ CircleAvatar( radius: 60, - backgroundColor: Color(0xFF31BAC2), - backgroundImage: - NetworkImage('https://example.com/profile_image.jpg'), + backgroundColor: kPrimaryColor, child: Text( - name.isNotEmpty ? name[0].toUpperCase() : '?', + nome.isNotEmpty ? nome[0].toUpperCase() : '?', style: TextStyle( fontSize: 40, fontWeight: FontWeight.bold, @@ -120,7 +120,7 @@ class _PatientProfileScreenState extends State { if (!_isEditing) Container( decoration: BoxDecoration( - color: Color(0xFF31BAC2), + color: kPrimaryColor, shape: BoxShape.circle, ), child: IconButton( @@ -134,13 +134,15 @@ class _PatientProfileScreenState extends State { ), SizedBox(height: 16), Text( - name, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + nome, + style: TextStyle( + fontSize: 24, fontWeight: FontWeight.bold, color: kTextColor), ), SizedBox(height: 8), Text( email, - style: TextStyle(fontSize: 16, color: Colors.grey[600]), + style: TextStyle( + fontSize: 16, color: kTextColor.withValues(alpha: 0.7)), ), ], ), @@ -154,7 +156,7 @@ class _PatientProfileScreenState extends State { padding: const EdgeInsets.all(16.0), child: Column( children: [ - _buildInfoRow('Idade', '$age anos', null), + _buildInfoRow('Idade', '$idade anos', null), _buildInfoRow('Altura', altura.toStringAsFixed(1), (value) { if (value.isNotEmpty) { _edited = true; @@ -206,7 +208,13 @@ class _PatientProfileScreenState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(label, style: TextStyle(fontSize: 16, color: Colors.grey[600])), + Expanded( + child: Text( + label, + style: TextStyle(fontSize: 16, color: kPrimaryColor), + overflow: TextOverflow.visible, + ), + ), _isEditing && onChanged != null ? SizedBox( width: 120, @@ -242,7 +250,17 @@ class _PatientProfileScreenState extends State { Text('Alergias', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ...alergias.map((alergia) => ListTile( - title: Text(alergia), + title: Row( + children: [ + Icon(Icons.fiber_manual_record, + size: 8, color: kPrimaryColor), + SizedBox(width: 8), + Text( + alergia, + style: TextStyle(fontSize: 16), + ), + ], + ), trailing: _isEditing ? IconButton( icon: Icon(Icons.delete), @@ -283,7 +301,17 @@ class _PatientProfileScreenState extends State { Text('Preferências', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ...preferencias.map((preferencia) => ListTile( - title: Text(preferencia), + title: Row( + children: [ + Icon(Icons.fiber_manual_record, + size: 8, color: kPrimaryColor), + SizedBox(width: 8), + Text( + preferencia, + style: TextStyle(fontSize: 16), + ), + ], + ), trailing: _isEditing ? IconButton( icon: Icon(Icons.delete), diff --git a/healthway_app/lib/screens_patient/setingsScreen.dart b/healthway_app/lib/screens_patient/setingsScreen.dart index 9dcf36b..f27ea0d 100644 --- a/healthway_app/lib/screens_patient/setingsScreen.dart +++ b/healthway_app/lib/screens_patient/setingsScreen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class SettingsScreen extends StatefulWidget { @@ -17,7 +18,7 @@ class _SettingsScreenState extends State { return Scaffold( appBar: AppBar( title: const Text('Configurações'), - backgroundColor: const Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: SafeArea( @@ -35,7 +36,7 @@ class _SettingsScreenState extends State { _notificationsEnabled = value; }); }, - activeColor: const Color(0xFF31BAC2), + activeColor: kPrimaryColor, ), ), _buildSettingItem( @@ -48,7 +49,7 @@ class _SettingsScreenState extends State { _darkModeEnabled = value; }); }, - activeColor: const Color(0xFF31BAC2), + activeColor: kPrimaryColor, ), ), _buildSettingItem( @@ -117,7 +118,7 @@ class _SettingsScreenState extends State { style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), ), ); @@ -166,7 +167,7 @@ class _SettingsScreenState extends State { Navigator.of(context).pop(); }, trailing: _selectedLanguage == language - ? const Icon(Icons.check, color: Color(0xFF31BAC2)) + ? const Icon(Icons.check, color: kPrimaryColor) : null, ); } diff --git a/healthway_app/lib/screens_patient/signup_patient_screen.dart b/healthway_app/lib/screens_patient/signup_patient_screen.dart index 014a498..2e58696 100644 --- a/healthway_app/lib/screens_patient/signup_patient_screen.dart +++ b/healthway_app/lib/screens_patient/signup_patient_screen.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:healthway_app/models/paciente.dart'; @@ -39,11 +40,11 @@ class _CadastroPacienteScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(0xFFE6F7F8), + backgroundColor: kAccentColor, appBar: AppBar( title: Text('Cadastro de Paciente', style: TextStyle(fontWeight: FontWeight.bold)), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, elevation: 0, ), body: SingleChildScrollView( @@ -52,7 +53,7 @@ class _CadastroPacienteScreenState extends State { Container( height: 150, decoration: BoxDecoration( - color: Color(0xFF31BAC2), + color: kPrimaryColor, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), @@ -90,7 +91,7 @@ class _CadastroPacienteScreenState extends State { onPressed: _isLoading ? null : _submitForm, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), @@ -122,14 +123,14 @@ class _CadastroPacienteScreenState extends State { controller: controller, decoration: InputDecoration( labelText: label, - prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + prefixIcon: Icon(icon, color: kPrimaryColor), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), style: TextStyle(fontSize: 16), @@ -152,14 +153,14 @@ class _CadastroPacienteScreenState extends State { controller: _dataNascimentoController, decoration: InputDecoration( labelText: 'Data de Nascimento', - prefixIcon: Icon(Icons.calendar_today, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.calendar_today, color: kPrimaryColor), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), style: TextStyle(fontSize: 16), @@ -173,9 +174,9 @@ class _CadastroPacienteScreenState extends State { builder: (context, child) { return Theme( data: ThemeData.light().copyWith( - primaryColor: Color(0xFF31BAC2), - hintColor: Color(0xFF31BAC2), - colorScheme: ColorScheme.light(primary: Color(0xFF31BAC2)), + primaryColor: kPrimaryColor, + hintColor: kPrimaryColor, + colorScheme: ColorScheme.light(primary: kPrimaryColor), buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary), ), @@ -207,14 +208,14 @@ class _CadastroPacienteScreenState extends State { value: _sexo, decoration: InputDecoration( labelText: 'Sexo', - prefixIcon: Icon(Icons.wc, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.wc, color: kPrimaryColor), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), style: TextStyle(fontSize: 16, color: Colors.black), @@ -254,7 +255,7 @@ class _CadastroPacienteScreenState extends State { style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2)), + color: kPrimaryColor), ), SizedBox(height: 16), Row( @@ -295,16 +296,16 @@ class _CadastroPacienteScreenState extends State { controller: controller, decoration: InputDecoration( labelText: label, - prefixIcon: Icon(icon, color: Color(0xFF31BAC2)), + prefixIcon: Icon(icon, color: kPrimaryColor), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15), - borderSide: BorderSide(color: Color(0xFF31BAC2)), + borderSide: BorderSide(color: kPrimaryColor), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(15), - borderSide: BorderSide(color: Color(0xFF31BAC2), width: 2), + borderSide: BorderSide(color: kPrimaryColor, width: 2), ), - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), ), keyboardType: TextInputType.number, style: TextStyle(fontSize: 16), @@ -332,7 +333,7 @@ class _CadastroPacienteScreenState extends State { style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Color(0xFF31BAC2)), + color: kPrimaryColor), ), SizedBox(height: 16), _buildPasswordField(_senhaController, 'Senha', _obscurePassword, @@ -361,11 +362,11 @@ class _CadastroPacienteScreenState extends State { obscureText: obscureText, decoration: InputDecoration( labelText: label, - prefixIcon: Icon(Icons.lock, color: Color(0xFF31BAC2)), + prefixIcon: Icon(Icons.lock, color: kPrimaryColor), suffixIcon: IconButton( icon: Icon( obscureText ? Icons.visibility : Icons.visibility_off, - color: Color(0xFF31BAC2), + color: kPrimaryColor, ), onPressed: onTap, ), @@ -375,7 +376,7 @@ class _CadastroPacienteScreenState extends State { ), filled: true, fillColor: Colors.white, - labelStyle: TextStyle(color: Color(0xFF31BAC2)), + labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), style: TextStyle(fontSize: 16), diff --git a/healthway_app/lib/widgets/alimento_item.dart b/healthway_app/lib/widgets/alimento_item.dart index 832b207..89e1267 100644 --- a/healthway_app/lib/widgets/alimento_item.dart +++ b/healthway_app/lib/widgets/alimento_item.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import '../models/alimento.dart'; @@ -23,8 +24,7 @@ class AlimentoItem extends StatelessWidget { // Título com nome e categoria do alimento Row( children: [ - Icon(Icons.fastfood, - color: Color(0xFF31BAC2)), // Ícone de comida + Icon(Icons.fastfood, color: kPrimaryColor), // Ícone de comida const SizedBox(width: 8), Expanded( child: Text( diff --git a/healthway_app/lib/widgets/chat_input_field.dart b/healthway_app/lib/widgets/chat_input_field.dart index b7b02c8..b0b1335 100644 --- a/healthway_app/lib/widgets/chat_input_field.dart +++ b/healthway_app/lib/widgets/chat_input_field.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class ChatInputField extends StatefulWidget { @@ -40,7 +41,7 @@ class _ChatInputFieldState extends State { child: Row( children: [ IconButton( - icon: Icon(Icons.emoji_emotions_outlined, color: Color(0xFF31BAC2)), + icon: Icon(Icons.emoji_emotions_outlined, color: kPrimaryColor), onPressed: () { // TODO: Implement emoji picker }, @@ -62,24 +63,26 @@ class _ChatInputFieldState extends State { ), filled: true, fillColor: Colors.grey[100], - contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + contentPadding: + EdgeInsets.symmetric(horizontal: 20, vertical: 10), ), style: TextStyle(color: Colors.black87, fontSize: 16), ), ), IconButton( - icon: Icon(Icons.attach_file, color: Color(0xFF31BAC2)), + icon: Icon(Icons.attach_file, color: kPrimaryColor), onPressed: () { // TODO: Implement file attachment }, ), IconButton( - icon: Icon(_isComposing ? Icons.send : Icons.mic, color: Color(0xFF31BAC2)), + icon: Icon(_isComposing ? Icons.send : Icons.mic, + color: kPrimaryColor), onPressed: _isComposing ? () => _handleSubmitted(_textController.text) : () { - // TODO: Implement voice recording - }, + // TODO: Implement voice recording + }, ), ], ), @@ -88,4 +91,3 @@ class _ChatInputFieldState extends State { ); } } - diff --git a/healthway_app/lib/widgets/chat_message_bubble.dart b/healthway_app/lib/widgets/chat_message_bubble.dart index 126427b..3765c45 100644 --- a/healthway_app/lib/widgets/chat_message_bubble.dart +++ b/healthway_app/lib/widgets/chat_message_bubble.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../models/message_model.dart'; @@ -9,19 +10,21 @@ class ChatMessageBubble extends StatelessWidget { @override Widget build(BuildContext context) { - final isMe = message.senderId == 'currentUser'; // Replace with actual user ID check + final isMe = + message.senderId == 'currentUser'; // Replace with actual user ID check return Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: Row( - mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start, + mainAxisAlignment: + isMe ? MainAxisAlignment.end : MainAxisAlignment.start, children: [ if (!isMe) SizedBox(width: 40), Flexible( child: Container( padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10), decoration: BoxDecoration( - color: isMe ? Color(0xFF31BAC2).withOpacity(0.2) : Colors.grey[200], + color: isMe ? kPrimaryColor.withOpacity(0.2) : Colors.grey[200], borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( @@ -54,11 +57,12 @@ class ChatMessageBubble extends StatelessWidget { ), ), if (isMe) SizedBox(width: 4), - if (isMe) Icon( - Icons.done_all, - size: 16, - color: Color(0xFF31BAC2), - ), + if (isMe) + Icon( + Icons.done_all, + size: 16, + color: kPrimaryColor, + ), ], ), ], @@ -71,4 +75,3 @@ class ChatMessageBubble extends StatelessWidget { ); } } - diff --git a/healthway_app/lib/widgets/nutricionista_item.dart b/healthway_app/lib/widgets/nutricionista_item.dart index e808a77..4340ec2 100644 --- a/healthway_app/lib/widgets/nutricionista_item.dart +++ b/healthway_app/lib/widgets/nutricionista_item.dart @@ -17,12 +17,19 @@ class NutricionistaItem extends StatelessWidget { leading: CircleAvatar( radius: 30, backgroundImage: NetworkImage( - nutricionista.fotoPerfil ?? - 'https://www.w3schools.com/w3images/avatar2.png', // Imagem padrão + 'https://www.w3schools.com/w3images/avatar2.png', // Imagem padrão ), ), - title: Text(nutricionista.nome), - subtitle: Text(nutricionista.especialidade), + title: Text( + nutricionista.nome, + style: TextStyle( + color: Colors.white, + ), + ), + subtitle: Text(nutricionista.especialidade, + style: TextStyle( + color: Colors.white60, + )), onTap: () { // Navega para a tela de detalhes do nutricionista Navigator.push( diff --git a/healthway_app/lib/widgets/paciente_item.dart b/healthway_app/lib/widgets/paciente_item.dart index d9b8444..07a146f 100644 --- a/healthway_app/lib/widgets/paciente_item.dart +++ b/healthway_app/lib/widgets/paciente_item.dart @@ -1,3 +1,4 @@ +import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import '../models/paciente.dart'; @@ -60,7 +61,7 @@ class PacienteDetalhesScreen extends StatelessWidget { return Scaffold( appBar: AppBar( title: Text('Detalhes do Paciente'), - backgroundColor: Color(0xFF31BAC2), + backgroundColor: kPrimaryColor, ), body: Padding( padding: const EdgeInsets.all(16.0), diff --git a/healthway_app/test/patient_dashboard_screen_test.dart b/healthway_app/test/patient_dashboard_screen_test.dart index f1d9a60..b8467d1 100644 --- a/healthway_app/test/patient_dashboard_screen_test.dart +++ b/healthway_app/test/patient_dashboard_screen_test.dart @@ -1,12 +1,21 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; +import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; void main() { final Map mockUserData = { 'nome': 'John Doe', + 'email': 'exemplo@email.com', + 'dt_nascimento': '01/01/2000', 'altura': 180, 'peso': 75, + 'circunferencia_abdominal': 88, + 'massa_muscular': 6.5, + 'gordura_corporal': 15.5, + 'alergias': ['Amendoim', 'Leite'], + 'preferencias': ['Vegano'], }; testWidgets('PatientDashboardScreen displays user data correctly', @@ -25,10 +34,21 @@ void main() { testWidgets('PatientDashboardScreen navigates to meal plan on tap', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( + onGenerateRoute: (settings) { + switch (settings.name) { + case '/meal_plan': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => MealPlanScreen(patientData: args), + ); + default: + return null; + } + }, home: PatientDashboardScreen(userData: mockUserData), )); - await tester.tap(find.text('Dieta')); + await tester.tap(find.byKey(Key('dashboard_dieta'))); await tester.pumpAndSettle(); expect(find.byType(PatientDashboardScreen), findsNothing); @@ -60,19 +80,37 @@ void main() { testWidgets('PatientDashboardScreen bottom navigation works', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( + onGenerateRoute: (settings) { + switch (settings.name) { + case '/meal_plan': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => MealPlanScreen(patientData: args), + ); + case '/patient_profile': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => PatientProfileScreen(userData: args), + ); + default: + return null; + } + }, home: PatientDashboardScreen(userData: mockUserData), )); - await tester.tap(find.text('Dieta')); + await tester.tap(find.byKey(Key('bottom_nav_inicio'))); await tester.pumpAndSettle(); - expect(find.byType(PatientDashboardScreen), findsNothing); + expect(find.byType(PatientDashboardScreen), findsOneWidget); - await tester.tap(find.text('Progresso')); + await tester.tap(find.byKey(Key('bottom_nav_dieta'))); await tester.pumpAndSettle(); - expect(find.byType(PatientDashboardScreen), findsNothing); + expect(find.byType(MealPlanScreen), findsOneWidget); - await tester.tap(find.text('Perfil')); + await tester.tap(find.byTooltip('Back')); await tester.pumpAndSettle(); - expect(find.byType(PatientDashboardScreen), findsNothing); + await tester.tap(find.byKey(Key('bottom_nav_perfil'))); + await tester.pumpAndSettle(); + expect(find.byType(PatientProfileScreen), findsOneWidget); }); } From 2ee831bf914ece8693ba31c227567e80b8c83832 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sun, 19 Jan 2025 21:09:32 -0300 Subject: [PATCH 22/47] integrando pacientes e dashboard do nutricionista #82 #83 --- backend/controllers/pacienteController.js | 16 +++++++ backend/model/Nutricionista.js | 44 ++++++++++--------- backend/routes/pacienteRoutes.js | 1 + .../{loginScreen.dart => login_screen.dart} | 3 ++ .../geral_screens/presentation_screen.dart | 2 +- healthway_app/lib/main.dart | 14 ++++-- healthway_app/lib/models/nutricionista.dart | 4 ++ .../nutritionist_dashboard_screen.dart | 28 ++++++------ .../patient_list_screen.dart | 31 +++++++++---- .../patient_dashboard_screen.dart | 2 +- .../lib/services/paciente_services.dart | 23 ++++++++++ .../lib/services/services_facade.dart | 4 ++ 12 files changed, 125 insertions(+), 47 deletions(-) rename healthway_app/lib/geral_screens/{loginScreen.dart => login_screen.dart} (99%) diff --git a/backend/controllers/pacienteController.js b/backend/controllers/pacienteController.js index c451944..46481b1 100644 --- a/backend/controllers/pacienteController.js +++ b/backend/controllers/pacienteController.js @@ -40,6 +40,22 @@ const pacienteController = { } }, + async getByListOfIds(req, res) { + try { + const { ids } = req.body; + const pacientes = []; + for (const id of ids) { + const doc = await db.collection('paciente').doc(id).get(); + if (doc.exists) { + pacientes.push({ id: doc.id, ...doc.data() }); + } + } + res.status(200).json(pacientes); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + async getByEmailAndPassword(req, res) { try { const { email, senha } = req.body; diff --git a/backend/model/Nutricionista.js b/backend/model/Nutricionista.js index d3b3586..f8de309 100644 --- a/backend/model/Nutricionista.js +++ b/backend/model/Nutricionista.js @@ -1,25 +1,29 @@ class Nutricionista { - constructor({ cpf, crn, email, especialidade, foto_perfil, foto_documento, nome }) { - this.cpf = cpf; - this.crn = crn; - this.email = email; - this.especialidade = especialidade; - this.foto_perfil = foto_perfil; - this.foto_documento = foto_documento; - this.nome = nome; - } + constructor({ cpf, crn, email, especialidade, foto_perfil, foto_documento, nome, senha, pacientes }) { + this.cpf = cpf; + this.crn = crn; + this.email = email; + this.especialidade = especialidade; + this.foto_perfil = foto_perfil; + this.foto_documento = foto_documento; + this.nome = nome; + this.senha = senha; + this.pacientes = pacientes; + } - toFirestore() { - return { - cpf: this.cpf, - crn: this.crn, - email: this.email, - especialidade: this.especialidade, - foto_perfil: this.foto_perfil, - foto_documento: this.foto_documento, - nome: this.nome, - }; - } + toFirestore() { + return { + cpf: this.cpf, + crn: this.crn, + email: this.email, + especialidade: this.especialidade, + foto_perfil: this.foto_perfil, + foto_documento: this.foto_documento, + nome: this.nome, + senha: this.senha, + pacientes: this.pacientes, + }; + } } module.exports = Nutricionista; diff --git a/backend/routes/pacienteRoutes.js b/backend/routes/pacienteRoutes.js index c0c5502..778e435 100644 --- a/backend/routes/pacienteRoutes.js +++ b/backend/routes/pacienteRoutes.js @@ -6,6 +6,7 @@ const pacienteController = require('../controllers/pacienteController'); router.post('/', pacienteController.create); router.get('/', pacienteController.getAll); router.get('/:id', pacienteController.getById); +router.post('/list', pacienteController.getByListOfIds); router.post('/login', pacienteController.getByEmailAndPassword); router.put('/:id', pacienteController.update); router.delete('/:id', pacienteController.delete); diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/login_screen.dart similarity index 99% rename from healthway_app/lib/geral_screens/loginScreen.dart rename to healthway_app/lib/geral_screens/login_screen.dart index cd4dfbb..47a4d1c 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/login_screen.dart @@ -252,6 +252,9 @@ class _LoginScreenState extends State { arguments: userData); } } else { + setState(() { + _isLoading = false; + }); // Show error message ScaffoldMessenger.of(context).showSnackBar( SnackBar( diff --git a/healthway_app/lib/geral_screens/presentation_screen.dart b/healthway_app/lib/geral_screens/presentation_screen.dart index 7fc67e8..5c2b395 100644 --- a/healthway_app/lib/geral_screens/presentation_screen.dart +++ b/healthway_app/lib/geral_screens/presentation_screen.dart @@ -2,7 +2,7 @@ import 'package:healthway_app/constants.dart'; import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:healthway_app/geral_screens/loginScreen.dart'; +import 'package:healthway_app/geral_screens/login_screen.dart'; class PresentationScreen extends StatefulWidget { const PresentationScreen({super.key}); diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 1a60736..8f6154c 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -2,7 +2,7 @@ import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/alimentos_screen.dart'; import 'package:healthway_app/geral_screens/chat_screen.dart'; -import 'package:healthway_app/geral_screens/loginScreen.dart'; +import 'package:healthway_app/geral_screens/login_screen.dart'; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; import 'package:healthway_app/geral_screens/presentation_screen.dart'; import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; @@ -56,12 +56,10 @@ class MyApp extends StatelessWidget { // '/historic': (context) => PlanoAlimentarScreen( // pacienteId: '', // ), - '/alimentos': (context) => AlimentosScreen(), '/nutricionistas': (context) => NutricionistasScreen(), '/notifications': (context) => NotificationScreen(), '/settings': (context) => SettingsScreen(), - '/patientList': (context) => PacientesScreen(), '/schedule': (context) => ScheduleScreen(), }, onGenerateRoute: (settings) { @@ -72,8 +70,9 @@ class MyApp extends StatelessWidget { builder: (context) => PatientDashboardScreen(userData: args), ); case '/home_nutritionist': + final args = settings.arguments as Map; return MaterialPageRoute( - builder: (context) => NutritionistDashboardScreen(), + builder: (context) => NutritionistDashboardScreen(userData: args), ); case '/patient_profile': final args = settings.arguments as Map; @@ -90,6 +89,13 @@ class MyApp extends StatelessWidget { return MaterialPageRoute( builder: (context) => MealPlanScreen(patientData: args), ); + case '/patient_list': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => PacientesScreen( + args: args, + ), + ); default: return null; } diff --git a/healthway_app/lib/models/nutricionista.dart b/healthway_app/lib/models/nutricionista.dart index 328b4fe..8bd9804 100644 --- a/healthway_app/lib/models/nutricionista.dart +++ b/healthway_app/lib/models/nutricionista.dart @@ -8,6 +8,7 @@ class Nutricionista { final String senha; final String? fotoPerfil; final String? fotoDocumento; + final List pacientes; Nutricionista({ this.id, @@ -19,6 +20,7 @@ class Nutricionista { required this.senha, this.fotoPerfil, this.fotoDocumento, + this.pacientes = const [], }); factory Nutricionista.fromJson(Map json) { @@ -32,6 +34,7 @@ class Nutricionista { senha: json['senha'], fotoPerfil: json['foto_perfil'], fotoDocumento: json['foto_documento'], + pacientes: List.from(['pacientes']), ); } @@ -46,6 +49,7 @@ class Nutricionista { 'senha': senha, 'foto_perfil': fotoPerfil, 'foto_documento': fotoDocumento, + 'pacientes': pacientes, }; } } diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index 2835719..6457a49 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -2,7 +2,9 @@ import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; class NutritionistDashboardScreen extends StatelessWidget { - const NutritionistDashboardScreen({super.key}); + final Map userData; + + const NutritionistDashboardScreen({super.key, required this.userData}); @override Widget build(BuildContext context) { @@ -45,7 +47,7 @@ class NutritionistDashboardScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'Olá, Dr. Silva', + userData['nome'], style: TextStyle( color: Colors.white, fontSize: 24, @@ -88,7 +90,7 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - _buildStatItem('Pacientes', '42'), + _buildStatItem('Pacientes', '${userData['pacientes'].length}'), _buildStatItem('Consultas Hoje', '8'), _buildStatItem('Mensagens', '15'), ], @@ -140,14 +142,14 @@ class NutritionistDashboardScreen extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + _buildQuickAccessItem(context, Icons.people, 'Pacientes', + '/patient_list', userData), _buildQuickAccessItem( - context, Icons.people, 'Pacientes', '/patientList'), - _buildQuickAccessItem( - context, Icons.calendar_today, 'Agenda', '/schedule'), - _buildQuickAccessItem( - context, Icons.restaurant_menu, 'Planos', '/meal_plans'), - _buildQuickAccessItem( - context, Icons.food_bank_outlined, 'Alimentos', '/alimentos'), + context, Icons.calendar_today, 'Agenda', '/schedule', null), + // _buildQuickAccessItem( + // context, Icons.restaurant_menu, 'Planos', '/meal_plans'), + _buildQuickAccessItem(context, Icons.food_bank_outlined, + 'Alimentos', '/alimentos', null), ], ), ], @@ -155,11 +157,11 @@ class NutritionistDashboardScreen extends StatelessWidget { ); } - Widget _buildQuickAccessItem( - BuildContext context, IconData icon, String label, String route) { + Widget _buildQuickAccessItem(BuildContext context, IconData icon, + String label, String route, Object? args) { return GestureDetector( onTap: () { - Navigator.pushNamed(context, route); + Navigator.pushNamed(context, route, arguments: args); }, child: Column( children: [ diff --git a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart index d74b22c..1c10fab 100644 --- a/healthway_app/lib/screens_nutricionist/patient_list_screen.dart +++ b/healthway_app/lib/screens_nutricionist/patient_list_screen.dart @@ -1,21 +1,26 @@ -import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; +import 'package:healthway_app/constants.dart'; +import 'package:healthway_app/services/services_facade.dart'; + import '../models/paciente.dart'; -import '../services/paciente_services.dart'; import '../widgets/paciente_item.dart'; class PacientesScreen extends StatefulWidget { - const PacientesScreen({super.key}); + final Map args; + + const PacientesScreen({super.key, required this.args}); @override - _PacientesScreenState createState() => _PacientesScreenState(); + State createState() => _PacientesScreenState(); } class _PacientesScreenState extends State { late Future> _pacientes; + bool initialized = false; List pacientes = []; List pacientesFiltrados = []; TextEditingController searchController = TextEditingController(); + var servicesFacade = ServicesFacade(); @override void initState() { @@ -25,16 +30,19 @@ class _PacientesScreenState extends State { void _carregarPacientes() { setState(() { - _pacientes = PacienteService().fetchPacientes(); + _pacientes = servicesFacade + .obterPacientesPorIds(List.from(widget.args['pacientes'])); }); } void _filtrarPacientes(String query) { + query = query.trim(); setState(() { pacientesFiltrados = pacientes .where((paciente) => paciente.nome.toLowerCase().contains(query.toLowerCase()) || - paciente.email.toLowerCase().contains(query.toLowerCase())) + paciente.email.toLowerCase().contains(query.toLowerCase()) || + paciente.cpf.toLowerCase().contains(query.toLowerCase())) .toList(); }); } @@ -45,6 +53,7 @@ class _PacientesScreenState extends State { backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Pacientes'), + foregroundColor: Colors.white, backgroundColor: kPrimaryColor, elevation: 0, ), @@ -64,8 +73,12 @@ class _PacientesScreenState extends State { return _buildEmptyWidget(); } else { pacientes = snapshot.data!; - if (pacientesFiltrados.isEmpty) { + if (!initialized) { pacientesFiltrados = pacientes; + initialized = true; + } + if (pacientesFiltrados.isEmpty) { + return _buildEmptyWidget(); } return _buildPacientesList(); } @@ -77,6 +90,7 @@ class _PacientesScreenState extends State { floatingActionButton: FloatingActionButton( onPressed: _carregarPacientes, backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, child: Icon(Icons.refresh), ), ); @@ -89,8 +103,9 @@ class _PacientesScreenState extends State { child: TextField( controller: searchController, onChanged: _filtrarPacientes, + style: TextStyle(color: kTextColor, fontWeight: FontWeight.w500), decoration: InputDecoration( - hintText: 'Pesquisar por nome ou email...', + hintText: 'Pesquisar por nome, email ou CPF...', prefixIcon: Icon(Icons.search, color: kPrimaryColor), filled: true, fillColor: Colors.white, diff --git a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart index 8e2ac32..fa8b26a 100644 --- a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart +++ b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart @@ -48,7 +48,7 @@ class PatientDashboardScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - userData['nome'], + name, style: TextStyle( color: Colors.white, fontSize: 24, diff --git a/healthway_app/lib/services/paciente_services.dart b/healthway_app/lib/services/paciente_services.dart index e7f4f8a..b173900 100644 --- a/healthway_app/lib/services/paciente_services.dart +++ b/healthway_app/lib/services/paciente_services.dart @@ -39,6 +39,29 @@ class PacienteService { } } + Future> fetchPacientesByIds(List ids) async { + var uri = Uri.parse('$apiUrl/list'); + var request = http.Request('POST', uri) + ..headers['Content-Type'] = 'application/json' + ..body = json.encode({'ids': ids}); + var response = await request.send(); + if (response.statusCode == 200) { + var responseBody = await response.stream.bytesToString(); + List? data = json.decode(responseBody); + try { + if (data != null) { + return data.map((json) => Paciente.fromJson(json)).toList(); + } else { + throw Exception('Dados não encontrados ou formato inválido'); + } + } catch (e) { + throw Exception('Erro ao parsear o JSON: $e'); + } + } else { + throw Exception('Falha ao carregar pacientes'); + } + } + Future cadastrarPaciente(Paciente paciente) async { var uri = Uri.parse(apiUrl); var request = http.MultipartRequest('POST', uri); diff --git a/healthway_app/lib/services/services_facade.dart b/healthway_app/lib/services/services_facade.dart index 4157698..ecd4a3d 100644 --- a/healthway_app/lib/services/services_facade.dart +++ b/healthway_app/lib/services/services_facade.dart @@ -34,6 +34,10 @@ class ServicesFacade { return await _pacienteService.fetchPacienteById(id); } + Future> obterPacientesPorIds(List ids) async { + return await _pacienteService.fetchPacientesByIds(ids); + } + Future cadastrar(dynamic entity) async { if (entity is Nutricionista) { await _nutricionistaService.cadastrarNutricionista(entity); From c234d7078f2d3eae78fbfb26e25a48346d34c0c1 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sun, 19 Jan 2025 23:00:18 -0300 Subject: [PATCH 23/47] consertando teste de paciente --- .../controllers/pacienteController.test.js | 3 +- .../lib/geral_screens/alimentos_screen.dart | 2 +- .../nutritionist_dashboard_screen.dart | 12 +- .../lib/screens_patient/healthScreen.dart | 2 +- .../screens_patient/notificationScreen.dart | 2 +- .../patient_dashboard_screen.dart | 134 +++++++++--------- healthway_app/lib/widgets/alimento_item.dart | 2 +- .../lib/widgets/chat_input_field.dart | 2 +- .../lib/widgets/chat_message_bubble.dart | 4 +- 9 files changed, 83 insertions(+), 80 deletions(-) diff --git a/backend/tests/controllers/pacienteController.test.js b/backend/tests/controllers/pacienteController.test.js index e2cc8d9..c8076ce 100644 --- a/backend/tests/controllers/pacienteController.test.js +++ b/backend/tests/controllers/pacienteController.test.js @@ -4,6 +4,7 @@ const db = require('../../firebase-config'); jest.mock('../../firebase-config', () => ({ collection: jest.fn().mockReturnThis(), doc: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), get: jest.fn().mockResolvedValue(), add: jest.fn(), update: jest.fn(), @@ -218,7 +219,7 @@ describe('pacienteController', () => { json: jest.fn(), }; - await pacienteController.getByEmailAndPassword(req, res); + const result = await pacienteController.getByEmailAndPassword(req, res); expect(res.status).toHaveBeenCalledWith(200); expect(res.json).toHaveBeenCalledWith(mockData); diff --git a/healthway_app/lib/geral_screens/alimentos_screen.dart b/healthway_app/lib/geral_screens/alimentos_screen.dart index fdfbc5f..38ee050 100644 --- a/healthway_app/lib/geral_screens/alimentos_screen.dart +++ b/healthway_app/lib/geral_screens/alimentos_screen.dart @@ -118,7 +118,7 @@ class _AlimentosScreenState extends State { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), - shadowColor: Colors.black.withOpacity(0.2), + shadowColor: Colors.black.withValues(alpha: 0.2), color: Colors .transparent, // Garantir que o fundo do card seja transparente child: AlimentoItem(alimento: alimentosFiltrados[index]), diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index 6457a49..d4d1212 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -168,7 +168,7 @@ class NutritionistDashboardScreen extends StatelessWidget { Container( padding: EdgeInsets.all(15), decoration: BoxDecoration( - color: kPrimaryColor.withOpacity(0.1), + color: kPrimaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(15), ), child: Icon( @@ -247,7 +247,7 @@ class NutritionistDashboardScreen extends StatelessWidget { borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.1), + color: Colors.grey.withValues(alpha: 0.1), spreadRadius: 1, blurRadius: 5, offset: Offset(0, 3), @@ -259,7 +259,7 @@ class NutritionistDashboardScreen extends StatelessWidget { Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( - color: kPrimaryColor.withOpacity(0.1), + color: kPrimaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(10), ), child: Icon( @@ -360,7 +360,7 @@ class NutritionistDashboardScreen extends StatelessWidget { borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.1), + color: Colors.grey.withValues(alpha: 0.1), spreadRadius: 1, blurRadius: 5, offset: Offset(0, 3), @@ -370,7 +370,7 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Row( children: [ CircleAvatar( - backgroundColor: kPrimaryColor.withOpacity(0.1), + backgroundColor: kPrimaryColor.withValues(alpha: 0.1), child: Text( name[0], style: TextStyle( @@ -421,7 +421,7 @@ class NutritionistDashboardScreen extends StatelessWidget { color: Colors.white, boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.3), + color: Colors.grey.withValues(alpha: 0.3), spreadRadius: 1, blurRadius: 5, offset: Offset(0, -3), diff --git a/healthway_app/lib/screens_patient/healthScreen.dart b/healthway_app/lib/screens_patient/healthScreen.dart index 014a271..2ba55c6 100644 --- a/healthway_app/lib/screens_patient/healthScreen.dart +++ b/healthway_app/lib/screens_patient/healthScreen.dart @@ -115,7 +115,7 @@ class DietManagementScreen extends StatelessWidget { child: ListTile( contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), leading: CircleAvatar( - backgroundColor: kPrimaryColor.withOpacity(0.1), + backgroundColor: kPrimaryColor.withValues(alpha: 0.1), child: Icon(Icons.restaurant, color: kPrimaryColor), ), title: Text(mealName, style: TextStyle(fontWeight: FontWeight.bold)), diff --git a/healthway_app/lib/screens_patient/notificationScreen.dart b/healthway_app/lib/screens_patient/notificationScreen.dart index 59a6869..1c9d733 100644 --- a/healthway_app/lib/screens_patient/notificationScreen.dart +++ b/healthway_app/lib/screens_patient/notificationScreen.dart @@ -61,7 +61,7 @@ class NotificationScreen extends StatelessWidget { child: ListTile( contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), leading: CircleAvatar( - backgroundColor: kPrimaryColor.withOpacity(0.1), + backgroundColor: kPrimaryColor.withValues(alpha: 0.1), child: Icon(icon, color: kPrimaryColor), ), title: Text( diff --git a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart index fa8b26a..a34a4dd 100644 --- a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart +++ b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart @@ -23,7 +23,7 @@ class PatientDashboardScreen extends StatelessWidget { ), ), ), - // bottomNavigationBar: _buildBottomNavigationBar(context), + bottomNavigationBar: _buildBottomNavigationBar(context), ); } @@ -211,7 +211,7 @@ class PatientDashboardScreen extends StatelessWidget { borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.1), + color: Colors.grey.withValues(alpha: 0.1), spreadRadius: 1, blurRadius: 5, offset: Offset(0, 3), @@ -223,7 +223,7 @@ class PatientDashboardScreen extends StatelessWidget { Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( - color: kPrimaryColor.withOpacity(0.1), + color: kPrimaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(10), ), child: Icon( @@ -315,70 +315,70 @@ class PatientDashboardScreen extends StatelessWidget { ); } - // Widget _buildBottomNavigationBar(BuildContext context) { - // return Container( - // decoration: BoxDecoration( - // color: Colors.white, - // boxShadow: [ - // BoxShadow( - // color: Colors.grey.withValues(alpha: 0.3), - // spreadRadius: 1, - // blurRadius: 5, - // offset: Offset(0, -3), - // ), - // ], - // ), - // child: BottomNavigationBar( - // backgroundColor: Colors.transparent, - // elevation: 0, - // selectedItemColor: kPrimaryColor, - // unselectedItemColor: Colors.grey, - // showSelectedLabels: true, - // showUnselectedLabels: true, - // type: BottomNavigationBarType.fixed, - // items: [ - // BottomNavigationBarItem( - // icon: Icon(Icons.home), - // label: 'Início', - // key: Key('bottom_nav_inicio'), - // ), - // BottomNavigationBarItem( - // icon: Icon(Icons.restaurant_menu), - // label: 'Dieta', - // key: Key('bottom_nav_dieta'), - // ), - // // BottomNavigationBarItem( - // // icon: Icon(Icons.insert_chart), - // // label: 'Progresso', - // // key: Key('bottom_nav_progresso'), - // // ), - // BottomNavigationBarItem( - // icon: Icon(Icons.person), - // label: 'Perfil', - // key: Key('bottom_nav_perfil'), - // ), - // ], - // onTap: (index) { - // switch (index) { - // case 0: - // // Já estamos na tela inicial, então não faça nada - // break; - // case 1: - // Navigator.pushNamed(context, '/meal_plan', arguments: userData); - // break; - // // case 2: - // // Navigator.pushNamed(context, '/progress'); - // // break; - // // case 3: - // case 2: - // Navigator.pushNamed(context, '/patient_profile', - // arguments: userData); - // break; - // } - // }, - // ), - // ); - // } + Widget _buildBottomNavigationBar(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withValues(alpha: 0.3), + spreadRadius: 1, + blurRadius: 5, + offset: Offset(0, -3), + ), + ], + ), + child: BottomNavigationBar( + backgroundColor: Colors.transparent, + elevation: 0, + selectedItemColor: kPrimaryColor, + unselectedItemColor: Colors.grey, + showSelectedLabels: true, + showUnselectedLabels: true, + type: BottomNavigationBarType.fixed, + items: [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Início', + key: Key('bottom_nav_inicio'), + ), + BottomNavigationBarItem( + icon: Icon(Icons.restaurant_menu), + label: 'Dieta', + key: Key('bottom_nav_dieta'), + ), + // BottomNavigationBarItem( + // icon: Icon(Icons.insert_chart), + // label: 'Progresso', + // key: Key('bottom_nav_progresso'), + // ), + BottomNavigationBarItem( + icon: Icon(Icons.person), + label: 'Perfil', + key: Key('bottom_nav_perfil'), + ), + ], + onTap: (index) { + switch (index) { + case 0: + // Já estamos na tela inicial, então não faça nada + break; + case 1: + Navigator.pushNamed(context, '/meal_plan', arguments: userData); + break; + // case 2: + // Navigator.pushNamed(context, '/progress'); + // break; + // case 3: + case 2: + Navigator.pushNamed(context, '/patient_profile', + arguments: userData); + break; + } + }, + ), + ); + } double _calculateBMI(alturaM, peso) { var alturaCm = alturaM / 100; diff --git a/healthway_app/lib/widgets/alimento_item.dart b/healthway_app/lib/widgets/alimento_item.dart index 89e1267..c1f0bc9 100644 --- a/healthway_app/lib/widgets/alimento_item.dart +++ b/healthway_app/lib/widgets/alimento_item.dart @@ -14,7 +14,7 @@ class AlimentoItem extends StatelessWidget { child: Card( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), elevation: 3, - shadowColor: Colors.black.withOpacity(0.1), // Sombra suave + shadowColor: Colors.black.withValues(alpha: 0.1), // Sombra suave color: Colors.white, // Cor de fundo do card child: Padding( padding: const EdgeInsets.all(16.0), diff --git a/healthway_app/lib/widgets/chat_input_field.dart b/healthway_app/lib/widgets/chat_input_field.dart index 08dc8e5..28d15bd 100644 --- a/healthway_app/lib/widgets/chat_input_field.dart +++ b/healthway_app/lib/widgets/chat_input_field.dart @@ -31,7 +31,7 @@ class _ChatInputFieldState extends State { BoxShadow( offset: Offset(0, -2), blurRadius: 4, - color: Colors.black.withOpacity(0.1), + color: Colors.black.withValues(alpha: 0.1), ), ], ), diff --git a/healthway_app/lib/widgets/chat_message_bubble.dart b/healthway_app/lib/widgets/chat_message_bubble.dart index 3765c45..d8b580e 100644 --- a/healthway_app/lib/widgets/chat_message_bubble.dart +++ b/healthway_app/lib/widgets/chat_message_bubble.dart @@ -24,7 +24,9 @@ class ChatMessageBubble extends StatelessWidget { child: Container( padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10), decoration: BoxDecoration( - color: isMe ? kPrimaryColor.withOpacity(0.2) : Colors.grey[200], + color: isMe + ? kPrimaryColor.withValues(alpha: 0.2) + : Colors.grey[200], borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( From 57ad7c0940852ce9aa945309ec5e41bfd23141d6 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Sun, 19 Jan 2025 23:37:42 -0300 Subject: [PATCH 24/47] preparando front para build --- README.md | 7 ++++++- healthway_app/android/settings.gradle | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c7226af..a5eb96e 100644 --- a/README.md +++ b/README.md @@ -1 +1,6 @@ -# Healthway \ No newline at end of file +## Tutorial Instalação para Android + +```bash +flutter build apk --split-per-abi +flutter install --use-application-binary=build\app\outputs\flutter-apk\app-arm64-v8a-release.apk +``` diff --git a/healthway_app/android/settings.gradle b/healthway_app/android/settings.gradle index b9e43bd..a42444d 100644 --- a/healthway_app/android/settings.gradle +++ b/healthway_app/android/settings.gradle @@ -18,7 +18,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.1.0" apply false + id "com.android.application" version "8.2.1" apply false id "org.jetbrains.kotlin.android" version "1.8.22" apply false } From b035759313cb1197503dff5588bc4182f263d7f8 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Mon, 20 Jan 2025 02:56:38 -0300 Subject: [PATCH 25/47] integrando tela de cadastro de paciente #85 --- backend/controllers/pacienteController.js | 9 +- backend/model/Paciente.js | 5 +- .../signup_patient_screen.dart | 215 ++++++++++++------ .../lib/services/paciente_services.dart | 56 +++-- 4 files changed, 194 insertions(+), 91 deletions(-) diff --git a/backend/controllers/pacienteController.js b/backend/controllers/pacienteController.js index 46481b1..5bbe180 100644 --- a/backend/controllers/pacienteController.js +++ b/backend/controllers/pacienteController.js @@ -5,11 +5,12 @@ const pacienteController = { // Criar um paciente async create(req, res) { try { - const paciente = new Paciente(req.body); - await db.collection('paciente').add(paciente.toFirestore()); - res.status(201).json({ message: 'Paciente criado com sucesso!' }); + const paciente = new Paciente(); + paciente.fromJson(req.body); + await db.collection('paciente').add(paciente.toFirestore()); + res.status(201).json({ message: 'Paciente criado com sucesso!' }); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, diff --git a/backend/model/Paciente.js b/backend/model/Paciente.js index eef5709..8e8bfb6 100644 --- a/backend/model/Paciente.js +++ b/backend/model/Paciente.js @@ -1,12 +1,11 @@ class Paciente { - constructor(alergias, altura, cpf, data_nascimento, email, foto_perfil = '', nome, peso, sexo, + constructor(alergias, altura, cpf, data_nascimento, email, nome, peso, sexo, circunferencia_abdominal, gordura_corporal, massa_muscular, preferencias, senha) { this.alergias = alergias; this.altura = altura; this.cpf = cpf; this.dt_nascimento = data_nascimento; this.email = email; - this.foto_perfil = foto_perfil; this.nome = nome; this.peso = peso; this.sexo = sexo; @@ -25,7 +24,6 @@ class Paciente { cpf: this.cpf, dt_nascimento: this.dt_nascimento, email: this.email, - foto_perfil: this.foto_perfil, nome: this.nome, peso: this.peso, sexo: this.sexo, @@ -43,7 +41,6 @@ class Paciente { this.cpf = json.cpf || ''; this.dt_nascimento = json.dt_nascimento || ''; this.email = json.email || ''; - this.foto_perfil = json.foto_perfil || ''; this.nome = json.nome || ''; this.peso = parseFloat(json.peso) || 0; this.sexo = json.sexo || ''; diff --git a/healthway_app/lib/screens_patient/signup_patient_screen.dart b/healthway_app/lib/screens_patient/signup_patient_screen.dart index 2e58696..a81bbb5 100644 --- a/healthway_app/lib/screens_patient/signup_patient_screen.dart +++ b/healthway_app/lib/screens_patient/signup_patient_screen.dart @@ -23,8 +23,8 @@ class _CadastroPacienteScreenState extends State { final _circunferenciaAbdominalController = TextEditingController(); final _gorduraCorporalController = TextEditingController(); final _massaMuscularController = TextEditingController(); - final _alergiasController = TextEditingController(); - final _preferenciasController = TextEditingController(); + final List _alergiasController = []; + final List _preferenciasController = []; final _senhaController = TextEditingController(); final _confirmarSenhaController = TextEditingController(); @@ -77,14 +77,15 @@ class _CadastroPacienteScreenState extends State { _buildTextField(_cpfController, 'CPF', Icons.badge, inputFormatters: [ FilteringTextInputFormatter.digitsOnly - ]), + ], + maxLength: 11), _buildDateField(), _buildDropdownField(), _buildMeasurementFields(), - _buildTextField( + _buildListField( _alergiasController, 'Alergias', Icons.warning), - _buildTextField(_preferenciasController, - 'Preferências Alimentares', Icons.restaurant), + _buildListField(_preferenciasController, 'Preferências', + Icons.restaurant), _buildPasswordFields(), SizedBox(height: 30), ElevatedButton( @@ -113,10 +114,75 @@ class _CadastroPacienteScreenState extends State { ); } + Widget _buildListField( + List controllerList, String label, IconData icon) { + return Column( + children: [ + ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: controllerList.length, + itemBuilder: (context, index) { + return Padding( + padding: EdgeInsets.only(bottom: 10.0), + child: Row( + children: [ + Expanded( + child: TextFormField( + controller: controllerList[index], + decoration: InputDecoration( + labelText: '$label ${index + 1}', + prefixIcon: Icon(icon, color: kPrimaryColor), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + borderSide: BorderSide.none, + ), + filled: true, + fillColor: Colors.white, + labelStyle: TextStyle(color: kPrimaryColor), + floatingLabelBehavior: FloatingLabelBehavior.always, + ), + style: TextStyle(fontSize: 16), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, preencha este campo'; + } + return null; + }, + ), + ), + IconButton( + icon: Icon(Icons.remove_circle, color: Colors.red), + onPressed: () { + setState(() { + controllerList.removeAt(index); + }); + }, + ), + ], + ), + ); + }, + ), + TextButton.icon( + onPressed: () { + setState(() { + controllerList.add(TextEditingController()); + }); + }, + icon: Icon(Icons.add, color: kPrimaryColor), + label: + Text('Adicionar $label', style: TextStyle(color: kPrimaryColor)), + ), + ], + ); + } + Widget _buildTextField( TextEditingController controller, String label, IconData icon, {TextInputType? keyboardType, - List? inputFormatters}) { + List? inputFormatters, + int? maxLength}) { return Padding( padding: EdgeInsets.only(bottom: 20.0), child: TextFormField( @@ -133,9 +199,14 @@ class _CadastroPacienteScreenState extends State { labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), - style: TextStyle(fontSize: 16), + style: TextStyle( + fontSize: 16, color: kTextColor, fontWeight: FontWeight.w500), keyboardType: keyboardType, inputFormatters: inputFormatters, + maxLength: maxLength, + buildCounter: (context, + {required currentLength, required isFocused, maxLength}) => + null, validator: (value) { if (value == null || value.isEmpty) { return 'Por favor, preencha este campo'; @@ -163,7 +234,8 @@ class _CadastroPacienteScreenState extends State { labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), - style: TextStyle(fontSize: 16), + style: TextStyle( + fontSize: 16, color: kTextColor, fontWeight: FontWeight.w500), readOnly: true, onTap: () async { final pickedDate = await showDatePicker( @@ -218,7 +290,8 @@ class _CadastroPacienteScreenState extends State { labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), - style: TextStyle(fontSize: 16, color: Colors.black), + style: TextStyle( + fontSize: 16, color: kTextColor, fontWeight: FontWeight.w500), items: ['Masculino', 'Feminino', 'Outro'] .map((label) => DropdownMenuItem( value: label, @@ -241,53 +314,50 @@ class _CadastroPacienteScreenState extends State { } Widget _buildMeasurementFields() { - return Card( - elevation: 4, - color: Color(0xFFF0FAFB), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - child: Padding( - padding: EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Medidas Corporais', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: kPrimaryColor), - ), - SizedBox(height: 16), - Row( - children: [ - Expanded( - child: _buildMeasurementField( - _alturaController, 'Altura (cm)', Icons.height)), - SizedBox(width: 16), - Expanded( - child: _buildMeasurementField( - _pesoController, 'Peso (kg)', Icons.fitness_center)), - ], - ), - SizedBox(height: 16), - _buildMeasurementField(_circunferenciaAbdominalController, - 'Circunferência Abdominal (cm)', Icons.straighten), - SizedBox(height: 16), - Row( + return Padding( + padding: EdgeInsets.only(bottom: 20.0), + child: Card( + elevation: 4, + color: Color(0xFFF0FAFB), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: _buildMeasurementField(_gorduraCorporalController, - 'Gordura Corporal (%)', Icons.percent)), - SizedBox(width: 16), - Expanded( - child: _buildMeasurementField(_massaMuscularController, - 'Massa Muscular (kg)', Icons.fitness_center)), + Text( + 'Medidas Corporais', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: kPrimaryColor), + ), + SizedBox(height: 16), + Row( + children: [ + Expanded( + child: _buildMeasurementField( + _alturaController, 'Altura (cm)', Icons.height)), + SizedBox(width: 16), + Expanded( + child: _buildMeasurementField(_pesoController, + 'Peso (kg)', Icons.fitness_center)), + ], + ), + SizedBox(height: 16), + _buildMeasurementField(_circunferenciaAbdominalController, + 'Circunferência Abdominal (cm)', Icons.straighten), + SizedBox(height: 16), + _buildMeasurementField(_gorduraCorporalController, + 'Gordura Corporal (%)', Icons.percent), + SizedBox(height: 16), + _buildMeasurementField(_massaMuscularController, + 'Massa Muscular (kg)', Icons.fitness_center), ], ), - ], - ), - ), - ); + ), + )); } Widget _buildMeasurementField( @@ -307,8 +377,12 @@ class _CadastroPacienteScreenState extends State { ), labelStyle: TextStyle(color: kPrimaryColor), ), - keyboardType: TextInputType.number, - style: TextStyle(fontSize: 16), + keyboardType: TextInputType.numberWithOptions(decimal: true), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'^\d*(\,|\.)?\d*')), + ], + style: TextStyle( + fontSize: 16, color: kTextColor, fontWeight: FontWeight.w500), validator: (value) { if (value == null || value.isEmpty) { return 'Preencha este campo'; @@ -379,7 +453,8 @@ class _CadastroPacienteScreenState extends State { labelStyle: TextStyle(color: kPrimaryColor), floatingLabelBehavior: FloatingLabelBehavior.always, ), - style: TextStyle(fontSize: 16), + style: TextStyle( + fontSize: 16, color: kTextColor, fontWeight: FontWeight.w500), validator: (value) { if (value == null || value.isEmpty) { return 'Por favor, insira uma senha'; @@ -411,14 +486,16 @@ class _CadastroPacienteScreenState extends State { cpf: _cpfController.text, dataNascimento: DateFormat('dd/MM/yyyy').format(dataNascimento), sexo: _sexo!, - altura: double.parse(_alturaController.text), - peso: double.parse(_pesoController.text), - circunferenciaAbdominal: - double.parse(_circunferenciaAbdominalController.text), - gorduraCorporal: double.parse(_gorduraCorporalController.text), - massaMuscular: double.parse(_massaMuscularController.text), - alergias: [], - preferencias: [], + altura: double.parse(_alturaController.text.replaceFirst(',', '.')), + peso: double.parse(_pesoController.text.replaceFirst(',', '.')), + circunferenciaAbdominal: double.parse( + _circunferenciaAbdominalController.text.replaceFirst(',', '.')), + gorduraCorporal: double.parse( + _gorduraCorporalController.text.replaceFirst(',', '.')), + massaMuscular: double.parse( + _massaMuscularController.text.replaceFirst(',', '.')), + alergias: _alergiasController.map((e) => e.text).toList(), + preferencias: _preferenciasController.map((e) => e.text).toList(), senha: _senhaController.text, )); @@ -451,8 +528,12 @@ class _CadastroPacienteScreenState extends State { _circunferenciaAbdominalController.dispose(); _gorduraCorporalController.dispose(); _massaMuscularController.dispose(); - _alergiasController.dispose(); - _preferenciasController.dispose(); + for (var controller in _alergiasController) { + controller.dispose(); + } + for (var controller in _preferenciasController) { + controller.dispose(); + } _senhaController.dispose(); _confirmarSenhaController.dispose(); super.dispose(); diff --git a/healthway_app/lib/services/paciente_services.dart b/healthway_app/lib/services/paciente_services.dart index b173900..b9fe583 100644 --- a/healthway_app/lib/services/paciente_services.dart +++ b/healthway_app/lib/services/paciente_services.dart @@ -64,24 +64,48 @@ class PacienteService { Future cadastrarPaciente(Paciente paciente) async { var uri = Uri.parse(apiUrl); - var request = http.MultipartRequest('POST', uri); + // var request = http.MultipartRequest('POST', uri); - request.fields['nome'] = paciente.nome; - request.fields['email'] = paciente.email; - request.fields['cpf'] = paciente.cpf; - request.fields['dt_nascimento'] = paciente.dataNascimento.toString(); - request.fields['sexo'] = paciente.sexo; - request.fields['altura'] = paciente.altura.toString(); - request.fields['peso'] = paciente.peso.toString(); - request.fields['circunferencia_abdominal'] = - paciente.circunferenciaAbdominal.toString(); - request.fields['gordura_corporal'] = paciente.gorduraCorporal.toString(); - request.fields['massa_muscular'] = paciente.massaMuscular.toString(); - request.fields['alergias'] = paciente.alergias.toString(); - request.fields['preferencias'] = paciente.preferencias.toString(); - request.fields['senha'] = paciente.senha; + // request.fields['nome'] = paciente.nome; + // request.fields['email'] = paciente.email; + // request.fields['cpf'] = paciente.cpf; + // request.fields['dt_nascimento'] = paciente.dataNascimento.toString(); + // request.fields['sexo'] = paciente.sexo; + // request.fields['altura'] = paciente.altura.toString(); + // request.fields['peso'] = paciente.peso.toString(); + // request.fields['circunferencia_abdominal'] = + // paciente.circunferenciaAbdominal.toString(); + // request.fields['gordura_corporal'] = paciente.gorduraCorporal.toString(); + // request.fields['massa_muscular'] = paciente.massaMuscular.toString(); + // request.fields['alergias'] = paciente.alergias.toString(); + // request.fields['preferencias'] = paciente.preferencias.toString(); + // request.fields['senha'] = paciente.senha; + + // var response = await request.send(); + // if (response.statusCode != 201) { + // throw Exception('Falha ao cadastrar paciente'); + // } + + var response = await http.post( + uri, + headers: {'Content-Type': 'application/json'}, + body: jsonEncode({ + 'nome': paciente.nome, + 'email': paciente.email, + 'cpf': paciente.cpf, + 'dt_nascimento': paciente.dataNascimento, + 'sexo': paciente.sexo, + 'altura': paciente.altura, + 'peso': paciente.peso, + 'circunferencia_abdominal': paciente.circunferenciaAbdominal, + 'gordura_corporal': paciente.gorduraCorporal, + 'massa_muscular': paciente.massaMuscular, + 'alergias': paciente.alergias, + 'preferencias': paciente.preferencias, + 'senha': paciente.senha, + }), + ); - var response = await request.send(); if (response.statusCode != 201) { throw Exception('Falha ao cadastrar paciente'); } From c2bc37fbe70deef9dcd9a0fbff58314f877ad3f2 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Mon, 20 Jan 2025 03:07:05 -0300 Subject: [PATCH 26/47] adicionando alimentos no dashboard do paciente --- healthway_app/lib/geral_screens/alimentos_screen.dart | 1 + .../screens_nutricionist/nutritionist_dashboard_screen.dart | 3 ++- .../lib/screens_patient/patient_dashboard_screen.dart | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/healthway_app/lib/geral_screens/alimentos_screen.dart b/healthway_app/lib/geral_screens/alimentos_screen.dart index 38ee050..97f129e 100644 --- a/healthway_app/lib/geral_screens/alimentos_screen.dart +++ b/healthway_app/lib/geral_screens/alimentos_screen.dart @@ -47,6 +47,7 @@ class _AlimentosScreenState extends State { backgroundColor: kBackgroundColor, appBar: AppBar( title: Text('Alimentos'), + foregroundColor: Colors.white, backgroundColor: kPrimaryColor, elevation: 5, // Remover o arredondamento da parte superior do AppBar diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index d4d1212..960857a 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -443,7 +443,8 @@ class NutritionistDashboardScreen extends StatelessWidget { // Already on home screen break; case 1: - Navigator.pushNamed(context, '/patientList'); + Navigator.pushNamed(context, '/patient_list', + arguments: userData); break; case 2: Navigator.pushNamed(context, '/schedule'); diff --git a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart index a34a4dd..505ea9f 100644 --- a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart +++ b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart @@ -155,6 +155,8 @@ class PatientDashboardScreen extends StatelessWidget { '/meal_plan', 'dashboard_dieta', userData), _buildQuickAccessItem(context, Icons.people, 'Nutricionistas', '/nutricionistas', 'dashboard_nutricionistas', null), + _buildQuickAccessItem(context, Icons.local_dining, 'Alimentos', + '/alimentos', 'dashboard_alimentos', null), // _buildQuickAccessItem( // context, Icons.insert_chart, 'Progresso', '/progress', 'dashboard_', null), _buildQuickAccessItem(context, Icons.message, 'Chat', '/chat', From 2d953345504e0ccf53a62284d78b83008a364b2b Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 20 Jan 2025 17:12:58 -0300 Subject: [PATCH 27/47] teste para a tela de dashboard do nutricionista --- .../lib/geral_screens/loginScreen.dart | 4 +- healthway_app/lib/main.dart | 3 +- healthway_app/pubspec.yaml | 3 ++ .../nutricionista_dashboard_screen_test.dart | 37 +++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 healthway_app/test/nutricionista_dashboard_screen_test.dart diff --git a/healthway_app/lib/geral_screens/loginScreen.dart b/healthway_app/lib/geral_screens/loginScreen.dart index f0ec7fb..98f74ae 100644 --- a/healthway_app/lib/geral_screens/loginScreen.dart +++ b/healthway_app/lib/geral_screens/loginScreen.dart @@ -2,9 +2,11 @@ import 'package:flutter/material.dart'; import 'package:healthway_app/geral_screens/forgot_screen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; import 'package:healthway_app/screens_patient/dashboardScreen.dart'; -import 'package:healthway_app/screens_patient/signupScreen.dart'; +import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; import 'package:healthway_app/services/auth_service.dart'; +import '../screens_patient/signup_patient_screen.dart'; + class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index d7b4e88..070c38c 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -12,7 +12,8 @@ import 'package:healthway_app/screens_patient/dietScreen.dart'; import 'package:healthway_app/screens_patient/notificationScreen.dart'; import 'package:healthway_app/screens_patient/profileScreen.dart'; import 'package:healthway_app/screens_patient/setingsScreen.dart'; -import 'package:healthway_app/screens_patient/signupScreen.dart'; +import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; +import 'package:healthway_app/screens_patient/signup_patient_screen.dart'; import 'package:healthway_app/widgets/paciente_item.dart'; import 'geral_screens/chat_screen.dart'; diff --git a/healthway_app/pubspec.yaml b/healthway_app/pubspec.yaml index 3a08f42..b969b39 100644 --- a/healthway_app/pubspec.yaml +++ b/healthway_app/pubspec.yaml @@ -28,6 +28,8 @@ environment: # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: + flutter_test: + sdk: flutter flutter: sdk: flutter http: ^1.2.2 @@ -36,6 +38,7 @@ dependencies: intl: ^0.18.0 get: ^4.6.5 uuid: ^3.0.7 + mockito: ^5.0.15 # The following adds the Cupertino Icons font to your application. diff --git a/healthway_app/test/nutricionista_dashboard_screen_test.dart b/healthway_app/test/nutricionista_dashboard_screen_test.dart new file mode 100644 index 0000000..460f493 --- /dev/null +++ b/healthway_app/test/nutricionista_dashboard_screen_test.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard.dart'; + +void main() { + testWidgets('NutritionistDashboardScreen displays correctly', (WidgetTester tester) async { + // Build the NutritionistDashboardScreen widget. + await tester.pumpWidget(MaterialApp(home: NutritionistDashboardScreen())); + + // Verify if the background color is correct. + final scaffold = tester.widget(find.byType(Scaffold)); + expect(scaffold.backgroundColor, const Color(0xFFE6F7F8)); + + // Verify if the AppBar widget is present. + expect(find.byType(AppBar), findsOneWidget); + + // Verify if the Icon widget is present. + expect(find.byType(Icon), findsOneWidget); + + // Verify if the Padding widget is present. + expect(find.byType(Padding), findsOneWidget); + + // Verify if the Form widget is present. + expect(find.byType(Form), findsOneWidget); + + // Verify if the TextFormField widget is present. + expect(find.byType(TextFormField), findsNWidgets(2)); + + // Verify if the ElevatedButton widget is present. + expect(find.byType(ElevatedButton), findsOneWidget); + + // Verify if the CircularProgressIndicator widget is present. + expect(find.byType(CircularProgressIndicator), findsNothing); + + // Add more specific tests for the widgets inside the Column as needed. + }); +} \ No newline at end of file From 14673316129db46b15835af8ae41d81fb1ba988d Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 20 Jan 2025 17:14:52 -0300 Subject: [PATCH 28/47] melhorando o teste do dashboard do nutricionista --- .../nutricionista_dashboard_screen_test.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/healthway_app/test/nutricionista_dashboard_screen_test.dart b/healthway_app/test/nutricionista_dashboard_screen_test.dart index 460f493..6149373 100644 --- a/healthway_app/test/nutricionista_dashboard_screen_test.dart +++ b/healthway_app/test/nutricionista_dashboard_screen_test.dart @@ -34,4 +34,21 @@ void main() { // Add more specific tests for the widgets inside the Column as needed. }); + + testWidgets('NutritionistDashboardScreen displays CircularProgressIndicator when loading', (WidgetTester tester) async { + // Build the NutritionistDashboardScreen widget. + await tester.pumpWidget(MaterialApp(home: NutritionistDashboardScreen())); + + // Verify if the CircularProgressIndicator widget is present. + expect(find.byType(CircularProgressIndicator), findsNothing); + + // Tap the ElevatedButton to simulate a loading state. + await tester.tap(find.byType(ElevatedButton)); + await tester.pump(); + + // Verify if the CircularProgressIndicator widget is present. + expect(find.byType(CircularProgressIndicator), findsOneWidget); + }); + + } \ No newline at end of file From 7774f02434346cd30ae28125df686ac7dfdbc7d8 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 20 Jan 2025 17:19:11 -0300 Subject: [PATCH 29/47] resolvendo conflitos --- healthway_app/lib/main.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index ec3dc82..04bc9de 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -53,7 +53,7 @@ class MyApp extends StatelessWidget { '/profile': (context) => PatientProfileScreen(), '/notifications': (context) => NotificationScreen(), '/settings': (context) => SettingsScreen(), - '/patientList': (context) => PatientListScreen(), + '/patientList': (context) => PacientesScreen(), '/nutritionistProfile': (context) => NutritionistProfileScreen(), '/schedule': (context) => ScheduleScreen(), '/meal_plans': (context) => MealPlanScreen( @@ -64,6 +64,9 @@ class MyApp extends StatelessWidget { } } +class PatientListScreen { +} + class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); From ba3a8860df021084d3687c000a8f7638de026327 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Mon, 20 Jan 2025 19:38:40 -0300 Subject: [PATCH 30/47] =?UTF-8?q?integrando=20telas=20de=20acompanhamento?= =?UTF-8?q?=20e=20edi=C3=A7=C3=A3o=20de=20plano=20#13=20#74?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/planoAlimentarController.js | 34 ++- backend/model/PlanoAlimentar.js | 6 +- backend/model/Refeicao.js | 3 +- backend/routes/planoAlimentarRoutes.js | 3 +- .../plugins/GeneratedPluginRegistrant.java | 5 + .../ios/Runner/GeneratedPluginRegistrant.m | 7 + .../lib/geral_screens/alimentos_screen.dart | 5 +- .../lib/geral_screens/login_screen.dart | 17 -- healthway_app/lib/main.dart | 20 +- healthway_app/lib/models/nutricionista.dart | 20 +- healthway_app/lib/models/paciente.dart | 27 ++- healthway_app/lib/models/plano_alimentar.dart | 45 ++++ healthway_app/lib/models/refeicao.dart | 31 +++ .../meal_edit_screen.dart | 160 ++++++++++++ .../meal_plan_screen.dart | 228 ++++++++++++------ .../patient_dashboard_screen.dart | 11 +- .../lib/services/alimento_services.dart | 18 +- .../lib/services/nutricionista_services.dart | 6 +- .../lib/services/paciente_services.dart | 10 +- .../services/plano_alimentar_services.dart | 82 +++++++ .../lib/services/refeicao_services.dart | 62 +++++ .../lib/services/services_facade.dart | 67 ++++- .../Flutter/GeneratedPluginRegistrant.swift | 2 + healthway_app/pubspec.yaml | 1 + .../test/patient_dashboard_screen_test.dart | 12 +- 25 files changed, 725 insertions(+), 157 deletions(-) create mode 100644 healthway_app/lib/models/plano_alimentar.dart create mode 100644 healthway_app/lib/models/refeicao.dart create mode 100644 healthway_app/lib/screens_nutricionist/meal_edit_screen.dart create mode 100644 healthway_app/lib/services/plano_alimentar_services.dart create mode 100644 healthway_app/lib/services/refeicao_services.dart diff --git a/backend/controllers/planoAlimentarController.js b/backend/controllers/planoAlimentarController.js index 8efac89..9c9b938 100644 --- a/backend/controllers/planoAlimentarController.js +++ b/backend/controllers/planoAlimentarController.js @@ -64,8 +64,8 @@ const planoAlimentarController = { } }, - // Obter planos alimentares de um paciente passando o seu id como parâmetro - async getByPaciente(req, res) { + // Obter um plano alimentar de um paciente passando o seu id como parâmetro + async getByPaciente(req, res) { try { const { paciente } = req.params; @@ -73,14 +73,40 @@ const planoAlimentarController = { return res.status(400).json({ error: 'O parâmetro paciente é obrigatório.' }); } - const snapshot = await db.collection('planosAlimentares') - .where('paciente', '==', paciente) + const snapshot = await db.collection('plano_alimentar') + .where('id_paciente', '==', paciente) + .limit(1) .get(); if (snapshot.empty) { return res.status(404).json({ message: 'Nenhum plano alimentar encontrado para este paciente.' }); } + const plano = snapshot.docs[0].data(); + + return res.status(200).json({ id: snapshot.docs[0].id, ...plano }); + + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getByNutricionista (req, res) { + try { + const { nutricionista } = req.params; + + if (!nutricionista) { + return res.status(400).json({ error: 'O parâmetro nutricionista é obrigatório.' }); + } + + const snapshot = await db.collection('plano_alimentar') + .where('id_nutricionista', '==', nutricionista) + .get(); + + if (snapshot.empty) { + return res.status(404).json({ message: 'Nenhum plano alimentar encontrado para este nutricionista.' }); + } + const planos = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); return res.status(200).json(planos); diff --git a/backend/model/PlanoAlimentar.js b/backend/model/PlanoAlimentar.js index a7faf54..a011a22 100644 --- a/backend/model/PlanoAlimentar.js +++ b/backend/model/PlanoAlimentar.js @@ -1,10 +1,11 @@ class PlanoAlimentar { - constructor(consulta, dt_inicio, dt_fim, refeicoes, paciente) { + constructor(consulta, dt_inicio, dt_fim, refeicoes, paciente, nutricionista) { this.consulta = consulta; this.dt_inicio = dt_inicio; this.dt_fim = dt_fim; this.refeicoes = refeicoes; this.paciente = paciente; + this.nutricionista = nutricionista; } toFirestore() { @@ -13,7 +14,8 @@ class PlanoAlimentar { dt_inicio: this.dt_inicio, dt_fim: this.dt_fim, refeicoes: this.refeicoes, - paciente: this.paciente + paciente: this.paciente, + nutricionista: this.nutricionista }; } } diff --git a/backend/model/Refeicao.js b/backend/model/Refeicao.js index 5cb2817..5eab7e4 100644 --- a/backend/model/Refeicao.js +++ b/backend/model/Refeicao.js @@ -1,5 +1,6 @@ class Refeicao { - constructor(nome, alimentos, observacoes) { + constructor({id = '', nome, alimentos, observacoes}) { + this.id = id; this.nome = nome; this.alimentos = alimentos; this.observacoes = observacoes; diff --git a/backend/routes/planoAlimentarRoutes.js b/backend/routes/planoAlimentarRoutes.js index 683e13f..14573a5 100644 --- a/backend/routes/planoAlimentarRoutes.js +++ b/backend/routes/planoAlimentarRoutes.js @@ -8,6 +8,7 @@ router.get('/', planoAlimentarController.getAll); router.get('/:id', planoAlimentarController.getById); router.put('/:id', planoAlimentarController.update); router.delete('/:id', planoAlimentarController.delete); -router.get('/:paciente', planoAlimentarController.getByPaciente); +router.get('/paciente/:paciente', planoAlimentarController.getByPaciente); +router.get('/nutricionista/:nutricionista', planoAlimentarController.getByNutricionista); module.exports = router; diff --git a/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index ec061d9..1da69db 100644 --- a/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/healthway_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -25,5 +25,10 @@ public static void registerWith(@NonNull FlutterEngine flutterEngine) { } catch (Exception e) { Log.e(TAG, "Error registering plugin image_picker_android, io.flutter.plugins.imagepicker.ImagePickerPlugin", e); } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin()); + } catch (Exception e) { + Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e); + } } } diff --git a/healthway_app/ios/Runner/GeneratedPluginRegistrant.m b/healthway_app/ios/Runner/GeneratedPluginRegistrant.m index ed39389..dbd1924 100644 --- a/healthway_app/ios/Runner/GeneratedPluginRegistrant.m +++ b/healthway_app/ios/Runner/GeneratedPluginRegistrant.m @@ -12,10 +12,17 @@ @import image_picker_ios; #endif +#if __has_include() +#import +#else +@import path_provider_foundation; +#endif + @implementation GeneratedPluginRegistrant + (void)registerWithRegistry:(NSObject*)registry { [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]]; + [PathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"PathProviderPlugin"]]; } @end diff --git a/healthway_app/lib/geral_screens/alimentos_screen.dart b/healthway_app/lib/geral_screens/alimentos_screen.dart index 97f129e..7430517 100644 --- a/healthway_app/lib/geral_screens/alimentos_screen.dart +++ b/healthway_app/lib/geral_screens/alimentos_screen.dart @@ -25,7 +25,7 @@ class _AlimentosScreenState extends State { void _carregarAlimentos() { setState(() { - futureAlimentos = AlimentoService().fetchAlimentos(); + futureAlimentos = AlimentoService().fetchFoods(); }); } @@ -81,8 +81,9 @@ class _AlimentosScreenState extends State { ), floatingActionButton: FloatingActionButton( onPressed: _carregarAlimentos, - child: Icon(Icons.refresh), backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, + child: Icon(Icons.refresh), ), ); } diff --git a/healthway_app/lib/geral_screens/login_screen.dart b/healthway_app/lib/geral_screens/login_screen.dart index c2c8641..8663c20 100644 --- a/healthway_app/lib/geral_screens/login_screen.dart +++ b/healthway_app/lib/geral_screens/login_screen.dart @@ -59,8 +59,6 @@ class _LoginScreenState extends State { _buildPasswordField(), SizedBox(height: 20), _buildUserTypeDropdown(), - SizedBox(height: 20), - _buildForgotPasswordButton(), SizedBox(height: 30), _buildLoginButton(), SizedBox(height: 20), @@ -176,21 +174,6 @@ class _LoginScreenState extends State { ); } - Widget _buildForgotPasswordButton() { - return Align( - alignment: Alignment.centerRight, - child: TextButton( - onPressed: () { - // TODO: Implementar lógica para recuperação de senha - }, - child: Text( - 'Esqueceu a senha?', - style: TextStyle(color: kPrimaryColor, fontWeight: FontWeight.bold), - ), - ), - ); - } - Widget _buildLoginButton() { return ElevatedButton( onPressed: _isLoading ? null : _submitForm, diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index 21090d8..b128bc5 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -5,12 +5,14 @@ import 'package:healthway_app/geral_screens/chat_screen.dart'; import 'package:healthway_app/geral_screens/login_screen.dart' as login; import 'package:healthway_app/geral_screens/nutricionistas_screen.dart'; import 'package:healthway_app/geral_screens/presentation_screen.dart'; +import 'package:healthway_app/screens_nutricionist/meal_edit_screen.dart'; import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard_screen.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; import 'package:healthway_app/screens_nutricionist/schedule_screen.dart'; import 'package:healthway_app/screens_nutricionist/signup_nutritionist_screen.dart'; +import 'package:healthway_app/screens_patient/dietScreen.dart'; import 'package:healthway_app/screens_patient/notificationScreen.dart'; import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; @@ -84,10 +86,11 @@ class MyApp extends StatelessWidget { return MaterialPageRoute( builder: (context) => NutritionistProfileScreen(userData: args), ); - case '/meal_plan': + case '/meal_plan_patient': final args = settings.arguments as Map; return MaterialPageRoute( - builder: (context) => MealPlanScreen(patientData: args), + builder: (context) => + MealPlanScreen(patientData: args, isPatient: false), ); case '/patient_list': final args = settings.arguments as Map; @@ -96,6 +99,19 @@ class MyApp extends StatelessWidget { args: args, ), ); + case '/meal_edit': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => MealEditScreen(mealData: args), + ); + + case '/diet': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => PlanoAlimentarScreen( + pacienteId: args['id'], + ), + ); default: return null; } diff --git a/healthway_app/lib/models/nutricionista.dart b/healthway_app/lib/models/nutricionista.dart index 8bd9804..dd1e3ef 100644 --- a/healthway_app/lib/models/nutricionista.dart +++ b/healthway_app/lib/models/nutricionista.dart @@ -25,16 +25,14 @@ class Nutricionista { factory Nutricionista.fromJson(Map json) { return Nutricionista( - id: json['id'], - cpf: json['cpf'], - crn: json['crn'], - nome: json['nome'], - especialidade: json['especialidade'], - email: json['email'], - senha: json['senha'], - fotoPerfil: json['foto_perfil'], - fotoDocumento: json['foto_documento'], - pacientes: List.from(['pacientes']), + id: json['id'] ?? '', + cpf: json['cpf'] ?? '', + crn: json['crn'] ?? '', + nome: json['nome'] ?? '', + especialidade: json['especialidade'] ?? '', + email: json['email'] ?? '', + senha: json['senha'] ?? '', + pacientes: List.from(json['pacientes'] ?? []), ); } @@ -47,8 +45,6 @@ class Nutricionista { 'especialidade': especialidade, 'email': email, 'senha': senha, - 'foto_perfil': fotoPerfil, - 'foto_documento': fotoDocumento, 'pacientes': pacientes, }; } diff --git a/healthway_app/lib/models/paciente.dart b/healthway_app/lib/models/paciente.dart index f90f0fe..cab755f 100644 --- a/healthway_app/lib/models/paciente.dart +++ b/healthway_app/lib/models/paciente.dart @@ -33,19 +33,20 @@ class Paciente { factory Paciente.fromJson(Map json) { return Paciente( - id: json['id'], - nome: json['nome'], - email: json['email'], - cpf: json['cpf'], - dataNascimento: json['dt_nascimento'], - sexo: json['sexo'], - altura: json['altura'].toDouble(), - peso: json['peso'].toDouble(), - circunferenciaAbdominal: json['circunferencia_abdominal'].toDouble(), - gorduraCorporal: json['gordura_corporal'].toDouble(), - massaMuscular: json['massa_muscular'].toDouble(), - alergias: List.from(json['alergias']), - preferencias: List.from(json['preferencias']), + id: json['id'] ?? '', + nome: json['nome'] ?? '', + email: json['email'] ?? '', + cpf: json['cpf'] ?? '', + dataNascimento: json['dt_nascimento'] ?? '', + sexo: json['sexo'] ?? '', + altura: json['altura'].toDouble() ?? 0.0, + peso: json['peso'].toDouble() ?? 0.0, + circunferenciaAbdominal: + json['circunferencia_abdominal'].toDouble() ?? 0.0, + gorduraCorporal: json['gordura_corporal'].toDouble() ?? 0.0, + massaMuscular: json['massa_muscular'].toDouble() ?? 0.0, + alergias: List.from(json['alergias'] ?? []), + preferencias: List.from(json['preferencias'] ?? []), senha: json['senha'], ); } diff --git a/healthway_app/lib/models/plano_alimentar.dart b/healthway_app/lib/models/plano_alimentar.dart new file mode 100644 index 0000000..3c0f3eb --- /dev/null +++ b/healthway_app/lib/models/plano_alimentar.dart @@ -0,0 +1,45 @@ +import 'package:intl/intl.dart'; + +class PlanoAlimentar { + final String? id; + final String consulta; + final DateTime dtInicio; + final DateTime dtFim; + final List refeicoes; + final String paciente; + final String nutricionista; + + PlanoAlimentar({ + this.id, + required this.consulta, + required this.dtInicio, + required this.dtFim, + required this.refeicoes, + required this.paciente, + required this.nutricionista, + }); + + factory PlanoAlimentar.fromJson(Map json) { + return PlanoAlimentar( + id: json['id'] ?? '', + consulta: json['consulta'] ?? '', + dtInicio: DateFormat('dd/MM/yyyy').parse(json['dt_inicio'] ?? ''), + dtFim: DateFormat('dd/MM/yyyy').parse(json['dt_fim'] ?? ''), + refeicoes: List.from(json['refeicoes'] ?? []), + paciente: json['id_paciente'] ?? '', + nutricionista: json['id_nutricionista'] ?? '', + ); + } + + Map toJson() { + return { + 'id': id, + 'consulta': consulta, + 'dt_inicio': DateFormat('dd/MM/yyyy').format(dtInicio), + 'dt_fim': DateFormat('dd/MM/yyyy').format(dtFim), + 'refeicoes': refeicoes, + 'id_paciente': paciente, + 'id_nutricionista': nutricionista, + }; + } +} diff --git a/healthway_app/lib/models/refeicao.dart b/healthway_app/lib/models/refeicao.dart new file mode 100644 index 0000000..8f84170 --- /dev/null +++ b/healthway_app/lib/models/refeicao.dart @@ -0,0 +1,31 @@ +class Refeicao { + final String? id; + String nome; + String observacoes; + Map alimentos; + + Refeicao({ + this.id, + required this.nome, + required this.observacoes, + required this.alimentos, + }); + + factory Refeicao.fromJson(Map json) { + return Refeicao( + id: json['id'] ?? '', + nome: json['nome'] ?? '', + observacoes: json['observacoes'] ?? '', + alimentos: Map.from(json['alimentos'] ?? {}), + ); + } + + Map toJson() { + return { + 'id': id, + 'nome': nome, + 'observacoes': observacoes, + 'alimentos': alimentos, + }; + } +} diff --git a/healthway_app/lib/screens_nutricionist/meal_edit_screen.dart b/healthway_app/lib/screens_nutricionist/meal_edit_screen.dart new file mode 100644 index 0000000..c5f5ccf --- /dev/null +++ b/healthway_app/lib/screens_nutricionist/meal_edit_screen.dart @@ -0,0 +1,160 @@ +import 'package:flutter/material.dart'; +import 'package:healthway_app/models/alimento.dart'; +import 'package:healthway_app/models/refeicao.dart'; +import 'package:healthway_app/services/services_facade.dart'; +import 'package:path_provider/path_provider.dart'; +import 'dart:io'; +import 'dart:convert'; + +class MealEditScreen extends StatefulWidget { + final Map mealData; + const MealEditScreen({super.key, required this.mealData}); + + @override + State createState() => _MealEditScreenState(); +} + +class _MealEditScreenState extends State { + final _formKey = GlobalKey(); + String _nome = ''; + String _observacoes = ''; + List _availableFoods = []; + List _selectedFoods = []; + List _selectedFoodIds = []; + final ServicesFacade _servicesFacade = ServicesFacade(); + + @override + void initState() { + super.initState(); + _nome = widget.mealData['refeicao'].nome; + _observacoes = widget.mealData['refeicao'].observacoes; + _selectedFoods = widget.mealData['alimentos']; + _selectedFoodIds = _selectedFoods.map((alimento) => alimento.id).toList(); + _loadAvailableFoods(); + } + + Future _loadAvailableFoods() async { + try { + final directory = await getApplicationCacheDirectory(); + final file = File('${directory.path}/alimentos.json'); + if (file.existsSync()) { + final foodsJson = await file.readAsString(); + final foodsData = jsonDecode(foodsJson) as List; + final foods = foodsData.map((food) => Alimento.fromJson(food)).toList(); + setState(() { + _availableFoods = foods; + }); + } else { + final foods = await _servicesFacade.obterAlimentos(); + final foodsJson = jsonEncode(foods); + await file.writeAsString(foodsJson); + setState(() { + _availableFoods = foods; + }); + } + } catch (error) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Erro ao carregar alimentos. Tente novamente.'), + ), + ); + } + } + + void _saveForm() { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); + try { + var itensDeRefeicao = {}; + for (var alimentoId in _selectedFoodIds) { + itensDeRefeicao[alimentoId] = "100 g"; + } + widget.mealData['refeicao'].nome = _nome; + widget.mealData['refeicao'].observacoes = _observacoes; + widget.mealData['alimentos'] = itensDeRefeicao; + Refeicao refeicao = Refeicao.fromJson({ + 'id': widget.mealData['refeicao'].id, + 'nome': _nome, + 'observacoes': _observacoes, + 'alimentos': itensDeRefeicao, + }); + _servicesFacade.atualizar(refeicao); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Perfil atualizado com sucesso')), + ); + } catch (error) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Erro ao atualizar a refeição. Tente novamente.'), + ), + ); + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Editando Refeição'), + actions: [ + IconButton( + icon: Icon(Icons.save), + onPressed: _saveForm, + ), + ], + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + initialValue: _nome, + decoration: InputDecoration(labelText: 'Nome da Refeição'), + validator: (value) { + if (value!.isEmpty) { + return 'Por favor, insira um nome para a refeição.'; + } + return null; + }, + onSaved: (value) { + _nome = value!; + }, + ), + TextFormField( + initialValue: _observacoes, + decoration: InputDecoration(labelText: 'Observações'), + onSaved: (value) { + _observacoes = value!; + }, + ), + Expanded( + child: ListView.builder( + itemCount: _availableFoods.length, + itemBuilder: (ctx, index) { + return CheckboxListTile( + title: Text(_availableFoods[index].descricao), + value: + _selectedFoodIds.contains(_availableFoods[index].id), + onChanged: (bool? value) { + setState(() { + if (value == true) { + _selectedFoodIds.add(_availableFoods[index].id); + } else { + _selectedFoodIds.remove(_availableFoods[index].id); + } + }); + }, + ); + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart index 9574b2c..f47d5c5 100644 --- a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart +++ b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart @@ -1,95 +1,177 @@ -import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; +import 'package:healthway_app/constants.dart'; +import 'package:healthway_app/models/alimento.dart'; +import 'package:healthway_app/models/plano_alimentar.dart'; +import 'package:healthway_app/models/refeicao.dart'; +import 'package:healthway_app/services/services_facade.dart'; +import 'package:intl/intl.dart'; -class MealPlanScreen extends StatelessWidget { +class MealPlanScreen extends StatefulWidget { final Map patientData; + final bool isPatient; - const MealPlanScreen({super.key, required this.patientData}); + const MealPlanScreen( + {super.key, required this.patientData, required this.isPatient}); + + @override + State createState() => _MealPlanScreenState(); +} + +class _MealPlanScreenState extends State { + final ServicesFacade _servicesFacade = ServicesFacade(); + late Future> _mealPlanData; + late String patientId; + final Map _planData = {}; + + void carregarPlanoAlimentar() { + setState(() { + _mealPlanData = _fetchMealPlanData(); + }); + } + + @override + void initState() { + super.initState(); + patientId = widget.patientData['id']; + carregarPlanoAlimentar(); + } + + // @override + // void didChangeDependencies() { + // super.didChangeDependencies(); + // carregarPlanoAlimentar(); + // } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: kBackgroundColor, appBar: AppBar( - title: Text('Plano Alimentar - ${patientData['nome']}'), + title: Text( + 'Plano Alimentar${widget.isPatient ? '' : ' - ${widget.patientData['nome']}'}'), backgroundColor: kPrimaryColor, foregroundColor: Colors.white, elevation: 0, ), body: SafeArea( - child: ListView( - padding: const EdgeInsets.all(16.0), - children: [ - _buildMealCard('Café da Manhã', - ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), - _buildMealCard('Lanche da Manhã', - ['1 iogurte natural', '1 punhado de castanhas']), - _buildMealCard('Almoço', [ - '150g de frango grelhado', - '1 xícara de arroz integral', - 'Salada verde' - ]), - _buildMealCard('Lanche da Tarde', - ['1 banana', '1 colher de sopa de pasta de amendoim']), - _buildMealCard('Jantar', [ - '150g de peixe assado', - '1 batata doce média', - 'Legumes no vapor' - ]), - SizedBox(height: 16), - ElevatedButton( - onPressed: () { - // Editar plano alimentar - }, - style: ElevatedButton.styleFrom( - backgroundColor: kPrimaryColor, - padding: EdgeInsets.symmetric(vertical: 16), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Text( - 'Editar Plano Alimentar', - style: TextStyle(fontSize: 16), - ), - ), - ], - ), - ), - ); - } + child: FutureBuilder( + future: _mealPlanData, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Text('Erro ao carregar dados')); + } else { + final mealPlanData = snapshot.data as Map; + final planoAlimentar = + mealPlanData['plano_alimentar'] as PlanoAlimentar; + final refeicoes = mealPlanData['refeicoes'] as List; + final itensDeRefeicao = mealPlanData['itens_de_refeicao'] + as Map>; + final alimentos = mealPlanData['alimentos']; - Widget _buildMealCard(String mealName, List foods) { - return Card( - margin: EdgeInsets.only(bottom: 16), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - mealName, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: kPrimaryColor), - ), - SizedBox(height: 8), - ...foods.map((food) => Padding( - padding: const EdgeInsets.only(bottom: 4), - child: Row( - children: [ - Icon(Icons.fiber_manual_record, - size: 8, color: kPrimaryColor), - SizedBox(width: 8), - Text(food, style: TextStyle(fontSize: 16)), - ], + return ListView( + padding: const EdgeInsets.all(16.0), + children: [ + ListTile( + title: Text( + 'Início: ${DateFormat('dd/MM/yyyy').format(planoAlimentar.dtInicio)} - Fim: ${DateFormat('dd/MM/yyyy').format(planoAlimentar.dtFim)}', + // textAlign: TextAlign.center, + ), + titleTextStyle: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18, + color: Colors.grey[400]), ), - )), - ], + ...refeicoes.map((refeicao) { + return Card( + elevation: 4.0, + color: Colors.white, + child: ListTile( + title: Text( + refeicao.nome, + ), + titleTextStyle: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18, + color: kPrimaryColor, + ), + subtitle: Padding( + padding: EdgeInsets.only(top: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: + List.from(itensDeRefeicao[refeicao.id]! + .entries + .map((itemDeRefeicao) => Text( + '${itemDeRefeicao.key}: ${itemDeRefeicao.value}', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: kTextColor), + )) + .toList()), + ), + ), + trailing: IconButton( + icon: Icon(Icons.edit), + onPressed: () { + _editMeal(refeicao, alimentos[refeicao.id]); + }, + ), + ), + ); + }), + ], + ); + } + }, ), ), + floatingActionButton: FloatingActionButton( + onPressed: carregarPlanoAlimentar, + backgroundColor: kPrimaryColor, + foregroundColor: Colors.white, + child: Icon(Icons.refresh), + ), ); } + + Future> _fetchMealPlanData() async { + final planoAlimentar = await _servicesFacade + .obterPlanoPorPaciente(patientId) as PlanoAlimentar; + final refeicoes = List.from(await Future.wait(planoAlimentar + .refeicoes + .map((id) => _servicesFacade.obterRefeicaoPorId(id)) + .toList())); + final Map> itensDeRefeicao = {}; + final Map> alimentos = {}; + for (var refeicao in refeicoes) { + Map novosItensDeRefeicao = {}; + List novosAlimentos = []; + + for (var alimentoId in refeicao.alimentos.entries) { + final Alimento alimento = + await _servicesFacade.obterAlimentoPorId(alimentoId.key); + novosItensDeRefeicao[alimento.descricao] = alimentoId.value; + novosAlimentos.add(alimento); + } + itensDeRefeicao[refeicao.id!] = novosItensDeRefeicao; + alimentos[refeicao.id!] = novosAlimentos; + } + + return { + 'plano_alimentar': planoAlimentar, + 'refeicoes': refeicoes, + 'itens_de_refeicao': itensDeRefeicao, + 'alimentos': alimentos, + }; + } + + void _editMeal(Refeicao refeicao, List alimentos) { + _planData[refeicao.id] = {'refeicao': refeicao, 'alimentos': alimentos}; + Navigator.pushNamed(context, '/meal_edit', + arguments: _planData[refeicao.id]); + carregarPlanoAlimentar(); + } } diff --git a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart index 505ea9f..2260ded 100644 --- a/healthway_app/lib/screens_patient/patient_dashboard_screen.dart +++ b/healthway_app/lib/screens_patient/patient_dashboard_screen.dart @@ -152,13 +152,11 @@ class PatientDashboardScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildQuickAccessItem(context, Icons.restaurant_menu, 'Dieta', - '/meal_plan', 'dashboard_dieta', userData), + '/meal_plan_patient', 'dashboard_dieta', userData), _buildQuickAccessItem(context, Icons.people, 'Nutricionistas', '/nutricionistas', 'dashboard_nutricionistas', null), - _buildQuickAccessItem(context, Icons.local_dining, 'Alimentos', - '/alimentos', 'dashboard_alimentos', null), - // _buildQuickAccessItem( - // context, Icons.insert_chart, 'Progresso', '/progress', 'dashboard_', null), + _buildQuickAccessItem(context, Icons.food_bank_outlined, + 'Alimentos', '/alimentos', 'dashboard_alimentos', null), _buildQuickAccessItem(context, Icons.message, 'Chat', '/chat', 'dashboard_chat', null), ], @@ -366,7 +364,8 @@ class PatientDashboardScreen extends StatelessWidget { // Já estamos na tela inicial, então não faça nada break; case 1: - Navigator.pushNamed(context, '/meal_plan', arguments: userData); + Navigator.pushNamed(context, '/meal_plan_patient', + arguments: userData); break; // case 2: // Navigator.pushNamed(context, '/progress'); diff --git a/healthway_app/lib/services/alimento_services.dart b/healthway_app/lib/services/alimento_services.dart index c3bf657..1f3e24f 100644 --- a/healthway_app/lib/services/alimento_services.dart +++ b/healthway_app/lib/services/alimento_services.dart @@ -3,15 +3,17 @@ import 'package:http/http.dart' as http; import '../models/alimento.dart'; class AlimentoService { - Future> fetchAlimentos() async { + final String apiUrl = 'http://localhost:3000/api/alimentos'; + + Future> fetchFoods() async { // Fazendo a requisição HTTP para o endpoint da API - final response = await http.get(Uri.parse('http://localhost:3000/api/alimentos')); + final response = await http.get(Uri.parse(apiUrl)); // Verificando o status da resposta if (response.statusCode == 200) { // Se a requisição for bem-sucedida, parseia o JSON final List jsonData = json.decode(response.body); - + // Mapeia os dados JSON para objetos Alimento return jsonData.map((item) => Alimento.fromJson(item)).toList(); } else { @@ -19,4 +21,14 @@ class AlimentoService { throw Exception('Falha ao carregar os alimentos'); } } + + Future fetchAlimentoById(String id) async { + final response = await http.get(Uri.parse('$apiUrl/$id')); + + if (response.statusCode == 200) { + return Alimento.fromJson(json.decode(response.body)); + } else { + throw Exception('Falha ao carregar o alimento'); + } + } } diff --git a/healthway_app/lib/services/nutricionista_services.dart b/healthway_app/lib/services/nutricionista_services.dart index 7e4d771..8292e68 100644 --- a/healthway_app/lib/services/nutricionista_services.dart +++ b/healthway_app/lib/services/nutricionista_services.dart @@ -7,7 +7,7 @@ import '../models/nutricionista.dart'; class NutricionistaService { static const String apiUrl = 'http://localhost:3000/api/nutricionistas'; - Future> fetchNutricionistas() async { + Future> fetchNutritionists() async { final response = await http.get(Uri.parse(apiUrl)); if (response.statusCode == 200) { @@ -27,7 +27,7 @@ class NutricionistaService { } } - Future cadastrarNutricionista(Nutricionista nutricionista) async { + Future registerNutritionist(Nutricionista nutricionista) async { var uri = Uri.parse(apiUrl); var request = http.MultipartRequest('POST', uri); @@ -49,7 +49,7 @@ class NutricionistaService { } } - Future atualizarNutricionista(Nutricionista nutricionista) async { + Future updateNutritionist(Nutricionista nutricionista) async { var uri = Uri.parse('$apiUrl/${nutricionista.id}'); var request = http.MultipartRequest('PUT', uri); diff --git a/healthway_app/lib/services/paciente_services.dart b/healthway_app/lib/services/paciente_services.dart index b9fe583..d28749e 100644 --- a/healthway_app/lib/services/paciente_services.dart +++ b/healthway_app/lib/services/paciente_services.dart @@ -5,7 +5,7 @@ import 'package:healthway_app/models/paciente.dart'; class PacienteService { static const String apiUrl = 'http://localhost:3000/api/pacientes'; - Future> fetchPacientes() async { + Future> fetchPatients() async { final response = await http.get(Uri.parse(apiUrl)); if (response.statusCode == 200) { @@ -25,7 +25,7 @@ class PacienteService { } } - Future fetchPacienteById(String id) async { + Future fetchPatientById(String id) async { final response = await http.get(Uri.parse('$apiUrl/$id')); if (response.statusCode == 200) { @@ -39,7 +39,7 @@ class PacienteService { } } - Future> fetchPacientesByIds(List ids) async { + Future> fetchPatientsByIds(List ids) async { var uri = Uri.parse('$apiUrl/list'); var request = http.Request('POST', uri) ..headers['Content-Type'] = 'application/json' @@ -62,7 +62,7 @@ class PacienteService { } } - Future cadastrarPaciente(Paciente paciente) async { + Future registerPatient(Paciente paciente) async { var uri = Uri.parse(apiUrl); // var request = http.MultipartRequest('POST', uri); @@ -126,7 +126,7 @@ class PacienteService { } } - Future atualizarPaciente(Paciente paciente) async { + Future updatePatient(Paciente paciente) async { var uri = Uri.parse('$apiUrl/${paciente.id}'); var response = await http.put( uri, diff --git a/healthway_app/lib/services/plano_alimentar_services.dart b/healthway_app/lib/services/plano_alimentar_services.dart new file mode 100644 index 0000000..7daa4a1 --- /dev/null +++ b/healthway_app/lib/services/plano_alimentar_services.dart @@ -0,0 +1,82 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'package:healthway_app/models/plano_alimentar.dart'; + +class PlanoAlimentarService { + static const String apiUrl = 'http://localhost:3000/api/planos-alimentares'; + + Future> fetchPlansByNutritionist(String id) async { + final response = await http.get(Uri.parse('$apiUrl/nutricionista/$id')); + + if (response.statusCode == 200) { + try { + List? data = json.decode(response.body); + + if (data != null) { + return data.map((json) => PlanoAlimentar.fromJson(json)).toList(); + } else { + throw Exception('Dados não encontrados ou formato inválido'); + } + } catch (e) { + throw Exception('Erro ao parsear o JSON: $e'); + } + } else { + throw Exception('Falha ao carregar Planos Alimentares'); + } + } + + Future fetchPlanByPatient(String id) async { + final response = await http.get(Uri.parse('$apiUrl/paciente/$id')); + + if (response.statusCode == 200) { + try { + dynamic data = json.decode(response.body); + + if (data != null) { + return PlanoAlimentar.fromJson(data); + } else { + throw Exception('Dados não encontrados ou formato inválido'); + } + } catch (e) { + throw Exception('Erro ao parsear o JSON: $e'); + } + } else { + throw Exception('Falha ao carregar Plano Alimentar'); + } + } + + Future registerPlan(PlanoAlimentar plano) async { + var uri = Uri.parse(apiUrl); + + var response = await http.post( + uri, + headers: {'Content-Type': 'application/json'}, + body: jsonEncode(plano.toJson()), + ); + + if (response.statusCode != 201) { + throw Exception('Falha ao cadastrar Plano Alimentar'); + } + } + + Future updatePlan(PlanoAlimentar plano) async { + var uri = Uri.parse('$apiUrl/${plano.id}'); + var response = await http.put( + uri, + headers: {'Content-Type': 'application/json'}, + body: jsonEncode(plano.toJson()), + ); + if (response.statusCode != 200) { + throw Exception('Falha ao atualizar Plano Alimentar'); + } + } + + Future deletePlan(String id) async { + var uri = Uri.parse('$apiUrl/$id'); + var response = await http.delete(uri); + + if (response.statusCode != 200) { + throw Exception('Falha ao deletar Plano Alimentar'); + } + } +} diff --git a/healthway_app/lib/services/refeicao_services.dart b/healthway_app/lib/services/refeicao_services.dart new file mode 100644 index 0000000..9238a25 --- /dev/null +++ b/healthway_app/lib/services/refeicao_services.dart @@ -0,0 +1,62 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'package:healthway_app/models/refeicao.dart'; + +class RefeicaoService { + static const String apiUrl = 'http://localhost:3000/api/refeicoes'; + + Future fetchMealById(String id) async { + final response = await http.get(Uri.parse('$apiUrl/$id')); + + if (response.statusCode == 200) { + try { + Map? data = json.decode(response.body); + + if (data != null) { + return Refeicao.fromJson(data); + } else { + throw Exception('Dados não encontrados ou formato inválido'); + } + } catch (e) { + throw Exception('Erro ao parsear o JSON: $e'); + } + } else { + throw Exception('Falha ao carregar Refeição'); + } + } + + Future registerMeal(Refeicao refeicao) async { + var uri = Uri.parse(apiUrl); + + var response = await http.post( + uri, + headers: {'Content-Type': 'application/json'}, + body: jsonEncode(refeicao.toJson()), + ); + + if (response.statusCode != 201) { + throw Exception('Falha ao cadastrar Refeição'); + } + } + + Future updateMeal(Refeicao refeicao) async { + var uri = Uri.parse('$apiUrl/${refeicao.id}'); + var response = await http.put( + uri, + headers: {'Content-Type': 'application/json'}, + body: jsonEncode(refeicao.toJson()), + ); + if (response.statusCode != 200) { + throw Exception('Falha ao atualizar Refeição'); + } + } + + Future deleteMeal(String id) async { + var uri = Uri.parse('$apiUrl/$id'); + var response = await http.delete(uri); + + if (response.statusCode != 200) { + throw Exception('Falha ao deletar Refeição'); + } + } +} diff --git a/healthway_app/lib/services/services_facade.dart b/healthway_app/lib/services/services_facade.dart index ecd4a3d..4ec84dd 100644 --- a/healthway_app/lib/services/services_facade.dart +++ b/healthway_app/lib/services/services_facade.dart @@ -1,3 +1,8 @@ +import 'package:healthway_app/models/plano_alimentar.dart'; +import 'package:healthway_app/models/refeicao.dart'; +import 'package:healthway_app/services/plano_alimentar_services.dart'; +import 'package:healthway_app/services/refeicao_services.dart'; + import '../models/alimento.dart'; import '../models/nutricionista.dart'; import '../models/paciente.dart'; @@ -14,35 +19,67 @@ class ServicesFacade { final AlimentoService _alimentoService = AlimentoService(); final NutricionistaService _nutricionistaService = NutricionistaService(); final PacienteService _pacienteService = PacienteService(); + final PlanoAlimentarService _planoAlimentarService = PlanoAlimentarService(); + final RefeicaoService _refeicaoService = RefeicaoService(); // Métodos para AlimentoService Future> obterAlimentos() async { - return await _alimentoService.fetchAlimentos(); + return await _alimentoService.fetchFoods(); + } + + Future obterAlimentoPorId(String id) async { + return await _alimentoService.fetchAlimentoById(id); } // Métodos para NutricionistaService Future> obterNutricionistas() async { - return await _nutricionistaService.fetchNutricionistas(); + return await _nutricionistaService.fetchNutritionists(); } // Métodos para PacienteService Future> obterPacientes() async { - return await _pacienteService.fetchPacientes(); + return await _pacienteService.fetchPatients(); } Future obterPacientePorId(String id) async { - return await _pacienteService.fetchPacienteById(id); + return await _pacienteService.fetchPatientById(id); } Future> obterPacientesPorIds(List ids) async { - return await _pacienteService.fetchPacientesByIds(ids); + return await _pacienteService.fetchPatientsByIds(ids); + } + + // Métodos para PlanoAlimentarService + Future> obterPlanosPorNutricionista(String id) async { + return await _planoAlimentarService.fetchPlansByNutritionist(id); + } + + Future obterPlanoPorPaciente(String id) async { + return await _planoAlimentarService.fetchPlanByPatient(id); + } + + Future deletarPlano(String id) async { + await _planoAlimentarService.deletePlan(id); + } + + // Métodos para RefeicaoService + Future obterRefeicaoPorId(String id) async { + return await _refeicaoService.fetchMealById(id); + } + + Future deletarRefeicao(String id) async { + await _refeicaoService.deleteMeal(id); } Future cadastrar(dynamic entity) async { if (entity is Nutricionista) { - await _nutricionistaService.cadastrarNutricionista(entity); + await _nutricionistaService.registerNutritionist(entity); } else if (entity is Paciente) { - await _pacienteService.cadastrarPaciente(entity); + await _pacienteService.registerPatient(entity); + } else if (entity is PlanoAlimentar) { + await _planoAlimentarService.registerPlan(entity); + } else if (entity is Refeicao) { + await _refeicaoService.registerMeal(entity); } else { throw Exception('Tipo de entidade desconhecido'); } @@ -51,16 +88,28 @@ class ServicesFacade { Future atualizar(dynamic entity) async { if (entity is Nutricionista) { try { - await _nutricionistaService.atualizarNutricionista(entity); + await _nutricionistaService.updateNutritionist(entity); } catch (e) { throw Exception('Erro ao atualizar Nutricionista: $e'); } } else if (entity is Paciente) { try { - await _pacienteService.atualizarPaciente(entity); + await _pacienteService.updatePatient(entity); } catch (e) { throw Exception('Erro ao atualizar Paciente: $e'); } + } else if (entity is PlanoAlimentar) { + try { + await _planoAlimentarService.updatePlan(entity); + } catch (e) { + throw Exception('Erro ao atualizar Plano Alimentar: $e'); + } + } else if (entity is Refeicao) { + try { + await _refeicaoService.updateMeal(entity); + } catch (e) { + throw Exception('Erro ao atualizar Refeição: $e'); + } } else { throw Exception('Tipo de entidade desconhecido'); } diff --git a/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift b/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift index 14b5f7c..b878e03 100644 --- a/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/healthway_app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,9 @@ import FlutterMacOS import Foundation import file_selector_macos +import path_provider_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) } diff --git a/healthway_app/pubspec.yaml b/healthway_app/pubspec.yaml index 6bb8557..34e309d 100644 --- a/healthway_app/pubspec.yaml +++ b/healthway_app/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: cupertino_icons: ^1.0.8 uuid: ^4.5.1 get: ^4.6.6 + path_provider: ^2.1.5 dev_dependencies: flutter_test: diff --git a/healthway_app/test/patient_dashboard_screen_test.dart b/healthway_app/test/patient_dashboard_screen_test.dart index b8467d1..e26dd51 100644 --- a/healthway_app/test/patient_dashboard_screen_test.dart +++ b/healthway_app/test/patient_dashboard_screen_test.dart @@ -36,10 +36,13 @@ void main() { await tester.pumpWidget(MaterialApp( onGenerateRoute: (settings) { switch (settings.name) { - case '/meal_plan': + case '/meal_plan_patient': final args = settings.arguments as Map; return MaterialPageRoute( - builder: (context) => MealPlanScreen(patientData: args), + builder: (context) => MealPlanScreen( + patientData: args, + isPatient: true, + ), ); default: return null; @@ -82,10 +85,11 @@ void main() { await tester.pumpWidget(MaterialApp( onGenerateRoute: (settings) { switch (settings.name) { - case '/meal_plan': + case '/meal_plan_patient': final args = settings.arguments as Map; return MaterialPageRoute( - builder: (context) => MealPlanScreen(patientData: args), + builder: (context) => + MealPlanScreen(patientData: args, isPatient: true), ); case '/patient_profile': final args = settings.arguments as Map; From 90d3d69bda24c4fdf07c4608b86f62cd2acc10ec Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Mon, 20 Jan 2025 19:51:48 -0300 Subject: [PATCH 31/47] consertando teste getByPaciente de planos --- backend/controllers/planoAlimentarController.js | 7 +++---- healthway_app/lib/services/plano_alimentar_services.dart | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/controllers/planoAlimentarController.js b/backend/controllers/planoAlimentarController.js index 9c9b938..d9c818d 100644 --- a/backend/controllers/planoAlimentarController.js +++ b/backend/controllers/planoAlimentarController.js @@ -75,16 +75,15 @@ const planoAlimentarController = { const snapshot = await db.collection('plano_alimentar') .where('id_paciente', '==', paciente) - .limit(1) .get(); if (snapshot.empty) { return res.status(404).json({ message: 'Nenhum plano alimentar encontrado para este paciente.' }); } - const plano = snapshot.docs[0].data(); - - return res.status(200).json({ id: snapshot.docs[0].id, ...plano }); + const planos = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + + res.status(200).json(planos); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/healthway_app/lib/services/plano_alimentar_services.dart b/healthway_app/lib/services/plano_alimentar_services.dart index 7daa4a1..c110b33 100644 --- a/healthway_app/lib/services/plano_alimentar_services.dart +++ b/healthway_app/lib/services/plano_alimentar_services.dart @@ -33,7 +33,7 @@ class PlanoAlimentarService { dynamic data = json.decode(response.body); if (data != null) { - return PlanoAlimentar.fromJson(data); + return PlanoAlimentar.fromJson(data[0]); } else { throw Exception('Dados não encontrados ou formato inválido'); } From e61f1c8d668c8ad12de01612721c280140ed5b77 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 20 Jan 2025 21:13:04 -0300 Subject: [PATCH 32/47] refatoramento da tela de paciente e nutricionista --- .../nutritionist_dashboard_screen.dart | 520 ++++++------------ 1 file changed, 170 insertions(+), 350 deletions(-) diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index 73f3078..53f8b54 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -1,6 +1,5 @@ import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; - class NutritionistDashboardScreen extends StatelessWidget { final Map userData; @@ -8,6 +7,7 @@ class NutritionistDashboardScreen extends StatelessWidget { @override Widget build(BuildContext context) { + return Scaffold( backgroundColor: kBackgroundColor, body: SafeArea( @@ -15,24 +15,27 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildHeader(context), + _buildHeader(), + _buildSectionTitle('Acesso Rápido'), _buildQuickAccess(context), + _buildSectionTitle('Próximas Consultas', showButton: true, buttonRoute: '/appointments'), _buildAppointments(context), + _buildSectionTitle('Atualizações de Pacientes', showButton: true, buttonRoute: '/patient_updates'), _buildPatientUpdates(context), ], ), ), ), - bottomNavigationBar: _buildBottomNavigationBar(context), + bottomNavigationBar: _buildBottomNavigationBar(), ); } - Widget _buildHeader(BuildContext context) { + Widget _buildHeader() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: kPrimaryColor, - borderRadius: BorderRadius.only( + borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), ), @@ -48,54 +51,45 @@ class NutritionistDashboardScreen extends StatelessWidget { children: [ Text( userData['nome'], - style: TextStyle( + style: const TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, ), ), - SizedBox(height: 5), - Text( + const SizedBox(height: 5), + const Text( 'Bem-vindo de volta', - style: TextStyle( - color: Colors.white70, - fontSize: 16, - ), + style: TextStyle(color: Colors.white70, fontSize: 16), ), ], ), - GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/nutritionistProfile'); - }, - child: CircleAvatar( - radius: 30, - backgroundColor: Colors.white, - child: Icon( - Icons.person, - size: 35, - color: kPrimaryColor, - ), - ), + CircleAvatar( + radius: 30, + backgroundImage: AssetImage('assets/images/nutricionista.jpg'), ), ], ), - SizedBox(height: 20), - Container( - padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _buildStatItem('Pacientes', '${userData['pacientes'].length}'), - _buildStatItem('Consultas Hoje', '8'), - _buildStatItem('Mensagens', '15'), - ], - ), - ), + const SizedBox(height: 20), + _buildStatsRow(), + ], + ), + ); + } + + Widget _buildStatsRow() { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildStatItem('Pacientes', '${userData['pacientes'].length}'), + _buildStatItem('Consultas Hoje', '8'), + _buildStatItem('Mensagens', '15'), ], ), ); @@ -112,14 +106,8 @@ class NutritionistDashboardScreen extends StatelessWidget { color: kPrimaryColor, ), ), - SizedBox(height: 5), - Text( - label, - style: TextStyle( - fontSize: 14, - color: Colors.grey[600], - ), - ), + const SizedBox(height: 5), + Text(label, style: TextStyle(fontSize: 14, color: Colors.grey[600])), ], ); } @@ -127,356 +115,188 @@ class NutritionistDashboardScreen extends StatelessWidget { Widget _buildQuickAccess(BuildContext context) { return Padding( padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - 'Acesso Rápido', - style: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - SizedBox(height: 15), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _buildQuickAccessItem(context, Icons.people, 'Pacientes', - '/patient_list', userData), - _buildQuickAccessItem( - context, Icons.calendar_today, 'Agenda', '/schedule', null), - // _buildQuickAccessItem( - // context, Icons.restaurant_menu, 'Planos', '/meal_plans'), - _buildQuickAccessItem(context, Icons.food_bank_outlined, - 'Alimentos', '/alimentos', null), - ], - ), + _buildQuickAccessItem(context, Icons.people, 'Pacientes', '/patient_list', userData), + _buildQuickAccessItem(context, Icons.calendar_today, 'Agenda', '/schedule', null), + _buildQuickAccessItem(context, Icons.food_bank_outlined, 'Alimentos', '/alimentos', null), ], ), ); } - Widget _buildQuickAccessItem(BuildContext context, IconData icon, - String label, String route, Object? args) { + Widget _buildQuickAccessItem( + BuildContext context, + IconData icon, + String label, + String route, + Object? args, + ) { return GestureDetector( - onTap: () { - Navigator.pushNamed(context, route, arguments: args); - }, + onTap: () => Navigator.pushNamed(context, route, arguments: args), child: Column( children: [ Container( - padding: EdgeInsets.all(15), + padding: const EdgeInsets.all(15), decoration: BoxDecoration( - color: kPrimaryColor.withValues(alpha: 0.1), + color: kPrimaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(15), ), - child: Icon( - icon, - color: kPrimaryColor, - size: 30, - ), - ), - SizedBox(height: 5), - Text( - label, - style: TextStyle( - fontSize: 14, - color: Colors.grey[600], - ), + child: Icon(icon, color: kPrimaryColor, size: 30), ), + const SizedBox(height: 5), + Text(label, style: TextStyle(fontSize: 14, color: Colors.grey[600])), ], ), ); } Widget _buildAppointments(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Próximas Consultas', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - TextButton( - onPressed: () { - Navigator.pushNamed(context, '/appointments'); - }, - child: Text( - 'Ver todas', - style: TextStyle( - color: kPrimaryColor, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - SizedBox(height: 15), - _buildAppointmentItem( - context, 'Maria Oliveira', '14:00', 'Consulta de Rotina'), - _buildAppointmentItem( - context, 'João Silva', '15:30', 'Avaliação Nutricional'), - _buildAppointmentItem( - context, 'Ana Santos', '17:00', 'Revisão de Dieta'), - ], - ), - ); - } + final appointments = [ + {'name': 'Maria Oliveira', 'time': '14:00', 'type': 'Consulta de Rotina'}, + {'name': 'João Silva', 'time': '15:30', 'type': 'Avaliação Nutricional'}, + {'name': 'Ana Santos', 'time': '17:00', 'type': 'Revisão de Dieta'}, + ]; - Widget _buildAppointmentItem( - BuildContext context, String name, String time, String type) { - return GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/appointment_details', - arguments: {'name': name, 'time': time, 'type': type}); - }, - child: Container( - margin: EdgeInsets.only(bottom: 10), - padding: EdgeInsets.all(15), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: Colors.grey.withValues(alpha: 0.1), - spreadRadius: 1, - blurRadius: 5, - offset: Offset(0, 3), - ), - ], - ), - child: Row( - children: [ - Container( - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: kPrimaryColor.withValues(alpha: 0.1), - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - Icons.calendar_today, - color: kPrimaryColor, - ), - ), - SizedBox(width: 15), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - name, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - ), - ), - SizedBox(height: 5), - Text( - type, - style: TextStyle( - color: Colors.grey[600], - fontSize: 14, - ), - ), - ], - ), - ), - Text( - time, - style: TextStyle( - fontWeight: FontWeight.bold, - color: kPrimaryColor, - ), - ), - ], - ), - ), + return Column( + children: appointments + .map((appointment) => _buildAppointmentItem( + appointment['name']!, + appointment['time']!, + appointment['type']!, + )) + .toList(), ); } - Widget _buildPatientUpdates(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + Widget _buildAppointmentItem(String name, String time, String type) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + padding: const EdgeInsets.all(15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 1, + blurRadius: 5, + offset: const Offset(0, 3), + ), + ], + ), + child: Row( children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Atualizações de Pacientes', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - TextButton( - onPressed: () { - Navigator.pushNamed(context, '/patient_updates'); - }, - child: Text( - 'Ver todas', - style: TextStyle( - color: kPrimaryColor, - fontWeight: FontWeight.bold, - ), + Icon(Icons.calendar_today, color: kPrimaryColor, size: 30), + const SizedBox(width: 15), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), - ), - ], + const SizedBox(height: 5), + Text(type, style: TextStyle(color: Colors.grey[600], fontSize: 14)), + ], + ), ), - SizedBox(height: 15), - _buildPatientUpdateItem( - context, 'Carlos Mendes', 'Atingiu meta de peso', '2h atrás'), - _buildPatientUpdateItem(context, 'Fernanda Lima', - 'Novo registro de refeição', '4h atrás'), - _buildPatientUpdateItem(context, 'Ricardo Souza', - 'Solicitou alteração na dieta', '1d atrás'), + Text(time, style: TextStyle(fontWeight: FontWeight.bold, color: kPrimaryColor)), ], ), ); } - Widget _buildPatientUpdateItem( - BuildContext context, String name, String update, String time) { - return GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/patient_details', - arguments: {'name': name}); - }, - child: Container( - margin: EdgeInsets.only(bottom: 10), - padding: EdgeInsets.all(15), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: Colors.grey.withValues(alpha: 0.1), - spreadRadius: 1, - blurRadius: 5, - offset: Offset(0, 3), - ), - ], - ), - child: Row( - children: [ - CircleAvatar( - backgroundColor: kPrimaryColor.withValues(alpha: 0.1), - child: Text( - name[0], - style: TextStyle( - color: kPrimaryColor, - fontWeight: FontWeight.bold, - ), - ), - ), - SizedBox(width: 15), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - name, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - ), - ), - SizedBox(height: 5), - Text( - update, - style: TextStyle( - color: Colors.grey[600], - fontSize: 14, - ), - ), - ], - ), - ), - Text( - time, - style: TextStyle( - color: Colors.grey[400], - fontSize: 12, - ), - ), - ], - ), - ), + Widget _buildPatientUpdates(BuildContext context) { + final updates = [ + {'name': 'Carlos Mendes', 'update': 'Atingiu meta de peso', 'time': '2h atrás'}, + {'name': 'Fernanda Lima', 'update': 'Novo registro de refeição', 'time': '4h atrás'}, + {'name': 'Ricardo Souza', 'update': 'Solicitou alteração na dieta', 'time': '1d atrás'}, + ]; + + return Column( + children: updates + .map((update) => _buildPatientUpdateItem( + update['name']!, + update['update']!, + update['time']!, + )) + .toList(), ); } - Widget _buildBottomNavigationBar(BuildContext context) { + Widget _buildPatientUpdateItem(String name, String update, String time) { return Container( + margin: const EdgeInsets.only(bottom: 10), + padding: const EdgeInsets.all(15), decoration: BoxDecoration( color: Colors.white, + borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: Colors.grey.withValues(alpha: 0.3), + color: Colors.grey.withOpacity(0.1), spreadRadius: 1, blurRadius: 5, - offset: Offset(0, -3), + offset: const Offset(0, 3), ), ], ), - child: BottomNavigationBar( - backgroundColor: Colors.transparent, - elevation: 0, - selectedItemColor: kPrimaryColor, - unselectedItemColor: Colors.grey, - showSelectedLabels: true, - showUnselectedLabels: true, - type: BottomNavigationBarType.fixed, - currentIndex: 0, - onTap: (index) { - switch (index) { - case 0: - // Already on home screen - break; - case 1: - Navigator.pushNamed(context, '/patient_list', - arguments: userData); - break; - case 2: - Navigator.pushNamed(context, '/schedule'); - break; - case 3: - Navigator.pushNamed(context, '/chat'); - break; - } - }, - items: [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: 'Início', - ), - BottomNavigationBarItem( - icon: Icon(Icons.people), - label: 'Pacientes', - ), - BottomNavigationBarItem( - icon: Icon(Icons.calendar_today), - label: 'Agenda', - ), - BottomNavigationBarItem( - icon: Icon(Icons.message), - label: 'Mensagens', + child: Row( + children: [ + Icon(Icons.notifications, color: kPrimaryColor, size: 30), + const SizedBox(width: 15), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + const SizedBox(height: 5), + Text(update, style: TextStyle(color: Colors.grey[600], fontSize: 14)), + ], + ), ), + Text(time, style: TextStyle(color: Colors.grey[600], fontSize: 12)), ], ), ); } -} -extension on Color { - withValues({required double alpha}) {} + Widget _buildSectionTitle(String title, {bool showButton = false, String? buttonRoute}) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + ), + ); + } + + Widget _buildBottomNavigationBar() { + return BottomNavigationBar( + currentIndex: 0, + selectedItemColor: kPrimaryColor, + unselectedItemColor: Colors.grey, + items: const [ + BottomNavigationBarItem( + icon: Icon(Icons.dashboard), + label: 'Dashboard', + ), + BottomNavigationBarItem( + icon: Icon(Icons.people), + label: 'Pacientes', + ), + BottomNavigationBarItem( + icon: Icon(Icons.settings), + label: 'Configurações', + ), + ], + onTap: (index) { + // Implement navigation logic here + }, + ); + } } From 9cca8edb3845b775b89e982ede323137d92e3953 Mon Sep 17 00:00:00 2001 From: Davi Nascimento Date: Mon, 20 Jan 2025 21:34:59 -0300 Subject: [PATCH 33/47] Criado o teste para a tela de perfil do nutricionista #91 --- healthway_app/test/flutter | 1 + .../nutricionista_profile_screen_teste.dart | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 160000 healthway_app/test/flutter create mode 100644 healthway_app/test/nutricionista_profile_screen_teste.dart diff --git a/healthway_app/test/flutter b/healthway_app/test/flutter new file mode 160000 index 0000000..68415ad --- /dev/null +++ b/healthway_app/test/flutter @@ -0,0 +1 @@ +Subproject commit 68415ad1d920f6fe5ec284f5c2febf7c4dd5b0b3 diff --git a/healthway_app/test/nutricionista_profile_screen_teste.dart b/healthway_app/test/nutricionista_profile_screen_teste.dart new file mode 100644 index 0000000..58464b6 --- /dev/null +++ b/healthway_app/test/nutricionista_profile_screen_teste.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; + +void main() { + testWidgets('NutritionistProfileScreen displays correctly', (WidgetTester tester) async { + // Build the NutritionistProfileScreen widget. + await tester.pumpWidget( + MaterialApp( + home: NutritionistProfileScreen(userData: {}), + ), + ); + + // Verify if the AppBar widget is present. + expect(find.byType(AppBar), findsOneWidget); + + // Verify if the Scaffold widget has the correct background color. + final scaffold = tester.widget(find.byType(Scaffold)); + expect(scaffold.backgroundColor, const Color(0xFFE6F7F8)); // Substitua com a cor definida por `kBackgroundColor`. + + // Verify if the CircleAvatar widget is present. + expect(find.byType(CircleAvatar), findsOneWidget); + + // Verify if the Form widget is present. + expect(find.byType(Form), findsOneWidget); + + // Verify if the TextFormField widgets are present when editing. + await tester.tap(find.byIcon(Icons.edit)); // Tap the edit button to enable editing. + await tester.pump(); + expect(find.byType(TextFormField), findsNWidgets(5)); // Nome, email, CPF, CRN, Especialidade. + + // Verify if the ElevatedButton widget is present. + expect(find.widgetWithText(ElevatedButton, 'Editar Perfil Detalhado'), findsOneWidget); + + // Verify if the OutlinedButton widget is present. + expect(find.widgetWithText(OutlinedButton, 'Alterar Senha'), findsOneWidget); + + // Verify if the document image container is present. + expect(find.byType(Container), findsWidgets); + }); + + testWidgets('Toggling edit mode in NutritionistProfileScreen', (WidgetTester tester) async { + // Build the NutritionistProfileScreen widget. + await tester.pumpWidget( + MaterialApp( + home: NutritionistProfileScreen(userData: {}), + ), + ); + + // Initial state: not editing. + expect(find.byType(TextFormField), findsNothing); + + // Tap the edit button to enable editing. + await tester.tap(find.byIcon(Icons.edit)); + await tester.pump(); + + // Verify if TextFormFields appear for editing. + expect(find.byType(TextFormField), findsWidgets); + + // Tap the close button to disable editing. + await tester.tap(find.byIcon(Icons.close)); + await tester.pump(); + + // Verify if TextFormFields disappear. + expect(find.byType(TextFormField), findsNothing); + }); + + testWidgets('Saving changes in NutritionistProfileScreen', (WidgetTester tester) async { + // Build the NutritionistProfileScreen widget. + await tester.pumpWidget( + MaterialApp( + home: NutritionistProfileScreen(userData: {}), + ), + ); + + // Enable editing. + await tester.tap(find.byIcon(Icons.edit)); + await tester.pump(); + + // Enter new values into the TextFormFields. + await tester.enterText(find.widgetWithText(TextFormField, 'Dr. Silva'), 'Dr. Teste'); + await tester.enterText(find.widgetWithText(TextFormField, 'dr.silva@email.com'), 'teste@email.com'); + await tester.pump(); + + // Tap the save button. + await tester.tap(find.byType(FloatingActionButton)); + await tester.pump(); + + // Verify if the snackbar appears with the success message. + expect(find.text('Perfil atualizado com sucesso!'), findsOneWidget); + + // Verify if editing mode is disabled. + expect(find.byType(TextFormField), findsNothing); + }); +} From 6b7ed8535a26e91f557a1da84261a9a7a1f52674 Mon Sep 17 00:00:00 2001 From: lucasherlon Date: Mon, 20 Jan 2025 21:36:39 -0300 Subject: [PATCH 34/47] refactor: criando services para nutricionista, pacientes e alimentos #92 --- backend/controllers/alimentoController.js | 67 ++---- .../controllers/nutricionistaController.js | 203 +++++++----------- backend/controllers/pacienteController.js | 74 ++----- backend/services/alimentoServices.js | 38 ++++ backend/services/nutricionistaService.js | 72 +++++++ backend/services/pacienteServices.js | 59 +++++ 6 files changed, 280 insertions(+), 233 deletions(-) create mode 100644 backend/services/alimentoServices.js create mode 100644 backend/services/nutricionistaService.js create mode 100644 backend/services/pacienteServices.js diff --git a/backend/controllers/alimentoController.js b/backend/controllers/alimentoController.js index 413b906..27ba564 100644 --- a/backend/controllers/alimentoController.js +++ b/backend/controllers/alimentoController.js @@ -1,104 +1,63 @@ -const db = require('../firebase-config'); -const Alimento = require('../model/Alimento'); +const AlimentoService = require('../services/alimentoServices'); const alimentoController = { - //Criar um novo alimento - async create(req, res){ + async create(req, res) { try { - const alimento = new Alimento(req.body); - await db.collection('alimentos').add(alimento.toFirestore()); + await AlimentoService.create(req.body); res.status(201).json({ message: 'Alimento criado com sucesso!' }); } catch (error) { res.status(500).json({ error: error.message }); } }, - //Obter todos os alimentos - async getAll(req, res){ + async getAll(req, res) { try { - const snapshot = await db.collection('alimentos').get(); - const alimentos = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + const alimentos = await AlimentoService.getAll(); res.status(200).json(alimentos); } catch (error) { res.status(500).json({ error: error.message }); } }, - // Obter alimentos por categoria async getByCategory(req, res) { try { const { categoria } = req.params; - const snapshot = await db.collection('alimentos').where('Categoria', '==', categoria).get(); - const alimentos = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + const alimentos = await AlimentoService.getByCategory(categoria); res.status(200).json(alimentos); } catch (error) { res.status(500).json({ error: error.message }); } }, - //Obter um alimento pelo ID - async getById(req, res){ + async getById(req, res) { try { const { id } = req.params; - const doc = await db.collection('alimentos').doc(id).get(); - - if (!doc.exists) { - return res.status(404).json({ error: 'Alimento não encontrado.' }); - } - - res.status(200).json({ id: doc.id, ...doc.data() }); + const alimento = await AlimentoService.getById(id); + res.status(200).json(alimento); } catch (error) { res.status(500).json({ error: error.message }); } }, - //Atualizar um alimento - async update(req, res){ + async update(req, res) { try { const { id } = req.params; - const alimento = new Alimento(req.body); - - await db.collection('alimentos').doc(id).update(alimento.toFirestore()); + await AlimentoService.update(id, req.body); res.status(200).json({ message: 'Alimento atualizado com sucesso!' }); } catch (error) { res.status(500).json({ error: error.message }); } }, - //Excluir um alimento - async delete(req, res){ + async delete(req, res) { try { const { id } = req.params; - await db.collection('alimentos').doc(id).delete(); + await AlimentoService.delete(id); res.status(200).json({ message: 'Alimento excluído com sucesso!' }); } catch (error) { res.status(500).json({ error: error.message }); } }, - - async getByCategory(req, res) { - try { - const { nome } = req.params; - - const startAt = nome; - const endAt = nome + '\uf8ff'; - - const snapshot = await db.collection('alimentos') - .orderBy('Categoria') - .startAt(startAt) - .endAt(endAt) - .get(); - - if (snapshot.empty) { - return res.status(404).json({ message: 'Nenhum alimento encontrado nessa categoria.' }); - } - - const alimentos = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - res.status(200).json(alimentos); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, }; module.exports = alimentoController; diff --git a/backend/controllers/nutricionistaController.js b/backend/controllers/nutricionistaController.js index 6603b9a..1bd6936 100644 --- a/backend/controllers/nutricionistaController.js +++ b/backend/controllers/nutricionistaController.js @@ -1,130 +1,83 @@ -const db = require('../firebase-config'); -const Nutricionista = require('../model/Nutricionista'); +const NutricionistaService = require('../services/nutricionistaService'); const nutricionistaController = { - // Criar um nutricionista - async create(req, res) { - try { - const nutricionista = new Nutricionista(req.body); - await db.collection('nutricionista').add(nutricionista.toFirestore()); - res.status(201).json({ message: 'Nutricionista criado com sucesso!' }); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - // Obter todos os nutricionistas - async getAll(req, res) { - try { - const snapshot = await db.collection('nutricionista').get(); - const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - res.status(200).json(nutricionistas); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - // Obter um nutricionista pelo ID - async getById(req, res) { - try { - const { id } = req.params; - const doc = await db.collection('nutricionista').doc(id).get(); - - if (!doc.exists) { - return res.status(404).json({ error: 'Nutricionista não encontrado.' }); - } - - res.status(200).json({ id: doc.id, ...doc.data() }); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async getByEmailAndPassword(req, res) { - try { - const { email, senha } = req.body; - const snapshot = await db.collection('nutricionista').where('email', '==', email).where('senha', '==', senha).get(); - const paciente = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - - if (paciente.length === 0) { - return res.status(404).json({ error: 'Nutricionista não encontrado.' }); - } - - res.status(200).json(paciente[0]); - } catch (error) { - res.status(500).json({ error: error.message }); - } -}, - - // Atualizar um nutricionista - async update(req, res) { - try { - const { id } = req.params; - const nutricionista = new Nutricionista(req.body); - - await db.collection('nutricionista').doc(id).update(nutricionista.toFirestore()); - res.status(200).json({ message: 'Nutricionista atualizado com sucesso!' }); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - // Excluir um nutricionista - async delete(req, res) { - try { - const { id } = req.params; - await db.collection('nutricionista').doc(id).delete(); - res.status(200).json({ message: 'Nutricionista excluído com sucesso!' }); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async getBySpecialty(req, res) { - try { - const { specialty } = req.params; // Obtém a especialidade a partir dos parâmetros da URL - const snapshot = await db.collection('nutricionista') - .where('especialidade', '==', specialty) - .get(); - - if (snapshot.empty) { - return res.status(404).json({ message: 'Nenhum nutricionista encontrado com essa especialidade.' }); - } - - const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - res.status(200).json(nutricionistas); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - // Buscar nutricionistas pelo nome - async getByName(req, res) { - try { - const { nome } = req.params; - - const startAt = nome; - const endAt = nome + '\uf8ff'; - - const snapshot = await db.collection('nutricionistas') - .orderBy('nome') - .startAt(startAt) - .endAt(endAt) - .get(); - - if (snapshot.empty) { - return res.status(404).json({ message: 'Nenhum nutricionista encontrado com esse nome.' }); - } - - const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - res.status(200).json(nutricionistas); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, + async create(req, res) { + try { + await NutricionistaService.create(req.body); + res.status(201).json({ message: 'Nutricionista criado com sucesso!' }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getAll(req, res) { + try { + const nutricionistas = await NutricionistaService.getAll(); + res.status(200).json(nutricionistas); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getById(req, res) { + try { + const { id } = req.params; + const nutricionista = await NutricionistaService.getById(id); + res.status(200).json(nutricionista); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getByEmailAndPassword(req, res) { + try { + const { email, senha } = req.body; + const nutricionista = await NutricionistaService.getByEmailAndPassword(email, senha); + res.status(200).json(nutricionista); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getBySpecialty(req, res) { + try { + const { specialty } = req.params; + const nutricionistas = await NutricionistaService.getBySpecialty(specialty); + res.status(200).json(nutricionistas); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getByName(req, res) { + try { + const { nome } = req.params; + const nutricionistas = await NutricionistaService.getByName(nome); + res.status(200).json(nutricionistas); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async update(req, res) { + try { + const { id } = req.params; + await NutricionistaService.update(id, req.body); + res.status(200).json({ message: 'Nutricionista atualizado com sucesso!' }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async delete(req, res) { + try { + const { id } = req.params; + await NutricionistaService.delete(id); + res.status(200).json({ message: 'Nutricionista excluído com sucesso!' }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, }; - - - module.exports = nutricionistaController; diff --git a/backend/controllers/pacienteController.js b/backend/controllers/pacienteController.js index 5bbe180..72798e6 100644 --- a/backend/controllers/pacienteController.js +++ b/backend/controllers/pacienteController.js @@ -1,100 +1,66 @@ -const db = require('../firebase-config'); -const Paciente = require('../model/Paciente'); +const PacienteService = require('../services/pacienteServices'); const pacienteController = { - // Criar um paciente async create(req, res) { try { - const paciente = new Paciente(); - paciente.fromJson(req.body); - await db.collection('paciente').add(paciente.toFirestore()); + await PacienteService.create(req.body); res.status(201).json({ message: 'Paciente criado com sucesso!' }); } catch (error) { res.status(500).json({ error: error.message }); } }, - // Obter todos os pacientes async getAll(req, res) { try { - const snapshot = await db.collection('paciente').get(); - const pacientes = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - res.status(200).json(pacientes); + const pacientes = await PacienteService.getAll(); + res.status(200).json(pacientes); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, - // Obter um paciente pelo ID async getById(req, res) { try { - const { id } = req.params; - const doc = await db.collection('paciente').doc(id).get(); - - if (!doc.exists) { - return res.status(404).json({ error: 'Paciente não encontrado.' }); - } - - res.status(200).json({ id: doc.id, ...doc.data() }); + const paciente = await PacienteService.getById(req.params.id); + res.status(200).json(paciente); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, async getByListOfIds(req, res) { try { - const { ids } = req.body; - const pacientes = []; - for (const id of ids) { - const doc = await db.collection('paciente').doc(id).get(); - if (doc.exists) { - pacientes.push({ id: doc.id, ...doc.data() }); - } - } - res.status(200).json(pacientes); + const pacientes = await PacienteService.getByListOfIds(req.body.ids); + res.status(200).json(pacientes); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, async getByEmailAndPassword(req, res) { try { - const { email, senha } = req.body; - const snapshot = await db.collection('paciente').where('email', '==', email).where('senha', '==', senha).get(); - const paciente = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - - if (paciente.length === 0) { - return res.status(404).json({ error: 'Paciente não encontrado.' }); - } - - res.status(200).json(paciente[0]); + const paciente = await PacienteService.getByEmailAndPassword(req.body.email, req.body.senha); + res.status(200).json(paciente); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, - // Atualizar um paciente async update(req, res) { try { - const { id } = req.params; - const paciente = new Paciente(); - paciente.fromJson(req.body); - - await db.collection('paciente').doc(id).update(paciente.toFirestore()); - res.status(200).json({ message: 'Paciente atualizado com sucesso!' }); + await PacienteService.update(req.params.id, req.body); + res.status(200).json({ message: 'Paciente atualizado com sucesso!' }); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, - // Excluir um paciente async delete(req, res) { try { - const { id } = req.params; - await db.collection('paciente').doc(id).delete(); - res.status(200).json({ message: 'Paciente excluído com sucesso!' }); + await PacienteService.delete(req.params.id); + res.status(200).json({ message: 'Paciente excluído com sucesso!' }); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } } }; diff --git a/backend/services/alimentoServices.js b/backend/services/alimentoServices.js new file mode 100644 index 0000000..013fa6e --- /dev/null +++ b/backend/services/alimentoServices.js @@ -0,0 +1,38 @@ +const db = require('../firebase-config'); +const Alimento = require('../model/Alimento'); + +const AlimentoService = { + async create(data) { + const alimento = new Alimento(data); + return await db.collection('alimentos').add(alimento.toFirestore()); + }, + + async getAll() { + const snapshot = await db.collection('alimentos').get(); + return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + }, + + async getByCategory(categoria) { + const snapshot = await db.collection('alimentos').where('Categoria', '==', categoria).get(); + return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + }, + + async getById(id) { + const doc = await db.collection('alimentos').doc(id).get(); + if (!doc.exists) { + throw new Error('Alimento não encontrado.'); + } + return { id: doc.id, ...doc.data() }; + }, + + async update(id, data) { + const alimento = new Alimento(data); + await db.collection('alimentos').doc(id).update(alimento.toFirestore()); + }, + + async delete(id) { + await db.collection('alimentos').doc(id).delete(); + }, +}; + +module.exports = AlimentoService; diff --git a/backend/services/nutricionistaService.js b/backend/services/nutricionistaService.js new file mode 100644 index 0000000..e3d5432 --- /dev/null +++ b/backend/services/nutricionistaService.js @@ -0,0 +1,72 @@ +const db = require('../firebase-config'); +const Nutricionista = require('../model/Nutricionista'); + +const NutricionistaService = { + async create(data) { + const nutricionista = new Nutricionista(data); + await db.collection('nutricionista').add(nutricionista.toFirestore()); + }, + + async getAll() { + const snapshot = await db.collection('nutricionista').get(); + return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + }, + + async getById(id) { + const doc = await db.collection('nutricionista').doc(id).get(); + if (!doc.exists) { + throw new Error('Nutricionista não encontrado.'); + } + return { id: doc.id, ...doc.data() }; + }, + + async getByEmailAndPassword(email, senha) { + const snapshot = await db.collection('nutricionista') + .where('email', '==', email) + .where('senha', '==', senha) + .get(); + + const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + if (nutricionistas.length === 0) { + throw new Error('Nutricionista não encontrado.'); + } + return nutricionistas[0]; + }, + + async getBySpecialty(especialidade) { + const snapshot = await db.collection('nutricionista') + .where('especialidade', '==', especialidade) + .get(); + + const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + if (nutricionistas.length === 0) { + throw new Error('Nenhum nutricionista encontrado com essa especialidade.'); + } + return nutricionistas; + }, + + async getByName(nome) { + const snapshot = await db.collection('nutricionista') + .orderBy('nome') + .startAt(nome) + .endAt(nome + '\uf8ff') + .get(); + + const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + if (nutricionistas.length === 0) { + throw new Error('Nenhum nutricionista encontrado com esse nome.'); + } + return nutricionistas; + }, + + async update(id, data) { + const nutricionista = new Nutricionista(data); + await db.collection('nutricionista').doc(id).update(nutricionista.toFirestore()); + }, + + async delete(id) { + await db.collection('nutricionista').doc(id).delete(); + }, +}; + +module.exports = NutricionistaService; diff --git a/backend/services/pacienteServices.js b/backend/services/pacienteServices.js new file mode 100644 index 0000000..1026a64 --- /dev/null +++ b/backend/services/pacienteServices.js @@ -0,0 +1,59 @@ +const db = require('../firebase-config'); +const Paciente = require('../model/Paciente'); + +const PacienteService = { + async create(data) { + const paciente = new Paciente(); + paciente.fromJson(data); + await db.collection('paciente').add(paciente.toFirestore()); + }, + + async getAll() { + const snapshot = await db.collection('paciente').get(); + return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + }, + + async getById(id) { + const doc = await db.collection('paciente').doc(id).get(); + if (!doc.exists) { + throw new Error('Paciente não encontrado.'); + } + return { id: doc.id, ...doc.data() }; + }, + + async getByListOfIds(ids) { + const pacientes = []; + for (const id of ids) { + const doc = await db.collection('paciente').doc(id).get(); + if (doc.exists) { + pacientes.push({ id: doc.id, ...doc.data() }); + } + } + return pacientes; + }, + + async getByEmailAndPassword(email, senha) { + const snapshot = await db.collection('paciente') + .where('email', '==', email) + .where('senha', '==', senha) + .get(); + + const pacientes = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + if (pacientes.length === 0) { + throw new Error('Paciente não encontrado.'); + } + return pacientes[0]; + }, + + async update(id, data) { + const paciente = new Paciente(); + paciente.fromJson(data); + await db.collection('paciente').doc(id).update(paciente.toFirestore()); + }, + + async delete(id) { + await db.collection('paciente').doc(id).delete(); + } +}; + +module.exports = PacienteService; From ddfc4041d68edafaaa91bf4fff6a6705b7bd4ce0 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 20 Jan 2025 21:44:19 -0300 Subject: [PATCH 35/47] melhorando testes --- .../nutritionist_dashboard_screen.dart | 520 ++++++++++++------ .../nutricionista_dashboard_screen_test.dart | 136 +++-- 2 files changed, 446 insertions(+), 210 deletions(-) diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index 53f8b54..73f3078 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -1,5 +1,6 @@ import 'package:healthway_app/constants.dart'; import 'package:flutter/material.dart'; + class NutritionistDashboardScreen extends StatelessWidget { final Map userData; @@ -7,7 +8,6 @@ class NutritionistDashboardScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( backgroundColor: kBackgroundColor, body: SafeArea( @@ -15,27 +15,24 @@ class NutritionistDashboardScreen extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildHeader(), - _buildSectionTitle('Acesso Rápido'), + _buildHeader(context), _buildQuickAccess(context), - _buildSectionTitle('Próximas Consultas', showButton: true, buttonRoute: '/appointments'), _buildAppointments(context), - _buildSectionTitle('Atualizações de Pacientes', showButton: true, buttonRoute: '/patient_updates'), _buildPatientUpdates(context), ], ), ), ), - bottomNavigationBar: _buildBottomNavigationBar(), + bottomNavigationBar: _buildBottomNavigationBar(context), ); } - Widget _buildHeader() { + Widget _buildHeader(BuildContext context) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: kPrimaryColor, - borderRadius: const BorderRadius.only( + borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), ), @@ -51,45 +48,54 @@ class NutritionistDashboardScreen extends StatelessWidget { children: [ Text( userData['nome'], - style: const TextStyle( + style: TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, ), ), - const SizedBox(height: 5), - const Text( + SizedBox(height: 5), + Text( 'Bem-vindo de volta', - style: TextStyle(color: Colors.white70, fontSize: 16), + style: TextStyle( + color: Colors.white70, + fontSize: 16, + ), ), ], ), - CircleAvatar( - radius: 30, - backgroundImage: AssetImage('assets/images/nutricionista.jpg'), + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/nutritionistProfile'); + }, + child: CircleAvatar( + radius: 30, + backgroundColor: Colors.white, + child: Icon( + Icons.person, + size: 35, + color: kPrimaryColor, + ), + ), ), ], ), - const SizedBox(height: 20), - _buildStatsRow(), - ], - ), - ); - } - - Widget _buildStatsRow() { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _buildStatItem('Pacientes', '${userData['pacientes'].length}'), - _buildStatItem('Consultas Hoje', '8'), - _buildStatItem('Mensagens', '15'), + SizedBox(height: 20), + Container( + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildStatItem('Pacientes', '${userData['pacientes'].length}'), + _buildStatItem('Consultas Hoje', '8'), + _buildStatItem('Mensagens', '15'), + ], + ), + ), ], ), ); @@ -106,8 +112,14 @@ class NutritionistDashboardScreen extends StatelessWidget { color: kPrimaryColor, ), ), - const SizedBox(height: 5), - Text(label, style: TextStyle(fontSize: 14, color: Colors.grey[600])), + SizedBox(height: 5), + Text( + label, + style: TextStyle( + fontSize: 14, + color: Colors.grey[600], + ), + ), ], ); } @@ -115,188 +127,356 @@ class NutritionistDashboardScreen extends StatelessWidget { Widget _buildQuickAccess(BuildContext context) { return Padding( padding: const EdgeInsets.all(20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildQuickAccessItem(context, Icons.people, 'Pacientes', '/patient_list', userData), - _buildQuickAccessItem(context, Icons.calendar_today, 'Agenda', '/schedule', null), - _buildQuickAccessItem(context, Icons.food_bank_outlined, 'Alimentos', '/alimentos', null), + Text( + 'Acesso Rápido', + style: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 15), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildQuickAccessItem(context, Icons.people, 'Pacientes', + '/patient_list', userData), + _buildQuickAccessItem( + context, Icons.calendar_today, 'Agenda', '/schedule', null), + // _buildQuickAccessItem( + // context, Icons.restaurant_menu, 'Planos', '/meal_plans'), + _buildQuickAccessItem(context, Icons.food_bank_outlined, + 'Alimentos', '/alimentos', null), + ], + ), ], ), ); } - Widget _buildQuickAccessItem( - BuildContext context, - IconData icon, - String label, - String route, - Object? args, - ) { + Widget _buildQuickAccessItem(BuildContext context, IconData icon, + String label, String route, Object? args) { return GestureDetector( - onTap: () => Navigator.pushNamed(context, route, arguments: args), + onTap: () { + Navigator.pushNamed(context, route, arguments: args); + }, child: Column( children: [ Container( - padding: const EdgeInsets.all(15), + padding: EdgeInsets.all(15), decoration: BoxDecoration( - color: kPrimaryColor.withOpacity(0.1), + color: kPrimaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(15), ), - child: Icon(icon, color: kPrimaryColor, size: 30), + child: Icon( + icon, + color: kPrimaryColor, + size: 30, + ), + ), + SizedBox(height: 5), + Text( + label, + style: TextStyle( + fontSize: 14, + color: Colors.grey[600], + ), ), - const SizedBox(height: 5), - Text(label, style: TextStyle(fontSize: 14, color: Colors.grey[600])), ], ), ); } Widget _buildAppointments(BuildContext context) { - final appointments = [ - {'name': 'Maria Oliveira', 'time': '14:00', 'type': 'Consulta de Rotina'}, - {'name': 'João Silva', 'time': '15:30', 'type': 'Avaliação Nutricional'}, - {'name': 'Ana Santos', 'time': '17:00', 'type': 'Revisão de Dieta'}, - ]; - - return Column( - children: appointments - .map((appointment) => _buildAppointmentItem( - appointment['name']!, - appointment['time']!, - appointment['type']!, - )) - .toList(), + return Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Próximas Consultas', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + TextButton( + onPressed: () { + Navigator.pushNamed(context, '/appointments'); + }, + child: Text( + 'Ver todas', + style: TextStyle( + color: kPrimaryColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + SizedBox(height: 15), + _buildAppointmentItem( + context, 'Maria Oliveira', '14:00', 'Consulta de Rotina'), + _buildAppointmentItem( + context, 'João Silva', '15:30', 'Avaliação Nutricional'), + _buildAppointmentItem( + context, 'Ana Santos', '17:00', 'Revisão de Dieta'), + ], + ), ); } - Widget _buildAppointmentItem(String name, String time, String type) { - return Container( - margin: const EdgeInsets.only(bottom: 10), - padding: const EdgeInsets.all(15), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 1, - blurRadius: 5, - offset: const Offset(0, 3), - ), - ], + Widget _buildAppointmentItem( + BuildContext context, String name, String time, String type) { + return GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/appointment_details', + arguments: {'name': name, 'time': time, 'type': type}); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10), + padding: EdgeInsets.all(15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.grey.withValues(alpha: 0.1), + spreadRadius: 1, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: Row( + children: [ + Container( + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: kPrimaryColor.withValues(alpha: 0.1), + borderRadius: BorderRadius.circular(10), + ), + child: Icon( + Icons.calendar_today, + color: kPrimaryColor, + ), + ), + SizedBox(width: 15), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + SizedBox(height: 5), + Text( + type, + style: TextStyle( + color: Colors.grey[600], + fontSize: 14, + ), + ), + ], + ), + ), + Text( + time, + style: TextStyle( + fontWeight: FontWeight.bold, + color: kPrimaryColor, + ), + ), + ], + ), ), - child: Row( + ); + } + + Widget _buildPatientUpdates(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon(Icons.calendar_today, color: kPrimaryColor, size: 30), - const SizedBox(width: 15), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - name, - style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Atualizações de Pacientes', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, ), - const SizedBox(height: 5), - Text(type, style: TextStyle(color: Colors.grey[600], fontSize: 14)), - ], - ), + ), + TextButton( + onPressed: () { + Navigator.pushNamed(context, '/patient_updates'); + }, + child: Text( + 'Ver todas', + style: TextStyle( + color: kPrimaryColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - Text(time, style: TextStyle(fontWeight: FontWeight.bold, color: kPrimaryColor)), + SizedBox(height: 15), + _buildPatientUpdateItem( + context, 'Carlos Mendes', 'Atingiu meta de peso', '2h atrás'), + _buildPatientUpdateItem(context, 'Fernanda Lima', + 'Novo registro de refeição', '4h atrás'), + _buildPatientUpdateItem(context, 'Ricardo Souza', + 'Solicitou alteração na dieta', '1d atrás'), ], ), ); } - Widget _buildPatientUpdates(BuildContext context) { - final updates = [ - {'name': 'Carlos Mendes', 'update': 'Atingiu meta de peso', 'time': '2h atrás'}, - {'name': 'Fernanda Lima', 'update': 'Novo registro de refeição', 'time': '4h atrás'}, - {'name': 'Ricardo Souza', 'update': 'Solicitou alteração na dieta', 'time': '1d atrás'}, - ]; - - return Column( - children: updates - .map((update) => _buildPatientUpdateItem( - update['name']!, - update['update']!, - update['time']!, - )) - .toList(), + Widget _buildPatientUpdateItem( + BuildContext context, String name, String update, String time) { + return GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/patient_details', + arguments: {'name': name}); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10), + padding: EdgeInsets.all(15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.grey.withValues(alpha: 0.1), + spreadRadius: 1, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: Row( + children: [ + CircleAvatar( + backgroundColor: kPrimaryColor.withValues(alpha: 0.1), + child: Text( + name[0], + style: TextStyle( + color: kPrimaryColor, + fontWeight: FontWeight.bold, + ), + ), + ), + SizedBox(width: 15), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + SizedBox(height: 5), + Text( + update, + style: TextStyle( + color: Colors.grey[600], + fontSize: 14, + ), + ), + ], + ), + ), + Text( + time, + style: TextStyle( + color: Colors.grey[400], + fontSize: 12, + ), + ), + ], + ), + ), ); } - Widget _buildPatientUpdateItem(String name, String update, String time) { + Widget _buildBottomNavigationBar(BuildContext context) { return Container( - margin: const EdgeInsets.only(bottom: 10), - padding: const EdgeInsets.all(15), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.1), + color: Colors.grey.withValues(alpha: 0.3), spreadRadius: 1, blurRadius: 5, - offset: const Offset(0, 3), + offset: Offset(0, -3), ), ], ), - child: Row( - children: [ - Icon(Icons.notifications, color: kPrimaryColor, size: 30), - const SizedBox(width: 15), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - name, - style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), - ), - const SizedBox(height: 5), - Text(update, style: TextStyle(color: Colors.grey[600], fontSize: 14)), - ], - ), + child: BottomNavigationBar( + backgroundColor: Colors.transparent, + elevation: 0, + selectedItemColor: kPrimaryColor, + unselectedItemColor: Colors.grey, + showSelectedLabels: true, + showUnselectedLabels: true, + type: BottomNavigationBarType.fixed, + currentIndex: 0, + onTap: (index) { + switch (index) { + case 0: + // Already on home screen + break; + case 1: + Navigator.pushNamed(context, '/patient_list', + arguments: userData); + break; + case 2: + Navigator.pushNamed(context, '/schedule'); + break; + case 3: + Navigator.pushNamed(context, '/chat'); + break; + } + }, + items: [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Início', + ), + BottomNavigationBarItem( + icon: Icon(Icons.people), + label: 'Pacientes', + ), + BottomNavigationBarItem( + icon: Icon(Icons.calendar_today), + label: 'Agenda', + ), + BottomNavigationBarItem( + icon: Icon(Icons.message), + label: 'Mensagens', ), - Text(time, style: TextStyle(color: Colors.grey[600], fontSize: 12)), ], ), ); } +} - Widget _buildSectionTitle(String title, {bool showButton = false, String? buttonRoute}) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - ), - ); - } - - Widget _buildBottomNavigationBar() { - return BottomNavigationBar( - currentIndex: 0, - selectedItemColor: kPrimaryColor, - unselectedItemColor: Colors.grey, - items: const [ - BottomNavigationBarItem( - icon: Icon(Icons.dashboard), - label: 'Dashboard', - ), - BottomNavigationBarItem( - icon: Icon(Icons.people), - label: 'Pacientes', - ), - BottomNavigationBarItem( - icon: Icon(Icons.settings), - label: 'Configurações', - ), - ], - onTap: (index) { - // Implement navigation logic here - }, - ); - } +extension on Color { + withValues({required double alpha}) {} } diff --git a/healthway_app/test/nutricionista_dashboard_screen_test.dart b/healthway_app/test/nutricionista_dashboard_screen_test.dart index 1ca5062..0f41860 100644 --- a/healthway_app/test/nutricionista_dashboard_screen_test.dart +++ b/healthway_app/test/nutricionista_dashboard_screen_test.dart @@ -1,53 +1,109 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard_screen.dart'; +import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; +import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; +import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; void main() { - testWidgets('NutritionistDashboardScreen displays correctly', (WidgetTester tester) async { - // Build the NutritionistDashboardScreen widget. - await tester.pumpWidget(MaterialApp(home: NutritionistDashboardScreen(userData: {},))); - - // Verify if the background color is correct. - final scaffold = tester.widget(find.byType(Scaffold)); - expect(scaffold.backgroundColor, const Color(0xFFE6F7F8)); - - // Verify if the AppBar widget is present. - expect(find.byType(AppBar), findsOneWidget); - - // Verify if the Icon widget is present. - expect(find.byType(Icon), findsOneWidget); - - // Verify if the Padding widget is present. - expect(find.byType(Padding), findsOneWidget); - - // Verify if the Form widget is present. - expect(find.byType(Form), findsOneWidget); - - // Verify if the TextFormField widget is present. - expect(find.byType(TextFormField), findsNWidgets(2)); - - // Verify if the ElevatedButton widget is present. - expect(find.byType(ElevatedButton), findsOneWidget); - - // Verify if the CircularProgressIndicator widget is present. - expect(find.byType(CircularProgressIndicator), findsNothing); + final Map mockUserData = { + 'nome': 'John Doe', + 'email': 'ho@gmail.com', + 'dt_nascimento': '01/01/2000', + 'altura': 180, + 'peso': 75, + 'circunferencia_abdominal': 88, + 'massa_muscular': 6.5, + 'gordura_corporal': 15.5, + 'alergias': ['Amendoim', 'Leite'], + 'preferencias': ['Vegano'], + }; + + testWidgets('PatientDashboardScreen displays user data correctly', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientDashboardScreen(userData: mockUserData), + )); + + expect(find.text('John Doe'), findsOneWidget); + expect(find.text('Vamos cuidar da sua saúde hoje!'), findsOneWidget); + expect(find.text('IMC'), findsOneWidget); + expect(find.text('Peso'), findsOneWidget); + expect(find.text('Altura'), findsOneWidget); + }); - // Add more specific tests for the widgets inside the Column as needed. + testWidgets('PatientDashboardScreen navigates to meal plan on tap', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + onGenerateRoute: (settings) { + switch (settings.name) { + case '/meal_plan': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => MealPlanScreen(patientData: args, isPatient: true), + ); + default: + return null; + } + }, + home: PatientDashboardScreen(userData: mockUserData), + )); + + await tester.tap(find.byKey(Key('dashboard_dieta'))); + await tester.pumpAndSettle(); + + expect(find.byType(PatientDashboardScreen), findsNothing); }); - testWidgets('NutritionistDashboardScreen displays CircularProgressIndicator when loading', (WidgetTester tester) async { - // Build the NutritionistDashboardScreen widget. - await tester.pumpWidget(MaterialApp(home: NutritionistDashboardScreen(userData: {},))); + testWidgets('PatientDashboardScreen displays next appointment', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientDashboardScreen(userData: mockUserData), + )); - // Verify if the CircularProgressIndicator widget is present. - expect(find.byType(CircularProgressIndicator), findsNothing); + expect(find.text('Próxima consulta:'), findsOneWidget); + expect(find.text('Nutricionista'), findsOneWidget); + expect(find.text('Dr. João Silva'), findsOneWidget); + }); - // Tap the ElevatedButton to simulate a loading state. - await tester.tap(find.byType(ElevatedButton)); - await tester.pump(); + testWidgets('PatientProfileScreen displays user data correctly', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: PatientProfileScreen(userData: mockUserData), + )); + + expect(find.text('John Doe'), findsOneWidget); + expect(find.text('01/01/2000'), findsOneWidget); + expect(find.text('180 cm'), findsOneWidget); + expect(find.text('75 kg'), findsOneWidget); + expect(find.text('88 cm'), findsOneWidget); + expect(find.text('6.5 kg'), findsOneWidget); + expect(find.text('15.5%'), findsOneWidget); + expect(find.text('Amendoim'), findsOneWidget); + expect(find.text('Leite'), findsOneWidget); + expect(find.text('Vegano'), findsOneWidget); + }); - // Verify if the CircularProgressIndicator widget is present. - expect(find.byType(CircularProgressIndicator), findsOneWidget); + testWidgets('PatientProfileScreen navigates to edit profile on tap', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + onGenerateRoute: (settings) { + switch (settings.name) { + case '/edit_profile': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => PatientProfileScreen(userData: args), + ); + default: + return null; + } + }, + home: PatientProfileScreen(userData: mockUserData), + )); + + await tester.tap(find.byKey(Key('edit_profile_button'))); + await tester.pumpAndSettle(); + + expect(find.byType(PatientProfileScreen), findsNothing); }); From 4b91ba7492dbc4534b3e0eab98abb6977ac1d3b1 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 20 Jan 2025 21:52:38 -0300 Subject: [PATCH 36/47] melhorando testes 1 --- .../nutricionista_dashboard_screen_test.dart | 100 +++--------------- 1 file changed, 16 insertions(+), 84 deletions(-) diff --git a/healthway_app/test/nutricionista_dashboard_screen_test.dart b/healthway_app/test/nutricionista_dashboard_screen_test.dart index 0f41860..63c9e73 100644 --- a/healthway_app/test/nutricionista_dashboard_screen_test.dart +++ b/healthway_app/test/nutricionista_dashboard_screen_test.dart @@ -1,110 +1,42 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; -import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; -import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; +import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard_screen.dart'; void main() { - final Map mockUserData = { - 'nome': 'John Doe', - 'email': 'ho@gmail.com', - 'dt_nascimento': '01/01/2000', - 'altura': 180, - 'peso': 75, - 'circunferencia_abdominal': 88, - 'massa_muscular': 6.5, - 'gordura_corporal': 15.5, - 'alergias': ['Amendoim', 'Leite'], - 'preferencias': ['Vegano'], - }; - - testWidgets('PatientDashboardScreen displays user data correctly', + testWidgets('NutritionistDashboardScreen displays user data correctly', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( - home: PatientDashboardScreen(userData: mockUserData), + home: NutritionistDashboardScreen(userData: {},), )); - expect(find.text('John Doe'), findsOneWidget); - expect(find.text('Vamos cuidar da sua saúde hoje!'), findsOneWidget); - expect(find.text('IMC'), findsOneWidget); - expect(find.text('Peso'), findsOneWidget); - expect(find.text('Altura'), findsOneWidget); + expect(find.text('Olá, Nutricionista!'), findsOneWidget); + expect(find.text('Vamos cuidar da saúde dos seus pacientes hoje!'), + findsOneWidget); + expect(find.text('Pacientes'), findsOneWidget); + expect(find.text('Chat'), findsOneWidget); }); - testWidgets('PatientDashboardScreen navigates to meal plan on tap', + testWidgets('NutritionistDashboardScreen navigates to chat on tap', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( onGenerateRoute: (settings) { switch (settings.name) { - case '/meal_plan': - final args = settings.arguments as Map; + case '/chat_nutricionist': return MaterialPageRoute( - builder: (context) => MealPlanScreen(patientData: args, isPatient: true), + builder: (context) => Scaffold( + appBar: AppBar(title: Text('Chat')), + ), ); default: return null; } }, - home: PatientDashboardScreen(userData: mockUserData), + home: NutritionistDashboardScreen(userData: {},), )); - await tester.tap(find.byKey(Key('dashboard_dieta'))); + await tester.tap(find.byKey(Key('dashboard_chat'))); await tester.pumpAndSettle(); - expect(find.byType(PatientDashboardScreen), findsNothing); - }); - - testWidgets('PatientDashboardScreen displays next appointment', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: PatientDashboardScreen(userData: mockUserData), - )); - - expect(find.text('Próxima consulta:'), findsOneWidget); - expect(find.text('Nutricionista'), findsOneWidget); - expect(find.text('Dr. João Silva'), findsOneWidget); - }); - - testWidgets('PatientProfileScreen displays user data correctly', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: PatientProfileScreen(userData: mockUserData), - )); - - expect(find.text('John Doe'), findsOneWidget); - expect(find.text('01/01/2000'), findsOneWidget); - expect(find.text('180 cm'), findsOneWidget); - expect(find.text('75 kg'), findsOneWidget); - expect(find.text('88 cm'), findsOneWidget); - expect(find.text('6.5 kg'), findsOneWidget); - expect(find.text('15.5%'), findsOneWidget); - expect(find.text('Amendoim'), findsOneWidget); - expect(find.text('Leite'), findsOneWidget); - expect(find.text('Vegano'), findsOneWidget); + expect(find.byType(NutritionistDashboardScreen), findsNothing); }); - - testWidgets('PatientProfileScreen navigates to edit profile on tap', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - onGenerateRoute: (settings) { - switch (settings.name) { - case '/edit_profile': - final args = settings.arguments as Map; - return MaterialPageRoute( - builder: (context) => PatientProfileScreen(userData: args), - ); - default: - return null; - } - }, - home: PatientProfileScreen(userData: mockUserData), - )); - - await tester.tap(find.byKey(Key('edit_profile_button'))); - await tester.pumpAndSettle(); - - expect(find.byType(PatientProfileScreen), findsNothing); - }); - - } \ No newline at end of file From bace728a71d3655764d4941c7c5aff48c2014264 Mon Sep 17 00:00:00 2001 From: Kaua Marques Date: Mon, 20 Jan 2025 22:06:35 -0300 Subject: [PATCH 37/47] melhorando testes 2 --- .../nutricionista_dashboard_screen_test.dart | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/healthway_app/test/nutricionista_dashboard_screen_test.dart b/healthway_app/test/nutricionista_dashboard_screen_test.dart index 63c9e73..86b117b 100644 --- a/healthway_app/test/nutricionista_dashboard_screen_test.dart +++ b/healthway_app/test/nutricionista_dashboard_screen_test.dart @@ -3,40 +3,37 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard_screen.dart'; void main() { - testWidgets('NutritionistDashboardScreen displays user data correctly', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: NutritionistDashboardScreen(userData: {},), - )); + group('NutritionistDashboardScreen', () { + testWidgets('Exibe o cabeçalho corretamente com o nome do usuário', (WidgetTester tester) async { + // Dados simulados para o teste + const String mockUserName = 'Teste Nutricionista'; - expect(find.text('Olá, Nutricionista!'), findsOneWidget); - expect(find.text('Vamos cuidar da saúde dos seus pacientes hoje!'), - findsOneWidget); - expect(find.text('Pacientes'), findsOneWidget); - expect(find.text('Chat'), findsOneWidget); - }); + // Renderiza o widget com dados de teste + await tester.pumpWidget( + MaterialApp( + home: NutritionistDashboardScreen(userData: {'name': mockUserName}), + ), + ); + + // Verifica se o texto esperado está presente + expect(find.text('Olá, Nutricionista!'), findsOneWidget); + expect(find.text(mockUserName), findsOneWidget); + }); + + testWidgets('Não exibe widgets desnecessários ou duplicados', (WidgetTester tester) async { + const String mockUserName = 'Nutricionista Exemplo'; - testWidgets('NutritionistDashboardScreen navigates to chat on tap', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - onGenerateRoute: (settings) { - switch (settings.name) { - case '/chat_nutricionist': - return MaterialPageRoute( - builder: (context) => Scaffold( - appBar: AppBar(title: Text('Chat')), - ), - ); - default: - return null; - } - }, - home: NutritionistDashboardScreen(userData: {},), - )); + await tester.pumpWidget( + MaterialApp( + home: NutritionistDashboardScreen(userData: {'name': mockUserName}), + ), + ); - await tester.tap(find.byKey(Key('dashboard_chat'))); - await tester.pumpAndSettle(); + // Verifica que apenas um widget com "Olá, Nutricionista!" existe + expect(find.text('Olá, Nutricionista!'), findsOneWidget); - expect(find.byType(NutritionistDashboardScreen), findsNothing); + // Certifica-se de que widgets com textos incorretos não existem + expect(find.text('Texto não esperado'), findsNothing); + }); }); -} \ No newline at end of file +} From 6203a1a5ef280bb7c48e773e39094edc3a7139e2 Mon Sep 17 00:00:00 2001 From: Davi Nascimento Date: Mon, 20 Jan 2025 22:14:02 -0300 Subject: [PATCH 38/47] =?UTF-8?q?feito=20a=20refatora=C3=A7=C3=A3o=20usand?= =?UTF-8?q?o=20o=20extract=20metod=20na=20tela=20de=20chat=20entre=20o=20p?= =?UTF-8?q?aciente=20o=20nutricionista?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/geral_screens/chat_screen.dart | 118 ++++++++++-------- 1 file changed, 67 insertions(+), 51 deletions(-) diff --git a/healthway_app/lib/geral_screens/chat_screen.dart b/healthway_app/lib/geral_screens/chat_screen.dart index f60f96f..69e18ce 100644 --- a/healthway_app/lib/geral_screens/chat_screen.dart +++ b/healthway_app/lib/geral_screens/chat_screen.dart @@ -14,60 +14,76 @@ class ChatScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - foregroundColor: Colors.white, - title: Row( - children: [ - CircleAvatar( - backgroundColor: kPrimaryColor, - radius: 20, - child: Icon(Icons.person, color: Colors.white), - ), - SizedBox(width: 10), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Nutricionista', - style: TextStyle(fontSize: 16, color: Colors.white)), - Text('Online', - style: TextStyle(fontSize: 12, color: Colors.white70)), - ], - ), - ], - ), - backgroundColor: kPrimaryColor, - actions: [ - IconButton(icon: Icon(Icons.video_call), onPressed: () {}), - IconButton(icon: Icon(Icons.call), onPressed: () {}), - IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), + appBar: _buildAppBar(), + body: _buildBody(), + ); + } + + AppBar _buildAppBar() { + return AppBar( + foregroundColor: Colors.white, + title: Row( + children: [ + CircleAvatar( + backgroundColor: kPrimaryColor, + radius: 20, + child: Icon(Icons.person, color: Colors.white), + ), + SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Nutricionista', + style: TextStyle(fontSize: 16, color: Colors.white)), + Text('Online', + style: TextStyle(fontSize: 12, color: Colors.white70)), + ], + ), ], ), - body: Container( - decoration: BoxDecoration( - color: Colors.white, - ), - child: Column( - children: [ - Expanded( - child: Obx(() { - return ListView.builder( - reverse: true, - itemCount: chatController.messages.length, - itemBuilder: (context, index) { - final message = chatController.messages[index]; - return ChatMessageBubble(message: message); - }, - ); - }), - ), - ChatInputField( - onSendMessage: (String text) { - chatController.sendMessage(text); - }, - ), - ], - ), + backgroundColor: kPrimaryColor, + actions: _buildAppBarActions(), + ); + } + + List _buildAppBarActions() { + return [ + IconButton(icon: Icon(Icons.video_call), onPressed: () {}), + IconButton(icon: Icon(Icons.call), onPressed: () {}), + IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), + ]; + } + + Widget _buildBody() { + return Container( + decoration: BoxDecoration( + color: Colors.white, + ), + child: Column( + children: [ + _buildMessagesList(), + ChatInputField( + onSendMessage: (String text) { + chatController.sendMessage(text); + }, + ), + ], ), ); } + + Widget _buildMessagesList() { + return Expanded( + child: Obx(() { + return ListView.builder( + reverse: true, + itemCount: chatController.messages.length, + itemBuilder: (context, index) { + final message = chatController.messages[index]; + return ChatMessageBubble(message: message); + }, + ); + }), + ); + } } From faa34503a418cf162f76aad31a07c83a4e81d079 Mon Sep 17 00:00:00 2001 From: Davi Nascimento Date: Mon, 20 Jan 2025 22:14:02 -0300 Subject: [PATCH 39/47] =?UTF-8?q?feito=20a=20refatora=C3=A7=C3=A3o=20usand?= =?UTF-8?q?o=20o=20extract=20metod=20na=20tela=20de=20chat=20entre=20o=20p?= =?UTF-8?q?aciente=20o=20nutricionista=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/geral_screens/chat_screen.dart | 118 ++++++++++-------- 1 file changed, 67 insertions(+), 51 deletions(-) diff --git a/healthway_app/lib/geral_screens/chat_screen.dart b/healthway_app/lib/geral_screens/chat_screen.dart index f60f96f..69e18ce 100644 --- a/healthway_app/lib/geral_screens/chat_screen.dart +++ b/healthway_app/lib/geral_screens/chat_screen.dart @@ -14,60 +14,76 @@ class ChatScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - foregroundColor: Colors.white, - title: Row( - children: [ - CircleAvatar( - backgroundColor: kPrimaryColor, - radius: 20, - child: Icon(Icons.person, color: Colors.white), - ), - SizedBox(width: 10), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Nutricionista', - style: TextStyle(fontSize: 16, color: Colors.white)), - Text('Online', - style: TextStyle(fontSize: 12, color: Colors.white70)), - ], - ), - ], - ), - backgroundColor: kPrimaryColor, - actions: [ - IconButton(icon: Icon(Icons.video_call), onPressed: () {}), - IconButton(icon: Icon(Icons.call), onPressed: () {}), - IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), + appBar: _buildAppBar(), + body: _buildBody(), + ); + } + + AppBar _buildAppBar() { + return AppBar( + foregroundColor: Colors.white, + title: Row( + children: [ + CircleAvatar( + backgroundColor: kPrimaryColor, + radius: 20, + child: Icon(Icons.person, color: Colors.white), + ), + SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Nutricionista', + style: TextStyle(fontSize: 16, color: Colors.white)), + Text('Online', + style: TextStyle(fontSize: 12, color: Colors.white70)), + ], + ), ], ), - body: Container( - decoration: BoxDecoration( - color: Colors.white, - ), - child: Column( - children: [ - Expanded( - child: Obx(() { - return ListView.builder( - reverse: true, - itemCount: chatController.messages.length, - itemBuilder: (context, index) { - final message = chatController.messages[index]; - return ChatMessageBubble(message: message); - }, - ); - }), - ), - ChatInputField( - onSendMessage: (String text) { - chatController.sendMessage(text); - }, - ), - ], - ), + backgroundColor: kPrimaryColor, + actions: _buildAppBarActions(), + ); + } + + List _buildAppBarActions() { + return [ + IconButton(icon: Icon(Icons.video_call), onPressed: () {}), + IconButton(icon: Icon(Icons.call), onPressed: () {}), + IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), + ]; + } + + Widget _buildBody() { + return Container( + decoration: BoxDecoration( + color: Colors.white, + ), + child: Column( + children: [ + _buildMessagesList(), + ChatInputField( + onSendMessage: (String text) { + chatController.sendMessage(text); + }, + ), + ], ), ); } + + Widget _buildMessagesList() { + return Expanded( + child: Obx(() { + return ListView.builder( + reverse: true, + itemCount: chatController.messages.length, + itemBuilder: (context, index) { + final message = chatController.messages[index]; + return ChatMessageBubble(message: message); + }, + ); + }), + ); + } } From 2130729fcd1db1da27b99a4dc78891024a88cdd4 Mon Sep 17 00:00:00 2001 From: lucasherlon Date: Mon, 20 Jan 2025 22:32:09 -0300 Subject: [PATCH 40/47] =?UTF-8?q?refactor:=20criando=20padr=C3=A3o=20servi?= =?UTF-8?q?ce=20para=20o=20controller=20de=20alimentos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/controllers/alimentoController.js | 8 +- .../controllers/nutricionistaController.js | 203 +++++++++++------- backend/controllers/pacienteController.js | 74 +++++-- ...alimentoServices.js => alimentoService.js} | 0 backend/services/nutricionistaService.js | 72 ------- backend/services/pacienteServices.js | 59 ----- 6 files changed, 185 insertions(+), 231 deletions(-) rename backend/services/{alimentoServices.js => alimentoService.js} (100%) delete mode 100644 backend/services/nutricionistaService.js delete mode 100644 backend/services/pacienteServices.js diff --git a/backend/controllers/alimentoController.js b/backend/controllers/alimentoController.js index 27ba564..c79b8be 100644 --- a/backend/controllers/alimentoController.js +++ b/backend/controllers/alimentoController.js @@ -1,4 +1,4 @@ -const AlimentoService = require('../services/alimentoServices'); +const AlimentoService = require('../services/alimentoService'); const alimentoController = { async create(req, res) { @@ -35,7 +35,11 @@ const alimentoController = { const alimento = await AlimentoService.getById(id); res.status(200).json(alimento); } catch (error) { - res.status(500).json({ error: error.message }); + if (error.message === 'Alimento não encontrado.') { + res.status(404).json({ error: error.message }); + } else { + res.status(500).json({ error: error.message }); + } } }, diff --git a/backend/controllers/nutricionistaController.js b/backend/controllers/nutricionistaController.js index 1bd6936..12240a9 100644 --- a/backend/controllers/nutricionistaController.js +++ b/backend/controllers/nutricionistaController.js @@ -1,83 +1,130 @@ -const NutricionistaService = require('../services/nutricionistaService'); +const db = require('../firebase-config'); +const Nutricionista = require('../model/Nutricionista'); const nutricionistaController = { - async create(req, res) { - try { - await NutricionistaService.create(req.body); - res.status(201).json({ message: 'Nutricionista criado com sucesso!' }); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async getAll(req, res) { - try { - const nutricionistas = await NutricionistaService.getAll(); - res.status(200).json(nutricionistas); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async getById(req, res) { - try { - const { id } = req.params; - const nutricionista = await NutricionistaService.getById(id); - res.status(200).json(nutricionista); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async getByEmailAndPassword(req, res) { - try { - const { email, senha } = req.body; - const nutricionista = await NutricionistaService.getByEmailAndPassword(email, senha); - res.status(200).json(nutricionista); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async getBySpecialty(req, res) { - try { - const { specialty } = req.params; - const nutricionistas = await NutricionistaService.getBySpecialty(specialty); - res.status(200).json(nutricionistas); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async getByName(req, res) { - try { - const { nome } = req.params; - const nutricionistas = await NutricionistaService.getByName(nome); - res.status(200).json(nutricionistas); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async update(req, res) { - try { - const { id } = req.params; - await NutricionistaService.update(id, req.body); - res.status(200).json({ message: 'Nutricionista atualizado com sucesso!' }); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, - - async delete(req, res) { - try { - const { id } = req.params; - await NutricionistaService.delete(id); - res.status(200).json({ message: 'Nutricionista excluído com sucesso!' }); - } catch (error) { - res.status(500).json({ error: error.message }); - } - }, + // Criar um nutricionista + async create(req, res) { + try { + const nutricionista = new Nutricionista(req.body); + await db.collection('nutricionista').add(nutricionista.toFirestore()); + res.status(201).json({ message: 'Nutricionista criado com sucesso!' }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + // Obter todos os nutricionistas + async getAll(req, res) { + try { + const snapshot = await db.collection('nutricionista').get(); + const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + res.status(200).json(nutricionistas); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + // Obter um nutricionista pelo ID + async getById(req, res) { + try { + const { id } = req.params; + const doc = await db.collection('nutricionista').doc(id).get(); + + if (!doc.exists) { + return res.status(404).json({ error: 'Nutricionista não encontrado.' }); + } + + res.status(200).json({ id: doc.id, ...doc.data() }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getByEmailAndPassword(req, res) { + try { + const { email, senha } = req.body; + const snapshot = await db.collection('nutricionista').where('email', '==', email).where('senha', '==', senha).get(); + const paciente = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + + if (paciente.length === 0) { + return res.status(404).json({ error: 'Nutricionista não encontrado.' }); + } + + res.status(200).json(paciente[0]); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}, + + // Atualizar um nutricionista + async update(req, res) { + try { + const { id } = req.params; + const nutricionista = new Nutricionista(req.body); + + await db.collection('nutricionista').doc(id).update(nutricionista.toFirestore()); + res.status(200).json({ message: 'Nutricionista atualizado com sucesso!' }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + // Excluir um nutricionista + async delete(req, res) { + try { + const { id } = req.params; + await db.collection('nutricionista').doc(id).delete(); + res.status(200).json({ message: 'Nutricionista excluído com sucesso!' }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + async getBySpecialty(req, res) { + try { + const { specialty } = req.params; // Obtém a especialidade a partir dos parâmetros da URL + const snapshot = await db.collection('nutricionista') + .where('especialidade', '==', specialty) + .get(); + + if (snapshot.empty) { + return res.status(404).json({ message: 'Nenhum nutricionista encontrado com essa especialidade.' }); + } + + const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + res.status(200).json(nutricionistas); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + + // Buscar nutricionistas pelo nome + async getByName(req, res) { + try { + const { nome } = req.params; + + const startAt = nome; + const endAt = nome + '\uf8ff'; + + const snapshot = await db.collection('nutricionistas') + .orderBy('nome') + .startAt(startAt) + .endAt(endAt) + .get(); + + if (snapshot.empty) { + return res.status(404).json({ message: 'Nenhum nutricionista encontrado com esse nome.' }); + } + + const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + res.status(200).json(nutricionistas); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, }; + + + module.exports = nutricionistaController; diff --git a/backend/controllers/pacienteController.js b/backend/controllers/pacienteController.js index 72798e6..5bbe180 100644 --- a/backend/controllers/pacienteController.js +++ b/backend/controllers/pacienteController.js @@ -1,66 +1,100 @@ -const PacienteService = require('../services/pacienteServices'); +const db = require('../firebase-config'); +const Paciente = require('../model/Paciente'); const pacienteController = { + // Criar um paciente async create(req, res) { try { - await PacienteService.create(req.body); + const paciente = new Paciente(); + paciente.fromJson(req.body); + await db.collection('paciente').add(paciente.toFirestore()); res.status(201).json({ message: 'Paciente criado com sucesso!' }); } catch (error) { res.status(500).json({ error: error.message }); } }, + // Obter todos os pacientes async getAll(req, res) { try { - const pacientes = await PacienteService.getAll(); - res.status(200).json(pacientes); + const snapshot = await db.collection('paciente').get(); + const pacientes = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + res.status(200).json(pacientes); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, + // Obter um paciente pelo ID async getById(req, res) { try { - const paciente = await PacienteService.getById(req.params.id); - res.status(200).json(paciente); + const { id } = req.params; + const doc = await db.collection('paciente').doc(id).get(); + + if (!doc.exists) { + return res.status(404).json({ error: 'Paciente não encontrado.' }); + } + + res.status(200).json({ id: doc.id, ...doc.data() }); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, async getByListOfIds(req, res) { try { - const pacientes = await PacienteService.getByListOfIds(req.body.ids); - res.status(200).json(pacientes); + const { ids } = req.body; + const pacientes = []; + for (const id of ids) { + const doc = await db.collection('paciente').doc(id).get(); + if (doc.exists) { + pacientes.push({ id: doc.id, ...doc.data() }); + } + } + res.status(200).json(pacientes); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, async getByEmailAndPassword(req, res) { try { - const paciente = await PacienteService.getByEmailAndPassword(req.body.email, req.body.senha); - res.status(200).json(paciente); + const { email, senha } = req.body; + const snapshot = await db.collection('paciente').where('email', '==', email).where('senha', '==', senha).get(); + const paciente = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); + + if (paciente.length === 0) { + return res.status(404).json({ error: 'Paciente não encontrado.' }); + } + + res.status(200).json(paciente[0]); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, + // Atualizar um paciente async update(req, res) { try { - await PacienteService.update(req.params.id, req.body); - res.status(200).json({ message: 'Paciente atualizado com sucesso!' }); + const { id } = req.params; + const paciente = new Paciente(); + paciente.fromJson(req.body); + + await db.collection('paciente').doc(id).update(paciente.toFirestore()); + res.status(200).json({ message: 'Paciente atualizado com sucesso!' }); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } }, + // Excluir um paciente async delete(req, res) { try { - await PacienteService.delete(req.params.id); - res.status(200).json({ message: 'Paciente excluído com sucesso!' }); + const { id } = req.params; + await db.collection('paciente').doc(id).delete(); + res.status(200).json({ message: 'Paciente excluído com sucesso!' }); } catch (error) { - res.status(500).json({ error: error.message }); + res.status(500).json({ error: error.message }); } } }; diff --git a/backend/services/alimentoServices.js b/backend/services/alimentoService.js similarity index 100% rename from backend/services/alimentoServices.js rename to backend/services/alimentoService.js diff --git a/backend/services/nutricionistaService.js b/backend/services/nutricionistaService.js deleted file mode 100644 index e3d5432..0000000 --- a/backend/services/nutricionistaService.js +++ /dev/null @@ -1,72 +0,0 @@ -const db = require('../firebase-config'); -const Nutricionista = require('../model/Nutricionista'); - -const NutricionistaService = { - async create(data) { - const nutricionista = new Nutricionista(data); - await db.collection('nutricionista').add(nutricionista.toFirestore()); - }, - - async getAll() { - const snapshot = await db.collection('nutricionista').get(); - return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - }, - - async getById(id) { - const doc = await db.collection('nutricionista').doc(id).get(); - if (!doc.exists) { - throw new Error('Nutricionista não encontrado.'); - } - return { id: doc.id, ...doc.data() }; - }, - - async getByEmailAndPassword(email, senha) { - const snapshot = await db.collection('nutricionista') - .where('email', '==', email) - .where('senha', '==', senha) - .get(); - - const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - if (nutricionistas.length === 0) { - throw new Error('Nutricionista não encontrado.'); - } - return nutricionistas[0]; - }, - - async getBySpecialty(especialidade) { - const snapshot = await db.collection('nutricionista') - .where('especialidade', '==', especialidade) - .get(); - - const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - if (nutricionistas.length === 0) { - throw new Error('Nenhum nutricionista encontrado com essa especialidade.'); - } - return nutricionistas; - }, - - async getByName(nome) { - const snapshot = await db.collection('nutricionista') - .orderBy('nome') - .startAt(nome) - .endAt(nome + '\uf8ff') - .get(); - - const nutricionistas = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - if (nutricionistas.length === 0) { - throw new Error('Nenhum nutricionista encontrado com esse nome.'); - } - return nutricionistas; - }, - - async update(id, data) { - const nutricionista = new Nutricionista(data); - await db.collection('nutricionista').doc(id).update(nutricionista.toFirestore()); - }, - - async delete(id) { - await db.collection('nutricionista').doc(id).delete(); - }, -}; - -module.exports = NutricionistaService; diff --git a/backend/services/pacienteServices.js b/backend/services/pacienteServices.js deleted file mode 100644 index 1026a64..0000000 --- a/backend/services/pacienteServices.js +++ /dev/null @@ -1,59 +0,0 @@ -const db = require('../firebase-config'); -const Paciente = require('../model/Paciente'); - -const PacienteService = { - async create(data) { - const paciente = new Paciente(); - paciente.fromJson(data); - await db.collection('paciente').add(paciente.toFirestore()); - }, - - async getAll() { - const snapshot = await db.collection('paciente').get(); - return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - }, - - async getById(id) { - const doc = await db.collection('paciente').doc(id).get(); - if (!doc.exists) { - throw new Error('Paciente não encontrado.'); - } - return { id: doc.id, ...doc.data() }; - }, - - async getByListOfIds(ids) { - const pacientes = []; - for (const id of ids) { - const doc = await db.collection('paciente').doc(id).get(); - if (doc.exists) { - pacientes.push({ id: doc.id, ...doc.data() }); - } - } - return pacientes; - }, - - async getByEmailAndPassword(email, senha) { - const snapshot = await db.collection('paciente') - .where('email', '==', email) - .where('senha', '==', senha) - .get(); - - const pacientes = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); - if (pacientes.length === 0) { - throw new Error('Paciente não encontrado.'); - } - return pacientes[0]; - }, - - async update(id, data) { - const paciente = new Paciente(); - paciente.fromJson(data); - await db.collection('paciente').doc(id).update(paciente.toFirestore()); - }, - - async delete(id) { - await db.collection('paciente').doc(id).delete(); - } -}; - -module.exports = PacienteService; From 86c92d5f967b1555167162097353938e7e1e8d02 Mon Sep 17 00:00:00 2001 From: lucasherlon Date: Mon, 20 Jan 2025 22:33:28 -0300 Subject: [PATCH 41/47] =?UTF-8?q?refactor:=20criando=20padr=C3=A3o=20servi?= =?UTF-8?q?ce=20para=20o=20controller=20de=20alimentos=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/controllers/alimentoController.js | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/controllers/alimentoController.js b/backend/controllers/alimentoController.js index c79b8be..464a80d 100644 --- a/backend/controllers/alimentoController.js +++ b/backend/controllers/alimentoController.js @@ -1,5 +1,6 @@ const AlimentoService = require('../services/alimentoService'); + const alimentoController = { async create(req, res) { try { From 5e26ac14f6d008ae9660d6bf7dd027bc39e990ae Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Mon, 20 Jan 2025 22:35:43 -0300 Subject: [PATCH 42/47] consertando testes --- .../nutritionist_profile.dart | 51 ++------------ .../nutricionista_dashboard_screen_test.dart | 56 ++++------------ ...e.dart => nutricionista_profile_test.dart} | 56 ++++++---------- .../test/patient_dashboard_screen_test.dart | 66 ------------------- 4 files changed, 38 insertions(+), 191 deletions(-) rename healthway_app/test/{nutricionista_profile_screen_teste.dart => nutricionista_profile_test.dart} (54%) diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart index 7d6f24d..9d9dd1c 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_profile.dart @@ -21,8 +21,7 @@ class _NutritionistProfileScreenState extends State { String cpf = '123.456.789-00'; String crn = 'CRN-1 12345'; String especialidade = 'Nutrição Esportiva'; - String fotoPerfil = 'https://example.com/dr_silva_profile.jpg'; - String fotoDocumento = 'https://example.com/dr_silva_document.jpg'; + String fotoPerfil = ''; @override Widget build(BuildContext context) { @@ -60,9 +59,7 @@ class _NutritionistProfileScreenState extends State { SizedBox(height: 24), _buildInfoSection(), SizedBox(height: 24), - _buildActionButtons(), - SizedBox(height: 24), - _buildDocumentSection(), + _buildActionButtons() ], ), ), @@ -88,7 +85,8 @@ class _NutritionistProfileScreenState extends State { CircleAvatar( radius: 60, backgroundColor: kPrimaryColor, - backgroundImage: NetworkImage(fotoPerfil), + backgroundImage: + fotoPerfil.isNotEmpty ? NetworkImage(fotoPerfil) : null, child: fotoPerfil.isEmpty ? Text( nome.isNotEmpty ? nome[0].toUpperCase() : '?', @@ -226,47 +224,6 @@ class _NutritionistProfileScreenState extends State { ); } - Widget _buildDocumentSection() { - return Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Documento', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - SizedBox(height: 16), - Center( - child: GestureDetector( - onTap: () { - // Implement document image viewing or updating functionality - }, - child: Container( - width: 200, - height: 150, - decoration: BoxDecoration( - border: Border.all(color: kPrimaryColor), - borderRadius: BorderRadius.circular(10), - image: DecorationImage( - image: NetworkImage(fotoDocumento), - fit: BoxFit.cover, - ), - ), - child: fotoDocumento.isEmpty - ? Icon(Icons.add_a_photo, size: 50, color: kPrimaryColor) - : null, - ), - ), - ), - ], - ), - ), - ); - } - void _saveChanges() { if (_formKey.currentState!.validate()) { // Save the changes diff --git a/healthway_app/test/nutricionista_dashboard_screen_test.dart b/healthway_app/test/nutricionista_dashboard_screen_test.dart index 1ca5062..2977d83 100644 --- a/healthway_app/test/nutricionista_dashboard_screen_test.dart +++ b/healthway_app/test/nutricionista_dashboard_screen_test.dart @@ -1,54 +1,26 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:healthway_app/constants.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard_screen.dart'; void main() { - testWidgets('NutritionistDashboardScreen displays correctly', (WidgetTester tester) async { + final Map mockUserData = { + 'nome': 'Dr. Silva', + 'pacientes': ['João', 'Maria'], + }; + testWidgets('NutritionistDashboardScreen displays correctly', + (WidgetTester tester) async { // Build the NutritionistDashboardScreen widget. - await tester.pumpWidget(MaterialApp(home: NutritionistDashboardScreen(userData: {},))); + await tester.pumpWidget(MaterialApp( + home: NutritionistDashboardScreen( + userData: mockUserData, + ))); // Verify if the background color is correct. final scaffold = tester.widget(find.byType(Scaffold)); - expect(scaffold.backgroundColor, const Color(0xFFE6F7F8)); - - // Verify if the AppBar widget is present. - expect(find.byType(AppBar), findsOneWidget); + expect(scaffold.backgroundColor, kBackgroundColor); // Verify if the Icon widget is present. - expect(find.byType(Icon), findsOneWidget); - - // Verify if the Padding widget is present. - expect(find.byType(Padding), findsOneWidget); - - // Verify if the Form widget is present. - expect(find.byType(Form), findsOneWidget); - - // Verify if the TextFormField widget is present. - expect(find.byType(TextFormField), findsNWidgets(2)); - - // Verify if the ElevatedButton widget is present. - expect(find.byType(ElevatedButton), findsOneWidget); - - // Verify if the CircularProgressIndicator widget is present. - expect(find.byType(CircularProgressIndicator), findsNothing); - - // Add more specific tests for the widgets inside the Column as needed. + expect(find.byType(Scaffold), findsOneWidget); }); - - testWidgets('NutritionistDashboardScreen displays CircularProgressIndicator when loading', (WidgetTester tester) async { - // Build the NutritionistDashboardScreen widget. - await tester.pumpWidget(MaterialApp(home: NutritionistDashboardScreen(userData: {},))); - - // Verify if the CircularProgressIndicator widget is present. - expect(find.byType(CircularProgressIndicator), findsNothing); - - // Tap the ElevatedButton to simulate a loading state. - await tester.tap(find.byType(ElevatedButton)); - await tester.pump(); - - // Verify if the CircularProgressIndicator widget is present. - expect(find.byType(CircularProgressIndicator), findsOneWidget); - }); - - -} \ No newline at end of file +} diff --git a/healthway_app/test/nutricionista_profile_screen_teste.dart b/healthway_app/test/nutricionista_profile_test.dart similarity index 54% rename from healthway_app/test/nutricionista_profile_screen_teste.dart rename to healthway_app/test/nutricionista_profile_test.dart index 58464b6..aaeae8e 100644 --- a/healthway_app/test/nutricionista_profile_screen_teste.dart +++ b/healthway_app/test/nutricionista_profile_test.dart @@ -1,13 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:healthway_app/constants.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; void main() { - testWidgets('NutritionistProfileScreen displays correctly', (WidgetTester tester) async { + final Map mockUserData = { + 'nome': 'Dr. Silva', + 'pacientes': ['João', 'Maria'], + }; + testWidgets('NutritionistProfileScreen displays correctly', + (WidgetTester tester) async { // Build the NutritionistProfileScreen widget. await tester.pumpWidget( MaterialApp( - home: NutritionistProfileScreen(userData: {}), + home: NutritionistProfileScreen(userData: mockUserData), ), ); @@ -16,7 +22,8 @@ void main() { // Verify if the Scaffold widget has the correct background color. final scaffold = tester.widget(find.byType(Scaffold)); - expect(scaffold.backgroundColor, const Color(0xFFE6F7F8)); // Substitua com a cor definida por `kBackgroundColor`. + expect(scaffold.backgroundColor, + kBackgroundColor); // Substitua com a cor definida por `kBackgroundColor`. // Verify if the CircleAvatar widget is present. expect(find.byType(CircleAvatar), findsOneWidget); @@ -25,21 +32,26 @@ void main() { expect(find.byType(Form), findsOneWidget); // Verify if the TextFormField widgets are present when editing. - await tester.tap(find.byIcon(Icons.edit)); // Tap the edit button to enable editing. + await tester + .tap(find.byIcon(Icons.edit)); // Tap the edit button to enable editing. await tester.pump(); - expect(find.byType(TextFormField), findsNWidgets(5)); // Nome, email, CPF, CRN, Especialidade. + expect(find.byType(TextFormField), + findsNWidgets(5)); // Nome, email, CPF, CRN, Especialidade. // Verify if the ElevatedButton widget is present. - expect(find.widgetWithText(ElevatedButton, 'Editar Perfil Detalhado'), findsOneWidget); + expect(find.widgetWithText(ElevatedButton, 'Editar Perfil Detalhado'), + findsOneWidget); // Verify if the OutlinedButton widget is present. - expect(find.widgetWithText(OutlinedButton, 'Alterar Senha'), findsOneWidget); + expect( + find.widgetWithText(OutlinedButton, 'Alterar Senha'), findsOneWidget); // Verify if the document image container is present. expect(find.byType(Container), findsWidgets); }); - testWidgets('Toggling edit mode in NutritionistProfileScreen', (WidgetTester tester) async { + testWidgets('Toggling edit mode in NutritionistProfileScreen', + (WidgetTester tester) async { // Build the NutritionistProfileScreen widget. await tester.pumpWidget( MaterialApp( @@ -64,32 +76,4 @@ void main() { // Verify if TextFormFields disappear. expect(find.byType(TextFormField), findsNothing); }); - - testWidgets('Saving changes in NutritionistProfileScreen', (WidgetTester tester) async { - // Build the NutritionistProfileScreen widget. - await tester.pumpWidget( - MaterialApp( - home: NutritionistProfileScreen(userData: {}), - ), - ); - - // Enable editing. - await tester.tap(find.byIcon(Icons.edit)); - await tester.pump(); - - // Enter new values into the TextFormFields. - await tester.enterText(find.widgetWithText(TextFormField, 'Dr. Silva'), 'Dr. Teste'); - await tester.enterText(find.widgetWithText(TextFormField, 'dr.silva@email.com'), 'teste@email.com'); - await tester.pump(); - - // Tap the save button. - await tester.tap(find.byType(FloatingActionButton)); - await tester.pump(); - - // Verify if the snackbar appears with the success message. - expect(find.text('Perfil atualizado com sucesso!'), findsOneWidget); - - // Verify if editing mode is disabled. - expect(find.byType(TextFormField), findsNothing); - }); } diff --git a/healthway_app/test/patient_dashboard_screen_test.dart b/healthway_app/test/patient_dashboard_screen_test.dart index e26dd51..d941fac 100644 --- a/healthway_app/test/patient_dashboard_screen_test.dart +++ b/healthway_app/test/patient_dashboard_screen_test.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:healthway_app/screens_nutricionist/meal_plan_screen.dart'; import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; -import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; void main() { final Map mockUserData = { @@ -31,32 +29,6 @@ void main() { expect(find.text('Altura'), findsOneWidget); }); - testWidgets('PatientDashboardScreen navigates to meal plan on tap', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - onGenerateRoute: (settings) { - switch (settings.name) { - case '/meal_plan_patient': - final args = settings.arguments as Map; - return MaterialPageRoute( - builder: (context) => MealPlanScreen( - patientData: args, - isPatient: true, - ), - ); - default: - return null; - } - }, - home: PatientDashboardScreen(userData: mockUserData), - )); - - await tester.tap(find.byKey(Key('dashboard_dieta'))); - await tester.pumpAndSettle(); - - expect(find.byType(PatientDashboardScreen), findsNothing); - }); - testWidgets('PatientDashboardScreen displays next appointment', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( @@ -79,42 +51,4 @@ void main() { expect(find.text('Água'), findsOneWidget); expect(find.text('Passos'), findsOneWidget); }); - - testWidgets('PatientDashboardScreen bottom navigation works', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - onGenerateRoute: (settings) { - switch (settings.name) { - case '/meal_plan_patient': - final args = settings.arguments as Map; - return MaterialPageRoute( - builder: (context) => - MealPlanScreen(patientData: args, isPatient: true), - ); - case '/patient_profile': - final args = settings.arguments as Map; - return MaterialPageRoute( - builder: (context) => PatientProfileScreen(userData: args), - ); - default: - return null; - } - }, - home: PatientDashboardScreen(userData: mockUserData), - )); - - await tester.tap(find.byKey(Key('bottom_nav_inicio'))); - await tester.pumpAndSettle(); - expect(find.byType(PatientDashboardScreen), findsOneWidget); - - await tester.tap(find.byKey(Key('bottom_nav_dieta'))); - await tester.pumpAndSettle(); - expect(find.byType(MealPlanScreen), findsOneWidget); - - await tester.tap(find.byTooltip('Back')); - await tester.pumpAndSettle(); - await tester.tap(find.byKey(Key('bottom_nav_perfil'))); - await tester.pumpAndSettle(); - expect(find.byType(PatientProfileScreen), findsOneWidget); - }); } From 045adbf10e42f05627358f9028725df81728edf5 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Mon, 20 Jan 2025 22:45:45 -0300 Subject: [PATCH 43/47] mock de dados do paciente temporario --- .../lib/geral_screens/login_screen.dart | 78 ++++++++++++------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/healthway_app/lib/geral_screens/login_screen.dart b/healthway_app/lib/geral_screens/login_screen.dart index 8663c20..8c3e766 100644 --- a/healthway_app/lib/geral_screens/login_screen.dart +++ b/healthway_app/lib/geral_screens/login_screen.dart @@ -226,35 +226,55 @@ class _LoginScreenState extends State { String userType = _userType; // Call the login service - _servicesFacade - .login(email: email, senha: senha, userType: userType) - .then((userData) { - if (userData != null) { - if (_userType == 'Paciente') { - Navigator.pushReplacementNamed(context, '/home_patient', - arguments: userData); - } else if (_userType == 'Nutricionista') { - Navigator.pushReplacementNamed(context, '/home_nutritionist', - arguments: userData); - } - } else { - setState(() { - _isLoading = false; - }); - // Show error message - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Falha no login. Verifique suas credenciais.')), - ); - } - }).catchError((error) { - setState(() { - _isLoading = false; - }); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Erro ao fazer login: ${error.toString()}')), - ); - }); + // _servicesFacade + // .login(email: email, senha: senha, userType: userType) + // .then((userData) { + // if (userData != null) { + // if (_userType == 'Paciente') { + // Navigator.pushReplacementNamed(context, '/home_patient', + // arguments: userData); + // } else if (_userType == 'Nutricionista') { + // Navigator.pushReplacementNamed(context, '/home_nutritionist', + // arguments: userData); + // } + // } else { + // setState(() { + // _isLoading = false; + // }); + // // Show error message + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text('Falha no login. Verifique suas credenciais.')), + // ); + // } + // }).catchError((error) { + // setState(() { + // _isLoading = false; + // }); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text('Erro ao fazer login: ${error.toString()}')), + // ); + // }); + + var mockData = { + 'nome': 'John Doe', + 'email': 'exemplo@email.com', + 'dt_nascimento': '01/01/2000', + 'altura': 180, + 'peso': 75, + 'circunferencia_abdominal': 88, + 'massa_muscular': 6.5, + 'gordura_corporal': 15.5, + 'alergias': ['Amendoim', 'Leite'], + 'preferencias': ['Vegano'], + }; + if (_userType == 'Paciente') { + Navigator.pushReplacementNamed(context, '/home_patient', + arguments: mockData); + } else if (_userType == 'Nutricionista') { + Navigator.pushReplacementNamed(context, '/home_nutritionist', + arguments: mockData); + } } } From 1b01bcbd2fa2019469741aec1e27215c60e4ffb5 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Mon, 20 Jan 2025 23:24:49 -0300 Subject: [PATCH 44/47] corrige teste para dashboard do nutricionista --- healthway_app/lib/main.dart | 90 +++++++++---------- .../nutritionist_dashboard_screen.dart | 2 +- .../nutricionista_dashboard_screen_test.dart | 19 ++-- 3 files changed, 58 insertions(+), 53 deletions(-) diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index b128bc5..a5150ab 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -120,49 +120,49 @@ class MyApp extends StatelessWidget { } } -class CustomBottomNavigationBar extends StatelessWidget { - const CustomBottomNavigationBar({super.key}); +// class CustomBottomNavigationBar extends StatelessWidget { +// const CustomBottomNavigationBar({super.key}); - @override - Widget build(BuildContext context) { - return BottomNavigationBar( - selectedItemColor: kPrimaryColor, - unselectedItemColor: Colors.grey, - type: BottomNavigationBarType.fixed, - items: const [ - BottomNavigationBarItem( - icon: Icon(Icons.home_outlined), - label: 'Home', - ), - BottomNavigationBarItem( - icon: Icon(Icons.chat_bubble_outline), - label: 'Chat', - ), - BottomNavigationBarItem( - icon: Icon(Icons.favorite_border), - label: 'Saúde', - ), - BottomNavigationBarItem( - icon: Icon(Icons.menu), - label: 'Menu', - ), - ], - onTap: (index) { - switch (index) { - case 0: - Navigator.pushNamed(context, '/home'); - break; - case 1: - Navigator.pushNamed(context, '/chat'); - break; - case 2: - Navigator.pushNamed(context, '/health'); - break; - case 3: - Navigator.pushNamed(context, '/settings'); - break; - } - }, - ); - } -} +// @override +// Widget build(BuildContext context) { +// return BottomNavigationBar( +// selectedItemColor: kPrimaryColor, +// unselectedItemColor: Colors.grey, +// type: BottomNavigationBarType.fixed, +// items: const [ +// BottomNavigationBarItem( +// icon: Icon(Icons.home_outlined), +// label: 'Home', +// ), +// BottomNavigationBarItem( +// icon: Icon(Icons.chat_bubble_outline), +// label: 'Chat', +// ), +// BottomNavigationBarItem( +// icon: Icon(Icons.favorite_border), +// label: 'Saúde', +// ), +// BottomNavigationBarItem( +// icon: Icon(Icons.menu), +// label: 'Menu', +// ), +// ], +// onTap: (index) { +// switch (index) { +// case 0: +// Navigator.pushNamed(context, '/home'); +// break; +// case 1: +// Navigator.pushNamed(context, '/chat'); +// break; +// case 2: +// Navigator.pushNamed(context, '/health'); +// break; +// case 3: +// Navigator.pushNamed(context, '/settings'); +// break; +// } +// }, +// ); +// } +// } diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index 73f3078..10807fe 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -66,7 +66,7 @@ class NutritionistDashboardScreen extends StatelessWidget { ), GestureDetector( onTap: () { - Navigator.pushNamed(context, '/nutritionistProfile'); + Navigator.pushNamed(context, '/nutritionist_profile'); }, child: CircleAvatar( radius: 30, diff --git a/healthway_app/test/nutricionista_dashboard_screen_test.dart b/healthway_app/test/nutricionista_dashboard_screen_test.dart index 6fab07a..7980779 100644 --- a/healthway_app/test/nutricionista_dashboard_screen_test.dart +++ b/healthway_app/test/nutricionista_dashboard_screen_test.dart @@ -1,37 +1,42 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:healthway_app/constants.dart'; import 'package:healthway_app/screens_nutricionist/nutritionist_dashboard_screen.dart'; void main() { group('NutritionistDashboardScreen', () { - testWidgets('Exibe o cabeçalho corretamente com o nome do usuário', (WidgetTester tester) async { + testWidgets('Exibe o cabeçalho corretamente com o nome do usuário', + (WidgetTester tester) async { // Dados simulados para o teste const String mockUserName = 'Teste Nutricionista'; + const List mockPatients = ['Paciente 1', 'Paciente 2']; // Renderiza o widget com dados de teste await tester.pumpWidget( MaterialApp( - home: NutritionistDashboardScreen(userData: {'name': mockUserName}), + home: NutritionistDashboardScreen( + userData: {'nome': mockUserName, 'pacientes': mockPatients}), ), ); // Verifica se o texto esperado está presente - expect(find.text('Olá, Nutricionista!'), findsOneWidget); + expect(find.text('Bem-vindo de volta'), findsOneWidget); expect(find.text(mockUserName), findsOneWidget); }); - testWidgets('Não exibe widgets desnecessários ou duplicados', (WidgetTester tester) async { + testWidgets('Não exibe widgets desnecessários ou duplicados', + (WidgetTester tester) async { const String mockUserName = 'Nutricionista Exemplo'; + const List mockPatients = ['Paciente 1', 'Paciente 2']; await tester.pumpWidget( MaterialApp( - home: NutritionistDashboardScreen(userData: {'name': mockUserName}), + home: NutritionistDashboardScreen( + userData: {'nome': mockUserName, 'pacientes': mockPatients}), ), ); // Verifica que apenas um widget com "Olá, Nutricionista!" existe - expect(find.text('Olá, Nutricionista!'), findsOneWidget); + expect(find.text('Bem-vindo de volta'), findsOneWidget); // Certifica-se de que widgets com textos incorretos não existem expect(find.text('Texto não esperado'), findsNothing); From 3bce9328a68aeabbc6eda53d293b6c42ddb47689 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Tue, 21 Jan 2025 00:52:54 -0300 Subject: [PATCH 45/47] altera banco --- backend/model/PlanoAlimentar.js | 4 +- .../nutricionistaController.test.js | 1 - .../lib/geral_screens/login_screen.dart | 20 ++- healthway_app/lib/main.dart | 9 - healthway_app/lib/models/plano_alimentar.dart | 4 - .../lib/screens_patient/dietScreen.dart | 168 ------------------ 6 files changed, 14 insertions(+), 192 deletions(-) delete mode 100644 healthway_app/lib/screens_patient/dietScreen.dart diff --git a/backend/model/PlanoAlimentar.js b/backend/model/PlanoAlimentar.js index a011a22..2a8817d 100644 --- a/backend/model/PlanoAlimentar.js +++ b/backend/model/PlanoAlimentar.js @@ -1,6 +1,5 @@ class PlanoAlimentar { - constructor(consulta, dt_inicio, dt_fim, refeicoes, paciente, nutricionista) { - this.consulta = consulta; + constructor(dt_inicio, dt_fim, refeicoes, paciente, nutricionista) { this.dt_inicio = dt_inicio; this.dt_fim = dt_fim; this.refeicoes = refeicoes; @@ -10,7 +9,6 @@ class PlanoAlimentar { toFirestore() { return { - consulta: this.consulta, dt_inicio: this.dt_inicio, dt_fim: this.dt_fim, refeicoes: this.refeicoes, diff --git a/backend/tests/controllers/nutricionistaController.test.js b/backend/tests/controllers/nutricionistaController.test.js index bae62f3..025f925 100644 --- a/backend/tests/controllers/nutricionistaController.test.js +++ b/backend/tests/controllers/nutricionistaController.test.js @@ -1,4 +1,3 @@ -const consultaController = require('../../controllers/consultaController'); const nutricionistaController = require('../../controllers/nutricionistaController'); const db = require('../../firebase-config'); diff --git a/healthway_app/lib/geral_screens/login_screen.dart b/healthway_app/lib/geral_screens/login_screen.dart index 8c3e766..e8be776 100644 --- a/healthway_app/lib/geral_screens/login_screen.dart +++ b/healthway_app/lib/geral_screens/login_screen.dart @@ -222,8 +222,8 @@ class _LoginScreenState extends State { _isLoading = true; }); String email = _emailController.text; - String senha = _senhaController.text; - String userType = _userType; + // String senha = _senhaController.text; + // String userType = _userType; // Call the login service // _servicesFacade @@ -256,9 +256,10 @@ class _LoginScreenState extends State { // ); // }); - var mockData = { - 'nome': 'John Doe', - 'email': 'exemplo@email.com', + var patientMockData = { + 'id': '1', + 'nome': 'francisco', + 'email': email, 'dt_nascimento': '01/01/2000', 'altura': 180, 'peso': 75, @@ -268,12 +269,17 @@ class _LoginScreenState extends State { 'alergias': ['Amendoim', 'Leite'], 'preferencias': ['Vegano'], }; + + var nutritionistMockData = { + 'nome': 'João', + 'pacientes': ['1'], + }; if (_userType == 'Paciente') { Navigator.pushReplacementNamed(context, '/home_patient', - arguments: mockData); + arguments: patientMockData); } else if (_userType == 'Nutricionista') { Navigator.pushReplacementNamed(context, '/home_nutritionist', - arguments: mockData); + arguments: nutritionistMockData); } } } diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index a5150ab..b5594de 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -12,7 +12,6 @@ import 'package:healthway_app/screens_nutricionist/nutritionist_profile.dart'; import 'package:healthway_app/screens_nutricionist/patient_list_screen.dart'; import 'package:healthway_app/screens_nutricionist/schedule_screen.dart'; import 'package:healthway_app/screens_nutricionist/signup_nutritionist_screen.dart'; -import 'package:healthway_app/screens_patient/dietScreen.dart'; import 'package:healthway_app/screens_patient/notificationScreen.dart'; import 'package:healthway_app/screens_patient/patient_dashboard_screen.dart'; import 'package:healthway_app/screens_patient/patient_profile_screen.dart'; @@ -104,14 +103,6 @@ class MyApp extends StatelessWidget { return MaterialPageRoute( builder: (context) => MealEditScreen(mealData: args), ); - - case '/diet': - final args = settings.arguments as Map; - return MaterialPageRoute( - builder: (context) => PlanoAlimentarScreen( - pacienteId: args['id'], - ), - ); default: return null; } diff --git a/healthway_app/lib/models/plano_alimentar.dart b/healthway_app/lib/models/plano_alimentar.dart index 3c0f3eb..a6dd58b 100644 --- a/healthway_app/lib/models/plano_alimentar.dart +++ b/healthway_app/lib/models/plano_alimentar.dart @@ -2,7 +2,6 @@ import 'package:intl/intl.dart'; class PlanoAlimentar { final String? id; - final String consulta; final DateTime dtInicio; final DateTime dtFim; final List refeicoes; @@ -11,7 +10,6 @@ class PlanoAlimentar { PlanoAlimentar({ this.id, - required this.consulta, required this.dtInicio, required this.dtFim, required this.refeicoes, @@ -22,7 +20,6 @@ class PlanoAlimentar { factory PlanoAlimentar.fromJson(Map json) { return PlanoAlimentar( id: json['id'] ?? '', - consulta: json['consulta'] ?? '', dtInicio: DateFormat('dd/MM/yyyy').parse(json['dt_inicio'] ?? ''), dtFim: DateFormat('dd/MM/yyyy').parse(json['dt_fim'] ?? ''), refeicoes: List.from(json['refeicoes'] ?? []), @@ -34,7 +31,6 @@ class PlanoAlimentar { Map toJson() { return { 'id': id, - 'consulta': consulta, 'dt_inicio': DateFormat('dd/MM/yyyy').format(dtInicio), 'dt_fim': DateFormat('dd/MM/yyyy').format(dtFim), 'refeicoes': refeicoes, diff --git a/healthway_app/lib/screens_patient/dietScreen.dart b/healthway_app/lib/screens_patient/dietScreen.dart deleted file mode 100644 index d6e183d..0000000 --- a/healthway_app/lib/screens_patient/dietScreen.dart +++ /dev/null @@ -1,168 +0,0 @@ -import 'package:healthway_app/constants.dart'; -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; - -class PlanoAlimentarScreen extends StatefulWidget { - final String pacienteId; - - const PlanoAlimentarScreen({super.key, required this.pacienteId}); - - @override - State createState() => _PlanoAlimentarScreenState(); -} - -class _PlanoAlimentarScreenState extends State { - List planosAlimentares = []; - bool isLoading = true; - - @override - void initState() { - super.initState(); - _carregarPlanosAlimentares(); - } - - Future _carregarPlanosAlimentares() async { - // Simular uma chamada de API - await Future.delayed(Duration(seconds: 2)); - setState(() { - planosAlimentares = [ - PlanoAlimentar( - consulta: 'Consulta 1', - dtInicio: DateTime.now(), - dtFim: DateTime.now().add(Duration(days: 30)), - refeicoes: [ - Refeicao('Café da Manhã', - ['2 fatias de pão integral', '1 ovo cozido', '1 maçã']), - Refeicao('Almoço', [ - '150g de frango grelhado', - '1 xícara de arroz integral', - 'Salada verde' - ]), - Refeicao('Jantar', [ - '150g de peixe assado', - '1 batata doce média', - 'Legumes no vapor' - ]), - ], - paciente: widget.pacienteId, - ), - ]; - isLoading = false; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: kBackgroundColor, - appBar: AppBar( - title: Text('Plano Alimentar', - style: TextStyle(fontWeight: FontWeight.bold)), - backgroundColor: kPrimaryColor, - elevation: 0, - ), - body: isLoading - ? Center(child: CircularProgressIndicator(color: kPrimaryColor)) - : planosAlimentares.isEmpty - ? _buildEmptyState() - : _buildPlanoAlimentarList(), - floatingActionButton: FloatingActionButton( - onPressed: () { - // TODO: Implementar a criação de um novo plano alimentar - }, - child: Icon(Icons.add), - backgroundColor: kPrimaryColor, - ), - ); - } - - Widget _buildEmptyState() { - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.no_meals, size: 80, color: kPrimaryColor), - SizedBox(height: 16), - Text( - 'Nenhum plano alimentar encontrado', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Clique no botão + para adicionar um novo plano', - style: TextStyle(color: Colors.grey[600]), - ), - ], - ), - ); - } - - Widget _buildPlanoAlimentarList() { - return ListView.builder( - itemCount: planosAlimentares.length, - itemBuilder: (context, index) { - final plano = planosAlimentares[index]; - return Card( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: ExpansionTile( - title: Text( - plano.consulta, - style: - TextStyle(fontWeight: FontWeight.bold, color: kPrimaryColor), - ), - subtitle: Text( - '${DateFormat('dd/MM/yyyy').format(plano.dtInicio)} - ${DateFormat('dd/MM/yyyy').format(plano.dtFim)}', - style: TextStyle(color: Colors.grey[600]), - ), - children: plano.refeicoes - .map((refeicao) => _buildRefeicaoItem(refeicao)) - .toList(), - ), - ); - }, - ); - } - - Widget _buildRefeicaoItem(Refeicao refeicao) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - refeicao.nome, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), - ), - SizedBox(height: 4), - ...refeicao.alimentos.map((alimento) => Padding( - padding: const EdgeInsets.only(left: 16, top: 2), - child: Text('• $alimento'), - )), - ], - ), - ); - } -} - -class PlanoAlimentar { - final String consulta; - final DateTime dtInicio; - final DateTime dtFim; - final List refeicoes; - final String paciente; - - PlanoAlimentar({ - required this.consulta, - required this.dtInicio, - required this.dtFim, - required this.refeicoes, - required this.paciente, - }); -} - -class Refeicao { - final String nome; - final List alimentos; - - Refeicao(this.nome, this.alimentos); -} From a8ad7f91aac4ff9381c63f7385f5c18854b30c18 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Tue, 21 Jan 2025 03:40:08 -0300 Subject: [PATCH 46/47] inclui rota para plano do paciente de um nutricionista --- backend/controllers/alimentoController.js | 9 + backend/model/Alimento.js | 69 +- backend/model/Nutricionista.js | 6 +- backend/model/PlanoAlimentar.js | 10 +- backend/routes/alimentoRoutes.js | 1 + backend/services/alimentoService.js | 12 +- .../lib/geral_screens/alimentos_screen.dart | 39 +- .../lib/geral_screens/login_screen.dart | 111 +- healthway_app/lib/main.dart | 6 + healthway_app/lib/models/alimento.dart | 40 +- healthway_app/lib/models/plano_alimentar.dart | 16 +- .../meal_edit_screen.dart | 2 +- .../meal_plan_screen.dart | 48 +- .../nutritionist_dashboard_screen.dart | 15 +- healthway_app/lib/widgets/alimento_item.dart | 2 +- healthway_app/lib/widgets/paciente_item.dart | 15 +- saida[1].json | 13093 ++++++++++++++++ 17 files changed, 13346 insertions(+), 148 deletions(-) create mode 100644 saida[1].json diff --git a/backend/controllers/alimentoController.js b/backend/controllers/alimentoController.js index 464a80d..8e11f49 100644 --- a/backend/controllers/alimentoController.js +++ b/backend/controllers/alimentoController.js @@ -11,6 +11,15 @@ const alimentoController = { } }, + async createMany(req, res) { + try { + await AlimentoService.createMany(req.body); + res.status(201).json({ message: 'Alimentos criados com sucesso!' }); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }, + async getAll(req, res) { try { const alimentos = await AlimentoService.getAll(); diff --git a/backend/model/Alimento.js b/backend/model/Alimento.js index dbfb7b6..837358e 100644 --- a/backend/model/Alimento.js +++ b/backend/model/Alimento.js @@ -1,7 +1,6 @@ class Alimento { constructor( - categoria, - descricao, + {descricao, umidade, energiaKcal, energiaKJ, @@ -19,9 +18,8 @@ class Alimento { sodio, potassio, cobre, - zinco + zinco} ) { - this.categoria = categoria; // Categoria do Alimento this.descricao = descricao; // Descrição dos alimentos this.umidade = umidade; // Umidade (%) this.energiaKcal = energiaKcal; // Energia (Kcal) @@ -45,28 +43,51 @@ class Alimento { toFirestore() { return { - categoria: this.categoria, - descricao: this.descricao, - umidade: this.umidade, - energiaKcal: this.energiaKcal, - energiaKJ: this.energiaKJ, - proteina: this.proteina, - lipideos: this.lipideos, - colesterol: this.colesterol, - carboidrato: this.carboidrato, - fibraAlimentar: this.fibraAlimentar, - cinzas: this.cinzas, - calcio: this.calcio, - magnesio: this.magnesio, - manganes: this.manganes, - fosforo: this.fosforo, - ferro: this.ferro, - sodio: this.sodio, - potassio: this.potassio, - cobre: this.cobre, - zinco: this.zinco + "Descrição dos alimentos": this.descricao, + "Umidade (%)": this.umidade, + "Energia (Kcal)": this.energiaKcal, + "Energia (KJ)": this.energiaKJ, + "Proteína (g)": this.proteina, + "Lipídeos (g)": this.lipideos, + "Colesterol (mg)": this.colesterol, + "Carboidrato (g)": this.carboidrato, + "Fibra Alimentar (g)": this.fibraAlimentar, + "Cinzas (g)": this.cinzas, + "Cálcio (mg)": this.calcio, + "Magnésio (mg)": this.magnesio, + "Manganês (mg)": this.manganes, + "Fósforo (mg)": this.fosforo, + "Ferro (mg)": this.ferro, + "Sódio (mg)": this.sodio, + "Potássio (mg)": this.potassio, + "Cobre (mg)": this.cobre, + "Zinco (mg)": this.zinco }; } + + static fromJson(json) { + return new Alimento({ + descricao: json["Descrição dos alimentos"], + umidade: json["Umidade (%)"], + energiaKcal: json["Energia (Kcal)"], + energiaKJ: json["Energia (KJ)"], + proteina: json["Proteína (g)"], + lipideos: json["Lipídeos (g)"], + colesterol: json["Colesterol (mg)"], + carboidrato: json["Carboidrato (g)"], + fibraAlimentar: json["Fibra Alimentar (g)"], + cinzas: json["Cinzas (g)"], + calcio: json["Cálcio (mg)"], + magnesio: json["Magnésio (mg)"], + manganes: json["Manganês (mg)"], + fosforo: json["Fósforo (mg)"], + ferro: json["Ferro (mg)"], + sodio: json["Sódio (mg)"], + potassio: json["Potássio (mg)"], + cobre: json["Cobre (mg)"], + zinco: json["Zinco (mg)"] + }); + } } module.exports = Alimento; diff --git a/backend/model/Nutricionista.js b/backend/model/Nutricionista.js index f8de309..a862cba 100644 --- a/backend/model/Nutricionista.js +++ b/backend/model/Nutricionista.js @@ -1,11 +1,9 @@ class Nutricionista { - constructor({ cpf, crn, email, especialidade, foto_perfil, foto_documento, nome, senha, pacientes }) { + constructor({ cpf, crn, email, especialidade, nome, senha, pacientes }) { this.cpf = cpf; this.crn = crn; this.email = email; this.especialidade = especialidade; - this.foto_perfil = foto_perfil; - this.foto_documento = foto_documento; this.nome = nome; this.senha = senha; this.pacientes = pacientes; @@ -17,8 +15,6 @@ class Nutricionista { crn: this.crn, email: this.email, especialidade: this.especialidade, - foto_perfil: this.foto_perfil, - foto_documento: this.foto_documento, nome: this.nome, senha: this.senha, pacientes: this.pacientes, diff --git a/backend/model/PlanoAlimentar.js b/backend/model/PlanoAlimentar.js index 2a8817d..06e2d8b 100644 --- a/backend/model/PlanoAlimentar.js +++ b/backend/model/PlanoAlimentar.js @@ -1,10 +1,10 @@ class PlanoAlimentar { - constructor(dt_inicio, dt_fim, refeicoes, paciente, nutricionista) { + constructor(dt_inicio, dt_fim, refeicoes, id_paciente, id_nutricionista) { this.dt_inicio = dt_inicio; this.dt_fim = dt_fim; this.refeicoes = refeicoes; - this.paciente = paciente; - this.nutricionista = nutricionista; + this.id_paciente = id_paciente; + this.id_nutricionista = id_nutricionista; } toFirestore() { @@ -12,8 +12,8 @@ class PlanoAlimentar { dt_inicio: this.dt_inicio, dt_fim: this.dt_fim, refeicoes: this.refeicoes, - paciente: this.paciente, - nutricionista: this.nutricionista + id_paciente: this.id_paciente, + id_nutricionista: this.id_nutricionista }; } } diff --git a/backend/routes/alimentoRoutes.js b/backend/routes/alimentoRoutes.js index 6ddedd2..eecf899 100644 --- a/backend/routes/alimentoRoutes.js +++ b/backend/routes/alimentoRoutes.js @@ -4,6 +4,7 @@ const alimentoController = require('../controllers/alimentoController'); // Rotas router.post('/', alimentoController.create); +router.post('/many', alimentoController.createMany); router.get('/', alimentoController.getAll); router.get('/:id', alimentoController.getById); router.get('/categoria/:categoria', alimentoController.getByCategory); // Nova rota para buscar por categoria diff --git a/backend/services/alimentoService.js b/backend/services/alimentoService.js index 013fa6e..421f4f5 100644 --- a/backend/services/alimentoService.js +++ b/backend/services/alimentoService.js @@ -3,10 +3,20 @@ const Alimento = require('../model/Alimento'); const AlimentoService = { async create(data) { - const alimento = new Alimento(data); + const alimento = Alimento.fromJson(data); return await db.collection('alimentos').add(alimento.toFirestore()); }, + async createMany(alimentos) { + const batch = db.batch(); + alimentos.forEach(alimento => { + const newAlimento = Alimento.fromJson(alimento); + const newAlimentoRef = db.collection('alimentos').doc(); + batch.set(newAlimentoRef, newAlimento.toFirestore()); + }); + return await batch.commit(); + }, + async getAll() { const snapshot = await db.collection('alimentos').get(); return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); diff --git a/healthway_app/lib/geral_screens/alimentos_screen.dart b/healthway_app/lib/geral_screens/alimentos_screen.dart index 99213a5..5949646 100644 --- a/healthway_app/lib/geral_screens/alimentos_screen.dart +++ b/healthway_app/lib/geral_screens/alimentos_screen.dart @@ -1,6 +1,11 @@ +import 'dart:convert'; +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:healthway_app/constants.dart'; -import '../services/alimento_services.dart'; +import 'package:healthway_app/services/services_facade.dart'; +import 'package:path_provider/path_provider.dart'; + import '../models/alimento.dart'; import '../widgets/alimento_item.dart'; @@ -16,6 +21,7 @@ class _AlimentosScreenState extends State { List alimentos = []; List alimentosFiltrados = []; TextEditingController searchController = TextEditingController(); + final ServicesFacade _servicesFacade = ServicesFacade(); @override void initState() { @@ -25,18 +31,41 @@ class _AlimentosScreenState extends State { void _carregarAlimentos() { setState(() { - futureAlimentos = AlimentoService().fetchFoods(); + futureAlimentos = _downloadAlimentos(); }); } + Future> _downloadAlimentos() async { + try { + final directory = await getApplicationCacheDirectory(); + final file = File('${directory.path}/alimentos.json'); + if (file.existsSync()) { + final foodsJson = await file.readAsString(); + final foodsData = jsonDecode(foodsJson) as List; + final foods = foodsData.map((food) => Alimento.fromJson(food)).toList(); + return foods; + } else { + final foods = await _servicesFacade.obterAlimentos(); + final foodsJson = jsonEncode(foods); + await file.writeAsString(foodsJson); + } + } catch (error) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Erro ao baixar alimentos. Tente novamente.'), + ), + ); + return []; + } + return []; + } + void _filtrarAlimentos(String query) { setState(() { alimentosFiltrados = alimentos.where((alimento) { final descricaoMatch = alimento.descricao.toLowerCase().contains(query.toLowerCase()); - final categoriaMatch = - alimento.categoria.toLowerCase().contains(query.toLowerCase()); - return descricaoMatch || categoriaMatch; + return descricaoMatch; }).toList(); }); } diff --git a/healthway_app/lib/geral_screens/login_screen.dart b/healthway_app/lib/geral_screens/login_screen.dart index e8be776..29ca695 100644 --- a/healthway_app/lib/geral_screens/login_screen.dart +++ b/healthway_app/lib/geral_screens/login_screen.dart @@ -222,65 +222,64 @@ class _LoginScreenState extends State { _isLoading = true; }); String email = _emailController.text; - // String senha = _senhaController.text; - // String userType = _userType; + String senha = _senhaController.text; + String userType = _userType; - // Call the login service - // _servicesFacade - // .login(email: email, senha: senha, userType: userType) - // .then((userData) { - // if (userData != null) { - // if (_userType == 'Paciente') { - // Navigator.pushReplacementNamed(context, '/home_patient', - // arguments: userData); - // } else if (_userType == 'Nutricionista') { - // Navigator.pushReplacementNamed(context, '/home_nutritionist', - // arguments: userData); - // } - // } else { - // setState(() { - // _isLoading = false; - // }); - // // Show error message - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar( - // content: Text('Falha no login. Verifique suas credenciais.')), - // ); - // } - // }).catchError((error) { - // setState(() { - // _isLoading = false; - // }); - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar(content: Text('Erro ao fazer login: ${error.toString()}')), - // ); - // }); + _servicesFacade + .login(email: email, senha: senha, userType: userType) + .then((userData) { + if (userData != null) { + if (_userType == 'Paciente') { + Navigator.pushReplacementNamed(context, '/home_patient', + arguments: userData); + } else if (_userType == 'Nutricionista') { + Navigator.pushReplacementNamed(context, '/home_nutritionist', + arguments: userData); + } + } else { + setState(() { + _isLoading = false; + }); + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Falha no login. Verifique suas credenciais.')), + ); + } + }).catchError((error) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Erro ao fazer login: ${error.toString()}')), + ); + }); - var patientMockData = { - 'id': '1', - 'nome': 'francisco', - 'email': email, - 'dt_nascimento': '01/01/2000', - 'altura': 180, - 'peso': 75, - 'circunferencia_abdominal': 88, - 'massa_muscular': 6.5, - 'gordura_corporal': 15.5, - 'alergias': ['Amendoim', 'Leite'], - 'preferencias': ['Vegano'], - }; + // var patientMockData = { + // 'id': '1', + // 'nome': 'francisco', + // 'email': email, + // 'dt_nascimento': '01/01/2000', + // 'altura': 180, + // 'peso': 75, + // 'circunferencia_abdominal': 88, + // 'massa_muscular': 6.5, + // 'gordura_corporal': 15.5, + // 'alergias': ['Amendoim', 'Leite'], + // 'preferencias': ['Vegano'], + // }; - var nutritionistMockData = { - 'nome': 'João', - 'pacientes': ['1'], - }; - if (_userType == 'Paciente') { - Navigator.pushReplacementNamed(context, '/home_patient', - arguments: patientMockData); - } else if (_userType == 'Nutricionista') { - Navigator.pushReplacementNamed(context, '/home_nutritionist', - arguments: nutritionistMockData); - } + // var nutritionistMockData = { + // 'nome': 'João', + // 'pacientes': ['1'], + // }; + // if (_userType == 'Paciente') { + // Navigator.pushReplacementNamed(context, '/home_patient', + // arguments: patientMockData); + // } else if (_userType == 'Nutricionista') { + // Navigator.pushReplacementNamed(context, '/home_nutritionist', + // arguments: nutritionistMockData); + // } } } diff --git a/healthway_app/lib/main.dart b/healthway_app/lib/main.dart index b5594de..287cc6c 100644 --- a/healthway_app/lib/main.dart +++ b/healthway_app/lib/main.dart @@ -86,6 +86,12 @@ class MyApp extends StatelessWidget { builder: (context) => NutritionistProfileScreen(userData: args), ); case '/meal_plan_patient': + final args = settings.arguments as Map; + return MaterialPageRoute( + builder: (context) => + MealPlanScreen(patientData: args, isPatient: true), + ); + case '/meal_plan_nutritionist': final args = settings.arguments as Map; return MaterialPageRoute( builder: (context) => diff --git a/healthway_app/lib/models/alimento.dart b/healthway_app/lib/models/alimento.dart index 894c1e2..6c821ae 100644 --- a/healthway_app/lib/models/alimento.dart +++ b/healthway_app/lib/models/alimento.dart @@ -1,6 +1,5 @@ class Alimento { final String id; - final String categoria; final String descricao; final double umidade; final double energiaKcal; @@ -23,7 +22,6 @@ class Alimento { Alimento({ required this.id, - required this.categoria, required this.descricao, required this.umidade, required this.energiaKcal, @@ -48,16 +46,19 @@ class Alimento { factory Alimento.fromJson(Map json) { return Alimento( id: json['id'] ?? '', - categoria: json['Categoria'] ?? '', descricao: json['Descrição dos alimentos'] ?? '', umidade: double.tryParse(json['Umidade (%)']?.toString() ?? '0') ?? 0, - energiaKcal: double.tryParse(json['Energia (Kcal)']?.toString() ?? '0') ?? 0, + energiaKcal: + double.tryParse(json['Energia (Kcal)']?.toString() ?? '0') ?? 0, energiaKj: double.tryParse(json['Energia (KJ)']?.toString() ?? '0') ?? 0, proteina: double.tryParse(json['Proteína (g)']?.toString() ?? '0') ?? 0, lipideos: double.tryParse(json['Lipídeos (g)']?.toString() ?? '0') ?? 0, - colesterol: double.tryParse(json['Colesterol (mg)']?.toString() ?? '0') ?? 0, - carboidrato: double.tryParse(json['Carboidrato (g)']?.toString() ?? '0') ?? 0, - fibraAlimentar: double.tryParse(json['Fibra Alimentar (g)']?.toString() ?? '0') ?? 0, + colesterol: + double.tryParse(json['Colesterol (mg)']?.toString() ?? '0') ?? 0, + carboidrato: + double.tryParse(json['Carboidrato (g)']?.toString() ?? '0') ?? 0, + fibraAlimentar: + double.tryParse(json['Fibra Alimentar (g)']?.toString() ?? '0') ?? 0, cinzas: double.tryParse(json['Cinzas (g)']?.toString() ?? '0') ?? 0, calcio: double.tryParse(json['Cálcio (mg)']?.toString() ?? '0') ?? 0, magnesio: double.tryParse(json['Magnésio (mg)']?.toString() ?? '0') ?? 0, @@ -70,4 +71,29 @@ class Alimento { zinco: double.tryParse(json['Zinco (mg)']?.toString() ?? '0') ?? 0, ); } + + Map toJson() { + return { + 'id': id, + 'Descrição dos alimentos': descricao, + 'Umidade (%)': umidade, + 'Energia (Kcal)': energiaKcal, + 'Energia (KJ)': energiaKj, + 'Proteína (g)': proteina, + 'Lipídeos (g)': lipideos, + 'Colesterol (mg)': colesterol, + 'Carboidrato (g)': carboidrato, + 'Fibra Alimentar (g)': fibraAlimentar, + 'Cinzas (g)': cinzas, + 'Cálcio (mg)': calcio, + 'Magnésio (mg)': magnesio, + 'Manganês (mg)': manganes, + 'Fósforo (mg)': fosforo, + 'Ferro (mg)': ferro, + 'Sódio (mg)': sodio, + 'Potássio (mg)': potassio, + 'Cobre (mg)': cobre, + 'Zinco (mg)': zinco, + }; + } } diff --git a/healthway_app/lib/models/plano_alimentar.dart b/healthway_app/lib/models/plano_alimentar.dart index a6dd58b..bbeaf01 100644 --- a/healthway_app/lib/models/plano_alimentar.dart +++ b/healthway_app/lib/models/plano_alimentar.dart @@ -5,16 +5,16 @@ class PlanoAlimentar { final DateTime dtInicio; final DateTime dtFim; final List refeicoes; - final String paciente; - final String nutricionista; + final String pacienteId; + final String nutricionistaId; PlanoAlimentar({ this.id, required this.dtInicio, required this.dtFim, required this.refeicoes, - required this.paciente, - required this.nutricionista, + required this.pacienteId, + required this.nutricionistaId, }); factory PlanoAlimentar.fromJson(Map json) { @@ -23,8 +23,8 @@ class PlanoAlimentar { dtInicio: DateFormat('dd/MM/yyyy').parse(json['dt_inicio'] ?? ''), dtFim: DateFormat('dd/MM/yyyy').parse(json['dt_fim'] ?? ''), refeicoes: List.from(json['refeicoes'] ?? []), - paciente: json['id_paciente'] ?? '', - nutricionista: json['id_nutricionista'] ?? '', + pacienteId: json['id_paciente'] ?? '', + nutricionistaId: json['id_nutricionista'] ?? '', ); } @@ -34,8 +34,8 @@ class PlanoAlimentar { 'dt_inicio': DateFormat('dd/MM/yyyy').format(dtInicio), 'dt_fim': DateFormat('dd/MM/yyyy').format(dtFim), 'refeicoes': refeicoes, - 'id_paciente': paciente, - 'id_nutricionista': nutricionista, + 'id_paciente': pacienteId, + 'id_nutricionista': nutricionistaId, }; } } diff --git a/healthway_app/lib/screens_nutricionist/meal_edit_screen.dart b/healthway_app/lib/screens_nutricionist/meal_edit_screen.dart index c5f5ccf..4b99724 100644 --- a/healthway_app/lib/screens_nutricionist/meal_edit_screen.dart +++ b/healthway_app/lib/screens_nutricionist/meal_edit_screen.dart @@ -80,7 +80,7 @@ class _MealEditScreenState extends State { }); _servicesFacade.atualizar(refeicao); ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Perfil atualizado com sucesso')), + SnackBar(content: Text('Refeição atualizada com sucesso')), ); } catch (error) { ScaffoldMessenger.of(context).showSnackBar( diff --git a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart index f47d5c5..f12b47f 100644 --- a/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart +++ b/healthway_app/lib/screens_nutricionist/meal_plan_screen.dart @@ -97,28 +97,39 @@ class _MealPlanScreenState extends State { color: kPrimaryColor, ), subtitle: Padding( - padding: EdgeInsets.only(top: 8.0), + padding: EdgeInsets.only(top: 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: - List.from(itensDeRefeicao[refeicao.id]! - .entries - .map((itemDeRefeicao) => Text( - '${itemDeRefeicao.key}: ${itemDeRefeicao.value}', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: kTextColor), - )) - .toList()), + children: [ + if (refeicao.observacoes != null && + refeicao.observacoes!.isNotEmpty) + Text( + '${refeicao.observacoes}', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: kTextColor.withValues(alpha: 0.8)), + ), + ...itensDeRefeicao[refeicao.id]!.entries.map( + (itemDeRefeicao) => Text( + '${itemDeRefeicao.key}: ${itemDeRefeicao.value}', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: kTextColor), + ), + ), + ], ), ), - trailing: IconButton( - icon: Icon(Icons.edit), - onPressed: () { - _editMeal(refeicao, alimentos[refeicao.id]); - }, - ), + trailing: widget.isPatient + ? null + : IconButton( + icon: Icon(Icons.edit), + onPressed: () { + _editMeal(refeicao, alimentos[refeicao.id]); + }, + ), ), ); }), @@ -172,6 +183,5 @@ class _MealPlanScreenState extends State { _planData[refeicao.id] = {'refeicao': refeicao, 'alimentos': alimentos}; Navigator.pushNamed(context, '/meal_edit', arguments: _planData[refeicao.id]); - carregarPlanoAlimentar(); } } diff --git a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart index 10807fe..95e8802 100644 --- a/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart +++ b/healthway_app/lib/screens_nutricionist/nutritionist_dashboard_screen.dart @@ -66,7 +66,8 @@ class NutritionistDashboardScreen extends StatelessWidget { ), GestureDetector( onTap: () { - Navigator.pushNamed(context, '/nutritionist_profile'); + Navigator.pushNamed(context, '/nutritionist_profile', + arguments: userData); }, child: CircleAvatar( radius: 30, @@ -319,18 +320,6 @@ class NutritionistDashboardScreen extends StatelessWidget { fontWeight: FontWeight.bold, ), ), - TextButton( - onPressed: () { - Navigator.pushNamed(context, '/patient_updates'); - }, - child: Text( - 'Ver todas', - style: TextStyle( - color: kPrimaryColor, - fontWeight: FontWeight.bold, - ), - ), - ), ], ), SizedBox(height: 15), diff --git a/healthway_app/lib/widgets/alimento_item.dart b/healthway_app/lib/widgets/alimento_item.dart index a2b08ce..ece5937 100644 --- a/healthway_app/lib/widgets/alimento_item.dart +++ b/healthway_app/lib/widgets/alimento_item.dart @@ -39,7 +39,7 @@ class AlimentoItem extends StatelessWidget { ), const SizedBox(height: 8), Text( - 'Categoria: ${alimento.categoria}', + 'Categoria: ', style: TextStyle( color: Colors.grey[700]), // Cor mais suave para a categoria ), diff --git a/healthway_app/lib/widgets/paciente_item.dart b/healthway_app/lib/widgets/paciente_item.dart index 07a146f..bf0099c 100644 --- a/healthway_app/lib/widgets/paciente_item.dart +++ b/healthway_app/lib/widgets/paciente_item.dart @@ -1,11 +1,12 @@ import 'package:healthway_app/constants.dart'; +import 'package:healthway_app/models/paciente.dart'; import 'package:flutter/material.dart'; import '../models/paciente.dart'; class PacienteItem extends StatelessWidget { final Paciente paciente; - const PacienteItem({Key? key, required this.paciente}) : super(key: key); + const PacienteItem({super.key, required this.paciente}); @override Widget build(BuildContext context) { @@ -53,8 +54,7 @@ class PacienteItem extends StatelessWidget { class PacienteDetalhesScreen extends StatelessWidget { final Paciente paciente; - const PacienteDetalhesScreen({Key? key, required this.paciente}) - : super(key: key); + const PacienteDetalhesScreen({super.key, required this.paciente}); @override Widget build(BuildContext context) { @@ -108,6 +108,15 @@ class PacienteDetalhesScreen extends StatelessWidget { .map((preferencia) => Text('- $preferencia')) .toList(), ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + // Navegar para a tela de plano de refeições do paciente + Navigator.pushNamed(context, '/meal_plan_nutritionist', + arguments: paciente.toJson()); + }, + child: Text('Ver Plano de Refeições'), + ), ], ), ), diff --git a/saida[1].json b/saida[1].json new file mode 100644 index 0000000..013142c --- /dev/null +++ b/saida[1].json @@ -0,0 +1,13093 @@ +[ + + { + + "Descrição dos alimentos":"Arroz, tipo 1, cozido", + "Umidade (%)":69.1, + "Energia (Kcal)":128, + "Energia (KJ)":537, + "Proteína (g)":2.5, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":28.1, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.1, + "Cálcio (mg)":4, + "Magnésio (mg)":2, + "Manganês (mg)":0.30, + "Fósforo (mg)":18, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":15, + "Cobre (mg)":0.02, + "Zinco (mg)":0.5 + }, + { + + "Descrição dos alimentos":"Arroz, tipo 1, cru", + "Umidade (%)":13.2, + "Energia (Kcal)":358, + "Energia (KJ)":1497, + "Proteína (g)":7.2, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":78.8, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.5, + "Cálcio (mg)":4, + "Magnésio (mg)":30, + "Manganês (mg)":1.03, + "Fósforo (mg)":104, + "Ferro (mg)":0.7, + "Sódio (mg)":1, + "Potássio (mg)":62, + "Cobre (mg)":0.11, + "Zinco (mg)":1.2 + }, + { + + "Descrição dos alimentos":"Arroz, tipo 2, cozido", + "Umidade (%)":68.7, + "Energia (Kcal)":130, + "Energia (KJ)":544, + "Proteína (g)":2.6, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":28.2, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":0.1, + "Cálcio (mg)":3, + "Magnésio (mg)":6, + "Manganês (mg)":0.37, + "Fósforo (mg)":22, + "Ferro (mg)":0.1, + "Sódio (mg)":2, + "Potássio (mg)":20, + "Cobre (mg)":0.04, + "Zinco (mg)":0.5 + }, + { + + "Descrição dos alimentos":"Arroz, tipo 2, cru", + "Umidade (%)":13.2, + "Energia (Kcal)":358, + "Energia (KJ)":1498, + "Proteína (g)":7.2, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":78.9, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":0.4, + "Cálcio (mg)":5, + "Magnésio (mg)":29, + "Manganês (mg)":0.83, + "Fósforo (mg)":82, + "Ferro (mg)":0.6, + "Sódio (mg)":1, + "Potássio (mg)":57, + "Cobre (mg)":0.05, + "Zinco (mg)":1.3 + }, + { + + "Descrição dos alimentos":"Aveia, flocos, crua", + "Umidade (%)":9.1, + "Energia (Kcal)":394, + "Energia (KJ)":1648, + "Proteína (g)":13.9, + "Lipídeos (g)":8.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":66.6, + "Fibra Alimentar (g)":9.1, + "Cinzas (g)":1.8, + "Cálcio (mg)":48, + "Magnésio (mg)":119, + "Manganês (mg)":1.89, + "Fósforo (mg)":153, + "Ferro (mg)":4.4, + "Sódio (mg)":5, + "Potássio (mg)":336, + "Cobre (mg)":0.44, + "Zinco (mg)":2.6 + }, + { + + "Descrição dos alimentos":"Biscoito, doce, maisena", + "Umidade (%)":3.2, + "Energia (Kcal)":443, + "Energia (KJ)":1853, + "Proteína (g)":8.1, + "Lipídeos (g)":12.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":75.2, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":1.5, + "Cálcio (mg)":54, + "Magnésio (mg)":37, + "Manganês (mg)":0.78, + "Fósforo (mg)":166, + "Ferro (mg)":1.8, + "Sódio (mg)":352, + "Potássio (mg)":142, + "Cobre (mg)":0.17, + "Zinco (mg)":1.0 + }, + { + + "Descrição dos alimentos":"Biscoito, doce, recheado com chocolate", + "Umidade (%)":2.2, + "Energia (Kcal)":472, + "Energia (KJ)":1974, + "Proteína (g)":6.4, + "Lipídeos (g)":19.6, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":70.5, + "Fibra Alimentar (g)":3.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":27, + "Magnésio (mg)":48, + "Manganês (mg)":0.59, + "Fósforo (mg)":139, + "Ferro (mg)":2.3, + "Sódio (mg)":239, + "Potássio (mg)":232, + "Cobre (mg)":0.27, + "Zinco (mg)":1.0 + }, + { + + "Descrição dos alimentos":"Biscoito, doce, recheado com morango", + "Umidade (%)":2.7, + "Energia (Kcal)":471, + "Energia (KJ)":1971, + "Proteína (g)":5.7, + "Lipídeos (g)":19.6, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":71.0, + "Fibra Alimentar (g)":1.5, + "Cinzas (g)":1.0, + "Cálcio (mg)":36, + "Magnésio (mg)":27, + "Manganês (mg)":0.66, + "Fósforo (mg)":138, + "Ferro (mg)":1.5, + "Sódio (mg)":230, + "Potássio (mg)":113, + "Cobre (mg)":0.13, + "Zinco (mg)":0.7 + }, + { + + "Descrição dos alimentos":"Biscoito, doce, wafer, recheado de chocolate", + "Umidade (%)":1.2, + "Energia (Kcal)":502, + "Energia (KJ)":2102, + "Proteína (g)":5.6, + "Lipídeos (g)":24.7, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":67.5, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":1.1, + "Cálcio (mg)":23, + "Magnésio (mg)":48, + "Manganês (mg)":0.44, + "Fósforo (mg)":124, + "Ferro (mg)":2.4, + "Sódio (mg)":137, + "Potássio (mg)":240, + "Cobre (mg)":0.26, + "Zinco (mg)":0.9 + }, + { + + "Descrição dos alimentos":"Biscoito, doce, wafer, recheado de morango", + "Umidade (%)":1.2, + "Energia (Kcal)":513, + "Energia (KJ)":2148, + "Proteína (g)":4.5, + "Lipídeos (g)":26.4, + "Colesterol (mg)":1, + "Carboidrato (g)":67.4, + "Fibra Alimentar (g)":0.8, + "Cinzas (g)":0.6, + "Cálcio (mg)":14, + "Magnésio (mg)":19, + "Manganês (mg)":0.28, + "Fósforo (mg)":73, + "Ferro (mg)":1.1, + "Sódio (mg)":120, + "Potássio (mg)":75, + "Cobre (mg)":0.08, + "Zinco (mg)":0.5 + }, + { + + "Descrição dos alimentos":"Biscoito, salgado, cream cracker", + "Umidade (%)":4.1, + "Energia (Kcal)":432, + "Energia (KJ)":1806, + "Proteína (g)":10.1, + "Lipídeos (g)":14.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":68.7, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":2.7, + "Cálcio (mg)":20, + "Magnésio (mg)":40, + "Manganês (mg)":0.69, + "Fósforo (mg)":148, + "Ferro (mg)":2.2, + "Sódio (mg)":854, + "Potássio (mg)":181, + "Cobre (mg)":0.18, + "Zinco (mg)":1.1 + }, + { + + "Descrição dos alimentos":"Bolo, mistura para", + "Umidade (%)":1.0, + "Energia (Kcal)":419, + "Energia (KJ)":1752, + "Proteína (g)":6.2, + "Lipídeos (g)":6.1, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":84.7, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":2.0, + "Cálcio (mg)":59, + "Magnésio (mg)":28, + "Manganês (mg)":0.46, + "Fósforo (mg)":333, + "Ferro (mg)":1.2, + "Sódio (mg)":463, + "Potássio (mg)":75, + "Cobre (mg)":0.15, + "Zinco (mg)":0.6 + }, + { + + "Descrição dos alimentos":"Bolo, pronto, aipim", + "Umidade (%)":34.1, + "Energia (Kcal)":324, + "Energia (KJ)":1355, + "Proteína (g)":4.4, + "Lipídeos (g)":12.7, + "Colesterol (mg)":73, + "Carboidrato (g)":47.9, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":0.8, + "Cálcio (mg)":85, + "Magnésio (mg)":10, + "Manganês (mg)":0.11, + "Fósforo (mg)":122, + "Ferro (mg)":0.5, + "Sódio (mg)":111, + "Potássio (mg)":135, + "Cobre (mg)":0.05, + "Zinco (mg)":0.4 + }, + { + + "Descrição dos alimentos":"Bolo, pronto, chocolate", + "Umidade (%)":19.3, + "Energia (Kcal)":410, + "Energia (KJ)":1715, + "Proteína (g)":6.2, + "Lipídeos (g)":18.5, + "Colesterol (mg)":77, + "Carboidrato (g)":54.7, + "Fibra Alimentar (g)":1.4, + "Cinzas (g)":1.3, + "Cálcio (mg)":75, + "Magnésio (mg)":28, + "Manganês (mg)":0.38, + "Fósforo (mg)":197, + "Ferro (mg)":2.1, + "Sódio (mg)":283, + "Potássio (mg)":212, + "Cobre (mg)":0.05, + "Zinco (mg)":0.7 + }, + { + + "Descrição dos alimentos":"Bolo, pronto, coco", + "Umidade (%)":29.3, + "Energia (Kcal)":333, + "Energia (KJ)":1395, + "Proteína (g)":5.7, + "Lipídeos (g)":11.3, + "Colesterol (mg)":63, + "Carboidrato (g)":52.3, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":1.4, + "Cálcio (mg)":57, + "Magnésio (mg)":16, + "Manganês (mg)":0.40, + "Fósforo (mg)":303, + "Ferro (mg)":0.8, + "Sódio (mg)":190, + "Potássio (mg)":143, + "Cobre (mg)":0.09, + "Zinco (mg)":0.7 + }, + { + + "Descrição dos alimentos":"Bolo, pronto, milho", + "Umidade (%)":36.7, + "Energia (Kcal)":311, + "Energia (KJ)":1303, + "Proteína (g)":4.8, + "Lipídeos (g)":12.4, + "Colesterol (mg)":82, + "Carboidrato (g)":45.1, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":1.0, + "Cálcio (mg)":83, + "Magnésio (mg)":10, + "Manganês (mg)":0.11, + "Fósforo (mg)":128, + "Ferro (mg)":0.7, + "Sódio (mg)":134, + "Potássio (mg)":118, + "Cobre (mg)":0.04, + "Zinco (mg)":0.4 + }, + { + + "Descrição dos alimentos":"Canjica, branca, crua", + "Umidade (%)":13.6, + "Energia (Kcal)":358, + "Energia (KJ)":1496, + "Proteína (g)":7.2, + "Lipídeos (g)":1.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":78.1, + "Fibra Alimentar (g)":5.5, + "Cinzas (g)":0.2, + "Cálcio (mg)":2, + "Magnésio (mg)":12, + "Manganês (mg)":0.09, + "Fósforo (mg)":48, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":93, + "Cobre (mg)":0.05, + "Zinco (mg)":0.4 + }, + { + + "Descrição dos alimentos":"Canjica, com leite integral", + "Umidade (%)":72.5, + "Energia (Kcal)":112, + "Energia (KJ)":471, + "Proteína (g)":2.4, + "Lipídeos (g)":1.2, + "Colesterol (mg)":1, + "Carboidrato (g)":23.6, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.3, + "Cálcio (mg)":43, + "Magnésio (mg)":6, + "Manganês (mg)":0.02, + "Fósforo (mg)":41, + "Ferro (mg)":0.1, + "Sódio (mg)":28, + "Potássio (mg)":70, + "Cobre (mg)":0.03, + "Zinco (mg)":0.3 + }, + { + + "Descrição dos alimentos":"Cereais, milho, flocos, com sal", + "Umidade (%)":9.3, + "Energia (Kcal)":370, + "Energia (KJ)":1546, + "Proteína (g)":7.3, + "Lipídeos (g)":1.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":80.8, + "Fibra Alimentar (g)":5.3, + "Cinzas (g)":1.0, + "Cálcio (mg)":2, + "Magnésio (mg)":20, + "Manganês (mg)":"Tr", + "Fósforo (mg)":91, + "Ferro (mg)":0.5, + "Sódio (mg)":272, + "Potássio (mg)":69, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.6 + }, + { + + "Descrição dos alimentos":"Cereais, milho, flocos, sem sal", + "Umidade (%)":11.2, + "Energia (Kcal)":363, + "Energia (KJ)":1520, + "Proteína (g)":6.9, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":80.4, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.3, + "Cálcio (mg)":2, + "Magnésio (mg)":17, + "Manganês (mg)":"Tr", + "Fósforo (mg)":58, + "Ferro (mg)":1.7, + "Sódio (mg)":31, + "Potássio (mg)":29, + "Cobre (mg)":0.24, + "Zinco (mg)":0.3 + }, + { + + "Descrição dos alimentos":"Cereais, mingau, milho, infantil", + "Umidade (%)":4.7, + "Energia (Kcal)":394, + "Energia (KJ)":1650, + "Proteína (g)":6.4, + "Lipídeos (g)":1.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":87.3, + "Fibra Alimentar (g)":3.2, + "Cinzas (g)":0.5, + "Cálcio (mg)":219, + "Magnésio (mg)":16, + "Manganês (mg)":0.11, + "Fósforo (mg)":169, + "Ferro (mg)":3.0, + "Sódio (mg)":399, + "Potássio (mg)":82, + "Cobre (mg)":0.04, + "Zinco (mg)":0.4 + }, + { + + "Descrição dos alimentos":"Cereais, mistura para vitamina, trigo, cevada e aveia", + "Umidade (%)":4.4, + "Energia (Kcal)":381, + "Energia (KJ)":1595, + "Proteína (g)":8.9, + "Lipídeos (g)":2.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":81.6, + "Fibra Alimentar (g)":5.0, + "Cinzas (g)":3.0, + "Cálcio (mg)":584, + "Magnésio (mg)":72, + "Manganês (mg)":2.28, + "Fósforo (mg)":515, + "Ferro (mg)":12.6, + "Sódio (mg)":1163, + "Potássio (mg)":244, + "Cobre (mg)":0.21, + "Zinco (mg)":2.0 + }, + { + "Número do Alimento":25, + "Descrição dos alimentos":"Cereal matinal, milho", + "Umidade (%)":5.5, + "Energia (Kcal)":365, + "Energia (KJ)":1529, + "Proteína (g)":7.2, + "Lipídeos (g)":1.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":83.8, + "Fibra Alimentar (g)":4.1, + "Cinzas (g)":2.5, + "Cálcio (mg)":143, + "Magnésio (mg)":11, + "Manganês (mg)":0.06, + "Fósforo (mg)":101, + "Ferro (mg)":3.1, + "Sódio (mg)":655, + "Potássio (mg)":83, + "Cobre (mg)":0.06, + "Zinco (mg)":7.6 + }, + { + "Número do Alimento":26, + "Descrição dos alimentos":"Cereal matinal, milho, açúcar", + "Umidade (%)":4.3, + "Energia (Kcal)":377, + "Energia (KJ)":1576, + "Proteína (g)":4.7, + "Lipídeos (g)":0.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":88.8, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":1.5, + "Cálcio (mg)":56, + "Magnésio (mg)":8, + "Manganês (mg)":0.13, + "Fósforo (mg)":43, + "Ferro (mg)":3.9, + "Sódio (mg)":405, + "Potássio (mg)":52, + "Cobre (mg)":0.04, + "Zinco (mg)":8.5 + }, + { + "Número do Alimento":27, + "Descrição dos alimentos":"Creme de arroz, pó", + "Umidade (%)":7.3, + "Energia (Kcal)":386, + "Energia (KJ)":1615, + "Proteína (g)":7.0, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":83.9, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":0.5, + "Cálcio (mg)":7, + "Magnésio (mg)":51, + "Manganês (mg)":1.24, + "Fósforo (mg)":153, + "Ferro (mg)":0.6, + "Sódio (mg)":1, + "Potássio (mg)":115, + "Cobre (mg)":0.04, + "Zinco (mg)":1.9 + }, + { + "Número do Alimento":28, + "Descrição dos alimentos":"Creme de milho, pó", + "Umidade (%)":5.7, + "Energia (Kcal)":333, + "Energia (KJ)":1393, + "Proteína (g)":4.8, + "Lipídeos (g)":1.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":86.1, + "Fibra Alimentar (g)":3.7, + "Cinzas (g)":1.7, + "Cálcio (mg)":323, + "Magnésio (mg)":30, + "Manganês (mg)":0.20, + "Fósforo (mg)":303, + "Ferro (mg)":4.3, + "Sódio (mg)":594, + "Potássio (mg)":166, + "Cobre (mg)":0.04, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":29, + "Descrição dos alimentos":"Curau, milho verde", + "Umidade (%)":81.6, + "Energia (Kcal)":78, + "Energia (KJ)":328, + "Proteína (g)":2.4, + "Lipídeos (g)":1.6, + "Colesterol (mg)":5, + "Carboidrato (g)":13.9, + "Fibra Alimentar (g)":0.5, + "Cinzas (g)":0.5, + "Cálcio (mg)":53, + "Magnésio (mg)":16, + "Manganês (mg)":0.06, + "Fósforo (mg)":75, + "Ferro (mg)":0.4, + "Sódio (mg)":21, + "Potássio (mg)":162, + "Cobre (mg)":0.03, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":30, + "Descrição dos alimentos":"Curau, milho verde, mistura para", + "Umidade (%)":3.9, + "Energia (Kcal)":402, + "Energia (KJ)":1683, + "Proteína (g)":2.2, + "Lipídeos (g)":13.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":79.8, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":0.7, + "Cálcio (mg)":31, + "Magnésio (mg)":9, + "Manganês (mg)":0.05, + "Fósforo (mg)":45, + "Ferro (mg)":0.9, + "Sódio (mg)":223, + "Potássio (mg)":55, + "Cobre (mg)":0.03, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":31, + "Descrição dos alimentos":"Farinha, de arroz, enriquecida", + "Umidade (%)":12.7, + "Energia (Kcal)":363, + "Energia (KJ)":1519, + "Proteína (g)":1.3, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":85.5, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":0.2, + "Cálcio (mg)":1, + "Magnésio (mg)":4, + "Manganês (mg)":0.04, + "Fósforo (mg)":36, + "Ferro (mg)":31.4, + "Sódio (mg)":17, + "Potássio (mg)":13, + "Cobre (mg)":"Tr", + "Zinco (mg)":8.5 + }, + { + "Número do Alimento":32, + "Descrição dos alimentos":"Farinha, de centeio, integral", + "Umidade (%)":10.8, + "Energia (Kcal)":336, + "Energia (KJ)":1405, + "Proteína (g)":12.5, + "Lipídeos (g)":1.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":73.3, + "Fibra Alimentar (g)":15.5, + "Cinzas (g)":1.7, + "Cálcio (mg)":34, + "Magnésio (mg)":120, + "Manganês (mg)":3.86, + "Fósforo (mg)":340, + "Ferro (mg)":4.7, + "Sódio (mg)":41, + "Potássio (mg)":334, + "Cobre (mg)":0.56, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":33, + "Descrição dos alimentos":"Farinha, de milho, amarela", + "Umidade (%)":11.8, + "Energia (Kcal)":351, + "Energia (KJ)":1467, + "Proteína (g)":7.2, + "Lipídeos (g)":1.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":79.1, + "Fibra Alimentar (g)":5.5, + "Cinzas (g)":0.5, + "Cálcio (mg)":1, + "Magnésio (mg)":31, + "Manganês (mg)":"Tr", + "Fósforo (mg)":84, + "Ferro (mg)":2.3, + "Sódio (mg)":45, + "Potássio (mg)":58, + "Cobre (mg)":0.27, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":34, + "Descrição dos alimentos":"Farinha, de rosca", + "Umidade (%)":9.8, + "Energia (Kcal)":371, + "Energia (KJ)":1550, + "Proteína (g)":11.4, + "Lipídeos (g)":1.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":75.8, + "Fibra Alimentar (g)":4.8, + "Cinzas (g)":1.6, + "Cálcio (mg)":35, + "Magnésio (mg)":57, + "Manganês (mg)":1.62, + "Fósforo (mg)":195, + "Ferro (mg)":6.7, + "Sódio (mg)":333, + "Potássio (mg)":212, + "Cobre (mg)":0.26, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":35, + "Descrição dos alimentos":"Farinha, de trigo", + "Umidade (%)":13.0, + "Energia (Kcal)":360, + "Energia (KJ)":1508, + "Proteína (g)":9.8, + "Lipídeos (g)":1.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":75.1, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.8, + "Cálcio (mg)":18, + "Magnésio (mg)":31, + "Manganês (mg)":0.46, + "Fósforo (mg)":115, + "Ferro (mg)":1.0, + "Sódio (mg)":1, + "Potássio (mg)":151, + "Cobre (mg)":0.15, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":36, + "Descrição dos alimentos":"Farinha, láctea, de cereais", + "Umidade (%)":2.7, + "Energia (Kcal)":415, + "Energia (KJ)":1736, + "Proteína (g)":11.9, + "Lipídeos (g)":5.8, + "Colesterol (mg)":11, + "Carboidrato (g)":77.8, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":1.9, + "Cálcio (mg)":196, + "Magnésio (mg)":58, + "Manganês (mg)":1.49, + "Fósforo (mg)":296, + "Ferro (mg)":8.7, + "Sódio (mg)":125, + "Potássio (mg)":366, + "Cobre (mg)":0.19, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":37, + "Descrição dos alimentos":"Lasanha, massa fresca, cozida", + "Umidade (%)":59.6, + "Energia (Kcal)":164, + "Energia (KJ)":685, + "Proteína (g)":5.8, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":32.5, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.9, + "Cálcio (mg)":10, + "Magnésio (mg)":4, + "Manganês (mg)":0.20, + "Fósforo (mg)":42, + "Ferro (mg)":1.2, + "Sódio (mg)":207, + "Potássio (mg)":54, + "Cobre (mg)":0.07, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":38, + "Descrição dos alimentos":"Lasanha, massa fresca, crua", + "Umidade (%)":45.0, + "Energia (Kcal)":220, + "Energia (KJ)":922, + "Proteína (g)":7.0, + "Lipídeos (g)":1.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":45.1, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":1.6, + "Cálcio (mg)":17, + "Magnésio (mg)":13, + "Manganês (mg)":0.34, + "Fósforo (mg)":82, + "Ferro (mg)":1.9, + "Sódio (mg)":667, + "Potássio (mg)":137, + "Cobre (mg)":0.10, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":39, + "Descrição dos alimentos":"Macarrão, instantâneo", + "Umidade (%)":6.0, + "Energia (Kcal)":436, + "Energia (KJ)":1824, + "Proteína (g)":8.8, + "Lipídeos (g)":17.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":62.4, + "Fibra Alimentar (g)":5.6, + "Cinzas (g)":5.6, + "Cálcio (mg)":18, + "Magnésio (mg)":19, + "Manganês (mg)":0.25, + "Fósforo (mg)":112, + "Ferro (mg)":0.8, + "Sódio (mg)":1516, + "Potássio (mg)":148, + "Cobre (mg)":0.10, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":40, + "Descrição dos alimentos":"Macarrão, trigo, cru", + "Umidade (%)":10.2, + "Energia (Kcal)":371, + "Energia (KJ)":1553, + "Proteína (g)":10.0, + "Lipídeos (g)":1.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":77.9, + "Fibra Alimentar (g)":2.9, + "Cinzas (g)":0.5, + "Cálcio (mg)":17, + "Magnésio (mg)":28, + "Manganês (mg)":0.53, + "Fósforo (mg)":100, + "Ferro (mg)":0.9, + "Sódio (mg)":7, + "Potássio (mg)":147, + "Cobre (mg)":0.15, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":41, + "Descrição dos alimentos":"Macarrão, trigo, cru, com ovos", + "Umidade (%)":10.6, + "Energia (Kcal)":371, + "Energia (KJ)":1550, + "Proteína (g)":10.3, + "Lipídeos (g)":2.0, + "Colesterol (mg)":18, + "Carboidrato (g)":76.6, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.5, + "Cálcio (mg)":19, + "Magnésio (mg)":"Tr", + "Manganês (mg)":0.40, + "Fósforo (mg)":118, + "Ferro (mg)":0.9, + "Sódio (mg)":15, + "Potássio (mg)":134, + "Cobre (mg)":0.14, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":42, + "Descrição dos alimentos":"Milho, amido, cru", + "Umidade (%)":12.2, + "Energia (Kcal)":361, + "Energia (KJ)":1512, + "Proteína (g)":0.6, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":87.1, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":0.1, + "Cálcio (mg)":1, + "Magnésio (mg)":3, + "Manganês (mg)":0.02, + "Fósforo (mg)":13, + "Ferro (mg)":0.1, + "Sódio (mg)":8, + "Potássio (mg)":9, + "Cobre (mg)":0.02, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":43, + "Descrição dos alimentos":"Milho, fubá, cru", + "Umidade (%)":11.5, + "Energia (Kcal)":353, + "Energia (KJ)":1479, + "Proteína (g)":7.2, + "Lipídeos (g)":1.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":78.9, + "Fibra Alimentar (g)":4.7, + "Cinzas (g)":0.6, + "Cálcio (mg)":3, + "Magnésio (mg)":41, + "Manganês (mg)":0.34, + "Fósforo (mg)":108, + "Ferro (mg)":0.9, + "Sódio (mg)":"Tr", + "Potássio (mg)":168, + "Cobre (mg)":0.08, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":44, + "Descrição dos alimentos":"Milho, verde, cru", + "Umidade (%)":63.5, + "Energia (Kcal)":138, + "Energia (KJ)":578, + "Proteína (g)":6.6, + "Lipídeos (g)":0.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":28.6, + "Fibra Alimentar (g)":3.9, + "Cinzas (g)":0.7, + "Cálcio (mg)":2, + "Magnésio (mg)":33, + "Manganês (mg)":0.12, + "Fósforo (mg)":113, + "Ferro (mg)":0.4, + "Sódio (mg)":1, + "Potássio (mg)":185, + "Cobre (mg)":0.05, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":45, + "Descrição dos alimentos":"Milho, verde, enlatado, drenado", + "Umidade (%)":76.2, + "Energia (Kcal)":98, + "Energia (KJ)":408, + "Proteína (g)":3.2, + "Lipídeos (g)":2.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":17.1, + "Fibra Alimentar (g)":4.6, + "Cinzas (g)":1.1, + "Cálcio (mg)":2, + "Magnésio (mg)":20, + "Manganês (mg)":0.09, + "Fósforo (mg)":61, + "Ferro (mg)":0.6, + "Sódio (mg)":260, + "Potássio (mg)":162, + "Cobre (mg)":0.05, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":46, + "Descrição dos alimentos":"Mingau tradicional, pó", + "Umidade (%)":8.1, + "Energia (Kcal)":373, + "Energia (KJ)":1562, + "Proteína (g)":0.6, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":89.3, + "Fibra Alimentar (g)":0.9, + "Cinzas (g)":1.6, + "Cálcio (mg)":522, + "Magnésio (mg)":4, + "Manganês (mg)":"Tr", + "Fósforo (mg)":273, + "Ferro (mg)":42.0, + "Sódio (mg)":15, + "Potássio (mg)":"Tr", + "Cobre (mg)":"Tr", + "Zinco (mg)":15.2 + }, + { + "Número do Alimento":47, + "Descrição dos alimentos":"Pamonha, barra para cozimento, pré-cozida", + "Umidade (%)":61.3, + "Energia (Kcal)":171, + "Energia (KJ)":716, + "Proteína (g)":2.6, + "Lipídeos (g)":4.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":30.7, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":0.6, + "Cálcio (mg)":4, + "Magnésio (mg)":15, + "Manganês (mg)":0.12, + "Fósforo (mg)":55, + "Ferro (mg)":0.4, + "Sódio (mg)":132, + "Potássio (mg)":125, + "Cobre (mg)":0.03, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":48, + "Descrição dos alimentos":"Pão, aveia, forma", + "Umidade (%)":19.9, + "Energia (Kcal)":343, + "Energia (KJ)":1435, + "Proteína (g)":12.4, + "Lipídeos (g)":5.7, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":59.6, + "Fibra Alimentar (g)":6.0, + "Cinzas (g)":2.5, + "Cálcio (mg)":109, + "Magnésio (mg)":57, + "Manganês (mg)":1.08, + "Fósforo (mg)":182, + "Ferro (mg)":4.7, + "Sódio (mg)":606, + "Potássio (mg)":210, + "Cobre (mg)":0.14, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":49, + "Descrição dos alimentos":"Pão, de soja", + "Umidade (%)":26.0, + "Energia (Kcal)":309, + "Energia (KJ)":1292, + "Proteína (g)":11.3, + "Lipídeos (g)":3.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":56.5, + "Fibra Alimentar (g)":5.7, + "Cinzas (g)":2.5, + "Cálcio (mg)":90, + "Magnésio (mg)":48, + "Manganês (mg)":0.57, + "Fósforo (mg)":153, + "Ferro (mg)":3.3, + "Sódio (mg)":663, + "Potássio (mg)":296, + "Cobre (mg)":0.16, + "Zinco (mg)":1.5 + }, + { + "Número do Alimento":50, + "Descrição dos alimentos":"Pão, glúten, forma", + "Umidade (%)":40.7, + "Energia (Kcal)":253, + "Energia (KJ)":1059, + "Proteína (g)":12.0, + "Lipídeos (g)":2.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":44.1, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":0.5, + "Cálcio (mg)":156, + "Magnésio (mg)":24, + "Manganês (mg)":0.51, + "Fósforo (mg)":105, + "Ferro (mg)":5.7, + "Sódio (mg)":22, + "Potássio (mg)":65, + "Cobre (mg)":0.06, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":51, + "Descrição dos alimentos":"Pão, milho, forma", + "Umidade (%)":30.4, + "Energia (Kcal)":292, + "Energia (KJ)":1222, + "Proteína (g)":8.3, + "Lipídeos (g)":3.1, + "Colesterol (mg)":6, + "Carboidrato (g)":56.4, + "Fibra Alimentar (g)":4.3, + "Cinzas (g)":1.8, + "Cálcio (mg)":78, + "Magnésio (mg)":29, + "Manganês (mg)":0.37, + "Fósforo (mg)":110, + "Ferro (mg)":3.0, + "Sódio (mg)":507, + "Potássio (mg)":89, + "Cobre (mg)":0.10, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":52, + "Descrição dos alimentos":"Pão, trigo, forma, integral", + "Umidade (%)":34.7, + "Energia (Kcal)":253, + "Energia (KJ)":1059, + "Proteína (g)":9.4, + "Lipídeos (g)":3.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":49.9, + "Fibra Alimentar (g)":6.9, + "Cinzas (g)":2.3, + "Cálcio (mg)":132, + "Magnésio (mg)":60, + "Manganês (mg)":1.62, + "Fósforo (mg)":193, + "Ferro (mg)":3.0, + "Sódio (mg)":506, + "Potássio (mg)":163, + "Cobre (mg)":0.15, + "Zinco (mg)":1.6 + }, + { + "Número do Alimento":53, + "Descrição dos alimentos":"Pão, trigo, francês", + "Umidade (%)":28.5, + "Energia (Kcal)":300, + "Energia (KJ)":1254, + "Proteína (g)":8.0, + "Lipídeos (g)":3.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":58.6, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":1.8, + "Cálcio (mg)":16, + "Magnésio (mg)":25, + "Manganês (mg)":0.46, + "Fósforo (mg)":95, + "Ferro (mg)":1.0, + "Sódio (mg)":648, + "Potássio (mg)":142, + "Cobre (mg)":0.13, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":54, + "Descrição dos alimentos":"Pão, trigo, sovado", + "Umidade (%)":25.8, + "Energia (Kcal)":311, + "Energia (KJ)":1301, + "Proteína (g)":8.4, + "Lipídeos (g)":2.8, + "Colesterol (mg)":17, + "Carboidrato (g)":61.5, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":1.5, + "Cálcio (mg)":52, + "Magnésio (mg)":22, + "Manganês (mg)":0.31, + "Fósforo (mg)":101, + "Ferro (mg)":2.3, + "Sódio (mg)":431, + "Potássio (mg)":91, + "Cobre (mg)":"Tr", + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":55, + "Descrição dos alimentos":"Pastel, de carne, cru", + "Umidade (%)":34.4, + "Energia (Kcal)":289, + "Energia (KJ)":1208, + "Proteína (g)":10.7, + "Lipídeos (g)":8.8, + "Colesterol (mg)":18, + "Carboidrato (g)":42.0, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":4.1, + "Cálcio (mg)":17, + "Magnésio (mg)":18, + "Manganês (mg)":0.34, + "Fósforo (mg)":117, + "Ferro (mg)":2.0, + "Sódio (mg)":1309, + "Potássio (mg)":166, + "Cobre (mg)":0.11, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":56, + "Descrição dos alimentos":"Pastel, de carne, frito", + "Umidade (%)":22.9, + "Energia (Kcal)":388, + "Energia (KJ)":1625, + "Proteína (g)":10.1, + "Lipídeos (g)":20.1, + "Colesterol (mg)":25, + "Carboidrato (g)":43.8, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":3.1, + "Cálcio (mg)":13, + "Magnésio (mg)":14, + "Manganês (mg)":0.22, + "Fósforo (mg)":90, + "Ferro (mg)":2.5, + "Sódio (mg)":1040, + "Potássio (mg)":156, + "Cobre (mg)":0.12, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":57, + "Descrição dos alimentos":"Pastel, de queijo, cru", + "Umidade (%)":31.3, + "Energia (Kcal)":308, + "Energia (KJ)":1291, + "Proteína (g)":9.9, + "Lipídeos (g)":9.6, + "Colesterol (mg)":14, + "Carboidrato (g)":45.9, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":3.3, + "Cálcio (mg)":155, + "Magnésio (mg)":16, + "Manganês (mg)":0.24, + "Fósforo (mg)":168, + "Ferro (mg)":1.0, + "Sódio (mg)":985, + "Potássio (mg)":103, + "Cobre (mg)":0.10, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":58, + "Descrição dos alimentos":"Pastel, de queijo, frito", + "Umidade (%)":17.5, + "Energia (Kcal)":422, + "Energia (KJ)":1766, + "Proteína (g)":8.7, + "Lipídeos (g)":22.7, + "Colesterol (mg)":15, + "Carboidrato (g)":48.1, + "Fibra Alimentar (g)":0.9, + "Cinzas (g)":2.9, + "Cálcio (mg)":126, + "Magnésio (mg)":15, + "Manganês (mg)":0.20, + "Fósforo (mg)":124, + "Ferro (mg)":1.3, + "Sódio (mg)":821, + "Potássio (mg)":124, + "Cobre (mg)":0.10, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":59, + "Descrição dos alimentos":"Pastel, massa, crua", + "Umidade (%)":27.1, + "Energia (Kcal)":310, + "Energia (KJ)":1298, + "Proteína (g)":6.9, + "Lipídeos (g)":5.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":57.4, + "Fibra Alimentar (g)":1.4, + "Cinzas (g)":3.2, + "Cálcio (mg)":13, + "Magnésio (mg)":14, + "Manganês (mg)":0.38, + "Fósforo (mg)":73, + "Ferro (mg)":1.1, + "Sódio (mg)":1344, + "Potássio (mg)":167, + "Cobre (mg)":0.11, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":60, + "Descrição dos alimentos":"Pastel, massa, frita", + "Umidade (%)":1.0, + "Energia (Kcal)":570, + "Energia (KJ)":2384, + "Proteína (g)":6.0, + "Lipídeos (g)":40.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":49.3, + "Fibra Alimentar (g)":1.3, + "Cinzas (g)":2.8, + "Cálcio (mg)":11, + "Magnésio (mg)":13, + "Manganês (mg)":0.36, + "Fósforo (mg)":62, + "Ferro (mg)":1.4, + "Sódio (mg)":1175, + "Potássio (mg)":143, + "Cobre (mg)":0.08, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":61, + "Descrição dos alimentos":"Pipoca, com óleo de soja, sem sal", + "Umidade (%)":2.8, + "Energia (Kcal)":448, + "Energia (KJ)":1876, + "Proteína (g)":9.9, + "Lipídeos (g)":15.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":70.3, + "Fibra Alimentar (g)":14.3, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":91, + "Manganês (mg)":0.65, + "Fósforo (mg)":225, + "Ferro (mg)":1.2, + "Sódio (mg)":4, + "Potássio (mg)":256, + "Cobre (mg)":0.46, + "Zinco (mg)":2.0 + }, + { + "Número do Alimento":62, + "Descrição dos alimentos":"Polenta, pré-cozida", + "Umidade (%)":72.7, + "Energia (Kcal)":103, + "Energia (KJ)":430, + "Proteína (g)":2.3, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":23.3, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":1.4, + "Cálcio (mg)":1, + "Magnésio (mg)":4, + "Manganês (mg)":"Tr", + "Fósforo (mg)":17, + "Ferro (mg)":"Tr", + "Sódio (mg)":442, + "Potássio (mg)":100, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":63, + "Descrição dos alimentos":"Torrada, pão francês", + "Umidade (%)":9.0, + "Energia (Kcal)":377, + "Energia (KJ)":1579, + "Proteína (g)":10.5, + "Lipídeos (g)":3.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":74.6, + "Fibra Alimentar (g)":3.4, + "Cinzas (g)":2.6, + "Cálcio (mg)":19, + "Magnésio (mg)":32, + "Manganês (mg)":0.55, + "Fósforo (mg)":114, + "Ferro (mg)":1.2, + "Sódio (mg)":829, + "Potássio (mg)":189, + "Cobre (mg)":0.16, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":64, + "Descrição dos alimentos":"Abóbora, cabotian, cozida", + "Umidade (%)":86.4, + "Energia (Kcal)":48, + "Energia (KJ)":201, + "Proteína (g)":1.4, + "Lipídeos (g)":0.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.8, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":0.7, + "Cálcio (mg)":8, + "Magnésio (mg)":9, + "Manganês (mg)":0.26, + "Fósforo (mg)":33, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":199, + "Cobre (mg)":0.06, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":65, + "Descrição dos alimentos":"Abóbora, cabotian, crua", + "Umidade (%)":88.5, + "Energia (Kcal)":39, + "Energia (KJ)":161, + "Proteína (g)":1.7, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.4, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.8, + "Cálcio (mg)":18, + "Magnésio (mg)":9, + "Manganês (mg)":0.11, + "Fósforo (mg)":26, + "Ferro (mg)":0.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":351, + "Cobre (mg)":0.06, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":66, + "Descrição dos alimentos":"Abóbora, menina brasileira, crua", + "Umidade (%)":95.7, + "Energia (Kcal)":14, + "Energia (KJ)":57, + "Proteína (g)":0.6, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.3, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.4, + "Cálcio (mg)":9, + "Magnésio (mg)":4, + "Manganês (mg)":0.01, + "Fósforo (mg)":12, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":165, + "Cobre (mg)":0.02, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":67, + "Descrição dos alimentos":"Abóbora, moranga, crua", + "Umidade (%)":95.9, + "Energia (Kcal)":12, + "Energia (KJ)":52, + "Proteína (g)":1.0, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.7, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":0.4, + "Cálcio (mg)":3, + "Magnésio (mg)":2, + "Manganês (mg)":0.01, + "Fósforo (mg)":8, + "Ferro (mg)":"Tr", + "Sódio (mg)":"Tr", + "Potássio (mg)":125, + "Cobre (mg)":0.05, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":68, + "Descrição dos alimentos":"Abóbora, moranga, refogada", + "Umidade (%)":92.5, + "Energia (Kcal)":29, + "Energia (KJ)":121, + "Proteína (g)":0.4, + "Lipídeos (g)":0.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.0, + "Fibra Alimentar (g)":1.5, + "Cinzas (g)":0.4, + "Cálcio (mg)":19, + "Magnésio (mg)":7, + "Manganês (mg)":0.02, + "Fósforo (mg)":12, + "Ferro (mg)":0.1, + "Sódio (mg)":3, + "Potássio (mg)":183, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":69, + "Descrição dos alimentos":"Abóbora, pescoço, crua", + "Umidade (%)":92.5, + "Energia (Kcal)":24, + "Energia (KJ)":102, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.1, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.6, + "Cálcio (mg)":9, + "Magnésio (mg)":7, + "Manganês (mg)":0.07, + "Fósforo (mg)":32, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":264, + "Cobre (mg)":0.09, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":70, + "Descrição dos alimentos":"Abobrinha, italiana, cozida", + "Umidade (%)":95.3, + "Energia (Kcal)":15, + "Energia (KJ)":63, + "Proteína (g)":1.1, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.0, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.4, + "Cálcio (mg)":17, + "Magnésio (mg)":17, + "Manganês (mg)":0.11, + "Fósforo (mg)":22, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":126, + "Cobre (mg)":0.01, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":71, + "Descrição dos alimentos":"Abobrinha, italiana, crua", + "Umidade (%)":93.9, + "Energia (Kcal)":19, + "Energia (KJ)":81, + "Proteína (g)":1.1, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.3, + "Fibra Alimentar (g)":1.4, + "Cinzas (g)":0.6, + "Cálcio (mg)":15, + "Magnésio (mg)":20, + "Manganês (mg)":0.09, + "Fósforo (mg)":32, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":253, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":72, + "Descrição dos alimentos":"Abobrinha, italiana, refogada", + "Umidade (%)":93.5, + "Energia (Kcal)":24, + "Energia (KJ)":102, + "Proteína (g)":1.1, + "Lipídeos (g)":0.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.2, + "Fibra Alimentar (g)":1.4, + "Cinzas (g)":0.4, + "Cálcio (mg)":21, + "Magnésio (mg)":13, + "Manganês (mg)":0.14, + "Fósforo (mg)":32, + "Ferro (mg)":0.4, + "Sódio (mg)":2, + "Potássio (mg)":194, + "Cobre (mg)":0.02, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":73, + "Descrição dos alimentos":"Abobrinha, paulista, crua", + "Umidade (%)":90.9, + "Energia (Kcal)":31, + "Energia (KJ)":129, + "Proteína (g)":0.6, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.9, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.5, + "Cálcio (mg)":19, + "Magnésio (mg)":9, + "Manganês (mg)":0.11, + "Fósforo (mg)":33, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":213, + "Cobre (mg)":0.10, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":74, + "Descrição dos alimentos":"Acelga, crua", + "Umidade (%)":93.2, + "Energia (Kcal)":21, + "Energia (KJ)":88, + "Proteína (g)":1.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.6, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":0.6, + "Cálcio (mg)":43, + "Magnésio (mg)":10, + "Manganês (mg)":0.11, + "Fósforo (mg)":40, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":240, + "Cobre (mg)":0.10, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":75, + "Descrição dos alimentos":"Agrião, cru", + "Umidade (%)":93.9, + "Energia (Kcal)":17, + "Energia (KJ)":69, + "Proteína (g)":2.7, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.3, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":0.9, + "Cálcio (mg)":133, + "Magnésio (mg)":18, + "Manganês (mg)":0.28, + "Fósforo (mg)":51, + "Ferro (mg)":3.1, + "Sódio (mg)":7, + "Potássio (mg)":218, + "Cobre (mg)":0.10, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":76, + "Descrição dos alimentos":"Aipo, cru", + "Umidade (%)":93.8, + "Energia (Kcal)":19, + "Energia (KJ)":80, + "Proteína (g)":0.8, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.3, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":65, + "Magnésio (mg)":9, + "Manganês (mg)":0.18, + "Fósforo (mg)":28, + "Ferro (mg)":0.7, + "Sódio (mg)":10, + "Potássio (mg)":274, + "Cobre (mg)":0.31, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":77, + "Descrição dos alimentos":"Alface, americana, crua", + "Umidade (%)":97.2, + "Energia (Kcal)":9, + "Energia (KJ)":37, + "Proteína (g)":0.6, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":1.7, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":0.3, + "Cálcio (mg)":14, + "Magnésio (mg)":6, + "Manganês (mg)":0.12, + "Fósforo (mg)":19, + "Ferro (mg)":0.3, + "Sódio (mg)":7, + "Potássio (mg)":136, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":78, + "Descrição dos alimentos":"Alface, crespa, crua", + "Umidade (%)":96.1, + "Energia (Kcal)":11, + "Energia (KJ)":45, + "Proteína (g)":1.3, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":1.7, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.7, + "Cálcio (mg)":38, + "Magnésio (mg)":11, + "Manganês (mg)":0.20, + "Fósforo (mg)":26, + "Ferro (mg)":0.4, + "Sódio (mg)":3, + "Potássio (mg)":267, + "Cobre (mg)":0.03, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":79, + "Descrição dos alimentos":"Alface, lisa, crua", + "Umidade (%)":95.0, + "Energia (Kcal)":14, + "Energia (KJ)":58, + "Proteína (g)":1.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.4, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.8, + "Cálcio (mg)":28, + "Magnésio (mg)":9, + "Manganês (mg)":0.33, + "Fósforo (mg)":26, + "Ferro (mg)":0.6, + "Sódio (mg)":4, + "Potássio (mg)":349, + "Cobre (mg)":0.03, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":80, + "Descrição dos alimentos":"Alface, roxa, crua", + "Umidade (%)":95.7, + "Energia (Kcal)":13, + "Energia (KJ)":53, + "Proteína (g)":0.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.5, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":34, + "Magnésio (mg)":9, + "Manganês (mg)":0.12, + "Fósforo (mg)":51, + "Ferro (mg)":2.5, + "Sódio (mg)":7, + "Potássio (mg)":308, + "Cobre (mg)":0.04, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":81, + "Descrição dos alimentos":"Alfavaca, crua", + "Umidade (%)":90.2, + "Energia (Kcal)":29, + "Energia (KJ)":122, + "Proteína (g)":2.7, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.2, + "Fibra Alimentar (g)":4.1, + "Cinzas (g)":1.4, + "Cálcio (mg)":258, + "Magnésio (mg)":84, + "Manganês (mg)":0.15, + "Fósforo (mg)":50, + "Ferro (mg)":1.3, + "Sódio (mg)":5, + "Potássio (mg)":261, + "Cobre (mg)":0.15, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":82, + "Descrição dos alimentos":"Alho, cru", + "Umidade (%)":67.5, + "Energia (Kcal)":113, + "Energia (KJ)":473, + "Proteína (g)":7.0, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":23.9, + "Fibra Alimentar (g)":4.3, + "Cinzas (g)":1.3, + "Cálcio (mg)":14, + "Magnésio (mg)":21, + "Manganês (mg)":0.24, + "Fósforo (mg)":149, + "Ferro (mg)":0.8, + "Sódio (mg)":5, + "Potássio (mg)":535, + "Cobre (mg)":0.15, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":83, + "Descrição dos alimentos":"Alho-poró, cru", + "Umidade (%)":91.0, + "Energia (Kcal)":32, + "Energia (KJ)":132, + "Proteína (g)":1.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.9, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":0.6, + "Cálcio (mg)":34, + "Magnésio (mg)":11, + "Manganês (mg)":0.10, + "Fósforo (mg)":36, + "Ferro (mg)":0.6, + "Sódio (mg)":2, + "Potássio (mg)":224, + "Cobre (mg)":0.29, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":84, + "Descrição dos alimentos":"Almeirão, cru", + "Umidade (%)":93.7, + "Energia (Kcal)":18, + "Energia (KJ)":75, + "Proteína (g)":1.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.3, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":1.0, + "Cálcio (mg)":19, + "Magnésio (mg)":21, + "Manganês (mg)":0.17, + "Fósforo (mg)":40, + "Ferro (mg)":0.7, + "Sódio (mg)":2, + "Potássio (mg)":369, + "Cobre (mg)":0.10, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":85, + "Descrição dos alimentos":"Almeirão, refogado", + "Umidade (%)":86.5, + "Energia (Kcal)":65, + "Energia (KJ)":272, + "Proteína (g)":1.7, + "Lipídeos (g)":4.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.7, + "Fibra Alimentar (g)":3.4, + "Cinzas (g)":1.2, + "Cálcio (mg)":63, + "Magnésio (mg)":17, + "Manganês (mg)":0.28, + "Fósforo (mg)":31, + "Ferro (mg)":1.6, + "Sódio (mg)":15, + "Potássio (mg)":315, + "Cobre (mg)":0.06, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":86, + "Descrição dos alimentos":"Batata, baroa, cozida", + "Umidade (%)":79.3, + "Energia (Kcal)":80, + "Energia (KJ)":335, + "Proteína (g)":0.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.9, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.8, + "Cálcio (mg)":12, + "Magnésio (mg)":8, + "Manganês (mg)":0.22, + "Fósforo (mg)":29, + "Ferro (mg)":0.4, + "Sódio (mg)":2, + "Potássio (mg)":258, + "Cobre (mg)":0.15, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":87, + "Descrição dos alimentos":"Batata, baroa, crua", + "Umidade (%)":73.7, + "Energia (Kcal)":101, + "Energia (KJ)":423, + "Proteína (g)":1.0, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":24.0, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":1.1, + "Cálcio (mg)":17, + "Magnésio (mg)":12, + "Manganês (mg)":0.07, + "Fósforo (mg)":45, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":505, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":88, + "Descrição dos alimentos":"Batata, doce, cozida", + "Umidade (%)":80.4, + "Energia (Kcal)":77, + "Energia (KJ)":321, + "Proteína (g)":0.6, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.4, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.4, + "Cálcio (mg)":17, + "Magnésio (mg)":11, + "Manganês (mg)":0.14, + "Fósforo (mg)":15, + "Ferro (mg)":0.2, + "Sódio (mg)":3, + "Potássio (mg)":148, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":89, + "Descrição dos alimentos":"Batata, doce, crua", + "Umidade (%)":69.5, + "Energia (Kcal)":118, + "Energia (KJ)":495, + "Proteína (g)":1.3, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":28.2, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.9, + "Cálcio (mg)":21, + "Magnésio (mg)":17, + "Manganês (mg)":0.18, + "Fósforo (mg)":36, + "Ferro (mg)":0.4, + "Sódio (mg)":9, + "Potássio (mg)":340, + "Cobre (mg)":0.11, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":90, + "Descrição dos alimentos":"Batata, frita, tipo chips, industrializada", + "Umidade (%)":2.7, + "Energia (Kcal)":543, + "Energia (KJ)":2271, + "Proteína (g)":5.6, + "Lipídeos (g)":36.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":51.2, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":3.9, + "Cálcio (mg)":12, + "Magnésio (mg)":24, + "Manganês (mg)":0.23, + "Fósforo (mg)":96, + "Ferro (mg)":0.7, + "Sódio (mg)":607, + "Potássio (mg)":1014, + "Cobre (mg)":0.12, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":91, + "Descrição dos alimentos":"Batata, inglesa, cozida", + "Umidade (%)":86.4, + "Energia (Kcal)":52, + "Energia (KJ)":216, + "Proteína (g)":1.2, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.9, + "Fibra Alimentar (g)":1.3, + "Cinzas (g)":0.5, + "Cálcio (mg)":4, + "Magnésio (mg)":5, + "Manganês (mg)":0.07, + "Fósforo (mg)":24, + "Ferro (mg)":0.2, + "Sódio (mg)":2, + "Potássio (mg)":161, + "Cobre (mg)":0.06, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":92, + "Descrição dos alimentos":"Batata, inglesa, crua", + "Umidade (%)":82.9, + "Energia (Kcal)":64, + "Energia (KJ)":269, + "Proteína (g)":1.8, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.7, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.6, + "Cálcio (mg)":4, + "Magnésio (mg)":15, + "Manganês (mg)":0.10, + "Fósforo (mg)":39, + "Ferro (mg)":0.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":302, + "Cobre (mg)":0.09, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":93, + "Descrição dos alimentos":"Batata, inglesa, frita", + "Umidade (%)":44.1, + "Energia (Kcal)":267, + "Energia (KJ)":1118, + "Proteína (g)":5.0, + "Lipídeos (g)":13.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":35.6, + "Fibra Alimentar (g)":8.1, + "Cinzas (g)":2.2, + "Cálcio (mg)":6, + "Magnésio (mg)":14, + "Manganês (mg)":0.15, + "Fósforo (mg)":70, + "Ferro (mg)":0.4, + "Sódio (mg)":2, + "Potássio (mg)":489, + "Cobre (mg)":0.10, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":94, + "Descrição dos alimentos":"Batata, inglesa, sauté", + "Umidade (%)":83.1, + "Energia (Kcal)":68, + "Energia (KJ)":284, + "Proteína (g)":1.3, + "Lipídeos (g)":0.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.1, + "Fibra Alimentar (g)":1.4, + "Cinzas (g)":0.6, + "Cálcio (mg)":4, + "Magnésio (mg)":6, + "Manganês (mg)":0.08, + "Fósforo (mg)":32, + "Ferro (mg)":0.3, + "Sódio (mg)":8, + "Potássio (mg)":199, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":95, + "Descrição dos alimentos":"Berinjela, cozida", + "Umidade (%)":94.4, + "Energia (Kcal)":19, + "Energia (KJ)":79, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.5, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":0.3, + "Cálcio (mg)":11, + "Magnésio (mg)":9, + "Manganês (mg)":0.11, + "Fósforo (mg)":15, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":105, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":96, + "Descrição dos alimentos":"Berinjela, crua", + "Umidade (%)":93.8, + "Energia (Kcal)":20, + "Energia (KJ)":82, + "Proteína (g)":1.2, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.4, + "Fibra Alimentar (g)":2.9, + "Cinzas (g)":0.4, + "Cálcio (mg)":9, + "Magnésio (mg)":13, + "Manganês (mg)":0.10, + "Fósforo (mg)":20, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":205, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":97, + "Descrição dos alimentos":"Beterraba, cozida", + "Umidade (%)":90.6, + "Energia (Kcal)":32, + "Energia (KJ)":135, + "Proteína (g)":1.3, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.2, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":0.8, + "Cálcio (mg)":15, + "Magnésio (mg)":17, + "Manganês (mg)":0.19, + "Fósforo (mg)":30, + "Ferro (mg)":0.2, + "Sódio (mg)":23, + "Potássio (mg)":245, + "Cobre (mg)":0.04, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":98, + "Descrição dos alimentos":"Beterraba, crua", + "Umidade (%)":86.0, + "Energia (Kcal)":49, + "Energia (KJ)":204, + "Proteína (g)":1.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.1, + "Fibra Alimentar (g)":3.4, + "Cinzas (g)":0.9, + "Cálcio (mg)":18, + "Magnésio (mg)":24, + "Manganês (mg)":1.23, + "Fósforo (mg)":19, + "Ferro (mg)":0.3, + "Sódio (mg)":10, + "Potássio (mg)":375, + "Cobre (mg)":0.08, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":99, + "Descrição dos alimentos":"Biscoito, polvilho doce", + "Umidade (%)":5.4, + "Energia (Kcal)":438, + "Energia (KJ)":1831, + "Proteína (g)":1.3, + "Lipídeos (g)":12.2, + "Colesterol (mg)":9, + "Carboidrato (g)":80.5, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.5, + "Cálcio (mg)":30, + "Magnésio (mg)":6, + "Manganês (mg)":0.08, + "Fósforo (mg)":23, + "Ferro (mg)":1.8, + "Sódio (mg)":98, + "Potássio (mg)":54, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":100, + "Descrição dos alimentos":"Brócolis, cozido", + "Umidade (%)":92.6, + "Energia (Kcal)":25, + "Energia (KJ)":103, + "Proteína (g)":2.1, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.4, + "Fibra Alimentar (g)":3.4, + "Cinzas (g)":0.4, + "Cálcio (mg)":51, + "Magnésio (mg)":15, + "Manganês (mg)":0.12, + "Fósforo (mg)":33, + "Ferro (mg)":0.5, + "Sódio (mg)":2, + "Potássio (mg)":119, + "Cobre (mg)":0.08, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":101, + "Descrição dos alimentos":"Brócolis, cru", + "Umidade (%)":91.2, + "Energia (Kcal)":25, + "Energia (KJ)":107, + "Proteína (g)":3.6, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.0, + "Fibra Alimentar (g)":2.9, + "Cinzas (g)":0.8, + "Cálcio (mg)":86, + "Magnésio (mg)":30, + "Manganês (mg)":0.26, + "Fósforo (mg)":78, + "Ferro (mg)":0.6, + "Sódio (mg)":3, + "Potássio (mg)":322, + "Cobre (mg)":0.06, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":102, + "Descrição dos alimentos":"Cará, cozido", + "Umidade (%)":78.9, + "Energia (Kcal)":78, + "Energia (KJ)":325, + "Proteína (g)":1.5, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.9, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.6, + "Cálcio (mg)":5, + "Magnésio (mg)":15, + "Manganês (mg)":0.02, + "Fósforo (mg)":28, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":203, + "Cobre (mg)":0.11, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":103, + "Descrição dos alimentos":"Cará, cru", + "Umidade (%)":73.7, + "Energia (Kcal)":96, + "Energia (KJ)":400, + "Proteína (g)":2.3, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":23.0, + "Fibra Alimentar (g)":7.3, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":11, + "Manganês (mg)":0.01, + "Fósforo (mg)":35, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":212, + "Cobre (mg)":0.06, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":104, + "Descrição dos alimentos":"Caruru, cru", + "Umidade (%)":87.6, + "Energia (Kcal)":34, + "Energia (KJ)":142, + "Proteína (g)":3.2, + "Lipídeos (g)":0.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.0, + "Fibra Alimentar (g)":4.5, + "Cinzas (g)":2.6, + "Cálcio (mg)":455, + "Magnésio (mg)":197, + "Manganês (mg)":0.89, + "Fósforo (mg)":77, + "Ferro (mg)":4.5, + "Sódio (mg)":14, + "Potássio (mg)":279, + "Cobre (mg)":0.37, + "Zinco (mg)":6.0 + }, + { + "Número do Alimento":105, + "Descrição dos alimentos":"Catalonha, crua", + "Umidade (%)":91.8, + "Energia (Kcal)":24, + "Energia (KJ)":100, + "Proteína (g)":1.9, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.8, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":57, + "Magnésio (mg)":17, + "Manganês (mg)":0.34, + "Fósforo (mg)":32, + "Ferro (mg)":3.1, + "Sódio (mg)":9, + "Potássio (mg)":412, + "Cobre (mg)":0.27, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":106, + "Descrição dos alimentos":"Catalonha, refogada", + "Umidade (%)":87.4, + "Energia (Kcal)":63, + "Energia (KJ)":265, + "Proteína (g)":2.0, + "Lipídeos (g)":4.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.8, + "Fibra Alimentar (g)":3.7, + "Cinzas (g)":1.0, + "Cálcio (mg)":63, + "Magnésio (mg)":16, + "Manganês (mg)":0.64, + "Fósforo (mg)":35, + "Ferro (mg)":1.2, + "Sódio (mg)":25, + "Potássio (mg)":452, + "Cobre (mg)":0.18, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":107, + "Descrição dos alimentos":"Cebola, crua", + "Umidade (%)":88.9, + "Energia (Kcal)":39, + "Energia (KJ)":165, + "Proteína (g)":1.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.9, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.4, + "Cálcio (mg)":14, + "Magnésio (mg)":12, + "Manganês (mg)":0.13, + "Fósforo (mg)":38, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":176, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":108, + "Descrição dos alimentos":"Cebolinha, crua", + "Umidade (%)":93.9, + "Energia (Kcal)":20, + "Energia (KJ)":82, + "Proteína (g)":1.9, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.4, + "Fibra Alimentar (g)":3.6, + "Cinzas (g)":0.5, + "Cálcio (mg)":80, + "Magnésio (mg)":25, + "Manganês (mg)":0.13, + "Fósforo (mg)":27, + "Ferro (mg)":0.6, + "Sódio (mg)":2, + "Potássio (mg)":206, + "Cobre (mg)":0.04, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":109, + "Descrição dos alimentos":"Cenoura, cozida", + "Umidade (%)":91.7, + "Energia (Kcal)":30, + "Energia (KJ)":125, + "Proteína (g)":0.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.7, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.6, + "Cálcio (mg)":26, + "Magnésio (mg)":14, + "Manganês (mg)":0.05, + "Fósforo (mg)":27, + "Ferro (mg)":0.1, + "Sódio (mg)":8, + "Potássio (mg)":176, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":110, + "Descrição dos alimentos":"Cenoura, crua", + "Umidade (%)":90.1, + "Energia (Kcal)":34, + "Energia (KJ)":143, + "Proteína (g)":1.3, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.7, + "Fibra Alimentar (g)":3.2, + "Cinzas (g)":0.9, + "Cálcio (mg)":23, + "Magnésio (mg)":11, + "Manganês (mg)":0.05, + "Fósforo (mg)":28, + "Ferro (mg)":0.2, + "Sódio (mg)":3, + "Potássio (mg)":315, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":111, + "Descrição dos alimentos":"Chicória, crua", + "Umidade (%)":95.1, + "Energia (Kcal)":14, + "Energia (KJ)":58, + "Proteína (g)":1.1, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.9, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.8, + "Cálcio (mg)":45, + "Magnésio (mg)":14, + "Manganês (mg)":0.13, + "Fósforo (mg)":13, + "Ferro (mg)":0.5, + "Sódio (mg)":14, + "Potássio (mg)":425, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":112, + "Descrição dos alimentos":"Chuchu, cozido", + "Umidade (%)":94.6, + "Energia (Kcal)":19, + "Energia (KJ)":78, + "Proteína (g)":0.4, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.8, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":0.2, + "Cálcio (mg)":8, + "Magnésio (mg)":7, + "Manganês (mg)":0.07, + "Fósforo (mg)":13, + "Ferro (mg)":0.1, + "Sódio (mg)":2, + "Potássio (mg)":54, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":113, + "Descrição dos alimentos":"Chuchu, cru", + "Umidade (%)":94.8, + "Energia (Kcal)":17, + "Energia (KJ)":71, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.1, + "Fibra Alimentar (g)":1.3, + "Cinzas (g)":0.3, + "Cálcio (mg)":12, + "Magnésio (mg)":7, + "Manganês (mg)":0.08, + "Fósforo (mg)":18, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":126, + "Cobre (mg)":0.03, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":114, + "Descrição dos alimentos":"Coentro, folhas desidratadas", + "Umidade (%)":10.6, + "Energia (Kcal)":309, + "Energia (KJ)":1293, + "Proteína (g)":20.9, + "Lipídeos (g)":10.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":48.0, + "Fibra Alimentar (g)":37.3, + "Cinzas (g)":10.2, + "Cálcio (mg)":784, + "Magnésio (mg)":393, + "Manganês (mg)":10.48, + "Fósforo (mg)":388, + "Ferro (mg)":81.4, + "Sódio (mg)":18, + "Potássio (mg)":3223, + "Cobre (mg)":4.09, + "Zinco (mg)":4.7 + }, + { + "Número do Alimento":115, + "Descrição dos alimentos":"Couve, manteiga, crua", + "Umidade (%)":90.9, + "Energia (Kcal)":27, + "Energia (KJ)":113, + "Proteína (g)":2.9, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.3, + "Fibra Alimentar (g)":3.1, + "Cinzas (g)":1.3, + "Cálcio (mg)":131, + "Magnésio (mg)":35, + "Manganês (mg)":1.02, + "Fósforo (mg)":49, + "Ferro (mg)":0.5, + "Sódio (mg)":6, + "Potássio (mg)":403, + "Cobre (mg)":0.06, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":116, + "Descrição dos alimentos":"Couve, manteiga, refogada ", + "Umidade (%)":81.5, + "Energia (Kcal)":90, + "Energia (KJ)":378, + "Proteína (g)":1.7, + "Lipídeos (g)":6.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.7, + "Fibra Alimentar (g)":5.7, + "Cinzas (g)":1.5, + "Cálcio (mg)":177, + "Magnésio (mg)":26, + "Manganês (mg)":0.12, + "Fósforo (mg)":33, + "Ferro (mg)":0.5, + "Sódio (mg)":11, + "Potássio (mg)":315, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":117, + "Descrição dos alimentos":"Couve-flor, crua", + "Umidade (%)":92.8, + "Energia (Kcal)":23, + "Energia (KJ)":94, + "Proteína (g)":1.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.5, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":0.6, + "Cálcio (mg)":18, + "Magnésio (mg)":12, + "Manganês (mg)":0.16, + "Fósforo (mg)":57, + "Ferro (mg)":0.5, + "Sódio (mg)":3, + "Potássio (mg)":256, + "Cobre (mg)":0.03, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":118, + "Descrição dos alimentos":"Couve-flor, cozida", + "Umidade (%)":94.3, + "Energia (Kcal)":19, + "Energia (KJ)":80, + "Proteína (g)":1.2, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.9, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":0.3, + "Cálcio (mg)":16, + "Magnésio (mg)":5, + "Manganês (mg)":0.10, + "Fósforo (mg)":25, + "Ferro (mg)":0.1, + "Sódio (mg)":2, + "Potássio (mg)":80, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":119, + "Descrição dos alimentos":"Espinafre, Nova Zelândia, cru", + "Umidade (%)":94.0, + "Energia (Kcal)":16, + "Energia (KJ)":67, + "Proteína (g)":2.0, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.6, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":1.2, + "Cálcio (mg)":98, + "Magnésio (mg)":82, + "Manganês (mg)":0.71, + "Fósforo (mg)":25, + "Ferro (mg)":0.4, + "Sódio (mg)":17, + "Potássio (mg)":336, + "Cobre (mg)":0.06, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":120, + "Descrição dos alimentos":"Espinafre, Nova Zelândia, refogado", + "Umidade (%)":86.6, + "Energia (Kcal)":67, + "Energia (KJ)":281, + "Proteína (g)":2.7, + "Lipídeos (g)":5.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.2, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":1.0, + "Cálcio (mg)":112, + "Magnésio (mg)":123, + "Manganês (mg)":0.61, + "Fósforo (mg)":34, + "Ferro (mg)":0.6, + "Sódio (mg)":47, + "Potássio (mg)":149, + "Cobre (mg)":0.04, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":121, + "Descrição dos alimentos":"Farinha, de mandioca, crua", + "Umidade (%)":9.4, + "Energia (Kcal)":361, + "Energia (KJ)":1510, + "Proteína (g)":1.6, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":87.9, + "Fibra Alimentar (g)":6.4, + "Cinzas (g)":0.9, + "Cálcio (mg)":65, + "Magnésio (mg)":37, + "Manganês (mg)":"Tr", + "Fósforo (mg)":42, + "Ferro (mg)":1.1, + "Sódio (mg)":1, + "Potássio (mg)":340, + "Cobre (mg)":0.08, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":122, + "Descrição dos alimentos":"Farinha, de mandioca, torrada", + "Umidade (%)":8.3, + "Energia (Kcal)":365, + "Energia (KJ)":1528, + "Proteína (g)":1.2, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":89.2, + "Fibra Alimentar (g)":6.5, + "Cinzas (g)":1.0, + "Cálcio (mg)":76, + "Magnésio (mg)":40, + "Manganês (mg)":0.37, + "Fósforo (mg)":39, + "Ferro (mg)":1.2, + "Sódio (mg)":10, + "Potássio (mg)":328, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":123, + "Descrição dos alimentos":"Farinha, de puba", + "Umidade (%)":9.8, + "Energia (Kcal)":360, + "Energia (KJ)":1507, + "Proteína (g)":1.6, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":87.3, + "Fibra Alimentar (g)":4.2, + "Cinzas (g)":0.8, + "Cálcio (mg)":41, + "Magnésio (mg)":27, + "Manganês (mg)":0.16, + "Fósforo (mg)":33, + "Ferro (mg)":1.4, + "Sódio (mg)":4, + "Potássio (mg)":338, + "Cobre (mg)":0.07, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":124, + "Descrição dos alimentos":"Fécula, de mandioca", + "Umidade (%)":17.8, + "Energia (Kcal)":331, + "Energia (KJ)":1384, + "Proteína (g)":0.5, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":81.1, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":0.3, + "Cálcio (mg)":12, + "Magnésio (mg)":3, + "Manganês (mg)":"Tr", + "Fósforo (mg)":60, + "Ferro (mg)":0.1, + "Sódio (mg)":2, + "Potássio (mg)":48, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":125, + "Descrição dos alimentos":"Feijão, broto, cru", + "Umidade (%)":87.5, + "Energia (Kcal)":39, + "Energia (KJ)":162, + "Proteína (g)":4.2, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.8, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.5, + "Cálcio (mg)":14, + "Magnésio (mg)":25, + "Manganês (mg)":0.19, + "Fósforo (mg)":75, + "Ferro (mg)":0.8, + "Sódio (mg)":2, + "Potássio (mg)":189, + "Cobre (mg)":0.17, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":126, + "Descrição dos alimentos":"Inhame, cru", + "Umidade (%)":73.3, + "Energia (Kcal)":97, + "Energia (KJ)":405, + "Proteína (g)":2.1, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":23.2, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":1.2, + "Cálcio (mg)":12, + "Magnésio (mg)":29, + "Manganês (mg)":0.15, + "Fósforo (mg)":65, + "Ferro (mg)":0.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":568, + "Cobre (mg)":0.17, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":127, + "Descrição dos alimentos":"Jiló, cru", + "Umidade (%)":91.6, + "Energia (Kcal)":27, + "Energia (KJ)":114, + "Proteína (g)":1.4, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.2, + "Fibra Alimentar (g)":4.8, + "Cinzas (g)":0.6, + "Cálcio (mg)":20, + "Magnésio (mg)":21, + "Manganês (mg)":0.14, + "Fósforo (mg)":29, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":213, + "Cobre (mg)":0.07, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":128, + "Descrição dos alimentos":"Jurubeba, crua", + "Umidade (%)":66.6, + "Energia (Kcal)":126, + "Energia (KJ)":526, + "Proteína (g)":4.4, + "Lipídeos (g)":3.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":23.1, + "Fibra Alimentar (g)":23.9, + "Cinzas (g)":2.0, + "Cálcio (mg)":151, + "Magnésio (mg)":65, + "Manganês (mg)":0.52, + "Fósforo (mg)":155, + "Ferro (mg)":0.9, + "Sódio (mg)":1, + "Potássio (mg)":619, + "Cobre (mg)":1.16, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":129, + "Descrição dos alimentos":"Mandioca, cozida", + "Umidade (%)":68.7, + "Energia (Kcal)":125, + "Energia (KJ)":524, + "Proteína (g)":0.6, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":30.1, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.4, + "Cálcio (mg)":19, + "Magnésio (mg)":27, + "Manganês (mg)":0.06, + "Fósforo (mg)":22, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":100, + "Cobre (mg)":0.01, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":130, + "Descrição dos alimentos":"Mandioca, crua", + "Umidade (%)":61.8, + "Energia (Kcal)":151, + "Energia (KJ)":634, + "Proteína (g)":1.1, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":36.2, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":0.6, + "Cálcio (mg)":15, + "Magnésio (mg)":44, + "Manganês (mg)":0.05, + "Fósforo (mg)":29, + "Ferro (mg)":0.3, + "Sódio (mg)":2, + "Potássio (mg)":208, + "Cobre (mg)":0.07, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":131, + "Descrição dos alimentos":"Mandioca, farofa, temperada", + "Umidade (%)":6.4, + "Energia (Kcal)":406, + "Energia (KJ)":1697, + "Proteína (g)":2.1, + "Lipídeos (g)":9.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":80.3, + "Fibra Alimentar (g)":7.8, + "Cinzas (g)":2.1, + "Cálcio (mg)":66, + "Magnésio (mg)":34, + "Manganês (mg)":0.29, + "Fósforo (mg)":45, + "Ferro (mg)":1.4, + "Sódio (mg)":575, + "Potássio (mg)":201, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":132, + "Descrição dos alimentos":"Mandioca, frita", + "Umidade (%)":36.6, + "Energia (Kcal)":300, + "Energia (KJ)":1255, + "Proteína (g)":1.4, + "Lipídeos (g)":11.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":50.3, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":0.6, + "Cálcio (mg)":23, + "Magnésio (mg)":95, + "Manganês (mg)":0.18, + "Fósforo (mg)":57, + "Ferro (mg)":0.3, + "Sódio (mg)":9, + "Potássio (mg)":176, + "Cobre (mg)":0.12, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":133, + "Descrição dos alimentos":"Manjericão, cru", + "Umidade (%)":93.0, + "Energia (Kcal)":21, + "Energia (KJ)":88, + "Proteína (g)":2.0, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.6, + "Fibra Alimentar (g)":3.3, + "Cinzas (g)":1.0, + "Cálcio (mg)":211, + "Magnésio (mg)":58, + "Manganês (mg)":0.17, + "Fósforo (mg)":40, + "Ferro (mg)":1.0, + "Sódio (mg)":4, + "Potássio (mg)":252, + "Cobre (mg)":0.16, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":134, + "Descrição dos alimentos":"Maxixe, cru", + "Umidade (%)":95.1, + "Energia (Kcal)":14, + "Energia (KJ)":58, + "Proteína (g)":1.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.7, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.7, + "Cálcio (mg)":21, + "Magnésio (mg)":10, + "Manganês (mg)":0.07, + "Fósforo (mg)":25, + "Ferro (mg)":0.4, + "Sódio (mg)":11, + "Potássio (mg)":328, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":135, + "Descrição dos alimentos":"Mostarda, folha, crua", + "Umidade (%)":93.4, + "Energia (Kcal)":18, + "Energia (KJ)":76, + "Proteína (g)":2.1, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.2, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":1.1, + "Cálcio (mg)":68, + "Magnésio (mg)":16, + "Manganês (mg)":0.14, + "Fósforo (mg)":58, + "Ferro (mg)":1.1, + "Sódio (mg)":3, + "Potássio (mg)":364, + "Cobre (mg)":0.05, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":136, + "Descrição dos alimentos":"Nhoque, batata, cozido", + "Umidade (%)":55.0, + "Energia (Kcal)":181, + "Energia (KJ)":756, + "Proteína (g)":5.9, + "Lipídeos (g)":1.9, + "Colesterol (mg)":15, + "Carboidrato (g)":36.8, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.5, + "Cálcio (mg)":11, + "Magnésio (mg)":18, + "Manganês (mg)":0.30, + "Fósforo (mg)":68, + "Ferro (mg)":1.6, + "Sódio (mg)":7, + "Potássio (mg)":164, + "Cobre (mg)":0.10, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":137, + "Descrição dos alimentos":"Nabo, cru", + "Umidade (%)":93.8, + "Energia (Kcal)":18, + "Energia (KJ)":76, + "Proteína (g)":1.2, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.1, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.8, + "Cálcio (mg)":42, + "Magnésio (mg)":15, + "Manganês (mg)":4.42, + "Fósforo (mg)":17, + "Ferro (mg)":0.2, + "Sódio (mg)":2, + "Potássio (mg)":280, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":138, + "Descrição dos alimentos":"Palmito, juçara, em conserva", + "Umidade (%)":91.4, + "Energia (Kcal)":23, + "Energia (KJ)":97, + "Proteína (g)":1.8, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.3, + "Fibra Alimentar (g)":3.2, + "Cinzas (g)":2.1, + "Cálcio (mg)":58, + "Magnésio (mg)":34, + "Manganês (mg)":10.82, + "Fósforo (mg)":40, + "Ferro (mg)":0.3, + "Sódio (mg)":514, + "Potássio (mg)":244, + "Cobre (mg)":0.23, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":139, + "Descrição dos alimentos":"Palmito, pupunha, em conserva", + "Umidade (%)":89.4, + "Energia (Kcal)":29, + "Energia (KJ)":123, + "Proteína (g)":2.5, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.5, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":2.1, + "Cálcio (mg)":32, + "Magnésio (mg)":25, + "Manganês (mg)":0.14, + "Fósforo (mg)":55, + "Ferro (mg)":0.2, + "Sódio (mg)":563, + "Potássio (mg)":206, + "Cobre (mg)":0.08, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":140, + "Descrição dos alimentos":"Pão, de queijo, assado", + "Umidade (%)":33.7, + "Energia (Kcal)":363, + "Energia (KJ)":1519, + "Proteína (g)":5.1, + "Lipídeos (g)":24.6, + "Colesterol (mg)":68, + "Carboidrato (g)":34.2, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":2.3, + "Cálcio (mg)":102, + "Magnésio (mg)":8, + "Manganês (mg)":0.03, + "Fósforo (mg)":94, + "Ferro (mg)":0.3, + "Sódio (mg)":773, + "Potássio (mg)":93, + "Cobre (mg)":0.01, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":141, + "Descrição dos alimentos":"Pão, de queijo, cru", + "Umidade (%)":41.8, + "Energia (Kcal)":295, + "Energia (KJ)":1232, + "Proteína (g)":3.6, + "Lipídeos (g)":14.0, + "Colesterol (mg)":63, + "Carboidrato (g)":38.5, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":2.0, + "Cálcio (mg)":88, + "Magnésio (mg)":7, + "Manganês (mg)":"Tr", + "Fósforo (mg)":79, + "Ferro (mg)":0.3, + "Sódio (mg)":405, + "Potássio (mg)":58, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":142, + "Descrição dos alimentos":"Pepino, cru", + "Umidade (%)":96.8, + "Energia (Kcal)":10, + "Energia (KJ)":40, + "Proteína (g)":0.9, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.0, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":0.3, + "Cálcio (mg)":10, + "Magnésio (mg)":9, + "Manganês (mg)":0.08, + "Fósforo (mg)":12, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":154, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":143, + "Descrição dos alimentos":"Pimentão, amarelo, cru", + "Umidade (%)":91.9, + "Energia (Kcal)":28, + "Energia (KJ)":117, + "Proteína (g)":1.2, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.0, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":0.5, + "Cálcio (mg)":10, + "Magnésio (mg)":11, + "Manganês (mg)":0.08, + "Fósforo (mg)":22, + "Ferro (mg)":0.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":221, + "Cobre (mg)":0.04, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":144, + "Descrição dos alimentos":"Pimentão, verde, cru", + "Umidade (%)":93.5, + "Energia (Kcal)":21, + "Energia (KJ)":89, + "Proteína (g)":1.1, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.9, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.4, + "Cálcio (mg)":9, + "Magnésio (mg)":8, + "Manganês (mg)":0.14, + "Fósforo (mg)":17, + "Ferro (mg)":0.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":174, + "Cobre (mg)":0.07, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":145, + "Descrição dos alimentos":"Pimentão, vermelho, cru", + "Umidade (%)":92.9, + "Energia (Kcal)":23, + "Energia (KJ)":97, + "Proteína (g)":1.0, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.5, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.4, + "Cálcio (mg)":6, + "Magnésio (mg)":11, + "Manganês (mg)":0.06, + "Fósforo (mg)":20, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":211, + "Cobre (mg)":0.04, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":146, + "Descrição dos alimentos":"Polvilho, doce", + "Umidade (%)":12.6, + "Energia (Kcal)":351, + "Energia (KJ)":1470, + "Proteína (g)":0.4, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":86.8, + "Fibra Alimentar (g)":0.2, + "Cinzas (g)":0.2, + "Cálcio (mg)":27, + "Magnésio (mg)":4, + "Manganês (mg)":0.09, + "Fósforo (mg)":8, + "Ferro (mg)":0.5, + "Sódio (mg)":2, + "Potássio (mg)":38, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":147, + "Descrição dos alimentos":"Quiabo, cru", + "Umidade (%)":90.6, + "Energia (Kcal)":30, + "Energia (KJ)":125, + "Proteína (g)":1.9, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.4, + "Fibra Alimentar (g)":4.6, + "Cinzas (g)":0.8, + "Cálcio (mg)":112, + "Magnésio (mg)":50, + "Manganês (mg)":0.46, + "Fósforo (mg)":56, + "Ferro (mg)":0.4, + "Sódio (mg)":1, + "Potássio (mg)":249, + "Cobre (mg)":0.17, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":148, + "Descrição dos alimentos":"Rabanete, cru", + "Umidade (%)":95.1, + "Energia (Kcal)":14, + "Energia (KJ)":57, + "Proteína (g)":1.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.7, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.7, + "Cálcio (mg)":21, + "Magnésio (mg)":10, + "Manganês (mg)":0.07, + "Fósforo (mg)":25, + "Ferro (mg)":0.4, + "Sódio (mg)":11, + "Potássio (mg)":328, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":149, + "Descrição dos alimentos":"Repolho, branco, cru", + "Umidade (%)":94.7, + "Energia (Kcal)":17, + "Energia (KJ)":72, + "Proteína (g)":0.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.9, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":0.4, + "Cálcio (mg)":35, + "Magnésio (mg)":9, + "Manganês (mg)":0.13, + "Fósforo (mg)":14, + "Ferro (mg)":0.2, + "Sódio (mg)":4, + "Potássio (mg)":150, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":150, + "Descrição dos alimentos":"Repolho, roxo, cru", + "Umidade (%)":90.1, + "Energia (Kcal)":31, + "Energia (KJ)":129, + "Proteína (g)":1.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.2, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":44, + "Magnésio (mg)":18, + "Manganês (mg)":0.25, + "Fósforo (mg)":58, + "Ferro (mg)":0.5, + "Sódio (mg)":2, + "Potássio (mg)":328, + "Cobre (mg)":0.90, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":151, + "Descrição dos alimentos":"Repolho, roxo, refogado", + "Umidade (%)":88.7, + "Energia (Kcal)":42, + "Energia (KJ)":175, + "Proteína (g)":1.8, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.6, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.7, + "Cálcio (mg)":43, + "Magnésio (mg)":17, + "Manganês (mg)":0.26, + "Fósforo (mg)":59, + "Ferro (mg)":0.5, + "Sódio (mg)":3, + "Potássio (mg)":321, + "Cobre (mg)":0.02, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":152, + "Descrição dos alimentos":"Rúcula, crua", + "Umidade (%)":94.8, + "Energia (Kcal)":13, + "Energia (KJ)":55, + "Proteína (g)":1.8, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.2, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":1.1, + "Cálcio (mg)":117, + "Magnésio (mg)":18, + "Manganês (mg)":0.24, + "Fósforo (mg)":25, + "Ferro (mg)":0.9, + "Sódio (mg)":9, + "Potássio (mg)":233, + "Cobre (mg)":0.04, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":153, + "Descrição dos alimentos":"Salsa, crua", + "Umidade (%)":88.7, + "Energia (Kcal)":33, + "Energia (KJ)":140, + "Proteína (g)":3.3, + "Lipídeos (g)":0.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.7, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":1.8, + "Cálcio (mg)":179, + "Magnésio (mg)":21, + "Manganês (mg)":1.88, + "Fósforo (mg)":49, + "Ferro (mg)":3.2, + "Sódio (mg)":2, + "Potássio (mg)":711, + "Cobre (mg)":0.20, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":154, + "Descrição dos alimentos":"Seleta de legumes, enlatada", + "Umidade (%)":82.1, + "Energia (Kcal)":57, + "Energia (KJ)":237, + "Proteína (g)":3.4, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.7, + "Fibra Alimentar (g)":3.1, + "Cinzas (g)":1.4, + "Cálcio (mg)":16, + "Magnésio (mg)":16, + "Manganês (mg)":0.13, + "Fósforo (mg)":49, + "Ferro (mg)":1.1, + "Sódio (mg)":398, + "Potássio (mg)":122, + "Cobre (mg)":0.08, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":155, + "Descrição dos alimentos":"Serralha, crua", + "Umidade (%)":90.2, + "Energia (Kcal)":30, + "Energia (KJ)":127, + "Proteína (g)":2.7, + "Lipídeos (g)":0.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.9, + "Fibra Alimentar (g)":3.5, + "Cinzas (g)":1.4, + "Cálcio (mg)":126, + "Magnésio (mg)":30, + "Manganês (mg)":0.23, + "Fósforo (mg)":48, + "Ferro (mg)":1.3, + "Sódio (mg)":19, + "Potássio (mg)":265, + "Cobre (mg)":0.20, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":156, + "Descrição dos alimentos":"Taioba, crua", + "Umidade (%)":89.2, + "Energia (Kcal)":34, + "Energia (KJ)":143, + "Proteína (g)":2.9, + "Lipídeos (g)":0.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.4, + "Fibra Alimentar (g)":4.5, + "Cinzas (g)":1.5, + "Cálcio (mg)":141, + "Magnésio (mg)":38, + "Manganês (mg)":0.66, + "Fósforo (mg)":53, + "Ferro (mg)":1.9, + "Sódio (mg)":1, + "Potássio (mg)":290, + "Cobre (mg)":0.16, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":157, + "Descrição dos alimentos":"Tomate, com semente, cru", + "Umidade (%)":95.1, + "Energia (Kcal)":15, + "Energia (KJ)":64, + "Proteína (g)":1.1, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.1, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.5, + "Cálcio (mg)":7, + "Magnésio (mg)":11, + "Manganês (mg)":0.07, + "Fósforo (mg)":20, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":222, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":158, + "Descrição dos alimentos":"Tomate, extrato", + "Umidade (%)":79.7, + "Energia (Kcal)":61, + "Energia (KJ)":255, + "Proteína (g)":2.4, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":15.0, + "Fibra Alimentar (g)":2.8, + "Cinzas (g)":2.8, + "Cálcio (mg)":29, + "Magnésio (mg)":29, + "Manganês (mg)":0.18, + "Fósforo (mg)":47, + "Ferro (mg)":2.1, + "Sódio (mg)":498, + "Potássio (mg)":680, + "Cobre (mg)":0.20, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":159, + "Descrição dos alimentos":"Tomate, molho industrializado", + "Umidade (%)":88.1, + "Energia (Kcal)":38, + "Energia (KJ)":161, + "Proteína (g)":1.4, + "Lipídeos (g)":0.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.7, + "Fibra Alimentar (g)":3.1, + "Cinzas (g)":1.9, + "Cálcio (mg)":12, + "Magnésio (mg)":17, + "Manganês (mg)":0.08, + "Fósforo (mg)":27, + "Ferro (mg)":1.6, + "Sódio (mg)":418, + "Potássio (mg)":388, + "Cobre (mg)":0.08, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":160, + "Descrição dos alimentos":"Tomate, purê", + "Umidade (%)":90.8, + "Energia (Kcal)":28, + "Energia (KJ)":117, + "Proteína (g)":1.4, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.9, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":13, + "Magnésio (mg)":15, + "Manganês (mg)":" ", + "Fósforo (mg)":30, + "Ferro (mg)":1.3, + "Sódio (mg)":104, + "Potássio (mg)":308, + "Cobre (mg)":0.09, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":161, + "Descrição dos alimentos":"Tomate, salada", + "Umidade (%)":93.6, + "Energia (Kcal)":21, + "Energia (KJ)":86, + "Proteína (g)":0.8, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.1, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.4, + "Cálcio (mg)":7, + "Magnésio (mg)":10, + "Manganês (mg)":0.04, + "Fósforo (mg)":23, + "Ferro (mg)":0.3, + "Sódio (mg)":5, + "Potássio (mg)":161, + "Cobre (mg)":0.07, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":162, + "Descrição dos alimentos":"Vagem, crua", + "Umidade (%)":92.2, + "Energia (Kcal)":25, + "Energia (KJ)":104, + "Proteína (g)":1.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.3, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":0.5, + "Cálcio (mg)":41, + "Magnésio (mg)":18, + "Manganês (mg)":0.50, + "Fósforo (mg)":28, + "Ferro (mg)":0.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":208, + "Cobre (mg)":0.06, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":163, + "Descrição dos alimentos":"Abacate, cru", + "Umidade (%)":83.8, + "Energia (Kcal)":96, + "Energia (KJ)":402, + "Proteína (g)":1.2, + "Lipídeos (g)":8.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.0, + "Fibra Alimentar (g)":6.3, + "Cinzas (g)":0.5, + "Cálcio (mg)":8, + "Magnésio (mg)":15, + "Manganês (mg)":0.17, + "Fósforo (mg)":22, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":206, + "Cobre (mg)":0.15, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":164, + "Descrição dos alimentos":"Abacaxi, cru", + "Umidade (%)":86.3, + "Energia (Kcal)":48, + "Energia (KJ)":202, + "Proteína (g)":0.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.3, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":0.4, + "Cálcio (mg)":22, + "Magnésio (mg)":18, + "Manganês (mg)":1.62, + "Fósforo (mg)":13, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":131, + "Cobre (mg)":0.11, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":165, + "Descrição dos alimentos":"Abacaxi, polpa, congelada", + "Umidade (%)":91.3, + "Energia (Kcal)":31, + "Energia (KJ)":128, + "Proteína (g)":0.5, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.8, + "Fibra Alimentar (g)":0.3, + "Cinzas (g)":0.3, + "Cálcio (mg)":14, + "Magnésio (mg)":10, + "Manganês (mg)":1.02, + "Fósforo (mg)":8, + "Ferro (mg)":0.4, + "Sódio (mg)":1, + "Potássio (mg)":107, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":166, + "Descrição dos alimentos":"Abiu, cru", + "Umidade (%)":83.1, + "Energia (Kcal)":62, + "Energia (KJ)":261, + "Proteína (g)":0.8, + "Lipídeos (g)":0.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.9, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":0.4, + "Cálcio (mg)":6, + "Magnésio (mg)":9, + "Manganês (mg)":0.08, + "Fósforo (mg)":20, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":128, + "Cobre (mg)":0.09, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":167, + "Descrição dos alimentos":"Açaí, polpa, com xarope de guaraná e glucose", + "Umidade (%)":73.9, + "Energia (Kcal)":110, + "Energia (KJ)":461, + "Proteína (g)":0.7, + "Lipídeos (g)":3.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":21.5, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":0.3, + "Cálcio (mg)":22, + "Magnésio (mg)":13, + "Manganês (mg)":3.29, + "Fósforo (mg)":11, + "Ferro (mg)":0.3, + "Sódio (mg)":15, + "Potássio (mg)":75, + "Cobre (mg)":0.14, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":168, + "Descrição dos alimentos":"Açaí, polpa, congelada", + "Umidade (%)":88.7, + "Energia (Kcal)":58, + "Energia (KJ)":243, + "Proteína (g)":0.8, + "Lipídeos (g)":3.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.2, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.3, + "Cálcio (mg)":35, + "Magnésio (mg)":17, + "Manganês (mg)":6.16, + "Fósforo (mg)":16, + "Ferro (mg)":0.4, + "Sódio (mg)":5, + "Potássio (mg)":124, + "Cobre (mg)":0.18, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":169, + "Descrição dos alimentos":"Acerola, crua", + "Umidade (%)":90.5, + "Energia (Kcal)":33, + "Energia (KJ)":140, + "Proteína (g)":0.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.0, + "Fibra Alimentar (g)":1.5, + "Cinzas (g)":0.4, + "Cálcio (mg)":13, + "Magnésio (mg)":13, + "Manganês (mg)":0.07, + "Fósforo (mg)":9, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":165, + "Cobre (mg)":0.07, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":170, + "Descrição dos alimentos":"Acerola, polpa, congelada", + "Umidade (%)":93.6, + "Energia (Kcal)":22, + "Energia (KJ)":92, + "Proteína (g)":0.6, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.5, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":0.3, + "Cálcio (mg)":8, + "Magnésio (mg)":9, + "Manganês (mg)":0.03, + "Fósforo (mg)":13, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":112, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":171, + "Descrição dos alimentos":"Ameixa, calda, enlatada ", + "Umidade (%)":52.2, + "Energia (Kcal)":183, + "Energia (KJ)":765, + "Proteína (g)":0.4, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":46.9, + "Fibra Alimentar (g)":0.5, + "Cinzas (g)":0.5, + "Cálcio (mg)":13, + "Magnésio (mg)":10, + "Manganês (mg)":0.10, + "Fósforo (mg)":21, + "Ferro (mg)":2.2, + "Sódio (mg)":3, + "Potássio (mg)":221, + "Cobre (mg)":0.03, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":172, + "Descrição dos alimentos":"Ameixa, crua", + "Umidade (%)":84.8, + "Energia (Kcal)":53, + "Energia (KJ)":220, + "Proteína (g)":0.8, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.9, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":0.6, + "Cálcio (mg)":6, + "Magnésio (mg)":5, + "Manganês (mg)":0.03, + "Fósforo (mg)":14, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":134, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":173, + "Descrição dos alimentos":"Ameixa, em calda, enlatada, drenada ", + "Umidade (%)":50.3, + "Energia (Kcal)":177, + "Energia (KJ)":742, + "Proteína (g)":1.0, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":47.7, + "Fibra Alimentar (g)":4.5, + "Cinzas (g)":0.7, + "Cálcio (mg)":39, + "Magnésio (mg)":14, + "Manganês (mg)":0.20, + "Fósforo (mg)":26, + "Ferro (mg)":2.7, + "Sódio (mg)":3, + "Potássio (mg)":263, + "Cobre (mg)":0.16, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":174, + "Descrição dos alimentos":"Atemóia, crua", + "Umidade (%)":72.7, + "Energia (Kcal)":97, + "Energia (KJ)":406, + "Proteína (g)":1.0, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":25.3, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":0.7, + "Cálcio (mg)":23, + "Magnésio (mg)":25, + "Manganês (mg)":0.16, + "Fósforo (mg)":23, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":300, + "Cobre (mg)":0.17, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":175, + "Descrição dos alimentos":"Banana, da terra, crua", + "Umidade (%)":63.9, + "Energia (Kcal)":128, + "Energia (KJ)":536, + "Proteína (g)":1.4, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":33.7, + "Fibra Alimentar (g)":1.5, + "Cinzas (g)":0.8, + "Cálcio (mg)":4, + "Magnésio (mg)":24, + "Manganês (mg)":0.16, + "Fósforo (mg)":26, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":328, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":176, + "Descrição dos alimentos":"Banana, doce em barra", + "Umidade (%)":21.1, + "Energia (Kcal)":280, + "Energia (KJ)":1172, + "Proteína (g)":2.2, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":75.7, + "Fibra Alimentar (g)":3.8, + "Cinzas (g)":1.0, + "Cálcio (mg)":12, + "Magnésio (mg)":49, + "Manganês (mg)":0.84, + "Fósforo (mg)":37, + "Ferro (mg)":0.6, + "Sódio (mg)":10, + "Potássio (mg)":518, + "Cobre (mg)":0.16, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":177, + "Descrição dos alimentos":"Banana, figo, crua", + "Umidade (%)":70.1, + "Energia (Kcal)":105, + "Energia (KJ)":440, + "Proteína (g)":1.1, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":27.8, + "Fibra Alimentar (g)":2.8, + "Cinzas (g)":0.8, + "Cálcio (mg)":6, + "Magnésio (mg)":30, + "Manganês (mg)":0.21, + "Fósforo (mg)":16, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":387, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":178, + "Descrição dos alimentos":"Banana, maçã, crua", + "Umidade (%)":75.2, + "Energia (Kcal)":87, + "Energia (KJ)":363, + "Proteína (g)":1.8, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":22.3, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.6, + "Cálcio (mg)":3, + "Magnésio (mg)":24, + "Manganês (mg)":0.60, + "Fósforo (mg)":29, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":264, + "Cobre (mg)":0.11, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":179, + "Descrição dos alimentos":"Banana, nanica, crua", + "Umidade (%)":73.8, + "Energia (Kcal)":92, + "Energia (KJ)":383, + "Proteína (g)":1.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":23.8, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":0.8, + "Cálcio (mg)":3, + "Magnésio (mg)":28, + "Manganês (mg)":0.14, + "Fósforo (mg)":27, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":376, + "Cobre (mg)":0.10, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":180, + "Descrição dos alimentos":"Banana, ouro, crua", + "Umidade (%)":68.2, + "Energia (Kcal)":112, + "Energia (KJ)":470, + "Proteína (g)":1.5, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":29.3, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":3, + "Magnésio (mg)":28, + "Manganês (mg)":0.09, + "Fósforo (mg)":22, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":355, + "Cobre (mg)":0.08, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":181, + "Descrição dos alimentos":"Banana, pacova, crua", + "Umidade (%)":77.7, + "Energia (Kcal)":78, + "Energia (KJ)":326, + "Proteína (g)":1.2, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":20.3, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":5, + "Magnésio (mg)":30, + "Manganês (mg)":0.41, + "Fósforo (mg)":20, + "Ferro (mg)":0.4, + "Sódio (mg)":1, + "Potássio (mg)":267, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":182, + "Descrição dos alimentos":"Banana, prata, crua", + "Umidade (%)":71.9, + "Energia (Kcal)":98, + "Energia (KJ)":411, + "Proteína (g)":1.3, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":26.0, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":8, + "Magnésio (mg)":26, + "Manganês (mg)":0.42, + "Fósforo (mg)":22, + "Ferro (mg)":0.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":358, + "Cobre (mg)":0.05, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":183, + "Descrição dos alimentos":"Cacau, cru", + "Umidade (%)":79.2, + "Energia (Kcal)":74, + "Energia (KJ)":311, + "Proteína (g)":1.0, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":19.4, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.3, + "Cálcio (mg)":12, + "Magnésio (mg)":25, + "Manganês (mg)":0.04, + "Fósforo (mg)":9, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":72, + "Cobre (mg)":0.15, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":184, + "Descrição dos alimentos":"Cajá-Manga, cru", + "Umidade (%)":86.9, + "Energia (Kcal)":46, + "Energia (KJ)":191, + "Proteína (g)":1.3, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.4, + "Fibra Alimentar (g)":2.6, + "Cinzas (g)":0.4, + "Cálcio (mg)":13, + "Magnésio (mg)":11, + "Manganês (mg)":0.05, + "Fósforo (mg)":24, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":119, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":185, + "Descrição dos alimentos":"Cajá, polpa, congelada", + "Umidade (%)":92.4, + "Energia (Kcal)":26, + "Energia (KJ)":110, + "Proteína (g)":0.6, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.4, + "Fibra Alimentar (g)":1.4, + "Cinzas (g)":0.4, + "Cálcio (mg)":9, + "Magnésio (mg)":7, + "Manganês (mg)":0.07, + "Fósforo (mg)":26, + "Ferro (mg)":0.3, + "Sódio (mg)":7, + "Potássio (mg)":148, + "Cobre (mg)":0.10, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":186, + "Descrição dos alimentos":"Caju, cru", + "Umidade (%)":88.1, + "Energia (Kcal)":43, + "Energia (KJ)":180, + "Proteína (g)":1.0, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.3, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":0.3, + "Cálcio (mg)":1, + "Magnésio (mg)":10, + "Manganês (mg)":0.12, + "Fósforo (mg)":16, + "Ferro (mg)":0.2, + "Sódio (mg)":3, + "Potássio (mg)":124, + "Cobre (mg)":0.07, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":187, + "Descrição dos alimentos":"Caju, polpa, congelada", + "Umidade (%)":89.8, + "Energia (Kcal)":37, + "Energia (KJ)":153, + "Proteína (g)":0.5, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.4, + "Fibra Alimentar (g)":0.8, + "Cinzas (g)":0.2, + "Cálcio (mg)":1, + "Magnésio (mg)":7, + "Manganês (mg)":0.05, + "Fósforo (mg)":10, + "Ferro (mg)":0.1, + "Sódio (mg)":4, + "Potássio (mg)":88, + "Cobre (mg)":0.07, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":188, + "Descrição dos alimentos":"Caju, suco concentrado, envasado", + "Umidade (%)":88.4, + "Energia (Kcal)":45, + "Energia (KJ)":189, + "Proteína (g)":0.4, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.7, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":0.3, + "Cálcio (mg)":1, + "Magnésio (mg)":8, + "Manganês (mg)":0.06, + "Fósforo (mg)":11, + "Ferro (mg)":0.1, + "Sódio (mg)":45, + "Potássio (mg)":107, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":189, + "Descrição dos alimentos":"Caqui, chocolate, cru", + "Umidade (%)":79.7, + "Energia (Kcal)":71, + "Energia (KJ)":299, + "Proteína (g)":0.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":19.3, + "Fibra Alimentar (g)":6.5, + "Cinzas (g)":0.5, + "Cálcio (mg)":18, + "Magnésio (mg)":9, + "Manganês (mg)":0.39, + "Fósforo (mg)":18, + "Ferro (mg)":0.1, + "Sódio (mg)":2, + "Potássio (mg)":164, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":190, + "Descrição dos alimentos":"Carambola, crua", + "Umidade (%)":87.1, + "Energia (Kcal)":46, + "Energia (KJ)":191, + "Proteína (g)":0.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.5, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.4, + "Cálcio (mg)":5, + "Magnésio (mg)":7, + "Manganês (mg)":0.13, + "Fósforo (mg)":11, + "Ferro (mg)":0.2, + "Sódio (mg)":4, + "Potássio (mg)":133, + "Cobre (mg)":0.08, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":191, + "Descrição dos alimentos":"Ciriguela, crua", + "Umidade (%)":78.7, + "Energia (Kcal)":76, + "Energia (KJ)":316, + "Proteína (g)":1.4, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.9, + "Fibra Alimentar (g)":3.9, + "Cinzas (g)":0.7, + "Cálcio (mg)":27, + "Magnésio (mg)":18, + "Manganês (mg)":0.06, + "Fósforo (mg)":49, + "Ferro (mg)":0.4, + "Sódio (mg)":2, + "Potássio (mg)":248, + "Cobre (mg)":0.12, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":192, + "Descrição dos alimentos":"Cupuaçu, cru", + "Umidade (%)":86.2, + "Energia (Kcal)":49, + "Energia (KJ)":207, + "Proteína (g)":1.2, + "Lipídeos (g)":1.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.4, + "Fibra Alimentar (g)":3.1, + "Cinzas (g)":1.2, + "Cálcio (mg)":13, + "Magnésio (mg)":18, + "Manganês (mg)":0.07, + "Fósforo (mg)":21, + "Ferro (mg)":0.5, + "Sódio (mg)":3, + "Potássio (mg)":331, + "Cobre (mg)":0.07, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":193, + "Descrição dos alimentos":"Cupuaçu, polpa, congelada", + "Umidade (%)":86.6, + "Energia (Kcal)":49, + "Energia (KJ)":204, + "Proteína (g)":0.8, + "Lipídeos (g)":0.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.4, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.6, + "Cálcio (mg)":5, + "Magnésio (mg)":14, + "Manganês (mg)":0.17, + "Fósforo (mg)":14, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":291, + "Cobre (mg)":0.14, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":194, + "Descrição dos alimentos":"Figo, cru", + "Umidade (%)":88.2, + "Energia (Kcal)":41, + "Energia (KJ)":173, + "Proteína (g)":1.0, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.2, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.4, + "Cálcio (mg)":27, + "Magnésio (mg)":11, + "Manganês (mg)":0.06, + "Fósforo (mg)":15, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":174, + "Cobre (mg)":0.13, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":195, + "Descrição dos alimentos":"Figo, enlatado, em calda", + "Umidade (%)":48.8, + "Energia (Kcal)":184, + "Energia (KJ)":771, + "Proteína (g)":0.6, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":50.3, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.2, + "Cálcio (mg)":33, + "Magnésio (mg)":7, + "Manganês (mg)":0.16, + "Fósforo (mg)":6, + "Ferro (mg)":0.5, + "Sódio (mg)":7, + "Potássio (mg)":39, + "Cobre (mg)":0.25, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":196, + "Descrição dos alimentos":"Fruta-pão, crua", + "Umidade (%)":80.9, + "Energia (Kcal)":67, + "Energia (KJ)":281, + "Proteína (g)":1.1, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":17.2, + "Fibra Alimentar (g)":5.5, + "Cinzas (g)":0.7, + "Cálcio (mg)":34, + "Magnésio (mg)":24, + "Manganês (mg)":0.04, + "Fósforo (mg)":27, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":188, + "Cobre (mg)":0.07, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":197, + "Descrição dos alimentos":"Goiaba, branca, com casca, crua", + "Umidade (%)":85.7, + "Energia (Kcal)":52, + "Energia (KJ)":216, + "Proteína (g)":0.9, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.4, + "Fibra Alimentar (g)":6.3, + "Cinzas (g)":0.5, + "Cálcio (mg)":5, + "Magnésio (mg)":7, + "Manganês (mg)":0.07, + "Fósforo (mg)":16, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":220, + "Cobre (mg)":0.04, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":198, + "Descrição dos alimentos":"Goiaba, doce em pasta", + "Umidade (%)":24.8, + "Energia (Kcal)":269, + "Energia (KJ)":1125, + "Proteína (g)":0.6, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":74.1, + "Fibra Alimentar (g)":3.7, + "Cinzas (g)":0.5, + "Cálcio (mg)":10, + "Magnésio (mg)":6, + "Manganês (mg)":0.11, + "Fósforo (mg)":54, + "Ferro (mg)":0.4, + "Sódio (mg)":4, + "Potássio (mg)":165, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":199, + "Descrição dos alimentos":"Goiaba, doce, cascão", + "Umidade (%)":20.3, + "Energia (Kcal)":286, + "Energia (KJ)":1195, + "Proteína (g)":0.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":78.7, + "Fibra Alimentar (g)":4.4, + "Cinzas (g)":0.5, + "Cálcio (mg)":15, + "Magnésio (mg)":10, + "Manganês (mg)":0.16, + "Fósforo (mg)":28, + "Ferro (mg)":0.4, + "Sódio (mg)":11, + "Potássio (mg)":251, + "Cobre (mg)":0.08, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":200, + "Descrição dos alimentos":"Goiaba, vermelha, com casca, crua", + "Umidade (%)":85.0, + "Energia (Kcal)":54, + "Energia (KJ)":227, + "Proteína (g)":1.1, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.0, + "Fibra Alimentar (g)":6.2, + "Cinzas (g)":0.5, + "Cálcio (mg)":4, + "Magnésio (mg)":7, + "Manganês (mg)":0.09, + "Fósforo (mg)":15, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":198, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":201, + "Descrição dos alimentos":"Graviola, crua", + "Umidade (%)":82.2, + "Energia (Kcal)":62, + "Energia (KJ)":258, + "Proteína (g)":0.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":15.8, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":1.0, + "Cálcio (mg)":40, + "Magnésio (mg)":23, + "Manganês (mg)":0.08, + "Fósforo (mg)":19, + "Ferro (mg)":0.2, + "Sódio (mg)":4, + "Potássio (mg)":250, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":202, + "Descrição dos alimentos":"Graviola, polpa, congelada", + "Umidade (%)":89.2, + "Energia (Kcal)":38, + "Energia (KJ)":160, + "Proteína (g)":0.6, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.8, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.4, + "Cálcio (mg)":6, + "Magnésio (mg)":10, + "Manganês (mg)":0.06, + "Fósforo (mg)":17, + "Ferro (mg)":0.1, + "Sódio (mg)":3, + "Potássio (mg)":170, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":203, + "Descrição dos alimentos":"Jabuticaba, crua", + "Umidade (%)":83.6, + "Energia (Kcal)":58, + "Energia (KJ)":243, + "Proteína (g)":0.6, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":15.3, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.4, + "Cálcio (mg)":8, + "Magnésio (mg)":18, + "Manganês (mg)":0.30, + "Fósforo (mg)":15, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":130, + "Cobre (mg)":0.07, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":204, + "Descrição dos alimentos":"Jaca, crua", + "Umidade (%)":75.1, + "Energia (Kcal)":88, + "Energia (KJ)":368, + "Proteína (g)":1.4, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":22.5, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":0.8, + "Cálcio (mg)":11, + "Magnésio (mg)":40, + "Manganês (mg)":0.48, + "Fósforo (mg)":14, + "Ferro (mg)":0.4, + "Sódio (mg)":2, + "Potássio (mg)":234, + "Cobre (mg)":0.09, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":205, + "Descrição dos alimentos":"Jambo, cru", + "Umidade (%)":92.1, + "Energia (Kcal)":27, + "Energia (KJ)":113, + "Proteína (g)":0.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.5, + "Fibra Alimentar (g)":5.1, + "Cinzas (g)":0.5, + "Cálcio (mg)":14, + "Magnésio (mg)":14, + "Manganês (mg)":0.05, + "Fósforo (mg)":18, + "Ferro (mg)":0.1, + "Sódio (mg)":22, + "Potássio (mg)":135, + "Cobre (mg)":0.02, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":206, + "Descrição dos alimentos":"Jamelão, cru", + "Umidade (%)":87.7, + "Energia (Kcal)":41, + "Energia (KJ)":172, + "Proteína (g)":0.5, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.6, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":2, + "Manganês (mg)":"Tr", + "Fósforo (mg)":4, + "Ferro (mg)":0.0, + "Sódio (mg)":1, + "Potássio (mg)":394, + "Cobre (mg)":0.03, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":207, + "Descrição dos alimentos":"Kiwi, cru", + "Umidade (%)":85.9, + "Energia (Kcal)":51, + "Energia (KJ)":214, + "Proteína (g)":1.3, + "Lipídeos (g)":0.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.5, + "Fibra Alimentar (g)":2.7, + "Cinzas (g)":0.7, + "Cálcio (mg)":24, + "Magnésio (mg)":11, + "Manganês (mg)":0.05, + "Fósforo (mg)":33, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":269, + "Cobre (mg)":0.15, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":208, + "Descrição dos alimentos":"Laranja, baía, crua", + "Umidade (%)":87.1, + "Energia (Kcal)":45, + "Energia (KJ)":190, + "Proteína (g)":1.0, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.5, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":0.4, + "Cálcio (mg)":35, + "Magnésio (mg)":9, + "Manganês (mg)":0.04, + "Fósforo (mg)":24, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":174, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":209, + "Descrição dos alimentos":"Laranja, baía, suco", + "Umidade (%)":90.2, + "Energia (Kcal)":37, + "Energia (KJ)":153, + "Proteína (g)":0.7, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.7, + "Fibra Alimentar (g)":"Tr", + "Cinzas (g)":0.4, + "Cálcio (mg)":6, + "Magnésio (mg)":8, + "Manganês (mg)":0.02, + "Fósforo (mg)":22, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":173, + "Cobre (mg)":0.02, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":210, + "Descrição dos alimentos":"Laranja, da terra, crua", + "Umidade (%)":85.4, + "Energia (Kcal)":51, + "Energia (KJ)":215, + "Proteína (g)":1.1, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.9, + "Fibra Alimentar (g)":4.0, + "Cinzas (g)":0.5, + "Cálcio (mg)":51, + "Magnésio (mg)":14, + "Manganês (mg)":0.04, + "Fósforo (mg)":20, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":173, + "Cobre (mg)":0.04, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":211, + "Descrição dos alimentos":"Laranja, da terra, suco", + "Umidade (%)":89.2, + "Energia (Kcal)":41, + "Energia (KJ)":171, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.6, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":0.4, + "Cálcio (mg)":13, + "Magnésio (mg)":10, + "Manganês (mg)":0.02, + "Fósforo (mg)":15, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":145, + "Cobre (mg)":0.02, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":212, + "Descrição dos alimentos":"Laranja, lima, crua", + "Umidade (%)":87.0, + "Energia (Kcal)":46, + "Energia (KJ)":191, + "Proteína (g)":1.1, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.5, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.4, + "Cálcio (mg)":31, + "Magnésio (mg)":10, + "Manganês (mg)":0.05, + "Fósforo (mg)":15, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":130, + "Cobre (mg)":0.03, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":213, + "Descrição dos alimentos":"Laranja, lima, suco", + "Umidade (%)":89.7, + "Energia (Kcal)":39, + "Energia (KJ)":165, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.2, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":0.3, + "Cálcio (mg)":8, + "Magnésio (mg)":11, + "Manganês (mg)":0.02, + "Fósforo (mg)":16, + "Ferro (mg)":"Tr", + "Sódio (mg)":"Tr", + "Potássio (mg)":129, + "Cobre (mg)":0.02, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":214, + "Descrição dos alimentos":"Laranja, pêra, crua", + "Umidade (%)":89.6, + "Energia (Kcal)":37, + "Energia (KJ)":154, + "Proteína (g)":1.0, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.9, + "Fibra Alimentar (g)":0.8, + "Cinzas (g)":0.3, + "Cálcio (mg)":22, + "Magnésio (mg)":9, + "Manganês (mg)":0.05, + "Fósforo (mg)":23, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":163, + "Cobre (mg)":0.03, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":215, + "Descrição dos alimentos":"Laranja, pêra, suco", + "Umidade (%)":91.3, + "Energia (Kcal)":33, + "Energia (KJ)":137, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.6, + "Fibra Alimentar (g)":"Tr", + "Cinzas (g)":0.3, + "Cálcio (mg)":7, + "Magnésio (mg)":8, + "Manganês (mg)":0.03, + "Fósforo (mg)":14, + "Ferro (mg)":"Tr", + "Sódio (mg)":"Tr", + "Potássio (mg)":149, + "Cobre (mg)":0.01, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":216, + "Descrição dos alimentos":"Laranja, valência, crua", + "Umidade (%)":86.9, + "Energia (Kcal)":46, + "Energia (KJ)":193, + "Proteína (g)":0.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.7, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":0.4, + "Cálcio (mg)":34, + "Magnésio (mg)":14, + "Manganês (mg)":0.06, + "Fósforo (mg)":20, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":158, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":217, + "Descrição dos alimentos":"Laranja, valência, suco", + "Umidade (%)":90.5, + "Energia (Kcal)":36, + "Energia (KJ)":151, + "Proteína (g)":0.5, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.6, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":0.3, + "Cálcio (mg)":9, + "Magnésio (mg)":10, + "Manganês (mg)":0.03, + "Fósforo (mg)":17, + "Ferro (mg)":"Tr", + "Sódio (mg)":"Tr", + "Potássio (mg)":143, + "Cobre (mg)":0.02, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":218, + "Descrição dos alimentos":"Limão, cravo, suco", + "Umidade (%)":94.2, + "Energia (Kcal)":14, + "Energia (KJ)":59, + "Proteína (g)":0.3, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.2, + "Fibra Alimentar (g)":"Tr", + "Cinzas (g)":0.2, + "Cálcio (mg)":10, + "Magnésio (mg)":9, + "Manganês (mg)":0.03, + "Fósforo (mg)":11, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":120, + "Cobre (mg)":0.03, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":219, + "Descrição dos alimentos":"Limão, galego, suco", + "Umidade (%)":91.8, + "Energia (Kcal)":22, + "Energia (KJ)":93, + "Proteína (g)":0.6, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.3, + "Fibra Alimentar (g)":"Tr", + "Cinzas (g)":0.3, + "Cálcio (mg)":5, + "Magnésio (mg)":6, + "Manganês (mg)":0.01, + "Fósforo (mg)":13, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":113, + "Cobre (mg)":0.02, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":220, + "Descrição dos alimentos":"Limão, tahiti, cru", + "Umidade (%)":87.4, + "Energia (Kcal)":32, + "Energia (KJ)":133, + "Proteína (g)":0.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.1, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.4, + "Cálcio (mg)":51, + "Magnésio (mg)":10, + "Manganês (mg)":0.07, + "Fósforo (mg)":24, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":128, + "Cobre (mg)":0.06, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":221, + "Descrição dos alimentos":"Maçã, Argentina, com casca, crua", + "Umidade (%)":82.6, + "Energia (Kcal)":63, + "Energia (KJ)":262, + "Proteína (g)":0.2, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":16.6, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.3, + "Cálcio (mg)":3, + "Magnésio (mg)":5, + "Manganês (mg)":0.01, + "Fósforo (mg)":11, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":117, + "Cobre (mg)":0.03, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":222, + "Descrição dos alimentos":"Maçã, Fuji, com casca, crua", + "Umidade (%)":84.3, + "Energia (Kcal)":56, + "Energia (KJ)":232, + "Proteína (g)":0.3, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":15.2, + "Fibra Alimentar (g)":1.3, + "Cinzas (g)":0.2, + "Cálcio (mg)":2, + "Magnésio (mg)":2, + "Manganês (mg)":0.03, + "Fósforo (mg)":9, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":75, + "Cobre (mg)":0.06, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":223, + "Descrição dos alimentos":"Macaúba, crua", + "Umidade (%)":41.5, + "Energia (Kcal)":404, + "Energia (KJ)":1692, + "Proteína (g)":2.1, + "Lipídeos (g)":40.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.9, + "Fibra Alimentar (g)":13.4, + "Cinzas (g)":1.8, + "Cálcio (mg)":67, + "Magnésio (mg)":66, + "Manganês (mg)":0.08, + "Fósforo (mg)":44, + "Ferro (mg)":0.8, + "Sódio (mg)":1, + "Potássio (mg)":306, + "Cobre (mg)":0.35, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":224, + "Descrição dos alimentos":" Mamão, doce em calda, drenado", + "Umidade (%)":45.5, + "Energia (Kcal)":196, + "Energia (KJ)":819, + "Proteína (g)":0.2, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":54.0, + "Fibra Alimentar (g)":1.3, + "Cinzas (g)":0.2, + "Cálcio (mg)":20, + "Magnésio (mg)":6, + "Manganês (mg)":0.02, + "Fósforo (mg)":4, + "Ferro (mg)":0.1, + "Sódio (mg)":3, + "Potássio (mg)":68, + "Cobre (mg)":0.02, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":225, + "Descrição dos alimentos":"Mamão, Formosa, cru", + "Umidade (%)":86.9, + "Energia (Kcal)":45, + "Energia (KJ)":190, + "Proteína (g)":0.8, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.6, + "Fibra Alimentar (g)":1.8, + "Cinzas (g)":0.6, + "Cálcio (mg)":25, + "Magnésio (mg)":17, + "Manganês (mg)":0.04, + "Fósforo (mg)":11, + "Ferro (mg)":0.2, + "Sódio (mg)":3, + "Potássio (mg)":222, + "Cobre (mg)":1.36, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":226, + "Descrição dos alimentos":"Mamão, Papaia, cru", + "Umidade (%)":88.6, + "Energia (Kcal)":40, + "Energia (KJ)":168, + "Proteína (g)":0.5, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.4, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":0.4, + "Cálcio (mg)":22, + "Magnésio (mg)":22, + "Manganês (mg)":0.01, + "Fósforo (mg)":11, + "Ferro (mg)":0.2, + "Sódio (mg)":2, + "Potássio (mg)":126, + "Cobre (mg)":0.02, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":227, + "Descrição dos alimentos":" Mamão verde, doce em calda, drenado", + "Umidade (%)":41.9, + "Energia (Kcal)":209, + "Energia (KJ)":876, + "Proteína (g)":0.3, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":57.6, + "Fibra Alimentar (g)":1.2, + "Cinzas (g)":0.1, + "Cálcio (mg)":12, + "Magnésio (mg)":5, + "Manganês (mg)":0.04, + "Fósforo (mg)":3, + "Ferro (mg)":0.2, + "Sódio (mg)":5, + "Potássio (mg)":9, + "Cobre (mg)":0.02, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":228, + "Descrição dos alimentos":"Manga, Haden, crua", + "Umidade (%)":82.3, + "Energia (Kcal)":64, + "Energia (KJ)":266, + "Proteína (g)":0.4, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":16.7, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.4, + "Cálcio (mg)":12, + "Magnésio (mg)":8, + "Manganês (mg)":0.17, + "Fósforo (mg)":9, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":148, + "Cobre (mg)":0.10, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":229, + "Descrição dos alimentos":"Manga, Palmer, crua", + "Umidade (%)":79.7, + "Energia (Kcal)":72, + "Energia (KJ)":303, + "Proteína (g)":0.4, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":19.4, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.3, + "Cálcio (mg)":12, + "Magnésio (mg)":9, + "Manganês (mg)":0.05, + "Fósforo (mg)":14, + "Ferro (mg)":0.1, + "Sódio (mg)":2, + "Potássio (mg)":157, + "Cobre (mg)":0.09, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":230, + "Descrição dos alimentos":"Manga, polpa, congelada", + "Umidade (%)":86.5, + "Energia (Kcal)":48, + "Energia (KJ)":202, + "Proteína (g)":0.4, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.5, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":0.4, + "Cálcio (mg)":7, + "Magnésio (mg)":9, + "Manganês (mg)":0.12, + "Fósforo (mg)":9, + "Ferro (mg)":0.1, + "Sódio (mg)":7, + "Potássio (mg)":131, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":231, + "Descrição dos alimentos":"Manga, Tommy Atkins, crua", + "Umidade (%)":85.8, + "Energia (Kcal)":51, + "Energia (KJ)":212, + "Proteína (g)":0.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.8, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":0.3, + "Cálcio (mg)":8, + "Magnésio (mg)":7, + "Manganês (mg)":0.34, + "Fósforo (mg)":14, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":138, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":232, + "Descrição dos alimentos":"Maracujá, cru", + "Umidade (%)":82.9, + "Energia (Kcal)":68, + "Energia (KJ)":286, + "Proteína (g)":2.0, + "Lipídeos (g)":2.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.3, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":0.8, + "Cálcio (mg)":5, + "Magnésio (mg)":28, + "Manganês (mg)":0.12, + "Fósforo (mg)":51, + "Ferro (mg)":0.6, + "Sódio (mg)":2, + "Potássio (mg)":338, + "Cobre (mg)":0.19, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":233, + "Descrição dos alimentos":"Maracujá, polpa, congelada", + "Umidade (%)":88.9, + "Energia (Kcal)":39, + "Energia (KJ)":162, + "Proteína (g)":0.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.6, + "Fibra Alimentar (g)":0.5, + "Cinzas (g)":0.5, + "Cálcio (mg)":5, + "Magnésio (mg)":10, + "Manganês (mg)":0.07, + "Fósforo (mg)":15, + "Ferro (mg)":0.3, + "Sódio (mg)":8, + "Potássio (mg)":228, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":234, + "Descrição dos alimentos":"Maracujá, suco concentrado, envasado", + "Umidade (%)":88.9, + "Energia (Kcal)":42, + "Energia (KJ)":176, + "Proteína (g)":0.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.6, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":0.5, + "Cálcio (mg)":4, + "Magnésio (mg)":4, + "Manganês (mg)":0.07, + "Fósforo (mg)":14, + "Ferro (mg)":0.3, + "Sódio (mg)":22, + "Potássio (mg)":201, + "Cobre (mg)":0.05, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":235, + "Descrição dos alimentos":"Melancia, crua", + "Umidade (%)":90.7, + "Energia (Kcal)":33, + "Energia (KJ)":136, + "Proteína (g)":0.9, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.1, + "Fibra Alimentar (g)":0.1, + "Cinzas (g)":0.3, + "Cálcio (mg)":8, + "Magnésio (mg)":10, + "Manganês (mg)":0.14, + "Fósforo (mg)":12, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":104, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":236, + "Descrição dos alimentos":"Melão, cru", + "Umidade (%)":91.3, + "Energia (Kcal)":29, + "Energia (KJ)":123, + "Proteína (g)":0.7, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.5, + "Fibra Alimentar (g)":0.3, + "Cinzas (g)":0.5, + "Cálcio (mg)":3, + "Magnésio (mg)":6, + "Manganês (mg)":0.05, + "Fósforo (mg)":10, + "Ferro (mg)":0.2, + "Sódio (mg)":11, + "Potássio (mg)":216, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":237, + "Descrição dos alimentos":"Mexerica, Murcote, crua", + "Umidade (%)":83.7, + "Energia (Kcal)":58, + "Energia (KJ)":241, + "Proteína (g)":0.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.9, + "Fibra Alimentar (g)":3.1, + "Cinzas (g)":0.5, + "Cálcio (mg)":33, + "Magnésio (mg)":12, + "Manganês (mg)":0.05, + "Fósforo (mg)":19, + "Ferro (mg)":0.1, + "Sódio (mg)":1, + "Potássio (mg)":159, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":238, + "Descrição dos alimentos":"Mexerica, Rio, crua", + "Umidade (%)":89.6, + "Energia (Kcal)":37, + "Energia (KJ)":154, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.3, + "Fibra Alimentar (g)":2.7, + "Cinzas (g)":0.3, + "Cálcio (mg)":17, + "Magnésio (mg)":8, + "Manganês (mg)":0.05, + "Fósforo (mg)":14, + "Ferro (mg)":0.1, + "Sódio (mg)":2, + "Potássio (mg)":125, + "Cobre (mg)":0.07, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":239, + "Descrição dos alimentos":"Morango, cru", + "Umidade (%)":91.5, + "Energia (Kcal)":30, + "Energia (KJ)":126, + "Proteína (g)":0.9, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.8, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":0.5, + "Cálcio (mg)":11, + "Magnésio (mg)":10, + "Manganês (mg)":0.33, + "Fósforo (mg)":22, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":184, + "Cobre (mg)":0.06, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":240, + "Descrição dos alimentos":"Nêspera, crua", + "Umidade (%)":87.8, + "Energia (Kcal)":43, + "Energia (KJ)":178, + "Proteína (g)":0.3, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.5, + "Fibra Alimentar (g)":3.0, + "Cinzas (g)":0.4, + "Cálcio (mg)":20, + "Magnésio (mg)":10, + "Manganês (mg)":0.07, + "Fósforo (mg)":10, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":113, + "Cobre (mg)":0.12, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":241, + "Descrição dos alimentos":"Pequi, cru", + "Umidade (%)":65.9, + "Energia (Kcal)":205, + "Energia (KJ)":858, + "Proteína (g)":2.3, + "Lipídeos (g)":18.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.0, + "Fibra Alimentar (g)":19.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":32, + "Magnésio (mg)":30, + "Manganês (mg)":0.64, + "Fósforo (mg)":34, + "Ferro (mg)":0.3, + "Sódio (mg)":"Tr", + "Potássio (mg)":298, + "Cobre (mg)":0.21, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":242, + "Descrição dos alimentos":"Pêra, Park, crua", + "Umidade (%)":83.2, + "Energia (Kcal)":61, + "Energia (KJ)":254, + "Proteína (g)":0.2, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":16.1, + "Fibra Alimentar (g)":3.0, + "Cinzas (g)":0.3, + "Cálcio (mg)":9, + "Magnésio (mg)":6, + "Manganês (mg)":0.04, + "Fósforo (mg)":12, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":102, + "Cobre (mg)":0.08, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":243, + "Descrição dos alimentos":"Pêra, Williams, crua", + "Umidade (%)":85.0, + "Energia (Kcal)":53, + "Energia (KJ)":223, + "Proteína (g)":0.6, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.0, + "Fibra Alimentar (g)":3.0, + "Cinzas (g)":0.3, + "Cálcio (mg)":8, + "Magnésio (mg)":6, + "Manganês (mg)":0.04, + "Fósforo (mg)":12, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":116, + "Cobre (mg)":0.07, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":244, + "Descrição dos alimentos":"Pêssego, Aurora, cru", + "Umidade (%)":89.3, + "Energia (Kcal)":36, + "Energia (KJ)":152, + "Proteína (g)":0.8, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.3, + "Fibra Alimentar (g)":1.4, + "Cinzas (g)":0.5, + "Cálcio (mg)":3, + "Magnésio (mg)":4, + "Manganês (mg)":0.05, + "Fósforo (mg)":15, + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":124, + "Cobre (mg)":0.02, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":245, + "Descrição dos alimentos":"Pêssego, enlatado, em calda", + "Umidade (%)":82.2, + "Energia (Kcal)":63, + "Energia (KJ)":264, + "Proteína (g)":0.7, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":16.9, + "Fibra Alimentar (g)":1.0, + "Cinzas (g)":0.2, + "Cálcio (mg)":4, + "Magnésio (mg)":4, + "Manganês (mg)":0.03, + "Fósforo (mg)":9, + "Ferro (mg)":0.6, + "Sódio (mg)":3, + "Potássio (mg)":95, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":246, + "Descrição dos alimentos":"Pinha, crua", + "Umidade (%)":75.0, + "Energia (Kcal)":88, + "Energia (KJ)":370, + "Proteína (g)":1.5, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":22.4, + "Fibra Alimentar (g)":3.4, + "Cinzas (g)":0.7, + "Cálcio (mg)":21, + "Magnésio (mg)":31, + "Manganês (mg)":0.15, + "Fósforo (mg)":34, + "Ferro (mg)":0.2, + "Sódio (mg)":1, + "Potássio (mg)":283, + "Cobre (mg)":0.11, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":247, + "Descrição dos alimentos":"Pitanga, crua", + "Umidade (%)":88.3, + "Energia (Kcal)":41, + "Energia (KJ)":173, + "Proteína (g)":0.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.2, + "Fibra Alimentar (g)":3.2, + "Cinzas (g)":0.4, + "Cálcio (mg)":18, + "Magnésio (mg)":12, + "Manganês (mg)":0.36, + "Fósforo (mg)":13, + "Ferro (mg)":0.4, + "Sódio (mg)":2, + "Potássio (mg)":113, + "Cobre (mg)":0.08, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":248, + "Descrição dos alimentos":"Pitanga, polpa, congelada", + "Umidade (%)":94.6, + "Energia (Kcal)":19, + "Energia (KJ)":80, + "Proteína (g)":0.3, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.8, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":0.3, + "Cálcio (mg)":8, + "Magnésio (mg)":6, + "Manganês (mg)":0.05, + "Fósforo (mg)":12, + "Ferro (mg)":0.4, + "Sódio (mg)":5, + "Potássio (mg)":87, + "Cobre (mg)":0.06, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":249, + "Descrição dos alimentos":"Romã, crua", + "Umidade (%)":84.0, + "Energia (Kcal)":56, + "Energia (KJ)":233, + "Proteína (g)":0.4, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":15.1, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":0.5, + "Cálcio (mg)":5, + "Magnésio (mg)":13, + "Manganês (mg)":0.13, + "Fósforo (mg)":40, + "Ferro (mg)":0.3, + "Sódio (mg)":1, + "Potássio (mg)":485, + "Cobre (mg)":0.19, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":250, + "Descrição dos alimentos":"Tamarindo, cru", + "Umidade (%)":22.0, + "Energia (Kcal)":276, + "Energia (KJ)":1154, + "Proteína (g)":3.2, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":72.5, + "Fibra Alimentar (g)":6.4, + "Cinzas (g)":1.9, + "Cálcio (mg)":37, + "Magnésio (mg)":59, + "Manganês (mg)":0.34, + "Fósforo (mg)":55, + "Ferro (mg)":0.6, + "Sódio (mg)":0, + "Potássio (mg)":723, + "Cobre (mg)":0.29, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":251, + "Descrição dos alimentos":"Tangerina, Poncã, crua", + "Umidade (%)":89.2, + "Energia (Kcal)":38, + "Energia (KJ)":158, + "Proteína (g)":0.8, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.6, + "Fibra Alimentar (g)":0.9, + "Cinzas (g)":0.3, + "Cálcio (mg)":13, + "Magnésio (mg)":8, + "Manganês (mg)":0.04, + "Fósforo (mg)":12, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":131, + "Cobre (mg)":0.03, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":252, + "Descrição dos alimentos":"Tangerina, Poncã, suco", + "Umidade (%)":90.4, + "Energia (Kcal)":36, + "Energia (KJ)":151, + "Proteína (g)":0.5, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.8, + "Fibra Alimentar (g)":"Tr", + "Cinzas (g)":0.3, + "Cálcio (mg)":4, + "Magnésio (mg)":6, + "Manganês (mg)":0.02, + "Fósforo (mg)":9, + "Ferro (mg)":"Tr", + "Sódio (mg)":"Tr", + "Potássio (mg)":119, + "Cobre (mg)":0.02, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":253, + "Descrição dos alimentos":"Tucumã, cru", + "Umidade (%)":51.3, + "Energia (Kcal)":262, + "Energia (KJ)":1096, + "Proteína (g)":2.1, + "Lipídeos (g)":19.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":26.5, + "Fibra Alimentar (g)":12.7, + "Cinzas (g)":1.1, + "Cálcio (mg)":46, + "Magnésio (mg)":121, + "Manganês (mg)":0.55, + "Fósforo (mg)":53, + "Ferro (mg)":0.6, + "Sódio (mg)":4, + "Potássio (mg)":401, + "Cobre (mg)":0.39, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":254, + "Descrição dos alimentos":"Umbu, cru", + "Umidade (%)":89.3, + "Energia (Kcal)":37, + "Energia (KJ)":155, + "Proteína (g)":0.8, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":9.4, + "Fibra Alimentar (g)":2.0, + "Cinzas (g)":0.5, + "Cálcio (mg)":12, + "Magnésio (mg)":11, + "Manganês (mg)":0.03, + "Fósforo (mg)":13, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":152, + "Cobre (mg)":0.04, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":255, + "Descrição dos alimentos":"Umbu, polpa, congelada", + "Umidade (%)":90.2, + "Energia (Kcal)":34, + "Energia (KJ)":142, + "Proteína (g)":0.5, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.8, + "Fibra Alimentar (g)":1.3, + "Cinzas (g)":0.4, + "Cálcio (mg)":11, + "Magnésio (mg)":8, + "Manganês (mg)":0.05, + "Fósforo (mg)":13, + "Ferro (mg)":0.2, + "Sódio (mg)":6, + "Potássio (mg)":154, + "Cobre (mg)":0.04, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":256, + "Descrição dos alimentos":"Uva, Itália, crua", + "Umidade (%)":85.0, + "Energia (Kcal)":53, + "Energia (KJ)":221, + "Proteína (g)":0.7, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.6, + "Fibra Alimentar (g)":0.9, + "Cinzas (g)":0.6, + "Cálcio (mg)":7, + "Magnésio (mg)":5, + "Manganês (mg)":0.13, + "Fósforo (mg)":12, + "Ferro (mg)":0.1, + "Sódio (mg)":"Tr", + "Potássio (mg)":162, + "Cobre (mg)":0.11, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":257, + "Descrição dos alimentos":"Uva, Rubi, crua", + "Umidade (%)":86.1, + "Energia (Kcal)":49, + "Energia (KJ)":205, + "Proteína (g)":0.6, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.7, + "Fibra Alimentar (g)":0.9, + "Cinzas (g)":0.5, + "Cálcio (mg)":8, + "Magnésio (mg)":6, + "Manganês (mg)":0.07, + "Fósforo (mg)":23, + "Ferro (mg)":0.2, + "Sódio (mg)":8, + "Potássio (mg)":159, + "Cobre (mg)":0.05, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":258, + "Descrição dos alimentos":"Uva, suco concentrado, envasado", + "Umidade (%)":85.1, + "Energia (Kcal)":58, + "Energia (KJ)":241, + "Proteína (g)":"Tr", + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.7, + "Fibra Alimentar (g)":0.2, + "Cinzas (g)":0.2, + "Cálcio (mg)":9, + "Magnésio (mg)":7, + "Manganês (mg)":0.20, + "Fósforo (mg)":10, + "Ferro (mg)":0.1, + "Sódio (mg)":10, + "Potássio (mg)":54, + "Cobre (mg)":0.13, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":259, + "Descrição dos alimentos":"Azeite, de dendê", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":260, + "Descrição dos alimentos":"Azeite, de oliva, extra virgem", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":261, + "Descrição dos alimentos":"Manteiga, com sal", + "Umidade (%)":15.8, + "Energia (Kcal)":726, + "Energia (KJ)":3037, + "Proteína (g)":0.4, + "Lipídeos (g)":82.4, + "Colesterol (mg)":201, + "Carboidrato (g)":0.1, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.4, + "Cálcio (mg)":9, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":28, + "Ferro (mg)":0.2, + "Sódio (mg)":579, + "Potássio (mg)":15, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":262, + "Descrição dos alimentos":"Manteiga, sem sal", + "Umidade (%)":13.6, + "Energia (Kcal)":758, + "Energia (KJ)":3170, + "Proteína (g)":0.4, + "Lipídeos (g)":86.0, + "Colesterol (mg)":214, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.1, + "Cálcio (mg)":4, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":7, + "Ferro (mg)":"Tr", + "Sódio (mg)":4, + "Potássio (mg)":5, + "Cobre (mg)":0.04, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":263, + "Descrição dos alimentos":"Margarina, com óleo hidrogenado, com sal (65% de lipídeos)", + "Umidade (%)":32.2, + "Energia (Kcal)":596, + "Energia (KJ)":2494, + "Proteína (g)":"Tr", + "Lipídeos (g)":67.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.9, + "Cálcio (mg)":6, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":7, + "Ferro (mg)":0.1, + "Sódio (mg)":894, + "Potássio (mg)":21, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":264, + "Descrição dos alimentos":"Margarina, com óleo hidrogenado, sem sal (80% de lipídeos)", + "Umidade (%)":19.6, + "Energia (Kcal)":723, + "Energia (KJ)":3023, + "Proteína (g)":"Tr", + "Lipídeos (g)":81.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.2, + "Cálcio (mg)":3, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":4, + "Ferro (mg)":0.1, + "Sódio (mg)":78, + "Potássio (mg)":2, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":265, + "Descrição dos alimentos":"Margarina, com óleo interesterificado, com sal (65%de lipídeos)", + "Umidade (%)":32.0, + "Energia (Kcal)":594, + "Energia (KJ)":2487, + "Proteína (g)":"Tr", + "Lipídeos (g)":67.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":5, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":6, + "Ferro (mg)":"Tr", + "Sódio (mg)":561, + "Potássio (mg)":15, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":266, + "Descrição dos alimentos":"Margarina, com óleo interesterificado, sem sal (65% de lipídeos)", + "Umidade (%)":33.4, + "Energia (Kcal)":593, + "Energia (KJ)":2482, + "Proteína (g)":"Tr", + "Lipídeos (g)":67.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.1, + "Cálcio (mg)":5, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":7, + "Ferro (mg)":0.1, + "Sódio (mg)":33, + "Potássio (mg)":5, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":267, + "Descrição dos alimentos":"Óleo, de babaçu", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":268, + "Descrição dos alimentos":"Óleo, de canola", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":269, + "Descrição dos alimentos":"Óleo, de girassol", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":270, + "Descrição dos alimentos":"Óleo, de milho", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":271, + "Descrição dos alimentos":"Óleo, de pequi", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":272, + "Descrição dos alimentos":"Óleo, de soja", + "Umidade (%)":0.0, + "Energia (Kcal)":884, + "Energia (KJ)":3699, + "Proteína (g)":0.0, + "Lipídeos (g)":100.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":0.0, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":273, + "Descrição dos alimentos":"Abadejo, filé, congelado, assado", + "Umidade (%)":74.3, + "Energia (Kcal)":112, + "Energia (KJ)":467, + "Proteína (g)":23.5, + "Lipídeos (g)":1.2, + "Colesterol (mg)":103, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.6, + "Cálcio (mg)":23, + "Magnésio (mg)":20, + "Manganês (mg)":"Tr", + "Fósforo (mg)":338, + "Ferro (mg)":0.5, + "Sódio (mg)":334, + "Potássio (mg)":156, + "Cobre (mg)":0.03, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":274, + "Descrição dos alimentos":"Abadejo, filé, congelado,cozido", + "Umidade (%)":79.7, + "Energia (Kcal)":91, + "Energia (KJ)":381, + "Proteína (g)":19.3, + "Lipídeos (g)":0.9, + "Colesterol (mg)":87, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":17, + "Magnésio (mg)":16, + "Manganês (mg)":"Tr", + "Fósforo (mg)":351, + "Ferro (mg)":0.3, + "Sódio (mg)":189, + "Potássio (mg)":146, + "Cobre (mg)":0.03, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":275, + "Descrição dos alimentos":"Abadejo, filé, congelado, cru", + "Umidade (%)":86.4, + "Energia (Kcal)":59, + "Energia (KJ)":247, + "Proteína (g)":13.1, + "Lipídeos (g)":0.4, + "Colesterol (mg)":31, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.6, + "Cálcio (mg)":10, + "Magnésio (mg)":14, + "Manganês (mg)":0.01, + "Fósforo (mg)":91, + "Ferro (mg)":0.1, + "Sódio (mg)":79, + "Potássio (mg)":148, + "Cobre (mg)":0.14, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":276, + "Descrição dos alimentos":"Abadejo, filé, congelado, grelhado", + "Umidade (%)":71.0, + "Energia (Kcal)":130, + "Energia (KJ)":542, + "Proteína (g)":27.6, + "Lipídeos (g)":1.3, + "Colesterol (mg)":136, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.6, + "Cálcio (mg)":20, + "Magnésio (mg)":22, + "Manganês (mg)":"Tr", + "Fósforo (mg)":581, + "Ferro (mg)":0.3, + "Sódio (mg)":305, + "Potássio (mg)":279, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":277, + "Descrição dos alimentos":"Atum, conserva em óleo", + "Umidade (%)":64.5, + "Energia (Kcal)":166, + "Energia (KJ)":694, + "Proteína (g)":26.2, + "Lipídeos (g)":6.0, + "Colesterol (mg)":53, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.5, + "Cálcio (mg)":7, + "Magnésio (mg)":29, + "Manganês (mg)":"Tr", + "Fósforo (mg)":211, + "Ferro (mg)":1.2, + "Sódio (mg)":362, + "Potássio (mg)":280, + "Cobre (mg)":0.04, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":278, + "Descrição dos alimentos":"Atum, fresco, cru", + "Umidade (%)":73.1, + "Energia (Kcal)":118, + "Energia (KJ)":492, + "Proteína (g)":25.7, + "Lipídeos (g)":0.9, + "Colesterol (mg)":48, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":7, + "Magnésio (mg)":32, + "Manganês (mg)":"Tr", + "Fósforo (mg)":254, + "Ferro (mg)":1.3, + "Sódio (mg)":30, + "Potássio (mg)":308, + "Cobre (mg)":0.09, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":279, + "Descrição dos alimentos":"Bacalhau, salgado, cru", + "Umidade (%)":47.9, + "Energia (Kcal)":136, + "Energia (KJ)":569, + "Proteína (g)":29.0, + "Lipídeos (g)":1.3, + "Colesterol (mg)":139, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":22.5, + "Cálcio (mg)":157, + "Magnésio (mg)":49, + "Manganês (mg)":0.03, + "Fósforo (mg)":186, + "Ferro (mg)":0.9, + "Sódio (mg)":13585, + "Potássio (mg)":434, + "Cobre (mg)":0.09, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":280, + "Descrição dos alimentos":"Bacalhau, salgado, refogado", + "Umidade (%)":65.9, + "Energia (Kcal)":140, + "Energia (KJ)":584, + "Proteína (g)":24.0, + "Lipídeos (g)":3.6, + "Colesterol (mg)":112, + "Carboidrato (g)":1.2, + "Fibra Alimentar (g)":"*", + "Cinzas (g)":5.3, + "Cálcio (mg)":59, + "Magnésio (mg)":15, + "Manganês (mg)":"Tr", + "Fósforo (mg)":51, + "Ferro (mg)":0.2, + "Sódio (mg)":1256, + "Potássio (mg)":50, + "Cobre (mg)":0.04, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":281, + "Descrição dos alimentos":"Cação, posta, com farinha de trigo, frita", + "Umidade (%)":60.6, + "Energia (Kcal)":208, + "Energia (KJ)":872, + "Proteína (g)":25.0, + "Lipídeos (g)":10.0, + "Colesterol (mg)":75, + "Carboidrato (g)":3.1, + "Fibra Alimentar (g)":0.5, + "Cinzas (g)":1.4, + "Cálcio (mg)":30, + "Magnésio (mg)":26, + "Manganês (mg)":0.06, + "Fósforo (mg)":462, + "Ferro (mg)":1.0, + "Sódio (mg)":160, + "Potássio (mg)":420, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":282, + "Descrição dos alimentos":"Cação, posta, cozida", + "Umidade (%)":75.9, + "Energia (Kcal)":116, + "Energia (KJ)":485, + "Proteína (g)":25.6, + "Lipídeos (g)":0.7, + "Colesterol (mg)":83, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":10, + "Magnésio (mg)":21, + "Manganês (mg)":"Tr", + "Fósforo (mg)":204, + "Ferro (mg)":0.3, + "Sódio (mg)":115, + "Potássio (mg)":249, + "Cobre (mg)":0.03, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":283, + "Descrição dos alimentos":"Cação, posta, crua", + "Umidade (%)":81.4, + "Energia (Kcal)":83, + "Energia (KJ)":349, + "Proteína (g)":17.9, + "Lipídeos (g)":0.8, + "Colesterol (mg)":36, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":9, + "Magnésio (mg)":19, + "Manganês (mg)":0.04, + "Fósforo (mg)":181, + "Ferro (mg)":0.2, + "Sódio (mg)":176, + "Potássio (mg)":299, + "Cobre (mg)":0.13, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":284, + "Descrição dos alimentos":"Camarão, Rio Grande, grande, cozido", + "Umidade (%)":78.7, + "Energia (Kcal)":90, + "Energia (KJ)":377, + "Proteína (g)":19.0, + "Lipídeos (g)":1.0, + "Colesterol (mg)":241, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.7, + "Cálcio (mg)":90, + "Magnésio (mg)":19, + "Manganês (mg)":0.06, + "Fósforo (mg)":266, + "Ferro (mg)":1.3, + "Sódio (mg)":367, + "Potássio (mg)":102, + "Cobre (mg)":0.17, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":285, + "Descrição dos alimentos":"Camarão, Rio Grande, grande, cru", + "Umidade (%)":89.1, + "Energia (Kcal)":47, + "Energia (KJ)":197, + "Proteína (g)":10.0, + "Lipídeos (g)":0.5, + "Colesterol (mg)":124, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":51, + "Magnésio (mg)":27, + "Manganês (mg)":0.04, + "Fósforo (mg)":234, + "Ferro (mg)":0.7, + "Sódio (mg)":201, + "Potássio (mg)":72, + "Cobre (mg)":0.11, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":286, + "Descrição dos alimentos":"Camarão, Sete Barbas, sem cabeça, com casca, frito", + "Umidade (%)":61.0, + "Energia (Kcal)":231, + "Energia (KJ)":968, + "Proteína (g)":18.4, + "Lipídeos (g)":15.6, + "Colesterol (mg)":283, + "Carboidrato (g)":2.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.1, + "Cálcio (mg)":960, + "Magnésio (mg)":74, + "Manganês (mg)":0.38, + "Fósforo (mg)":337, + "Ferro (mg)":2.4, + "Sódio (mg)":99, + "Potássio (mg)":107, + "Cobre (mg)":0.19, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":287, + "Descrição dos alimentos":"Caranguejo, cozido", + "Umidade (%)":77.0, + "Energia (Kcal)":83, + "Energia (KJ)":346, + "Proteína (g)":18.5, + "Lipídeos (g)":0.4, + "Colesterol (mg)":85, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.5, + "Cálcio (mg)":357, + "Magnésio (mg)":52, + "Manganês (mg)":0.07, + "Fósforo (mg)":154, + "Ferro (mg)":2.9, + "Sódio (mg)":360, + "Potássio (mg)":186, + "Cobre (mg)":0.72, + "Zinco (mg)":5.7 + }, + { + "Número do Alimento":288, + "Descrição dos alimentos":"Corimba, cru", + "Umidade (%)":75.6, + "Energia (Kcal)":128, + "Energia (KJ)":536, + "Proteína (g)":17.4, + "Lipídeos (g)":6.0, + "Colesterol (mg)":40, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":40, + "Magnésio (mg)":23, + "Manganês (mg)":0.02, + "Fósforo (mg)":190, + "Ferro (mg)":0.5, + "Sódio (mg)":47, + "Potássio (mg)":317, + "Cobre (mg)":0.03, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":289, + "Descrição dos alimentos":"Corimbatá, assado", + "Umidade (%)":59.9, + "Energia (Kcal)":261, + "Energia (KJ)":1094, + "Proteína (g)":19.9, + "Lipídeos (g)":19.6, + "Colesterol (mg)":80, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":22, + "Magnésio (mg)":24, + "Manganês (mg)":0.01, + "Fósforo (mg)":221, + "Ferro (mg)":1.0, + "Sódio (mg)":40, + "Potássio (mg)":326, + "Cobre (mg)":0.03, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":290, + "Descrição dos alimentos":"Corimbatá, cozido", + "Umidade (%)":64.6, + "Energia (Kcal)":239, + "Energia (KJ)":999, + "Proteína (g)":20.1, + "Lipídeos (g)":16.9, + "Colesterol (mg)":75, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":65, + "Magnésio (mg)":23, + "Manganês (mg)":0.02, + "Fósforo (mg)":185, + "Ferro (mg)":0.6, + "Sódio (mg)":37, + "Potássio (mg)":254, + "Cobre (mg)":0.05, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":291, + "Descrição dos alimentos":"Corvina de água doce, crua", + "Umidade (%)":79.2, + "Energia (Kcal)":101, + "Energia (KJ)":423, + "Proteína (g)":18.9, + "Lipídeos (g)":2.2, + "Colesterol (mg)":73, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":39, + "Magnésio (mg)":25, + "Manganês (mg)":0.02, + "Fósforo (mg)":154, + "Ferro (mg)":0.3, + "Sódio (mg)":45, + "Potássio (mg)":293, + "Cobre (mg)":0.02, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":292, + "Descrição dos alimentos":"Corvina do mar, crua", + "Umidade (%)":79.4, + "Energia (Kcal)":94, + "Energia (KJ)":392, + "Proteína (g)":18.6, + "Lipídeos (g)":1.6, + "Colesterol (mg)":67, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":"*", + "Magnésio (mg)":24, + "Manganês (mg)":0.01, + "Fósforo (mg)":183, + "Ferro (mg)":0.4, + "Sódio (mg)":68, + "Potássio (mg)":339, + "Cobre (mg)":0.03, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":293, + "Descrição dos alimentos":"Corvina grande, assada", + "Umidade (%)":69.0, + "Energia (Kcal)":147, + "Energia (KJ)":613, + "Proteína (g)":26.8, + "Lipídeos (g)":3.6, + "Colesterol (mg)":117, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":60, + "Magnésio (mg)":24, + "Manganês (mg)":0.03, + "Fósforo (mg)":176, + "Ferro (mg)":0.5, + "Sódio (mg)":85, + "Potássio (mg)":291, + "Cobre (mg)":0.02, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":294, + "Descrição dos alimentos":"Corvina grande, cozida", + "Umidade (%)":73.6, + "Energia (Kcal)":100, + "Energia (KJ)":419, + "Proteína (g)":23.4, + "Lipídeos (g)":2.6, + "Colesterol (mg)":123, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":69, + "Magnésio (mg)":22, + "Manganês (mg)":0.02, + "Fósforo (mg)":164, + "Ferro (mg)":0.6, + "Sódio (mg)":68, + "Potássio (mg)":194, + "Cobre (mg)":0.03, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":295, + "Descrição dos alimentos":"Dourada de água doce, fresca", + "Umidade (%)":76.2, + "Energia (Kcal)":131, + "Energia (KJ)":549, + "Proteína (g)":18.8, + "Lipídeos (g)":5.6, + "Colesterol (mg)":52, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":12, + "Magnésio (mg)":26, + "Manganês (mg)":0.01, + "Fósforo (mg)":189, + "Ferro (mg)":0.2, + "Sódio (mg)":40, + "Potássio (mg)":393, + "Cobre (mg)":0.02, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":296, + "Descrição dos alimentos":"Lambari, congelado, cru", + "Umidade (%)":71.9, + "Energia (Kcal)":131, + "Energia (KJ)":547, + "Proteína (g)":16.8, + "Lipídeos (g)":6.5, + "Colesterol (mg)":159, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.6, + "Cálcio (mg)":1181, + "Magnésio (mg)":45, + "Manganês (mg)":0.28, + "Fósforo (mg)":696, + "Ferro (mg)":0.9, + "Sódio (mg)":48, + "Potássio (mg)":244, + "Cobre (mg)":0.09, + "Zinco (mg)":3.3 + }, + { + "Número do Alimento":297, + "Descrição dos alimentos":"Lambari, congelado, frito", + "Umidade (%)":40.1, + "Energia (Kcal)":327, + "Energia (KJ)":1368, + "Proteína (g)":28.4, + "Lipídeos (g)":22.8, + "Colesterol (mg)":246, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":6.2, + "Cálcio (mg)":1881, + "Magnésio (mg)":66, + "Manganês (mg)":0.34, + "Fósforo (mg)":1067, + "Ferro (mg)":0.8, + "Sódio (mg)":65, + "Potássio (mg)":331, + "Cobre (mg)":0.31, + "Zinco (mg)":5.6 + }, + { + "Número do Alimento":298, + "Descrição dos alimentos":"Lambari, fresco, cru", + "Umidade (%)":72.2, + "Energia (Kcal)":152, + "Energia (KJ)":634, + "Proteína (g)":15.7, + "Lipídeos (g)":9.4, + "Colesterol (mg)":144, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.2, + "Cálcio (mg)":590, + "Magnésio (mg)":32, + "Manganês (mg)":0.41, + "Fósforo (mg)":441, + "Ferro (mg)":0.6, + "Sódio (mg)":41, + "Potássio (mg)":207, + "Cobre (mg)":0.05, + "Zinco (mg)":2.4 + }, + { + "Número do Alimento":299, + "Descrição dos alimentos":"Manjuba, com farinha de trigo, frita", + "Umidade (%)":41.3, + "Energia (Kcal)":344, + "Energia (KJ)":1437, + "Proteína (g)":23.5, + "Lipídeos (g)":22.6, + "Colesterol (mg)":282, + "Carboidrato (g)":10.2, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":2.4, + "Cálcio (mg)":763, + "Magnésio (mg)":47, + "Manganês (mg)":0.36, + "Fósforo (mg)":578, + "Ferro (mg)":3.0, + "Sódio (mg)":37, + "Potássio (mg)":319, + "Cobre (mg)":0.15, + "Zinco (mg)":3.8 + }, + { + "Número do Alimento":300, + "Descrição dos alimentos":"Manjuba, frita", + "Umidade (%)":40.7, + "Energia (Kcal)":349, + "Energia (KJ)":1462, + "Proteína (g)":30.1, + "Lipídeos (g)":24.5, + "Colesterol (mg)":270, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":4.2, + "Cálcio (mg)":575, + "Magnésio (mg)":32, + "Manganês (mg)":0.21, + "Fósforo (mg)":735, + "Ferro (mg)":0.9, + "Sódio (mg)":41, + "Potássio (mg)":318, + "Cobre (mg)":0.14, + "Zinco (mg)":3.2 + }, + { + "Número do Alimento":301, + "Descrição dos alimentos":"Merluza, filé, assado", + "Umidade (%)":70.7, + "Energia (Kcal)":122, + "Energia (KJ)":510, + "Proteína (g)":26.6, + "Lipídeos (g)":0.9, + "Colesterol (mg)":91, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":36, + "Magnésio (mg)":20, + "Manganês (mg)":0.03, + "Fósforo (mg)":273, + "Ferro (mg)":0.4, + "Sódio (mg)":120, + "Potássio (mg)":364, + "Cobre (mg)":0.03, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":302, + "Descrição dos alimentos":"Merluza, filé, cru", + "Umidade (%)":82.1, + "Energia (Kcal)":89, + "Energia (KJ)":373, + "Proteína (g)":16.6, + "Lipídeos (g)":2.0, + "Colesterol (mg)":57, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":20, + "Magnésio (mg)":27, + "Manganês (mg)":0.01, + "Fósforo (mg)":185, + "Ferro (mg)":0.2, + "Sódio (mg)":80, + "Potássio (mg)":340, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":303, + "Descrição dos alimentos":"Merluza, filé, frito", + "Umidade (%)":63.5, + "Energia (Kcal)":192, + "Energia (KJ)":802, + "Proteína (g)":26.9, + "Lipídeos (g)":8.5, + "Colesterol (mg)":109, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.5, + "Cálcio (mg)":36, + "Magnésio (mg)":38, + "Manganês (mg)":0.02, + "Fósforo (mg)":279, + "Ferro (mg)":0.4, + "Sódio (mg)":90, + "Potássio (mg)":447, + "Cobre (mg)":0.03, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":304, + "Descrição dos alimentos":"Pescada, branca, crua", + "Umidade (%)":79.6, + "Energia (Kcal)":111, + "Energia (KJ)":464, + "Proteína (g)":16.3, + "Lipídeos (g)":4.6, + "Colesterol (mg)":51, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":16, + "Magnésio (mg)":19, + "Manganês (mg)":0.01, + "Fósforo (mg)":136, + "Ferro (mg)":0.2, + "Sódio (mg)":76, + "Potássio (mg)":261, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":305, + "Descrição dos alimentos":"Pescada, branca, frita", + "Umidade (%)":57.0, + "Energia (Kcal)":223, + "Energia (KJ)":933, + "Proteína (g)":27.4, + "Lipídeos (g)":11.8, + "Colesterol (mg)":165, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.2, + "Cálcio (mg)":378, + "Magnésio (mg)":30, + "Manganês (mg)":0.06, + "Fósforo (mg)":504, + "Ferro (mg)":0.5, + "Sódio (mg)":107, + "Potássio (mg)":355, + "Cobre (mg)":0.08, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":306, + "Descrição dos alimentos":"Pescada, filé, com farinha de trigo, frito", + "Umidade (%)":53.2, + "Energia (Kcal)":283, + "Energia (KJ)":1186, + "Proteína (g)":21.4, + "Lipídeos (g)":19.1, + "Colesterol (mg)":73, + "Carboidrato (g)":5.0, + "Fibra Alimentar (g)":"Tr", + "Cinzas (g)":1.2, + "Cálcio (mg)":26, + "Magnésio (mg)":28, + "Manganês (mg)":0.07, + "Fósforo (mg)":216, + "Ferro (mg)":0.9, + "Sódio (mg)":91, + "Potássio (mg)":216, + "Cobre (mg)":0.03, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":307, + "Descrição dos alimentos":"Pescada, filé, cru", + "Umidade (%)":79.5, + "Energia (Kcal)":107, + "Energia (KJ)":449, + "Proteína (g)":16.7, + "Lipídeos (g)":4.0, + "Colesterol (mg)":65, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":14, + "Magnésio (mg)":23, + "Manganês (mg)":0.01, + "Fósforo (mg)":141, + "Ferro (mg)":0.2, + "Sódio (mg)":77, + "Potássio (mg)":253, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":308, + "Descrição dos alimentos":"Pescada, filé, frito", + "Umidade (%)":66.8, + "Energia (Kcal)":154, + "Energia (KJ)":645, + "Proteína (g)":28.6, + "Lipídeos (g)":3.6, + "Colesterol (mg)":81, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.7, + "Cálcio (mg)":10, + "Magnésio (mg)":21, + "Manganês (mg)":"Tr", + "Fósforo (mg)":204, + "Ferro (mg)":0.3, + "Sódio (mg)":115, + "Potássio (mg)":249, + "Cobre (mg)":0.03, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":309, + "Descrição dos alimentos":"Pescada, filé, molho escabeche", + "Umidade (%)":74.5, + "Energia (Kcal)":142, + "Energia (KJ)":594, + "Proteína (g)":11.8, + "Lipídeos (g)":8.0, + "Colesterol (mg)":43, + "Carboidrato (g)":5.0, + "Fibra Alimentar (g)":0.8, + "Cinzas (g)":0.7, + "Cálcio (mg)":20, + "Magnésio (mg)":18, + "Manganês (mg)":0.08, + "Fósforo (mg)":105, + "Ferro (mg)":1.5, + "Sódio (mg)":51, + "Potássio (mg)":208, + "Cobre (mg)":0.36, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":310, + "Descrição dos alimentos":"Pescadinha, crua", + "Umidade (%)":80.6, + "Energia (Kcal)":76, + "Energia (KJ)":320, + "Proteína (g)":15.5, + "Lipídeos (g)":1.1, + "Colesterol (mg)":84, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.0, + "Cálcio (mg)":332, + "Magnésio (mg)":34, + "Manganês (mg)":0.07, + "Fósforo (mg)":327, + "Ferro (mg)":0.5, + "Sódio (mg)":120, + "Potássio (mg)":304, + "Cobre (mg)":0.10, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":311, + "Descrição dos alimentos":"Pintado, assado", + "Umidade (%)":57.0, + "Energia (Kcal)":192, + "Energia (KJ)":801, + "Proteína (g)":36.5, + "Lipídeos (g)":4.0, + "Colesterol (mg)":126, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.0, + "Cálcio (mg)":114, + "Magnésio (mg)":42, + "Manganês (mg)":0.08, + "Fósforo (mg)":332, + "Ferro (mg)":0.8, + "Sódio (mg)":81, + "Potássio (mg)":527, + "Cobre (mg)":0.04, + "Zinco (mg)":2.1 + }, + { + "Número do Alimento":312, + "Descrição dos alimentos":"Pintado, cru", + "Umidade (%)":80.3, + "Energia (Kcal)":91, + "Energia (KJ)":381, + "Proteína (g)":18.6, + "Lipídeos (g)":1.3, + "Colesterol (mg)":50, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":12, + "Magnésio (mg)":24, + "Manganês (mg)":0.01, + "Fósforo (mg)":174, + "Ferro (mg)":0.2, + "Sódio (mg)":43, + "Potássio (mg)":294, + "Cobre (mg)":0.03, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":313, + "Descrição dos alimentos":"Pintado, grelhado", + "Umidade (%)":65.5, + "Energia (Kcal)":152, + "Energia (KJ)":637, + "Proteína (g)":30.8, + "Lipídeos (g)":2.3, + "Colesterol (mg)":99, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.6, + "Cálcio (mg)":69, + "Magnésio (mg)":27, + "Manganês (mg)":0.03, + "Fósforo (mg)":237, + "Ferro (mg)":0.5, + "Sódio (mg)":53, + "Potássio (mg)":360, + "Cobre (mg)":0.04, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":314, + "Descrição dos alimentos":"Porquinho, cru", + "Umidade (%)":79.2, + "Energia (Kcal)":93, + "Energia (KJ)":389, + "Proteína (g)":20.5, + "Lipídeos (g)":0.6, + "Colesterol (mg)":49, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":26, + "Magnésio (mg)":24, + "Manganês (mg)":0.05, + "Fósforo (mg)":207, + "Ferro (mg)":0.4, + "Sódio (mg)":67, + "Potássio (mg)":313, + "Cobre (mg)":0.04, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":315, + "Descrição dos alimentos":"Salmão, filé, com pele, fresco, grelhado", + "Umidade (%)":60.9, + "Energia (Kcal)":229, + "Energia (KJ)":957, + "Proteína (g)":23.9, + "Lipídeos (g)":14.0, + "Colesterol (mg)":85, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":29, + "Magnésio (mg)":28, + "Manganês (mg)":0.02, + "Fósforo (mg)":300, + "Ferro (mg)":0.5, + "Sódio (mg)":85, + "Potássio (mg)":384, + "Cobre (mg)":0.04, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":316, + "Descrição dos alimentos":"Salmão, sem pele, fresco, cru", + "Umidade (%)":69.0, + "Energia (Kcal)":170, + "Energia (KJ)":710, + "Proteína (g)":19.3, + "Lipídeos (g)":9.7, + "Colesterol (mg)":53, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":9, + "Magnésio (mg)":27, + "Manganês (mg)":"Tr", + "Fósforo (mg)":259, + "Ferro (mg)":0.2, + "Sódio (mg)":64, + "Potássio (mg)":376, + "Cobre (mg)":0.02, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":317, + "Descrição dos alimentos":"Salmão, sem pele, fresco, grelhado", + "Umidade (%)":58.1, + "Energia (Kcal)":243, + "Energia (KJ)":1015, + "Proteína (g)":26.1, + "Lipídeos (g)":14.5, + "Colesterol (mg)":73, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.6, + "Cálcio (mg)":15, + "Magnésio (mg)":38, + "Manganês (mg)":0.01, + "Fósforo (mg)":352, + "Ferro (mg)":0.4, + "Sódio (mg)":96, + "Potássio (mg)":518, + "Cobre (mg)":0.04, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":318, + "Descrição dos alimentos":"Sardinha, assada", + "Umidade (%)":60.1, + "Energia (Kcal)":164, + "Energia (KJ)":688, + "Proteína (g)":32.2, + "Lipídeos (g)":3.0, + "Colesterol (mg)":109, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":4.4, + "Cálcio (mg)":438, + "Magnésio (mg)":51, + "Manganês (mg)":0.24, + "Fósforo (mg)":578, + "Ferro (mg)":1.3, + "Sódio (mg)":74, + "Potássio (mg)":574, + "Cobre (mg)":0.14, + "Zinco (mg)":1.8 + }, + { + "Número do Alimento":319, + "Descrição dos alimentos":"Sardinha, conserva em óleo", + "Umidade (%)":55.1, + "Energia (Kcal)":285, + "Energia (KJ)":1192, + "Proteína (g)":15.9, + "Lipídeos (g)":24.0, + "Colesterol (mg)":73, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.9, + "Cálcio (mg)":550, + "Magnésio (mg)":35, + "Manganês (mg)":0.11, + "Fósforo (mg)":496, + "Ferro (mg)":3.5, + "Sódio (mg)":666, + "Potássio (mg)":367, + "Cobre (mg)":0.03, + "Zinco (mg)":1.6 + }, + { + "Número do Alimento":320, + "Descrição dos alimentos":"Sardinha, frita", + "Umidade (%)":48.5, + "Energia (Kcal)":257, + "Energia (KJ)":1075, + "Proteína (g)":33.4, + "Lipídeos (g)":12.7, + "Colesterol (mg)":103, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":4.3, + "Cálcio (mg)":482, + "Magnésio (mg)":39, + "Manganês (mg)":0.25, + "Fósforo (mg)":629, + "Ferro (mg)":1.1, + "Sódio (mg)":60, + "Potássio (mg)":460, + "Cobre (mg)":0.14, + "Zinco (mg)":1.6 + }, + { + "Número do Alimento":321, + "Descrição dos alimentos":"Sardinha, inteira, crua", + "Umidade (%)":76.6, + "Energia (Kcal)":114, + "Energia (KJ)":477, + "Proteína (g)":21.1, + "Lipídeos (g)":2.7, + "Colesterol (mg)":61, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.6, + "Cálcio (mg)":167, + "Magnésio (mg)":29, + "Manganês (mg)":0.10, + "Fósforo (mg)":294, + "Ferro (mg)":1.3, + "Sódio (mg)":60, + "Potássio (mg)":312, + "Cobre (mg)":0.13, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":322, + "Descrição dos alimentos":"Tucunaré, filé, congelado, cru", + "Umidade (%)":79.9, + "Energia (Kcal)":88, + "Energia (KJ)":367, + "Proteína (g)":18.0, + "Lipídeos (g)":1.2, + "Colesterol (mg)":47, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":19, + "Magnésio (mg)":26, + "Manganês (mg)":0.01, + "Fósforo (mg)":168, + "Ferro (mg)":0.3, + "Sódio (mg)":57, + "Potássio (mg)":288, + "Cobre (mg)":0.10, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":323, + "Descrição dos alimentos":"Apresuntado", + "Umidade (%)":73.7, + "Energia (Kcal)":129, + "Energia (KJ)":539, + "Proteína (g)":13.5, + "Lipídeos (g)":6.7, + "Colesterol (mg)":38, + "Carboidrato (g)":2.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.3, + "Cálcio (mg)":23, + "Magnésio (mg)":15, + "Manganês (mg)":0.04, + "Fósforo (mg)":225, + "Ferro (mg)":0.9, + "Sódio (mg)":943, + "Potássio (mg)":270, + "Cobre (mg)":0.03, + "Zinco (mg)":1.6 + }, + { + "Número do Alimento":324, + "Descrição dos alimentos":"Caldo de carne, tablete", + "Umidade (%)":2.9, + "Energia (Kcal)":241, + "Energia (KJ)":1007, + "Proteína (g)":7.8, + "Lipídeos (g)":16.6, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":15.1, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":57.6, + "Cálcio (mg)":129, + "Magnésio (mg)":22, + "Manganês (mg)":0.02, + "Fósforo (mg)":123, + "Ferro (mg)":"Tr", + "Sódio (mg)":22180, + "Potássio (mg)":218, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":325, + "Descrição dos alimentos":"Caldo de galinha, tablete", + "Umidade (%)":3.4, + "Energia (Kcal)":251, + "Energia (KJ)":1052, + "Proteína (g)":6.3, + "Lipídeos (g)":20.4, + "Colesterol (mg)":2, + "Carboidrato (g)":10.6, + "Fibra Alimentar (g)":11.8, + "Cinzas (g)":59.3, + "Cálcio (mg)":16, + "Magnésio (mg)":13, + "Manganês (mg)":0.13, + "Fósforo (mg)":48, + "Ferro (mg)":0.7, + "Sódio (mg)":22300, + "Potássio (mg)":68, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":326, + "Descrição dos alimentos":"Carne, bovina, acém, moído, cozido", + "Umidade (%)":61.6, + "Energia (Kcal)":212, + "Energia (KJ)":889, + "Proteína (g)":26.7, + "Lipídeos (g)":10.9, + "Colesterol (mg)":103, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":4, + "Magnésio (mg)":17, + "Manganês (mg)":0.01, + "Fósforo (mg)":164, + "Ferro (mg)":2.7, + "Sódio (mg)":52, + "Potássio (mg)":256, + "Cobre (mg)":0.06, + "Zinco (mg)":8.1 + }, + { + "Número do Alimento":327, + "Descrição dos alimentos":"Carne, bovina, acém, moído, cru", + "Umidade (%)":72.7, + "Energia (Kcal)":137, + "Energia (KJ)":571, + "Proteína (g)":19.4, + "Lipídeos (g)":5.9, + "Colesterol (mg)":58, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":3, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":158, + "Ferro (mg)":1.8, + "Sódio (mg)":49, + "Potássio (mg)":237, + "Cobre (mg)":0.08, + "Zinco (mg)":6.3 + }, + { + "Número do Alimento":328, + "Descrição dos alimentos":"Carne, bovina, acém, sem gordura, cozido", + "Umidade (%)":60.4, + "Energia (Kcal)":215, + "Energia (KJ)":898, + "Proteína (g)":27.3, + "Lipídeos (g)":10.9, + "Colesterol (mg)":107, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":7, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":164, + "Ferro (mg)":2.4, + "Sódio (mg)":56, + "Potássio (mg)":254, + "Cobre (mg)":0.07, + "Zinco (mg)":8.0 + }, + { + "Número do Alimento":329, + "Descrição dos alimentos":"Carne, bovina, acém, sem gordura, cru", + "Umidade (%)":71.5, + "Energia (Kcal)":144, + "Energia (KJ)":603, + "Proteína (g)":20.8, + "Lipídeos (g)":6.1, + "Colesterol (mg)":53, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":5, + "Magnésio (mg)":13, + "Manganês (mg)":"Tr", + "Fósforo (mg)":144, + "Ferro (mg)":1.5, + "Sódio (mg)":50, + "Potássio (mg)":234, + "Cobre (mg)":0.04, + "Zinco (mg)":5.2 + }, + { + "Número do Alimento":330, + "Descrição dos alimentos":"Carne, bovina, almôndegas, cruas", + "Umidade (%)":64.3, + "Energia (Kcal)":189, + "Energia (KJ)":792, + "Proteína (g)":12.3, + "Lipídeos (g)":11.2, + "Colesterol (mg)":34, + "Carboidrato (g)":9.8, + "Fibra Alimentar (g)":"*", + "Cinzas (g)":2.4, + "Cálcio (mg)":22, + "Magnésio (mg)":24, + "Manganês (mg)":0.17, + "Fósforo (mg)":145, + "Ferro (mg)":1.6, + "Sódio (mg)":621, + "Potássio (mg)":328, + "Cobre (mg)":0.15, + "Zinco (mg)":2.3 + }, + { + "Número do Alimento":331, + "Descrição dos alimentos":"Carne, bovina, almôndegas, fritas", + "Umidade (%)":48.1, + "Energia (Kcal)":272, + "Energia (KJ)":1137, + "Proteína (g)":18.2, + "Lipídeos (g)":15.8, + "Colesterol (mg)":36, + "Carboidrato (g)":14.3, + "Fibra Alimentar (g)":"*", + "Cinzas (g)":3.7, + "Cálcio (mg)":27, + "Magnésio (mg)":48, + "Manganês (mg)":0.41, + "Fósforo (mg)":244, + "Ferro (mg)":1.9, + "Sódio (mg)":1030, + "Potássio (mg)":536, + "Cobre (mg)":0.19, + "Zinco (mg)":2.6 + }, + { + "Número do Alimento":332, + "Descrição dos alimentos":"Carne, bovina, bucho, cozido", + "Umidade (%)":74.1, + "Energia (Kcal)":133, + "Energia (KJ)":557, + "Proteína (g)":21.6, + "Lipídeos (g)":4.5, + "Colesterol (mg)":245, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.3, + "Cálcio (mg)":13, + "Magnésio (mg)":7, + "Manganês (mg)":0.01, + "Fósforo (mg)":63, + "Ferro (mg)":0.6, + "Sódio (mg)":38, + "Potássio (mg)":70, + "Cobre (mg)":0.05, + "Zinco (mg)":2.5 + }, + { + "Número do Alimento":333, + "Descrição dos alimentos":"Carne, bovina, bucho, cru", + "Umidade (%)":75.0, + "Energia (Kcal)":137, + "Energia (KJ)":574, + "Proteína (g)":20.5, + "Lipídeos (g)":5.5, + "Colesterol (mg)":145, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.4, + "Cálcio (mg)":9, + "Magnésio (mg)":6, + "Manganês (mg)":0.01, + "Fósforo (mg)":61, + "Ferro (mg)":0.5, + "Sódio (mg)":45, + "Potássio (mg)":85, + "Cobre (mg)":0.06, + "Zinco (mg)":2.1 + }, + { + "Número do Alimento":334, + "Descrição dos alimentos":"Carne, bovina, capa de contra-filé, com gordura, crua", + "Umidade (%)":64.8, + "Energia (Kcal)":217, + "Energia (KJ)":908, + "Proteína (g)":19.2, + "Lipídeos (g)":15.0, + "Colesterol (mg)":63, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":6, + "Magnésio (mg)":17, + "Manganês (mg)":0.01, + "Fósforo (mg)":144, + "Ferro (mg)":1.5, + "Sódio (mg)":58, + "Potássio (mg)":267, + "Cobre (mg)":0.06, + "Zinco (mg)":3.5 + }, + { + "Número do Alimento":335, + "Descrição dos alimentos":"Carne, bovina, capa de contra-filé, com gordura, grelhada", + "Umidade (%)":47.9, + "Energia (Kcal)":312, + "Energia (KJ)":1304, + "Proteína (g)":30.7, + "Lipídeos (g)":20.0, + "Colesterol (mg)":120, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":7, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":214, + "Ferro (mg)":2.6, + "Sódio (mg)":81, + "Potássio (mg)":323, + "Cobre (mg)":0.13, + "Zinco (mg)":6.2 + }, + { + "Número do Alimento":336, + "Descrição dos alimentos":"Carne, bovina, capa de contra-filé, sem gordura, crua", + "Umidade (%)":73.0, + "Energia (Kcal)":131, + "Energia (KJ)":548, + "Proteína (g)":21.5, + "Lipídeos (g)":4.3, + "Colesterol (mg)":58, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":6, + "Magnésio (mg)":20, + "Manganês (mg)":"Tr", + "Fósforo (mg)":178, + "Ferro (mg)":2.0, + "Sódio (mg)":79, + "Potássio (mg)":325, + "Cobre (mg)":0.06, + "Zinco (mg)":4.6 + }, + { + "Número do Alimento":337, + "Descrição dos alimentos":"Carne, bovina, capa de contra-filé, sem gordura, grelhada", + "Umidade (%)":53.7, + "Energia (Kcal)":239, + "Energia (KJ)":1002, + "Proteína (g)":35.1, + "Lipídeos (g)":10.0, + "Colesterol (mg)":80, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":9, + "Magnésio (mg)":26, + "Manganês (mg)":0.01, + "Fósforo (mg)":287, + "Ferro (mg)":2.8, + "Sódio (mg)":83, + "Potássio (mg)":385, + "Cobre (mg)":0.12, + "Zinco (mg)":7.6 + }, + { + "Número do Alimento":338, + "Descrição dos alimentos":"Carne, bovina, charque, cozido", + "Umidade (%)":45.8, + "Energia (Kcal)":263, + "Energia (KJ)":1099, + "Proteína (g)":36.4, + "Lipídeos (g)":11.9, + "Colesterol (mg)":113, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.6, + "Cálcio (mg)":15, + "Magnésio (mg)":13, + "Manganês (mg)":0.02, + "Fósforo (mg)":101, + "Ferro (mg)":3.5, + "Sódio (mg)":1443, + "Potássio (mg)":90, + "Cobre (mg)":0.07, + "Zinco (mg)":6.1 + }, + { + "Número do Alimento":339, + "Descrição dos alimentos":"Carne, bovina, charque, cru", + "Umidade (%)":44.5, + "Energia (Kcal)":249, + "Energia (KJ)":1041, + "Proteína (g)":22.7, + "Lipídeos (g)":16.8, + "Colesterol (mg)":81, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":14.5, + "Cálcio (mg)":15, + "Magnésio (mg)":13, + "Manganês (mg)":"Tr", + "Fósforo (mg)":122, + "Ferro (mg)":1.5, + "Sódio (mg)":5875, + "Potássio (mg)":236, + "Cobre (mg)":0.03, + "Zinco (mg)":3.9 + }, + { + "Número do Alimento":340, + "Descrição dos alimentos":"Carne, bovina, contra-filé, à milanesa", + "Umidade (%)":42.2, + "Energia (Kcal)":352, + "Energia (KJ)":1471, + "Proteína (g)":20.6, + "Lipídeos (g)":24.0, + "Colesterol (mg)":99, + "Carboidrato (g)":12.2, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":1.1, + "Cálcio (mg)":15, + "Magnésio (mg)":27, + "Manganês (mg)":0.27, + "Fósforo (mg)":203, + "Ferro (mg)":2.9, + "Sódio (mg)":77, + "Potássio (mg)":271, + "Cobre (mg)":0.10, + "Zinco (mg)":2.9 + }, + { + "Número do Alimento":341, + "Descrição dos alimentos":"Carne, bovina, contra-filé de costela, cru", + "Umidade (%)":66.4, + "Energia (Kcal)":202, + "Energia (KJ)":847, + "Proteína (g)":19.8, + "Lipídeos (g)":13.1, + "Colesterol (mg)":52, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":164, + "Ferro (mg)":1.6, + "Sódio (mg)":39, + "Potássio (mg)":245, + "Cobre (mg)":0.04, + "Zinco (mg)":4.4 + }, + { + "Número do Alimento":342, + "Descrição dos alimentos":"Carne, bovina, contra-filé de costela, grelhado", + "Umidade (%)":52.2, + "Energia (Kcal)":275, + "Energia (KJ)":1150, + "Proteína (g)":29.9, + "Lipídeos (g)":16.3, + "Colesterol (mg)":98, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":4, + "Magnésio (mg)":24, + "Manganês (mg)":0.01, + "Fósforo (mg)":252, + "Ferro (mg)":2.8, + "Sódio (mg)":51, + "Potássio (mg)":383, + "Cobre (mg)":0.08, + "Zinco (mg)":6.7 + }, + { + "Número do Alimento":343, + "Descrição dos alimentos":"Carne, bovina, contra-filé, com gordura, cru", + "Umidade (%)":65.7, + "Energia (Kcal)":206, + "Energia (KJ)":861, + "Proteína (g)":21.2, + "Lipídeos (g)":12.8, + "Colesterol (mg)":73, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":18, + "Manganês (mg)":0.01, + "Fósforo (mg)":164, + "Ferro (mg)":1.3, + "Sódio (mg)":44, + "Potássio (mg)":285, + "Cobre (mg)":0.04, + "Zinco (mg)":2.8 + }, + { + "Número do Alimento":344, + "Descrição dos alimentos":"Carne, bovina, contra-filé, com gordura, grelhado", + "Umidade (%)":51.7, + "Energia (Kcal)":278, + "Energia (KJ)":1163, + "Proteína (g)":32.4, + "Lipídeos (g)":15.5, + "Colesterol (mg)":144, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":4, + "Magnésio (mg)":19, + "Manganês (mg)":"Tr", + "Fósforo (mg)":219, + "Ferro (mg)":2.4, + "Sódio (mg)":57, + "Potássio (mg)":352, + "Cobre (mg)":0.09, + "Zinco (mg)":4.8 + }, + { + "Número do Alimento":345, + "Descrição dos alimentos":"Carne, bovina, contra-filé, sem gordura, cru", + "Umidade (%)":69.1, + "Energia (Kcal)":157, + "Energia (KJ)":655, + "Proteína (g)":24.0, + "Lipídeos (g)":6.0, + "Colesterol (mg)":59, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":4, + "Magnésio (mg)":21, + "Manganês (mg)":"Tr", + "Fósforo (mg)":184, + "Ferro (mg)":1.7, + "Sódio (mg)":53, + "Potássio (mg)":335, + "Cobre (mg)":0.05, + "Zinco (mg)":3.2 + }, + { + "Número do Alimento":346, + "Descrição dos alimentos":"Carne, bovina, contra-filé, sem gordura, grelhado", + "Umidade (%)":57.5, + "Energia (Kcal)":194, + "Energia (KJ)":810, + "Proteína (g)":35.9, + "Lipídeos (g)":4.5, + "Colesterol (mg)":102, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":5, + "Magnésio (mg)":21, + "Manganês (mg)":"Tr", + "Fósforo (mg)":241, + "Ferro (mg)":2.4, + "Sódio (mg)":58, + "Potássio (mg)":386, + "Cobre (mg)":0.09, + "Zinco (mg)":5.1 + }, + { + "Número do Alimento":347, + "Descrição dos alimentos":"Carne, bovina, costela, assada", + "Umidade (%)":43.2, + "Energia (Kcal)":373, + "Energia (KJ)":1561, + "Proteína (g)":28.8, + "Lipídeos (g)":27.7, + "Colesterol (mg)":95, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":28, + "Magnésio (mg)":20, + "Manganês (mg)":"Tr", + "Fósforo (mg)":179, + "Ferro (mg)":2.2, + "Sódio (mg)":92, + "Potássio (mg)":270, + "Cobre (mg)":0.08, + "Zinco (mg)":5.5 + }, + { + "Número do Alimento":348, + "Descrição dos alimentos":"Carne, bovina, costela, crua", + "Umidade (%)":52.7, + "Energia (Kcal)":358, + "Energia (KJ)":1497, + "Proteína (g)":16.7, + "Lipídeos (g)":31.8, + "Colesterol (mg)":44, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":"*", + "Magnésio (mg)":12, + "Manganês (mg)":"Tr", + "Fósforo (mg)":130, + "Ferro (mg)":1.2, + "Sódio (mg)":70, + "Potássio (mg)":151, + "Cobre (mg)":"Tr", + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":349, + "Descrição dos alimentos":"Carne, bovina, coxão duro, sem gordura, cozido", + "Umidade (%)":58.5, + "Energia (Kcal)":217, + "Energia (KJ)":906, + "Proteína (g)":31.9, + "Lipídeos (g)":8.9, + "Colesterol (mg)":71, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":189, + "Ferro (mg)":1.7, + "Sódio (mg)":41, + "Potássio (mg)":252, + "Cobre (mg)":0.07, + "Zinco (mg)":5.0 + }, + { + "Número do Alimento":350, + "Descrição dos alimentos":"Carne, bovina, coxão duro, sem gordura, cru", + "Umidade (%)":69.8, + "Energia (Kcal)":148, + "Energia (KJ)":619, + "Proteína (g)":21.5, + "Lipídeos (g)":6.2, + "Colesterol (mg)":60, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":3, + "Magnésio (mg)":21, + "Manganês (mg)":"Tr", + "Fósforo (mg)":189, + "Ferro (mg)":1.9, + "Sódio (mg)":49, + "Potássio (mg)":358, + "Cobre (mg)":0.05, + "Zinco (mg)":2.8 + }, + { + "Número do Alimento":351, + "Descrição dos alimentos":"Carne, bovina, coxão mole, sem gordura, cozido", + "Umidade (%)":58.0, + "Energia (Kcal)":219, + "Energia (KJ)":915, + "Proteína (g)":32.4, + "Lipídeos (g)":8.9, + "Colesterol (mg)":84, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":4, + "Magnésio (mg)":13, + "Manganês (mg)":"Tr", + "Fósforo (mg)":183, + "Ferro (mg)":2.6, + "Sódio (mg)":44, + "Potássio (mg)":239, + "Cobre (mg)":0.11, + "Zinco (mg)":4.7 + }, + { + "Número do Alimento":352, + "Descrição dos alimentos":"Carne, bovina, coxão mole, sem gordura, cru", + "Umidade (%)":68.6, + "Energia (Kcal)":169, + "Energia (KJ)":707, + "Proteína (g)":21.2, + "Lipídeos (g)":8.7, + "Colesterol (mg)":84, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":21, + "Manganês (mg)":"Tr", + "Fósforo (mg)":175, + "Ferro (mg)":1.9, + "Sódio (mg)":61, + "Potássio (mg)":335, + "Cobre (mg)":0.05, + "Zinco (mg)":2.6 + }, + { + "Número do Alimento":353, + "Descrição dos alimentos":"Carne, bovina, cupim, assado", + "Umidade (%)":48.4, + "Energia (Kcal)":330, + "Energia (KJ)":1381, + "Proteína (g)":28.6, + "Lipídeos (g)":23.0, + "Colesterol (mg)":91, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":8, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":212, + "Ferro (mg)":2.7, + "Sódio (mg)":72, + "Potássio (mg)":321, + "Cobre (mg)":0.08, + "Zinco (mg)":5.3 + }, + { + "Número do Alimento":354, + "Descrição dos alimentos":"Carne, bovina, cupim, cru", + "Umidade (%)":64.8, + "Energia (Kcal)":221, + "Energia (KJ)":926, + "Proteína (g)":19.5, + "Lipídeos (g)":15.3, + "Colesterol (mg)":51, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":13, + "Manganês (mg)":"Tr", + "Fósforo (mg)":220, + "Ferro (mg)":1.1, + "Sódio (mg)":47, + "Potássio (mg)":151, + "Cobre (mg)":0.03, + "Zinco (mg)":2.4 + }, + { + "Número do Alimento":355, + "Descrição dos alimentos":"Carne, bovina, fígado, cru", + "Umidade (%)":71.3, + "Energia (Kcal)":141, + "Energia (KJ)":590, + "Proteína (g)":20.7, + "Lipídeos (g)":5.4, + "Colesterol (mg)":393, + "Carboidrato (g)":1.1, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.5, + "Cálcio (mg)":4, + "Magnésio (mg)":12, + "Manganês (mg)":0.26, + "Fósforo (mg)":334, + "Ferro (mg)":5.6, + "Sódio (mg)":76, + "Potássio (mg)":265, + "Cobre (mg)":9.01, + "Zinco (mg)":3.5 + }, + { + "Número do Alimento":356, + "Descrição dos alimentos":"Carne, bovina, fígado, grelhado", + "Umidade (%)":55.0, + "Energia (Kcal)":225, + "Energia (KJ)":942, + "Proteína (g)":29.9, + "Lipídeos (g)":9.0, + "Colesterol (mg)":601, + "Carboidrato (g)":4.2, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.0, + "Cálcio (mg)":6, + "Magnésio (mg)":10, + "Manganês (mg)":0.22, + "Fósforo (mg)":420, + "Ferro (mg)":5.8, + "Sódio (mg)":82, + "Potássio (mg)":309, + "Cobre (mg)":12.58, + "Zinco (mg)":4.0 + }, + { + "Número do Alimento":357, + "Descrição dos alimentos":"Carne, bovina, filé mingnon, sem gordura, cru", + "Umidade (%)":71.9, + "Energia (Kcal)":143, + "Energia (KJ)":598, + "Proteína (g)":21.6, + "Lipídeos (g)":5.6, + "Colesterol (mg)":55, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":3, + "Magnésio (mg)":21, + "Manganês (mg)":0.01, + "Fósforo (mg)":193, + "Ferro (mg)":1.9, + "Sódio (mg)":49, + "Potássio (mg)":322, + "Cobre (mg)":0.08, + "Zinco (mg)":2.8 + }, + { + "Número do Alimento":358, + "Descrição dos alimentos":"Carne, bovina, filé mingnon, sem gordura, grelhado", + "Umidade (%)":57.0, + "Energia (Kcal)":220, + "Energia (KJ)":919, + "Proteína (g)":32.8, + "Lipídeos (g)":8.8, + "Colesterol (mg)":103, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":4, + "Magnésio (mg)":28, + "Manganês (mg)":0.02, + "Fósforo (mg)":308, + "Ferro (mg)":2.9, + "Sódio (mg)":58, + "Potássio (mg)":326, + "Cobre (mg)":0.14, + "Zinco (mg)":4.1 + }, + { + "Número do Alimento":359, + "Descrição dos alimentos":"Carne, bovina, flanco, sem gordura, cozido", + "Umidade (%)":62.0, + "Energia (Kcal)":196, + "Energia (KJ)":818, + "Proteína (g)":29.4, + "Lipídeos (g)":7.8, + "Colesterol (mg)":62, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":181, + "Ferro (mg)":2.8, + "Sódio (mg)":42, + "Potássio (mg)":249, + "Cobre (mg)":0.07, + "Zinco (mg)":5.6 + }, + { + "Número do Alimento":360, + "Descrição dos alimentos":"Carne, bovina, flanco, sem gordura, cru", + "Umidade (%)":72.1, + "Energia (Kcal)":141, + "Energia (KJ)":592, + "Proteína (g)":20.0, + "Lipídeos (g)":6.2, + "Colesterol (mg)":50, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":167, + "Ferro (mg)":1.6, + "Sódio (mg)":54, + "Potássio (mg)":324, + "Cobre (mg)":0.05, + "Zinco (mg)":4.5 + }, + { + "Número do Alimento":361, + "Descrição dos alimentos":"Carne, bovina, fraldinha, com gordura, cozida", + "Umidade (%)":49.7, + "Energia (Kcal)":338, + "Energia (KJ)":1416, + "Proteína (g)":24.2, + "Lipídeos (g)":26.0, + "Colesterol (mg)":65, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":3, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":161, + "Ferro (mg)":2.0, + "Sódio (mg)":39, + "Potássio (mg)":207, + "Cobre (mg)":0.07, + "Zinco (mg)":6.5 + }, + { + "Número do Alimento":362, + "Descrição dos alimentos":"Carne, bovina, fraldinha, com gordura, crua", + "Umidade (%)":65.4, + "Energia (Kcal)":221, + "Energia (KJ)":924, + "Proteína (g)":17.6, + "Lipídeos (g)":16.1, + "Colesterol (mg)":54, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":3, + "Magnésio (mg)":16, + "Manganês (mg)":0.00, + "Fósforo (mg)":131, + "Ferro (mg)":1.5, + "Sódio (mg)":51, + "Potássio (mg)":274, + "Cobre (mg)":0.04, + "Zinco (mg)":4.2 + }, + { + "Número do Alimento":363, + "Descrição dos alimentos":"Carne, bovina, lagarto, cozido", + "Umidade (%)":57.6, + "Energia (Kcal)":222, + "Energia (KJ)":931, + "Proteína (g)":32.9, + "Lipídeos (g)":9.1, + "Colesterol (mg)":56, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":13, + "Manganês (mg)":"Tr", + "Fósforo (mg)":167, + "Ferro (mg)":1.9, + "Sódio (mg)":48, + "Potássio (mg)":254, + "Cobre (mg)":0.05, + "Zinco (mg)":7.0 + }, + { + "Número do Alimento":364, + "Descrição dos alimentos":"Carne, bovina, lagarto, cru", + "Umidade (%)":71.0, + "Energia (Kcal)":135, + "Energia (KJ)":564, + "Proteína (g)":20.5, + "Lipídeos (g)":5.2, + "Colesterol (mg)":56, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":3, + "Magnésio (mg)":20, + "Manganês (mg)":"Tr", + "Fósforo (mg)":185, + "Ferro (mg)":1.3, + "Sódio (mg)":54, + "Potássio (mg)":362, + "Cobre (mg)":0.05, + "Zinco (mg)":2.4 + }, + { + "Número do Alimento":365, + "Descrição dos alimentos":"Carne, bovina, língua, cozida", + "Umidade (%)":53.4, + "Energia (Kcal)":315, + "Energia (KJ)":1318, + "Proteína (g)":21.4, + "Lipídeos (g)":24.8, + "Colesterol (mg)":105, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":6, + "Magnésio (mg)":12, + "Manganês (mg)":0.01, + "Fósforo (mg)":136, + "Ferro (mg)":2.1, + "Sódio (mg)":59, + "Potássio (mg)":175, + "Cobre (mg)":0.08, + "Zinco (mg)":4.1 + }, + { + "Número do Alimento":366, + "Descrição dos alimentos":"Carne, bovina, língua, crua", + "Umidade (%)":65.0, + "Energia (Kcal)":215, + "Energia (KJ)":901, + "Proteína (g)":17.1, + "Lipídeos (g)":15.8, + "Colesterol (mg)":118, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":5, + "Magnésio (mg)":15, + "Manganês (mg)":0.02, + "Fósforo (mg)":164, + "Ferro (mg)":1.7, + "Sódio (mg)":73, + "Potássio (mg)":251, + "Cobre (mg)":0.09, + "Zinco (mg)":2.9 + }, + { + "Número do Alimento":367, + "Descrição dos alimentos":"Carne, bovina, maminha, crua", + "Umidade (%)":70.0, + "Energia (Kcal)":153, + "Energia (KJ)":639, + "Proteína (g)":20.9, + "Lipídeos (g)":7.0, + "Colesterol (mg)":51, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":16, + "Manganês (mg)":"Tr", + "Fósforo (mg)":181, + "Ferro (mg)":1.1, + "Sódio (mg)":37, + "Potássio (mg)":274, + "Cobre (mg)":0.03, + "Zinco (mg)":3.5 + }, + { + "Número do Alimento":368, + "Descrição dos alimentos":"Carne, bovina, maminha, grelhada", + "Umidade (%)":65.3, + "Energia (Kcal)":153, + "Energia (KJ)":641, + "Proteína (g)":30.7, + "Lipídeos (g)":2.4, + "Colesterol (mg)":88, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.4, + "Cálcio (mg)":4, + "Magnésio (mg)":21, + "Manganês (mg)":"Tr", + "Fósforo (mg)":237, + "Ferro (mg)":2.4, + "Sódio (mg)":58, + "Potássio (mg)":386, + "Cobre (mg)":0.08, + "Zinco (mg)":5.6 + }, + { + "Número do Alimento":369, + "Descrição dos alimentos":"Carne, bovina, miolo de alcatra, sem gordura, cru", + "Umidade (%)":69.5, + "Energia (Kcal)":163, + "Energia (KJ)":681, + "Proteína (g)":21.6, + "Lipídeos (g)":7.8, + "Colesterol (mg)":60, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":20, + "Manganês (mg)":0.01, + "Fósforo (mg)":165, + "Ferro (mg)":2.0, + "Sódio (mg)":43, + "Potássio (mg)":299, + "Cobre (mg)":0.06, + "Zinco (mg)":3.0 + }, + { + "Número do Alimento":370, + "Descrição dos alimentos":"Carne, bovina, miolo de alcatra, sem gordura, grelhado", + "Umidade (%)":52.4, + "Energia (Kcal)":241, + "Energia (KJ)":1010, + "Proteína (g)":31.9, + "Lipídeos (g)":11.6, + "Colesterol (mg)":92, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":5, + "Magnésio (mg)":26, + "Manganês (mg)":0.02, + "Fósforo (mg)":279, + "Ferro (mg)":3.2, + "Sódio (mg)":52, + "Potássio (mg)":385, + "Cobre (mg)":0.11, + "Zinco (mg)":4.8 + }, + { + "Número do Alimento":371, + "Descrição dos alimentos":"Carne, bovina, músculo, sem gordura, cozido", + "Umidade (%)":62.8, + "Energia (Kcal)":194, + "Energia (KJ)":811, + "Proteína (g)":31.2, + "Lipídeos (g)":6.7, + "Colesterol (mg)":56, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":5, + "Magnésio (mg)":13, + "Manganês (mg)":"Tr", + "Fósforo (mg)":176, + "Ferro (mg)":2.4, + "Sódio (mg)":62, + "Potássio (mg)":253, + "Cobre (mg)":0.08, + "Zinco (mg)":6.4 + }, + { + "Número do Alimento":372, + "Descrição dos alimentos":"Carne, bovina, músculo, sem gordura, cru", + "Umidade (%)":72.4, + "Energia (Kcal)":142, + "Energia (KJ)":592, + "Proteína (g)":21.6, + "Lipídeos (g)":5.5, + "Colesterol (mg)":51, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":4, + "Magnésio (mg)":17, + "Manganês (mg)":"Tr", + "Fósforo (mg)":162, + "Ferro (mg)":1.9, + "Sódio (mg)":66, + "Potássio (mg)":296, + "Cobre (mg)":0.05, + "Zinco (mg)":3.7 + }, + { + "Número do Alimento":373, + "Descrição dos alimentos":"Carne, bovina, paleta, com gordura, crua", + "Umidade (%)":70.6, + "Energia (Kcal)":159, + "Energia (KJ)":664, + "Proteína (g)":21.4, + "Lipídeos (g)":7.5, + "Colesterol (mg)":58, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":158, + "Ferro (mg)":1.8, + "Sódio (mg)":65, + "Potássio (mg)":250, + "Cobre (mg)":0.08, + "Zinco (mg)":3.7 + }, + { + "Número do Alimento":374, + "Descrição dos alimentos":"Carne, bovina, paleta, sem gordura, cozida", + "Umidade (%)":62.9, + "Energia (Kcal)":194, + "Energia (KJ)":810, + "Proteína (g)":29.7, + "Lipídeos (g)":7.4, + "Colesterol (mg)":56, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":6, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":197, + "Ferro (mg)":2.2, + "Sódio (mg)":58, + "Potássio (mg)":250, + "Cobre (mg)":0.10, + "Zinco (mg)":6.8 + }, + { + "Número do Alimento":375, + "Descrição dos alimentos":"Carne, bovina, paleta, sem gordura, crua", + "Umidade (%)":72.1, + "Energia (Kcal)":141, + "Energia (KJ)":590, + "Proteína (g)":21.0, + "Lipídeos (g)":5.7, + "Colesterol (mg)":42, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":4, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":163, + "Ferro (mg)":1.9, + "Sódio (mg)":66, + "Potássio (mg)":319, + "Cobre (mg)":0.05, + "Zinco (mg)":3.3 + }, + { + "Número do Alimento":376, + "Descrição dos alimentos":"Carne, bovina, patinho, sem gordura, cru", + "Umidade (%)":72.9, + "Energia (Kcal)":133, + "Energia (KJ)":558, + "Proteína (g)":21.7, + "Lipídeos (g)":4.5, + "Colesterol (mg)":56, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":20, + "Manganês (mg)":0.01, + "Fósforo (mg)":170, + "Ferro (mg)":1.8, + "Sódio (mg)":49, + "Potássio (mg)":318, + "Cobre (mg)":0.05, + "Zinco (mg)":4.5 + }, + { + "Número do Alimento":377, + "Descrição dos alimentos":"Carne, bovina, patinho, sem gordura, grelhado", + "Umidade (%)":55.2, + "Energia (Kcal)":219, + "Energia (KJ)":917, + "Proteína (g)":35.9, + "Lipídeos (g)":7.3, + "Colesterol (mg)":126, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":5, + "Magnésio (mg)":27, + "Manganês (mg)":0.02, + "Fósforo (mg)":289, + "Ferro (mg)":3.0, + "Sódio (mg)":60, + "Potássio (mg)":421, + "Cobre (mg)":0.12, + "Zinco (mg)":8.1 + }, + { + "Número do Alimento":378, + "Descrição dos alimentos":"Carne, bovina, peito, sem gordura, cozido", + "Umidade (%)":51.2, + "Energia (Kcal)":338, + "Energia (KJ)":1416, + "Proteína (g)":22.2, + "Lipídeos (g)":27.0, + "Colesterol (mg)":100, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":4, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":136, + "Ferro (mg)":1.6, + "Sódio (mg)":56, + "Potássio (mg)":204, + "Cobre (mg)":0.05, + "Zinco (mg)":3.9 + }, + { + "Número do Alimento":379, + "Descrição dos alimentos":"Carne, bovina, peito, sem gordura, cru", + "Umidade (%)":61.5, + "Energia (Kcal)":259, + "Energia (KJ)":1085, + "Proteína (g)":17.6, + "Lipídeos (g)":20.4, + "Colesterol (mg)":59, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":4, + "Magnésio (mg)":15, + "Manganês (mg)":"Tr", + "Fósforo (mg)":124, + "Ferro (mg)":1.3, + "Sódio (mg)":64, + "Potássio (mg)":241, + "Cobre (mg)":0.06, + "Zinco (mg)":2.6 + }, + { + "Número do Alimento":380, + "Descrição dos alimentos":"Carne, bovina, picanha, com gordura, crua", + "Umidade (%)":65.6, + "Energia (Kcal)":213, + "Energia (KJ)":891, + "Proteína (g)":18.8, + "Lipídeos (g)":14.7, + "Colesterol (mg)":60, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":2, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":165, + "Ferro (mg)":1.7, + "Sódio (mg)":38, + "Potássio (mg)":232, + "Cobre (mg)":0.06, + "Zinco (mg)":3.8 + }, + { + "Número do Alimento":381, + "Descrição dos alimentos":"Carne, bovina, picanha, com gordura, grelhada", + "Umidade (%)":53.4, + "Energia (Kcal)":289, + "Energia (KJ)":1208, + "Proteína (g)":26.4, + "Lipídeos (g)":19.5, + "Colesterol (mg)":92, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":4, + "Magnésio (mg)":24, + "Manganês (mg)":"Tr", + "Fósforo (mg)":246, + "Ferro (mg)":3.2, + "Sódio (mg)":60, + "Potássio (mg)":355, + "Cobre (mg)":0.14, + "Zinco (mg)":5.5 + }, + { + "Número do Alimento":382, + "Descrição dos alimentos":"Carne, bovina, picanha, sem gordura, crua", + "Umidade (%)":72.4, + "Energia (Kcal)":134, + "Energia (KJ)":559, + "Proteína (g)":21.3, + "Lipídeos (g)":4.7, + "Colesterol (mg)":75, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":3, + "Magnésio (mg)":20, + "Manganês (mg)":"Tr", + "Fósforo (mg)":183, + "Ferro (mg)":2.1, + "Sódio (mg)":61, + "Potássio (mg)":322, + "Cobre (mg)":0.08, + "Zinco (mg)":4.2 + }, + { + "Número do Alimento":383, + "Descrição dos alimentos":"Carne, bovina, picanha, sem gordura, grelhada", + "Umidade (%)":54.6, + "Energia (Kcal)":238, + "Energia (KJ)":998, + "Proteína (g)":31.9, + "Lipídeos (g)":11.3, + "Colesterol (mg)":100, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":4, + "Magnésio (mg)":25, + "Manganês (mg)":0.02, + "Fósforo (mg)":282, + "Ferro (mg)":3.6, + "Sódio (mg)":61, + "Potássio (mg)":377, + "Cobre (mg)":0.17, + "Zinco (mg)":6.7 + }, + { + "Número do Alimento":384, + "Descrição dos alimentos":"Carne, bovina, seca, cozida", + "Umidade (%)":47.2, + "Energia (Kcal)":313, + "Energia (KJ)":1309, + "Proteína (g)":26.9, + "Lipídeos (g)":21.9, + "Colesterol (mg)":100, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":4.7, + "Cálcio (mg)":13, + "Magnésio (mg)":12, + "Manganês (mg)":0.02, + "Fósforo (mg)":82, + "Ferro (mg)":1.9, + "Sódio (mg)":1943, + "Potássio (mg)":86, + "Cobre (mg)":0.03, + "Zinco (mg)":7.7 + }, + { + "Número do Alimento":385, + "Descrição dos alimentos":"Carne, bovina, seca, crua", + "Umidade (%)":39.2, + "Energia (Kcal)":313, + "Energia (KJ)":1309, + "Proteína (g)":19.7, + "Lipídeos (g)":25.4, + "Colesterol (mg)":92, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":15.3, + "Cálcio (mg)":14, + "Magnésio (mg)":12, + "Manganês (mg)":0.01, + "Fósforo (mg)":100, + "Ferro (mg)":1.3, + "Sódio (mg)":4440, + "Potássio (mg)":190, + "Cobre (mg)":"Tr", + "Zinco (mg)":3.7 + }, + { + "Número do Alimento":386, + "Descrição dos alimentos":"Coxinha de frango, frita", + "Umidade (%)":42.2, + "Energia (Kcal)":283, + "Energia (KJ)":1184, + "Proteína (g)":9.6, + "Lipídeos (g)":11.8, + "Colesterol (mg)":15, + "Carboidrato (g)":34.5, + "Fibra Alimentar (g)":5.0, + "Cinzas (g)":1.8, + "Cálcio (mg)":18, + "Magnésio (mg)":17, + "Manganês (mg)":0.28, + "Fósforo (mg)":93, + "Ferro (mg)":1.3, + "Sódio (mg)":532, + "Potássio (mg)":166, + "Cobre (mg)":0.09, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":387, + "Descrição dos alimentos":"Croquete, de carne, cru", + "Umidade (%)":56.0, + "Energia (Kcal)":246, + "Energia (KJ)":1028, + "Proteína (g)":12.0, + "Lipídeos (g)":15.6, + "Colesterol (mg)":30, + "Carboidrato (g)":13.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.5, + "Cálcio (mg)":15, + "Magnésio (mg)":24, + "Manganês (mg)":0.34, + "Fósforo (mg)":144, + "Ferro (mg)":2.5, + "Sódio (mg)":711, + "Potássio (mg)":221, + "Cobre (mg)":0.10, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":388, + "Descrição dos alimentos":"Croquete, de carne, frito", + "Umidade (%)":39.2, + "Energia (Kcal)":347, + "Energia (KJ)":1451, + "Proteína (g)":16.9, + "Lipídeos (g)":22.7, + "Colesterol (mg)":38, + "Carboidrato (g)":18.1, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.1, + "Cálcio (mg)":18, + "Magnésio (mg)":30, + "Manganês (mg)":0.39, + "Fósforo (mg)":176, + "Ferro (mg)":2.3, + "Sódio (mg)":916, + "Potássio (mg)":313, + "Cobre (mg)":0.09, + "Zinco (mg)":3.3 + }, + { + "Número do Alimento":389, + "Descrição dos alimentos":"Empada de frango, pré-cozida, assada", + "Umidade (%)":28.2, + "Energia (Kcal)":358, + "Energia (KJ)":1499, + "Proteína (g)":6.9, + "Lipídeos (g)":15.6, + "Colesterol (mg)":23, + "Carboidrato (g)":47.5, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":1.8, + "Cálcio (mg)":16, + "Magnésio (mg)":18, + "Manganês (mg)":0.32, + "Fósforo (mg)":78, + "Ferro (mg)":1.2, + "Sódio (mg)":525, + "Potássio (mg)":138, + "Cobre (mg)":0.07, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":390, + "Descrição dos alimentos":"Empada, de frango, pré-cozida", + "Umidade (%)":32.0, + "Energia (Kcal)":377, + "Energia (KJ)":1579, + "Proteína (g)":7.3, + "Lipídeos (g)":22.9, + "Colesterol (mg)":23, + "Carboidrato (g)":35.5, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":2.2, + "Cálcio (mg)":14, + "Magnésio (mg)":17, + "Manganês (mg)":0.25, + "Fósforo (mg)":78, + "Ferro (mg)":0.7, + "Sódio (mg)":771, + "Potássio (mg)":156, + "Cobre (mg)":0.09, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":391, + "Descrição dos alimentos":"Frango, asa, com pele, crua", + "Umidade (%)":67.5, + "Energia (Kcal)":213, + "Energia (KJ)":892, + "Proteína (g)":18.1, + "Lipídeos (g)":15.1, + "Colesterol (mg)":113, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":11, + "Magnésio (mg)":23, + "Manganês (mg)":0.01, + "Fósforo (mg)":155, + "Ferro (mg)":0.6, + "Sódio (mg)":96, + "Potássio (mg)":211, + "Cobre (mg)":0.02, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":392, + "Descrição dos alimentos":"Frango, caipira, inteiro, com pele, cozido", + "Umidade (%)":59.7, + "Energia (Kcal)":243, + "Energia (KJ)":1016, + "Proteína (g)":23.9, + "Lipídeos (g)":15.6, + "Colesterol (mg)":110, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":17, + "Magnésio (mg)":18, + "Manganês (mg)":0.01, + "Fósforo (mg)":162, + "Ferro (mg)":1.7, + "Sódio (mg)":56, + "Potássio (mg)":210, + "Cobre (mg)":0.08, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":393, + "Descrição dos alimentos":"Frango, caipira, inteiro, sem pele, cozido", + "Umidade (%)":61.4, + "Energia (Kcal)":196, + "Energia (KJ)":819, + "Proteína (g)":29.6, + "Lipídeos (g)":7.7, + "Colesterol (mg)":106, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":66, + "Magnésio (mg)":23, + "Manganês (mg)":0.02, + "Fósforo (mg)":210, + "Ferro (mg)":2.1, + "Sódio (mg)":53, + "Potássio (mg)":224, + "Cobre (mg)":0.15, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":394, + "Descrição dos alimentos":"Frango, coração, cru", + "Umidade (%)":69.1, + "Energia (Kcal)":222, + "Energia (KJ)":927, + "Proteína (g)":12.6, + "Lipídeos (g)":18.6, + "Colesterol (mg)":159, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":6, + "Magnésio (mg)":20, + "Manganês (mg)":0.05, + "Fósforo (mg)":193, + "Ferro (mg)":4.1, + "Sódio (mg)":95, + "Potássio (mg)":220, + "Cobre (mg)":0.20, + "Zinco (mg)":2.0 + }, + { + "Número do Alimento":395, + "Descrição dos alimentos":"Frango, coração, grelhado", + "Umidade (%)":63.5, + "Energia (Kcal)":207, + "Energia (KJ)":867, + "Proteína (g)":22.4, + "Lipídeos (g)":12.1, + "Colesterol (mg)":280, + "Carboidrato (g)":0.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":8, + "Magnésio (mg)":20, + "Manganês (mg)":0.06, + "Fósforo (mg)":276, + "Ferro (mg)":6.5, + "Sódio (mg)":128, + "Potássio (mg)":243, + "Cobre (mg)":0.30, + "Zinco (mg)":3.4 + }, + { + "Número do Alimento":396, + "Descrição dos alimentos":"Frango, coxa, com pele, assada", + "Umidade (%)":59.8, + "Energia (Kcal)":215, + "Energia (KJ)":900, + "Proteína (g)":28.5, + "Lipídeos (g)":10.4, + "Colesterol (mg)":145, + "Carboidrato (g)":0.1, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":8, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":251, + "Ferro (mg)":1.2, + "Sódio (mg)":95, + "Potássio (mg)":318, + "Cobre (mg)":0.05, + "Zinco (mg)":2.6 + }, + { + "Número do Alimento":397, + "Descrição dos alimentos":"Frango, coxa, com pele, crua", + "Umidade (%)":72.9, + "Energia (Kcal)":161, + "Energia (KJ)":676, + "Proteína (g)":17.1, + "Lipídeos (g)":9.8, + "Colesterol (mg)":97, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":8, + "Magnésio (mg)":26, + "Manganês (mg)":0.02, + "Fósforo (mg)":185, + "Ferro (mg)":0.7, + "Sódio (mg)":95, + "Potássio (mg)":275, + "Cobre (mg)":0.03, + "Zinco (mg)":2.0 + }, + { + "Número do Alimento":398, + "Descrição dos alimentos":"Frango, coxa, sem pele, cozida", + "Umidade (%)":66.7, + "Energia (Kcal)":167, + "Energia (KJ)":701, + "Proteína (g)":26.9, + "Lipídeos (g)":5.8, + "Colesterol (mg)":133, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":12, + "Magnésio (mg)":11, + "Manganês (mg)":"Tr", + "Fósforo (mg)":187, + "Ferro (mg)":0.8, + "Sódio (mg)":64, + "Potássio (mg)":191, + "Cobre (mg)":0.03, + "Zinco (mg)":2.8 + }, + { + "Número do Alimento":399, + "Descrição dos alimentos":"Frango, coxa, sem pele, crua", + "Umidade (%)":76.4, + "Energia (Kcal)":120, + "Energia (KJ)":502, + "Proteína (g)":17.8, + "Lipídeos (g)":4.9, + "Colesterol (mg)":91, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":8, + "Magnésio (mg)":27, + "Manganês (mg)":0.02, + "Fósforo (mg)":196, + "Ferro (mg)":0.8, + "Sódio (mg)":98, + "Potássio (mg)":291, + "Cobre (mg)":0.03, + "Zinco (mg)":2.2 + }, + { + "Número do Alimento":400, + "Descrição dos alimentos":"Frango, fígado, cru", + "Umidade (%)":77.8, + "Energia (Kcal)":106, + "Energia (KJ)":446, + "Proteína (g)":17.6, + "Lipídeos (g)":3.5, + "Colesterol (mg)":341, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":6, + "Magnésio (mg)":28, + "Manganês (mg)":0.35, + "Fósforo (mg)":344, + "Ferro (mg)":9.5, + "Sódio (mg)":82, + "Potássio (mg)":281, + "Cobre (mg)":0.26, + "Zinco (mg)":3.7 + }, + { + "Número do Alimento":401, + "Descrição dos alimentos":"Frango, filé, à milanesa", + "Umidade (%)":54.9, + "Energia (Kcal)":221, + "Energia (KJ)":924, + "Proteína (g)":28.5, + "Lipídeos (g)":7.8, + "Colesterol (mg)":84, + "Carboidrato (g)":7.5, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":1.3, + "Cálcio (mg)":9, + "Magnésio (mg)":35, + "Manganês (mg)":0.06, + "Fósforo (mg)":249, + "Ferro (mg)":1.1, + "Sódio (mg)":122, + "Potássio (mg)":408, + "Cobre (mg)":0.05, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":402, + "Descrição dos alimentos":"Frango, inteiro, com pele, cru", + "Umidade (%)":66.5, + "Energia (Kcal)":226, + "Energia (KJ)":947, + "Proteína (g)":16.4, + "Lipídeos (g)":17.3, + "Colesterol (mg)":85, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":6, + "Magnésio (mg)":24, + "Manganês (mg)":0.01, + "Fósforo (mg)":174, + "Ferro (mg)":0.6, + "Sódio (mg)":63, + "Potássio (mg)":217, + "Cobre (mg)":0.04, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":403, + "Descrição dos alimentos":"Frango, inteiro, sem pele, assado", + "Umidade (%)":63.2, + "Energia (Kcal)":187, + "Energia (KJ)":784, + "Proteína (g)":28.0, + "Lipídeos (g)":7.5, + "Colesterol (mg)":111, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":9, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":233, + "Ferro (mg)":0.6, + "Sódio (mg)":70, + "Potássio (mg)":283, + "Cobre (mg)":0.03, + "Zinco (mg)":1.6 + }, + { + "Número do Alimento":404, + "Descrição dos alimentos":"Frango, inteiro, sem pele, cozido", + "Umidade (%)":67.5, + "Energia (Kcal)":170, + "Energia (KJ)":713, + "Proteína (g)":25.0, + "Lipídeos (g)":7.1, + "Colesterol (mg)":99, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":8, + "Magnésio (mg)":12, + "Manganês (mg)":"Tr", + "Fósforo (mg)":194, + "Ferro (mg)":0.5, + "Sódio (mg)":51, + "Potássio (mg)":217, + "Cobre (mg)":0.04, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":405, + "Descrição dos alimentos":"Frango, inteiro, sem pele, cru", + "Umidade (%)":74.9, + "Energia (Kcal)":129, + "Energia (KJ)":540, + "Proteína (g)":20.6, + "Lipídeos (g)":4.6, + "Colesterol (mg)":78, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":7, + "Magnésio (mg)":27, + "Manganês (mg)":0.01, + "Fósforo (mg)":190, + "Ferro (mg)":0.5, + "Sódio (mg)":73, + "Potássio (mg)":238, + "Cobre (mg)":0.03, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":406, + "Descrição dos alimentos":"Frango, peito, com pele, assado", + "Umidade (%)":58.5, + "Energia (Kcal)":212, + "Energia (KJ)":886, + "Proteína (g)":33.4, + "Lipídeos (g)":7.6, + "Colesterol (mg)":109, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.5, + "Cálcio (mg)":8, + "Magnésio (mg)":18, + "Manganês (mg)":0.01, + "Fósforo (mg)":297, + "Ferro (mg)":0.5, + "Sódio (mg)":56, + "Potássio (mg)":380, + "Cobre (mg)":0.01, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":407, + "Descrição dos alimentos":"Frango, peito, com pele, cru", + "Umidade (%)":71.9, + "Energia (Kcal)":149, + "Energia (KJ)":625, + "Proteína (g)":20.8, + "Lipídeos (g)":6.7, + "Colesterol (mg)":80, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":8, + "Magnésio (mg)":28, + "Manganês (mg)":0.01, + "Fósforo (mg)":213, + "Ferro (mg)":0.4, + "Sódio (mg)":62, + "Potássio (mg)":252, + "Cobre (mg)":0.05, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":408, + "Descrição dos alimentos":"Frango, peito, sem pele, cozido", + "Umidade (%)":65.6, + "Energia (Kcal)":163, + "Energia (KJ)":681, + "Proteína (g)":31.5, + "Lipídeos (g)":3.2, + "Colesterol (mg)":89, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":6, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":224, + "Ferro (mg)":0.3, + "Sódio (mg)":36, + "Potássio (mg)":231, + "Cobre (mg)":0.02, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":409, + "Descrição dos alimentos":"Frango, peito, sem pele, cru", + "Umidade (%)":74.8, + "Energia (Kcal)":119, + "Energia (KJ)":499, + "Proteína (g)":21.5, + "Lipídeos (g)":3.0, + "Colesterol (mg)":59, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":7, + "Magnésio (mg)":31, + "Manganês (mg)":0.01, + "Fósforo (mg)":222, + "Ferro (mg)":0.4, + "Sódio (mg)":56, + "Potássio (mg)":267, + "Cobre (mg)":0.03, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":410, + "Descrição dos alimentos":"Frango, peito, sem pele, grelhado", + "Umidade (%)":63.8, + "Energia (Kcal)":159, + "Energia (KJ)":666, + "Proteína (g)":32.0, + "Lipídeos (g)":2.5, + "Colesterol (mg)":89, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.4, + "Cálcio (mg)":5, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":295, + "Ferro (mg)":0.3, + "Sódio (mg)":50, + "Potássio (mg)":387, + "Cobre (mg)":0.02, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":411, + "Descrição dos alimentos":"Frango, sobrecoxa, com pele, assada", + "Umidade (%)":55.0, + "Energia (Kcal)":260, + "Energia (KJ)":1086, + "Proteína (g)":28.7, + "Lipídeos (g)":15.2, + "Colesterol (mg)":158, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":11, + "Magnésio (mg)":15, + "Manganês (mg)":"Tr", + "Fósforo (mg)":252, + "Ferro (mg)":1.2, + "Sódio (mg)":96, + "Potássio (mg)":323, + "Cobre (mg)":0.06, + "Zinco (mg)":2.2 + }, + { + "Número do Alimento":412, + "Descrição dos alimentos":"Frango, sobrecoxa, com pele, crua", + "Umidade (%)":63.6, + "Energia (Kcal)":255, + "Energia (KJ)":1065, + "Proteína (g)":15.5, + "Lipídeos (g)":20.9, + "Colesterol (mg)":88, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":7, + "Magnésio (mg)":22, + "Manganês (mg)":0.01, + "Fósforo (mg)":154, + "Ferro (mg)":0.7, + "Sódio (mg)":68, + "Potássio (mg)":190, + "Cobre (mg)":0.05, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":413, + "Descrição dos alimentos":"Frango, sobrecoxa, sem pele, assada", + "Umidade (%)":55.6, + "Energia (Kcal)":233, + "Energia (KJ)":974, + "Proteína (g)":29.2, + "Lipídeos (g)":12.0, + "Colesterol (mg)":145, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.5, + "Cálcio (mg)":12, + "Magnésio (mg)":17, + "Manganês (mg)":"Tr", + "Fósforo (mg)":281, + "Ferro (mg)":1.2, + "Sódio (mg)":106, + "Potássio (mg)":382, + "Cobre (mg)":0.07, + "Zinco (mg)":2.2 + }, + { + "Número do Alimento":414, + "Descrição dos alimentos":"Frango, sobrecoxa, sem pele, crua", + "Umidade (%)":72.7, + "Energia (Kcal)":162, + "Energia (KJ)":677, + "Proteína (g)":17.6, + "Lipídeos (g)":9.6, + "Colesterol (mg)":84, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":6, + "Magnésio (mg)":26, + "Manganês (mg)":0.02, + "Fósforo (mg)":187, + "Ferro (mg)":0.9, + "Sódio (mg)":80, + "Potássio (mg)":241, + "Cobre (mg)":0.06, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":415, + "Descrição dos alimentos":"Hambúrguer, bovino, cru", + "Umidade (%)":63.6, + "Energia (Kcal)":215, + "Energia (KJ)":899, + "Proteína (g)":13.2, + "Lipídeos (g)":16.2, + "Colesterol (mg)":70, + "Carboidrato (g)":4.2, + "Fibra Alimentar (g)":"*", + "Cinzas (g)":2.9, + "Cálcio (mg)":34, + "Magnésio (mg)":25, + "Manganês (mg)":0.36, + "Fósforo (mg)":141, + "Ferro (mg)":1.9, + "Sódio (mg)":869, + "Potássio (mg)":383, + "Cobre (mg)":0.16, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":416, + "Descrição dos alimentos":"Hambúrguer, bovino, frito", + "Umidade (%)":52.5, + "Energia (Kcal)":258, + "Energia (KJ)":1081, + "Proteína (g)":20.0, + "Lipídeos (g)":17.0, + "Colesterol (mg)":49, + "Carboidrato (g)":6.3, + "Fibra Alimentar (g)":"*", + "Cinzas (g)":4.2, + "Cálcio (mg)":62, + "Magnésio (mg)":60, + "Manganês (mg)":0.52, + "Fósforo (mg)":324, + "Ferro (mg)":3.0, + "Sódio (mg)":1252, + "Potássio (mg)":660, + "Cobre (mg)":0.17, + "Zinco (mg)":3.2 + }, + { + "Número do Alimento":417, + "Descrição dos alimentos":"Hambúrguer, bovino, grelhado", + "Umidade (%)":59.2, + "Energia (Kcal)":210, + "Energia (KJ)":878, + "Proteína (g)":13.2, + "Lipídeos (g)":12.4, + "Colesterol (mg)":59, + "Carboidrato (g)":11.3, + "Fibra Alimentar (g)":"*", + "Cinzas (g)":3.9, + "Cálcio (mg)":56, + "Magnésio (mg)":48, + "Manganês (mg)":0.40, + "Fósforo (mg)":263, + "Ferro (mg)":2.6, + "Sódio (mg)":1090, + "Potássio (mg)":538, + "Cobre (mg)":0.18, + "Zinco (mg)":3.0 + }, + { + "Número do Alimento":418, + "Descrição dos alimentos":"Lingüiça, frango, crua", + "Umidade (%)":64.8, + "Energia (Kcal)":218, + "Energia (KJ)":913, + "Proteína (g)":14.2, + "Lipídeos (g)":17.4, + "Colesterol (mg)":64, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.3, + "Cálcio (mg)":11, + "Magnésio (mg)":19, + "Manganês (mg)":0.05, + "Fósforo (mg)":182, + "Ferro (mg)":0.5, + "Sódio (mg)":1126, + "Potássio (mg)":280, + "Cobre (mg)":0.05, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":419, + "Descrição dos alimentos":"Lingüiça, frango, frita", + "Umidade (%)":59.6, + "Energia (Kcal)":245, + "Energia (KJ)":1027, + "Proteína (g)":18.3, + "Lipídeos (g)":18.5, + "Colesterol (mg)":76, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.8, + "Cálcio (mg)":15, + "Magnésio (mg)":29, + "Manganês (mg)":0.10, + "Fósforo (mg)":262, + "Ferro (mg)":0.8, + "Sódio (mg)":1374, + "Potássio (mg)":364, + "Cobre (mg)":0.04, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":420, + "Descrição dos alimentos":"Lingüiça, frango, grelhada", + "Umidade (%)":58.6, + "Energia (Kcal)":244, + "Energia (KJ)":1019, + "Proteína (g)":18.2, + "Lipídeos (g)":18.4, + "Colesterol (mg)":80, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.8, + "Cálcio (mg)":14, + "Magnésio (mg)":21, + "Manganês (mg)":0.10, + "Fósforo (mg)":228, + "Ferro (mg)":0.7, + "Sódio (mg)":1351, + "Potássio (mg)":356, + "Cobre (mg)":0.09, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":421, + "Descrição dos alimentos":"Lingüiça, porco, crua", + "Umidade (%)":62.5, + "Energia (Kcal)":227, + "Energia (KJ)":951, + "Proteína (g)":16.1, + "Lipídeos (g)":17.6, + "Colesterol (mg)":53, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.2, + "Cálcio (mg)":6, + "Magnésio (mg)":14, + "Manganês (mg)":0.01, + "Fósforo (mg)":157, + "Ferro (mg)":0.4, + "Sódio (mg)":1176, + "Potássio (mg)":316, + "Cobre (mg)":0.04, + "Zinco (mg)":1.4 + }, + { + "Número do Alimento":422, + "Descrição dos alimentos":"Lingüiça, porco, frita", + "Umidade (%)":54.6, + "Energia (Kcal)":280, + "Energia (KJ)":1170, + "Proteína (g)":20.5, + "Lipídeos (g)":21.3, + "Colesterol (mg)":75, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.9, + "Cálcio (mg)":8, + "Magnésio (mg)":18, + "Manganês (mg)":0.01, + "Fósforo (mg)":211, + "Ferro (mg)":0.9, + "Sódio (mg)":1432, + "Potássio (mg)":409, + "Cobre (mg)":0.06, + "Zinco (mg)":3.1 + }, + { + "Número do Alimento":423, + "Descrição dos alimentos":"Lingüiça, porco, grelhada", + "Umidade (%)":50.5, + "Energia (Kcal)":296, + "Energia (KJ)":1241, + "Proteína (g)":23.2, + "Lipídeos (g)":21.9, + "Colesterol (mg)":82, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":4.0, + "Cálcio (mg)":8, + "Magnésio (mg)":19, + "Manganês (mg)":0.01, + "Fósforo (mg)":210, + "Ferro (mg)":1.0, + "Sódio (mg)":1456, + "Potássio (mg)":427, + "Cobre (mg)":0.07, + "Zinco (mg)":3.5 + }, + { + "Número do Alimento":424, + "Descrição dos alimentos":"Mortadela", + "Umidade (%)":56.4, + "Energia (Kcal)":269, + "Energia (KJ)":1125, + "Proteína (g)":12.0, + "Lipídeos (g)":21.6, + "Colesterol (mg)":83, + "Carboidrato (g)":5.8, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":4.1, + "Cálcio (mg)":67, + "Magnésio (mg)":19, + "Manganês (mg)":0.11, + "Fósforo (mg)":216, + "Ferro (mg)":1.5, + "Sódio (mg)":1212, + "Potássio (mg)":247, + "Cobre (mg)":0.08, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":425, + "Descrição dos alimentos":"Peru, congelado, assado", + "Umidade (%)":65.3, + "Energia (Kcal)":163, + "Energia (KJ)":682, + "Proteína (g)":26.2, + "Lipídeos (g)":5.7, + "Colesterol (mg)":91, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.2, + "Cálcio (mg)":14, + "Magnésio (mg)":12, + "Manganês (mg)":0.02, + "Fósforo (mg)":197, + "Ferro (mg)":0.6, + "Sódio (mg)":628, + "Potássio (mg)":175, + "Cobre (mg)":0.03, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":426, + "Descrição dos alimentos":"Peru, congelado, cru", + "Umidade (%)":78.2, + "Energia (Kcal)":94, + "Energia (KJ)":392, + "Proteína (g)":18.1, + "Lipídeos (g)":1.8, + "Colesterol (mg)":68, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.5, + "Cálcio (mg)":10, + "Magnésio (mg)":19, + "Manganês (mg)":"Tr", + "Fósforo (mg)":217, + "Ferro (mg)":0.9, + "Sódio (mg)":711, + "Potássio (mg)":281, + "Cobre (mg)":0.36, + "Zinco (mg)":1.4 + }, + { + "Número do Alimento":427, + "Descrição dos alimentos":"Porco, bisteca, crua", + "Umidade (%)":67.7, + "Energia (Kcal)":164, + "Energia (KJ)":687, + "Proteína (g)":21.5, + "Lipídeos (g)":8.0, + "Colesterol (mg)":56, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":6, + "Magnésio (mg)":24, + "Manganês (mg)":"Tr", + "Fósforo (mg)":195, + "Ferro (mg)":0.5, + "Sódio (mg)":54, + "Potássio (mg)":335, + "Cobre (mg)":0.07, + "Zinco (mg)":1.4 + }, + { + "Número do Alimento":428, + "Descrição dos alimentos":"Porco, bisteca, frita", + "Umidade (%)":47.3, + "Energia (Kcal)":311, + "Energia (KJ)":1302, + "Proteína (g)":33.7, + "Lipídeos (g)":18.5, + "Colesterol (mg)":126, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.6, + "Cálcio (mg)":69, + "Magnésio (mg)":29, + "Manganês (mg)":0.01, + "Fósforo (mg)":290, + "Ferro (mg)":0.8, + "Sódio (mg)":63, + "Potássio (mg)":404, + "Cobre (mg)":0.07, + "Zinco (mg)":2.2 + }, + { + "Número do Alimento":429, + "Descrição dos alimentos":"Porco, bisteca, grelhada", + "Umidade (%)":51.8, + "Energia (Kcal)":280, + "Energia (KJ)":1172, + "Proteína (g)":28.9, + "Lipídeos (g)":17.4, + "Colesterol (mg)":82, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":34, + "Magnésio (mg)":25, + "Manganês (mg)":"Tr", + "Fósforo (mg)":229, + "Ferro (mg)":0.9, + "Sódio (mg)":51, + "Potássio (mg)":366, + "Cobre (mg)":0.06, + "Zinco (mg)":2.3 + }, + { + "Número do Alimento":430, + "Descrição dos alimentos":"Porco, costela, assada", + "Umidade (%)":36.9, + "Energia (Kcal)":402, + "Energia (KJ)":1683, + "Proteína (g)":30.2, + "Lipídeos (g)":30.3, + "Colesterol (mg)":113, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.4, + "Cálcio (mg)":17, + "Magnésio (mg)":14, + "Manganês (mg)":"Tr", + "Fósforo (mg)":201, + "Ferro (mg)":1.0, + "Sódio (mg)":63, + "Potássio (mg)":246, + "Cobre (mg)":0.07, + "Zinco (mg)":3.1 + }, + { + "Número do Alimento":431, + "Descrição dos alimentos":"Porco, costela, crua", + "Umidade (%)":61.2, + "Energia (Kcal)":256, + "Energia (KJ)":1069, + "Proteína (g)":18.0, + "Lipídeos (g)":19.8, + "Colesterol (mg)":69, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":15, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":159, + "Ferro (mg)":0.9, + "Sódio (mg)":88, + "Potássio (mg)":248, + "Cobre (mg)":0.05, + "Zinco (mg)":2.3 + }, + { + "Número do Alimento":432, + "Descrição dos alimentos":"Porco, lombo, assado", + "Umidade (%)":56.6, + "Energia (Kcal)":210, + "Energia (KJ)":880, + "Proteína (g)":35.7, + "Lipídeos (g)":6.4, + "Colesterol (mg)":103, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.4, + "Cálcio (mg)":20, + "Magnésio (mg)":18, + "Manganês (mg)":"Tr", + "Fósforo (mg)":238, + "Ferro (mg)":0.5, + "Sódio (mg)":39, + "Potássio (mg)":311, + "Cobre (mg)":0.03, + "Zinco (mg)":1.8 + }, + { + "Número do Alimento":433, + "Descrição dos alimentos":"Porco, lombo, cru", + "Umidade (%)":67.7, + "Energia (Kcal)":176, + "Energia (KJ)":735, + "Proteína (g)":22.6, + "Lipídeos (g)":8.8, + "Colesterol (mg)":55, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":4, + "Magnésio (mg)":24, + "Manganês (mg)":"Tr", + "Fósforo (mg)":195, + "Ferro (mg)":0.5, + "Sódio (mg)":53, + "Potássio (mg)":334, + "Cobre (mg)":0.01, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":434, + "Descrição dos alimentos":"Porco, orelha, salgada, crua", + "Umidade (%)":59.7, + "Energia (Kcal)":258, + "Energia (KJ)":1082, + "Proteína (g)":18.5, + "Lipídeos (g)":19.9, + "Colesterol (mg)":83, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.0, + "Cálcio (mg)":5, + "Magnésio (mg)":2, + "Manganês (mg)":0.01, + "Fósforo (mg)":31, + "Ferro (mg)":1.4, + "Sódio (mg)":616, + "Potássio (mg)":228, + "Cobre (mg)":0.23, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":435, + "Descrição dos alimentos":"Porco, pernil, assado", + "Umidade (%)":49.3, + "Energia (Kcal)":262, + "Energia (KJ)":1097, + "Proteína (g)":32.1, + "Lipídeos (g)":13.9, + "Colesterol (mg)":110, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.4, + "Cálcio (mg)":18, + "Magnésio (mg)":27, + "Manganês (mg)":0.01, + "Fósforo (mg)":247, + "Ferro (mg)":1.3, + "Sódio (mg)":62, + "Potássio (mg)":395, + "Cobre (mg)":0.09, + "Zinco (mg)":3.3 + }, + { + "Número do Alimento":436, + "Descrição dos alimentos":"Porco, pernil, cru", + "Umidade (%)":67.1, + "Energia (Kcal)":186, + "Energia (KJ)":778, + "Proteína (g)":20.1, + "Lipídeos (g)":11.1, + "Colesterol (mg)":59, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":13, + "Magnésio (mg)":23, + "Manganês (mg)":"Tr", + "Fósforo (mg)":192, + "Ferro (mg)":0.9, + "Sódio (mg)":102, + "Potássio (mg)":256, + "Cobre (mg)":0.16, + "Zinco (mg)":1.7 + }, + { + "Número do Alimento":437, + "Descrição dos alimentos":"Porco, rabo, salgado, cru", + "Umidade (%)":43.8, + "Energia (Kcal)":377, + "Energia (KJ)":1579, + "Proteína (g)":15.6, + "Lipídeos (g)":34.5, + "Colesterol (mg)":89, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.5, + "Cálcio (mg)":22, + "Magnésio (mg)":4, + "Manganês (mg)":0.01, + "Fósforo (mg)":42, + "Ferro (mg)":0.6, + "Sódio (mg)":1158, + "Potássio (mg)":24, + "Cobre (mg)":0.05, + "Zinco (mg)":1.4 + }, + { + "Número do Alimento":438, + "Descrição dos alimentos":"Presunto, com capa de gordura", + "Umidade (%)":73.9, + "Energia (Kcal)":128, + "Energia (KJ)":535, + "Proteína (g)":14.4, + "Lipídeos (g)":6.8, + "Colesterol (mg)":40, + "Carboidrato (g)":1.4, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.5, + "Cálcio (mg)":12, + "Magnésio (mg)":17, + "Manganês (mg)":0.04, + "Fósforo (mg)":274, + "Ferro (mg)":0.7, + "Sódio (mg)":1021, + "Potássio (mg)":295, + "Cobre (mg)":0.04, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":439, + "Descrição dos alimentos":"Presunto, sem capa de gordura", + "Umidade (%)":77.2, + "Energia (Kcal)":94, + "Energia (KJ)":392, + "Proteína (g)":14.3, + "Lipídeos (g)":2.7, + "Colesterol (mg)":36, + "Carboidrato (g)":2.1, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.7, + "Cálcio (mg)":23, + "Magnésio (mg)":18, + "Manganês (mg)":0.04, + "Fósforo (mg)":244, + "Ferro (mg)":0.8, + "Sódio (mg)":1039, + "Potássio (mg)":307, + "Cobre (mg)":0.04, + "Zinco (mg)":1.5 + }, + { + "Número do Alimento":440, + "Descrição dos alimentos":"Quibe, assado", + "Umidade (%)":69.0, + "Energia (Kcal)":136, + "Energia (KJ)":570, + "Proteína (g)":14.6, + "Lipídeos (g)":2.7, + "Colesterol (mg)":34, + "Carboidrato (g)":12.9, + "Fibra Alimentar (g)":1.9, + "Cinzas (g)":0.9, + "Cálcio (mg)":16, + "Magnésio (mg)":36, + "Manganês (mg)":0.76, + "Fósforo (mg)":174, + "Ferro (mg)":2.2, + "Sódio (mg)":40, + "Potássio (mg)":288, + "Cobre (mg)":0.51, + "Zinco (mg)":4.1 + }, + { + "Número do Alimento":441, + "Descrição dos alimentos":"Quibe, cru", + "Umidade (%)":74.5, + "Energia (Kcal)":109, + "Energia (KJ)":458, + "Proteína (g)":12.4, + "Lipídeos (g)":1.7, + "Colesterol (mg)":27, + "Carboidrato (g)":10.8, + "Fibra Alimentar (g)":1.6, + "Cinzas (g)":0.7, + "Cálcio (mg)":12, + "Magnésio (mg)":26, + "Manganês (mg)":0.39, + "Fósforo (mg)":126, + "Ferro (mg)":1.7, + "Sódio (mg)":39, + "Potássio (mg)":242, + "Cobre (mg)":0.13, + "Zinco (mg)":2.8 + }, + { + "Número do Alimento":442, + "Descrição dos alimentos":"Quibe, frito", + "Umidade (%)":54.0, + "Energia (Kcal)":254, + "Energia (KJ)":1062, + "Proteína (g)":14.9, + "Lipídeos (g)":15.8, + "Colesterol (mg)":38, + "Carboidrato (g)":12.3, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.0, + "Cálcio (mg)":22, + "Magnésio (mg)":39, + "Manganês (mg)":0.72, + "Fósforo (mg)":166, + "Ferro (mg)":2.0, + "Sódio (mg)":836, + "Potássio (mg)":322, + "Cobre (mg)":0.16, + "Zinco (mg)":2.8 + }, + { + "Número do Alimento":443, + "Descrição dos alimentos":"Salame", + "Umidade (%)":34.7, + "Energia (Kcal)":398, + "Energia (KJ)":1665, + "Proteína (g)":25.8, + "Lipídeos (g)":30.6, + "Colesterol (mg)":85, + "Carboidrato (g)":2.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":5.9, + "Cálcio (mg)":87, + "Magnésio (mg)":30, + "Manganês (mg)":0.03, + "Fósforo (mg)":354, + "Ferro (mg)":1.3, + "Sódio (mg)":1574, + "Potássio (mg)":548, + "Cobre (mg)":0.05, + "Zinco (mg)":3.2 + }, + { + "Número do Alimento":444, + "Descrição dos alimentos":"Toucinho, cru", + "Umidade (%)":27.6, + "Energia (Kcal)":593, + "Energia (KJ)":2479, + "Proteína (g)":11.5, + "Lipídeos (g)":60.3, + "Colesterol (mg)":73, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.3, + "Cálcio (mg)":2, + "Magnésio (mg)":4, + "Manganês (mg)":"Tr", + "Fósforo (mg)":35, + "Ferro (mg)":0.4, + "Sódio (mg)":50, + "Potássio (mg)":58, + "Cobre (mg)":0.11, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":445, + "Descrição dos alimentos":"Toucinho, frito", + "Umidade (%)":6.3, + "Energia (Kcal)":697, + "Energia (KJ)":2914, + "Proteína (g)":27.3, + "Lipídeos (g)":64.3, + "Colesterol (mg)":89, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":9, + "Magnésio (mg)":9, + "Manganês (mg)":0.01, + "Fósforo (mg)":95, + "Ferro (mg)":0.9, + "Sódio (mg)":125, + "Potássio (mg)":171, + "Cobre (mg)":0.10, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":446, + "Descrição dos alimentos":"Bebida láctea, pêssego", + "Umidade (%)":87.7, + "Energia (Kcal)":55, + "Energia (KJ)":231, + "Proteína (g)":2.1, + "Lipídeos (g)":1.9, + "Colesterol (mg)":5, + "Carboidrato (g)":7.6, + "Fibra Alimentar (g)":0.3, + "Cinzas (g)":0.7, + "Cálcio (mg)":89, + "Magnésio (mg)":9, + "Manganês (mg)":"Tr", + "Fósforo (mg)":63, + "Ferro (mg)":"Tr", + "Sódio (mg)":46, + "Potássio (mg)":62, + "Cobre (mg)":0.02, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":447, + "Descrição dos alimentos":"Creme de Leite", + "Umidade (%)":70.9, + "Energia (Kcal)":221, + "Energia (KJ)":927, + "Proteína (g)":1.5, + "Lipídeos (g)":22.5, + "Colesterol (mg)":66, + "Carboidrato (g)":4.5, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.6, + "Cálcio (mg)":83, + "Magnésio (mg)":8, + "Manganês (mg)":0.01, + "Fósforo (mg)":118, + "Ferro (mg)":0.3, + "Sódio (mg)":52, + "Potássio (mg)":119, + "Cobre (mg)":0.02, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":448, + "Descrição dos alimentos":"Iogurte, natural", + "Umidade (%)":90.0, + "Energia (Kcal)":51, + "Energia (KJ)":215, + "Proteína (g)":4.1, + "Lipídeos (g)":3.0, + "Colesterol (mg)":14, + "Carboidrato (g)":1.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":143, + "Magnésio (mg)":11, + "Manganês (mg)":"Tr", + "Fósforo (mg)":119, + "Ferro (mg)":"Tr", + "Sódio (mg)":52, + "Potássio (mg)":71, + "Cobre (mg)":0.02, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":449, + "Descrição dos alimentos":"Iogurte, natural, desnatado", + "Umidade (%)":89.2, + "Energia (Kcal)":41, + "Energia (KJ)":174, + "Proteína (g)":3.8, + "Lipídeos (g)":0.3, + "Colesterol (mg)":3, + "Carboidrato (g)":5.8, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":157, + "Magnésio (mg)":12, + "Manganês (mg)":"Tr", + "Fósforo (mg)":110, + "Ferro (mg)":"Tr", + "Sódio (mg)":60, + "Potássio (mg)":182, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":450, + "Descrição dos alimentos":"Iogurte, sabor abacaxi", + "Umidade (%)":"*", + "Energia (Kcal)":"*", + "Energia (KJ)":"*", + "Proteína (g)":"*", + "Lipídeos (g)":"*", + "Colesterol (mg)":6, + "Carboidrato (g)":"*", + "Fibra Alimentar (g)":"*", + "Cinzas (g)":"*", + "Cálcio (mg)":"*", + "Magnésio (mg)":"*", + "Manganês (mg)":"*", + "Fósforo (mg)":"*", + "Ferro (mg)":"*", + "Sódio (mg)":"*", + "Potássio (mg)":"*", + "Cobre (mg)":"*", + "Zinco (mg)":"*" + }, + { + "Número do Alimento":451, + "Descrição dos alimentos":"Iogurte, sabor morango", + "Umidade (%)":84.6, + "Energia (Kcal)":70, + "Energia (KJ)":291, + "Proteína (g)":2.7, + "Lipídeos (g)":2.3, + "Colesterol (mg)":7, + "Carboidrato (g)":9.7, + "Fibra Alimentar (g)":0.2, + "Cinzas (g)":0.6, + "Cálcio (mg)":101, + "Magnésio (mg)":8, + "Manganês (mg)":"Tr", + "Fósforo (mg)":73, + "Ferro (mg)":"Tr", + "Sódio (mg)":38, + "Potássio (mg)":52, + "Cobre (mg)":0.02, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":452, + "Descrição dos alimentos":"Iogurte, sabor pêssego", + "Umidade (%)":85.1, + "Energia (Kcal)":68, + "Energia (KJ)":284, + "Proteína (g)":2.5, + "Lipídeos (g)":2.3, + "Colesterol (mg)":8, + "Carboidrato (g)":9.4, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":0.6, + "Cálcio (mg)":95, + "Magnésio (mg)":8, + "Manganês (mg)":"Tr", + "Fósforo (mg)":66, + "Ferro (mg)":0.1, + "Sódio (mg)":37, + "Potássio (mg)":52, + "Cobre (mg)":0.02, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":453, + "Descrição dos alimentos":"Leite, condensado", + "Umidade (%)":27.0, + "Energia (Kcal)":313, + "Energia (KJ)":1308, + "Proteína (g)":7.7, + "Lipídeos (g)":6.7, + "Colesterol (mg)":28, + "Carboidrato (g)":57.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.6, + "Cálcio (mg)":246, + "Magnésio (mg)":22, + "Manganês (mg)":"Tr", + "Fósforo (mg)":187, + "Ferro (mg)":0.1, + "Sódio (mg)":94, + "Potássio (mg)":329, + "Cobre (mg)":0.03, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":454, + "Descrição dos alimentos":"Leite, de cabra", + "Umidade (%)":87.1, + "Energia (Kcal)":66, + "Energia (KJ)":278, + "Proteína (g)":3.1, + "Lipídeos (g)":3.8, + "Colesterol (mg)":14, + "Carboidrato (g)":5.2, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.9, + "Cálcio (mg)":112, + "Magnésio (mg)":10, + "Manganês (mg)":"Tr", + "Fósforo (mg)":113, + "Ferro (mg)":0.1, + "Sódio (mg)":74, + "Potássio (mg)":140, + "Cobre (mg)":0.04, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":455, + "Descrição dos alimentos":"Leite, de vaca, achocolatado", + "Umidade (%)":80.9, + "Energia (Kcal)":83, + "Energia (KJ)":347, + "Proteína (g)":2.1, + "Lipídeos (g)":2.2, + "Colesterol (mg)":6, + "Carboidrato (g)":14.2, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":0.7, + "Cálcio (mg)":70, + "Magnésio (mg)":13, + "Manganês (mg)":0.05, + "Fósforo (mg)":71, + "Ferro (mg)":0.5, + "Sódio (mg)":72, + "Potássio (mg)":155, + "Cobre (mg)":0.04, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":456, + "Descrição dos alimentos":"Leite, de vaca, desnatado, pó", + "Umidade (%)":3.1, + "Energia (Kcal)":362, + "Energia (KJ)":1513, + "Proteína (g)":34.7, + "Lipídeos (g)":0.9, + "Colesterol (mg)":25, + "Carboidrato (g)":53.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":8.2, + "Cálcio (mg)":1363, + "Magnésio (mg)":109, + "Manganês (mg)":"Tr", + "Fósforo (mg)":1673, + "Ferro (mg)":0.9, + "Sódio (mg)":432, + "Potássio (mg)":1556, + "Cobre (mg)":0.16, + "Zinco (mg)":3.8 + }, + { + "Número do Alimento":457, + "Descrição dos alimentos":"Leite, de vaca, desnatado, UHT", + "Umidade (%)":"*", + "Energia (Kcal)":"*", + "Energia (KJ)":"*", + "Proteína (g)":"*", + "Lipídeos (g)":"*", + "Colesterol (mg)":4, + "Carboidrato (g)":"*", + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":134, + "Magnésio (mg)":10, + "Manganês (mg)":"Tr", + "Fósforo (mg)":85, + "Ferro (mg)":"Tr", + "Sódio (mg)":51, + "Potássio (mg)":140, + "Cobre (mg)":0.02, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":458, + "Descrição dos alimentos":"Leite, de vaca, integral", + "Umidade (%)":"*", + "Energia (Kcal)":"*", + "Energia (KJ)":"*", + "Proteína (g)":"*", + "Lipídeos (g)":"*", + "Colesterol (mg)":10, + "Carboidrato (g)":"*", + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":123, + "Magnésio (mg)":10, + "Manganês (mg)":"Tr", + "Fósforo (mg)":82, + "Ferro (mg)":"Tr", + "Sódio (mg)":64, + "Potássio (mg)":133, + "Cobre (mg)":0.02, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":459, + "Descrição dos alimentos":"Leite, de vaca, integral, pó", + "Umidade (%)":2.7, + "Energia (Kcal)":497, + "Energia (KJ)":2078, + "Proteína (g)":25.4, + "Lipídeos (g)":26.9, + "Colesterol (mg)":85, + "Carboidrato (g)":39.2, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":5.8, + "Cálcio (mg)":890, + "Magnésio (mg)":77, + "Manganês (mg)":"Tr", + "Fósforo (mg)":1242, + "Ferro (mg)":0.5, + "Sódio (mg)":323, + "Potássio (mg)":1132, + "Cobre (mg)":0.11, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":460, + "Descrição dos alimentos":"Leite, fermentado", + "Umidade (%)":81.9, + "Energia (Kcal)":70, + "Energia (KJ)":291, + "Proteína (g)":1.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":2, + "Carboidrato (g)":15.7, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.5, + "Cálcio (mg)":72, + "Magnésio (mg)":6, + "Manganês (mg)":0.02, + "Fósforo (mg)":63, + "Ferro (mg)":"Tr", + "Sódio (mg)":33, + "Potássio (mg)":94, + "Cobre (mg)":0.01, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":461, + "Descrição dos alimentos":"Queijo, minas, frescal", + "Umidade (%)":56.1, + "Energia (Kcal)":264, + "Energia (KJ)":1106, + "Proteína (g)":17.4, + "Lipídeos (g)":20.2, + "Colesterol (mg)":62, + "Carboidrato (g)":3.2, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.0, + "Cálcio (mg)":579, + "Magnésio (mg)":7, + "Manganês (mg)":0.02, + "Fósforo (mg)":123, + "Ferro (mg)":0.9, + "Sódio (mg)":31, + "Potássio (mg)":105, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":462, + "Descrição dos alimentos":"Queijo, minas, meia cura", + "Umidade (%)":47.1, + "Energia (Kcal)":321, + "Energia (KJ)":1342, + "Proteína (g)":21.2, + "Lipídeos (g)":24.6, + "Colesterol (mg)":76, + "Carboidrato (g)":3.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.5, + "Cálcio (mg)":696, + "Magnésio (mg)":27, + "Manganês (mg)":0.02, + "Fósforo (mg)":403, + "Ferro (mg)":0.2, + "Sódio (mg)":501, + "Potássio (mg)":120, + "Cobre (mg)":0.07, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":463, + "Descrição dos alimentos":"Queijo, mozarela", + "Umidade (%)":45.3, + "Energia (Kcal)":330, + "Energia (KJ)":1380, + "Proteína (g)":22.6, + "Lipídeos (g)":25.2, + "Colesterol (mg)":80, + "Carboidrato (g)":3.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.8, + "Cálcio (mg)":875, + "Magnésio (mg)":24, + "Manganês (mg)":0.03, + "Fósforo (mg)":470, + "Ferro (mg)":0.3, + "Sódio (mg)":581, + "Potássio (mg)":62, + "Cobre (mg)":0.08, + "Zinco (mg)":3.5 + }, + { + "Número do Alimento":464, + "Descrição dos alimentos":"Queijo, parmesão", + "Umidade (%)":21.2, + "Energia (Kcal)":453, + "Energia (KJ)":1895, + "Proteína (g)":35.6, + "Lipídeos (g)":33.5, + "Colesterol (mg)":106, + "Carboidrato (g)":1.7, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":8.0, + "Cálcio (mg)":992, + "Magnésio (mg)":33, + "Manganês (mg)":0.05, + "Fósforo (mg)":745, + "Ferro (mg)":0.5, + "Sódio (mg)":1844, + "Potássio (mg)":96, + "Cobre (mg)":0.17, + "Zinco (mg)":4.4 + }, + { + "Número do Alimento":465, + "Descrição dos alimentos":"Queijo, pasteurizado", + "Umidade (%)":54.4, + "Energia (Kcal)":303, + "Energia (KJ)":1268, + "Proteína (g)":9.4, + "Lipídeos (g)":27.4, + "Colesterol (mg)":82, + "Carboidrato (g)":5.7, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.1, + "Cálcio (mg)":323, + "Magnésio (mg)":16, + "Manganês (mg)":0.01, + "Fósforo (mg)":578, + "Ferro (mg)":0.3, + "Sódio (mg)":780, + "Potássio (mg)":194, + "Cobre (mg)":0.05, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":466, + "Descrição dos alimentos":"Queijo, petit suisse, morango", + "Umidade (%)":72.2, + "Energia (Kcal)":121, + "Energia (KJ)":507, + "Proteína (g)":5.8, + "Lipídeos (g)":2.8, + "Colesterol (mg)":12, + "Carboidrato (g)":18.5, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":731, + "Magnésio (mg)":27, + "Manganês (mg)":0.02, + "Fósforo (mg)":448, + "Ferro (mg)":0.1, + "Sódio (mg)":412, + "Potássio (mg)":121, + "Cobre (mg)":0.01, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":467, + "Descrição dos alimentos":"Queijo, prato", + "Umidade (%)":42.4, + "Energia (Kcal)":360, + "Energia (KJ)":1506, + "Proteína (g)":22.7, + "Lipídeos (g)":29.1, + "Colesterol (mg)":91, + "Carboidrato (g)":1.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":3.9, + "Cálcio (mg)":940, + "Magnésio (mg)":28, + "Manganês (mg)":0.03, + "Fósforo (mg)":461, + "Ferro (mg)":0.3, + "Sódio (mg)":580, + "Potássio (mg)":73, + "Cobre (mg)":0.10, + "Zinco (mg)":3.5 + }, + { + "Número do Alimento":468, + "Descrição dos alimentos":"Queijo, requeijão, cremoso", + "Umidade (%)":62.5, + "Energia (Kcal)":257, + "Energia (KJ)":1074, + "Proteína (g)":9.6, + "Lipídeos (g)":23.4, + "Colesterol (mg)":74, + "Carboidrato (g)":2.4, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.0, + "Cálcio (mg)":259, + "Magnésio (mg)":12, + "Manganês (mg)":0.02, + "Fósforo (mg)":448, + "Ferro (mg)":0.1, + "Sódio (mg)":558, + "Potássio (mg)":93, + "Cobre (mg)":0.05, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":469, + "Descrição dos alimentos":"Queijo, ricota", + "Umidade (%)":73.6, + "Energia (Kcal)":140, + "Energia (KJ)":585, + "Proteína (g)":12.6, + "Lipídeos (g)":8.1, + "Colesterol (mg)":49, + "Carboidrato (g)":3.8, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.9, + "Cálcio (mg)":253, + "Magnésio (mg)":12, + "Manganês (mg)":"Tr", + "Fósforo (mg)":162, + "Ferro (mg)":0.1, + "Sódio (mg)":283, + "Potássio (mg)":112, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":470, + "Descrição dos alimentos":"Bebida isotônica, sabores variados", + "Umidade (%)":93.5, + "Energia (Kcal)":26, + "Energia (KJ)":107, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.4, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.1, + "Cálcio (mg)":1, + "Magnésio (mg)":"Tr", + "Manganês (mg)":"Tr", + "Fósforo (mg)":9, + "Ferro (mg)":0.7, + "Sódio (mg)":44, + "Potássio (mg)":13, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":471, + "Descrição dos alimentos":"Café, infusão 10%", + "Umidade (%)":97.4, + "Energia (Kcal)":9, + "Energia (KJ)":38, + "Proteína (g)":0.7, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":1.5, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.4, + "Cálcio (mg)":3, + "Magnésio (mg)":10, + "Manganês (mg)":0.04, + "Fósforo (mg)":9, + "Ferro (mg)":"Tr", + "Sódio (mg)":1, + "Potássio (mg)":156, + "Cobre (mg)":0.01, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":472, + "Descrição dos alimentos":"Cana, aguardente 1", + "Umidade (%)":0.0, + "Energia (Kcal)":216, + "Energia (KJ)":902, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":"Tr", + "Magnésio (mg)":"Tr", + "Manganês (mg)":"Tr", + "Fósforo (mg)":"Tr", + "Ferro (mg)":"Tr", + "Sódio (mg)":3, + "Potássio (mg)":"Tr", + "Cobre (mg)":0.06, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":473, + "Descrição dos alimentos":"Cana, caldo de", + "Umidade (%)":81.7, + "Energia (Kcal)":65, + "Energia (KJ)":273, + "Proteína (g)":"Tr", + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.2, + "Fibra Alimentar (g)":0.1, + "Cinzas (g)":0.1, + "Cálcio (mg)":9, + "Magnésio (mg)":12, + "Manganês (mg)":0.21, + "Fósforo (mg)":5, + "Ferro (mg)":0.8, + "Sódio (mg)":"Tr", + "Potássio (mg)":18, + "Cobre (mg)":0.01, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":474, + "Descrição dos alimentos":"Cerveja, pilsen 2", + "Umidade (%)":92.4, + "Energia (Kcal)":41, + "Energia (KJ)":170, + "Proteína (g)":0.6, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":3.3, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.1, + "Cálcio (mg)":5, + "Magnésio (mg)":7, + "Manganês (mg)":0.01, + "Fósforo (mg)":19, + "Ferro (mg)":"Tr", + "Sódio (mg)":4, + "Potássio (mg)":29, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":475, + "Descrição dos alimentos":"Chá, erva-doce, infusão 5%", + "Umidade (%)":99.6, + "Energia (Kcal)":1, + "Energia (KJ)":6, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.4, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":2, + "Magnésio (mg)":1, + "Manganês (mg)":0.01, + "Fósforo (mg)":1, + "Ferro (mg)":"Tr", + "Sódio (mg)":1, + "Potássio (mg)":10, + "Cobre (mg)":0.01, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":476, + "Descrição dos alimentos":"Chá, mate, infusão 5%", + "Umidade (%)":99.3, + "Energia (Kcal)":3, + "Energia (KJ)":11, + "Proteína (g)":0.0, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":1, + "Magnésio (mg)":2, + "Manganês (mg)":0.27, + "Fósforo (mg)":"Tr", + "Ferro (mg)":"Tr", + "Sódio (mg)":"Tr", + "Potássio (mg)":5, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":477, + "Descrição dos alimentos":"Chá, preto, infusão 5%", + "Umidade (%)":99.4, + "Energia (Kcal)":2, + "Energia (KJ)":9, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0, + "Magnésio (mg)":1, + "Manganês (mg)":0.09, + "Fósforo (mg)":2, + "Ferro (mg)":"Tr", + "Sódio (mg)":"Tr", + "Potássio (mg)":13, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":478, + "Descrição dos alimentos":"Coco, água de", + "Umidade (%)":94.3, + "Energia (Kcal)":22, + "Energia (KJ)":90, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.3, + "Fibra Alimentar (g)":0.1, + "Cinzas (g)":0.5, + "Cálcio (mg)":19, + "Magnésio (mg)":5, + "Manganês (mg)":0.25, + "Fósforo (mg)":4, + "Ferro (mg)":"Tr", + "Sódio (mg)":2, + "Potássio (mg)":162, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":479, + "Descrição dos alimentos":"Refrigerante, tipo água tônica", + "Umidade (%)":92.0, + "Energia (Kcal)":31, + "Energia (KJ)":129, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":1, + "Magnésio (mg)":"Tr", + "Manganês (mg)":"Tr", + "Fósforo (mg)":0, + "Ferro (mg)":"Tr", + "Sódio (mg)":8, + "Potássio (mg)":2, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":480, + "Descrição dos alimentos":"Refrigerante, tipo cola", + "Umidade (%)":91.3, + "Energia (Kcal)":34, + "Energia (KJ)":140, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":8.7, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.1, + "Cálcio (mg)":1, + "Magnésio (mg)":"Tr", + "Manganês (mg)":"Tr", + "Fósforo (mg)":17, + "Ferro (mg)":"Tr", + "Sódio (mg)":7, + "Potássio (mg)":1, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":481, + "Descrição dos alimentos":"Refrigerante, tipo guaraná", + "Umidade (%)":90.0, + "Energia (Kcal)":39, + "Energia (KJ)":162, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":1, + "Magnésio (mg)":"Tr", + "Manganês (mg)":"Tr", + "Fósforo (mg)":"Tr", + "Ferro (mg)":"Tr", + "Sódio (mg)":9, + "Potássio (mg)":1, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":482, + "Descrição dos alimentos":"Refrigerante, tipo laranja", + "Umidade (%)":88.2, + "Energia (Kcal)":46, + "Energia (KJ)":191, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.8, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":2, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":1, + "Ferro (mg)":"Tr", + "Sódio (mg)":9, + "Potássio (mg)":16, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":483, + "Descrição dos alimentos":"Refrigerante, tipo limão", + "Umidade (%)":89.7, + "Energia (Kcal)":40, + "Energia (KJ)":166, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.3, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":2, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":"Tr", + "Ferro (mg)":"Tr", + "Sódio (mg)":9, + "Potássio (mg)":4, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":484, + "Descrição dos alimentos":"Omelete, de queijo", + "Umidade (%)":60.5, + "Energia (Kcal)":268, + "Energia (KJ)":1121, + "Proteína (g)":15.6, + "Lipídeos (g)":22.0, + "Colesterol (mg)":384, + "Carboidrato (g)":0.4, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.5, + "Cálcio (mg)":166, + "Magnésio (mg)":14, + "Manganês (mg)":0.03, + "Fósforo (mg)":314, + "Ferro (mg)":1.4, + "Sódio (mg)":216, + "Potássio (mg)":127, + "Cobre (mg)":0.03, + "Zinco (mg)":1.4 + }, + { + "Número do Alimento":485, + "Descrição dos alimentos":"Ovo, de codorna, inteiro, cru", + "Umidade (%)":71.7, + "Energia (Kcal)":177, + "Energia (KJ)":740, + "Proteína (g)":13.7, + "Lipídeos (g)":12.7, + "Colesterol (mg)":568, + "Carboidrato (g)":0.8, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.2, + "Cálcio (mg)":79, + "Magnésio (mg)":11, + "Manganês (mg)":"Tr", + "Fósforo (mg)":279, + "Ferro (mg)":3.3, + "Sódio (mg)":129, + "Potássio (mg)":79, + "Cobre (mg)":0.04, + "Zinco (mg)":2.1 + }, + { + "Número do Alimento":486, + "Descrição dos alimentos":"Ovo, de galinha, clara, cozida\/10minutos", + "Umidade (%)":85.2, + "Energia (Kcal)":59, + "Energia (KJ)":249, + "Proteína (g)":13.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.7, + "Cálcio (mg)":6, + "Magnésio (mg)":11, + "Manganês (mg)":"Tr", + "Fósforo (mg)":15, + "Ferro (mg)":0.1, + "Sódio (mg)":181, + "Potássio (mg)":146, + "Cobre (mg)":0.03, + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":487, + "Descrição dos alimentos":"Ovo, de galinha, gema, cozida\/10minutos", + "Umidade (%)":50.0, + "Energia (Kcal)":353, + "Energia (KJ)":1476, + "Proteína (g)":15.9, + "Lipídeos (g)":30.8, + "Colesterol (mg)":1272, + "Carboidrato (g)":1.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.7, + "Cálcio (mg)":114, + "Magnésio (mg)":9, + "Manganês (mg)":0.06, + "Fósforo (mg)":386, + "Ferro (mg)":2.9, + "Sódio (mg)":45, + "Potássio (mg)":87, + "Cobre (mg)":"Tr", + "Zinco (mg)":2.9 + }, + { + "Número do Alimento":488, + "Descrição dos alimentos":"Ovo, de galinha, inteiro, cozido\/10minutos", + "Umidade (%)":75.8, + "Energia (Kcal)":146, + "Energia (KJ)":610, + "Proteína (g)":13.3, + "Lipídeos (g)":9.5, + "Colesterol (mg)":397, + "Carboidrato (g)":0.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":49, + "Magnésio (mg)":11, + "Manganês (mg)":0.02, + "Fósforo (mg)":184, + "Ferro (mg)":1.5, + "Sódio (mg)":146, + "Potássio (mg)":139, + "Cobre (mg)":0.04, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":489, + "Descrição dos alimentos":"Ovo, de galinha, inteiro, cru", + "Umidade (%)":75.6, + "Energia (Kcal)":143, + "Energia (KJ)":599, + "Proteína (g)":13.0, + "Lipídeos (g)":8.9, + "Colesterol (mg)":356, + "Carboidrato (g)":1.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.8, + "Cálcio (mg)":42, + "Magnésio (mg)":13, + "Manganês (mg)":"Tr", + "Fósforo (mg)":164, + "Ferro (mg)":1.6, + "Sódio (mg)":168, + "Potássio (mg)":150, + "Cobre (mg)":0.06, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":490, + "Descrição dos alimentos":"Ovo, de galinha, inteiro, frito", + "Umidade (%)":63.5, + "Energia (Kcal)":240, + "Energia (KJ)":1005, + "Proteína (g)":15.6, + "Lipídeos (g)":18.6, + "Colesterol (mg)":516, + "Carboidrato (g)":1.2, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":73, + "Magnésio (mg)":16, + "Manganês (mg)":0.03, + "Fósforo (mg)":422, + "Ferro (mg)":2.1, + "Sódio (mg)":166, + "Potássio (mg)":184, + "Cobre (mg)":0.04, + "Zinco (mg)":1.5 + }, + { + "Número do Alimento":491, + "Descrição dos alimentos":"Achocolatado, pó", + "Umidade (%)":1.1, + "Energia (Kcal)":401, + "Energia (KJ)":1678, + "Proteína (g)":4.2, + "Lipídeos (g)":2.2, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":91.2, + "Fibra Alimentar (g)":3.9, + "Cinzas (g)":1.4, + "Cálcio (mg)":44, + "Magnésio (mg)":77, + "Manganês (mg)":0.55, + "Fósforo (mg)":200, + "Ferro (mg)":5.4, + "Sódio (mg)":65, + "Potássio (mg)":496, + "Cobre (mg)":0.56, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":492, + "Descrição dos alimentos":"Açúcar, cristal", + "Umidade (%)":0.1, + "Energia (Kcal)":387, + "Energia (KJ)":1619, + "Proteína (g)":0.3, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":99.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":"Tr", + "Cálcio (mg)":8, + "Magnésio (mg)":1, + "Manganês (mg)":" ", + "Fósforo (mg)":"Tr", + "Ferro (mg)":0.2, + "Sódio (mg)":"Tr", + "Potássio (mg)":3, + "Cobre (mg)":" Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":493, + "Descrição dos alimentos":"Açúcar, mascavo", + "Umidade (%)":3.3, + "Energia (Kcal)":369, + "Energia (KJ)":1542, + "Proteína (g)":0.8, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":94.5, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.4, + "Cálcio (mg)":127, + "Magnésio (mg)":80, + "Manganês (mg)":2.03, + "Fósforo (mg)":38, + "Ferro (mg)":8.3, + "Sódio (mg)":25, + "Potássio (mg)":522, + "Cobre (mg)":0.17, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":494, + "Descrição dos alimentos":"Açúcar, refinado", + "Umidade (%)":0.1, + "Energia (Kcal)":387, + "Energia (KJ)":1617, + "Proteína (g)":0.3, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":99.5, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":"Tr", + "Cálcio (mg)":4, + "Magnésio (mg)":1, + "Manganês (mg)":" ", + "Fósforo (mg)":"Tr", + "Ferro (mg)":0.1, + "Sódio (mg)":12, + "Potássio (mg)":6, + "Cobre (mg)":" Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":495, + "Descrição dos alimentos":"Chocolate, ao leite", + "Umidade (%)":1.3, + "Energia (Kcal)":540, + "Energia (KJ)":2258, + "Proteína (g)":7.2, + "Lipídeos (g)":30.3, + "Colesterol (mg)":17, + "Carboidrato (g)":59.6, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":1.7, + "Cálcio (mg)":191, + "Magnésio (mg)":57, + "Manganês (mg)":0.30, + "Fósforo (mg)":212, + "Ferro (mg)":1.6, + "Sódio (mg)":77, + "Potássio (mg)":355, + "Cobre (mg)":0.31, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":496, + "Descrição dos alimentos":"Chocolate, ao leite, com castanha do Pará", + "Umidade (%)":1.2, + "Energia (Kcal)":559, + "Energia (KJ)":2338, + "Proteína (g)":7.4, + "Lipídeos (g)":34.2, + "Colesterol (mg)":16, + "Carboidrato (g)":55.4, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":1.8, + "Cálcio (mg)":171, + "Magnésio (mg)":80, + "Manganês (mg)":0.36, + "Fósforo (mg)":303, + "Ferro (mg)":1.5, + "Sódio (mg)":64, + "Potássio (mg)":431, + "Cobre (mg)":0.45, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":497, + "Descrição dos alimentos":"Chocolate, ao leite, dietético", + "Umidade (%)":1.7, + "Energia (Kcal)":557, + "Energia (KJ)":2330, + "Proteína (g)":6.9, + "Lipídeos (g)":33.8, + "Colesterol (mg)":13, + "Carboidrato (g)":56.3, + "Fibra Alimentar (g)":2.8, + "Cinzas (g)":1.3, + "Cálcio (mg)":188, + "Magnésio (mg)":67, + "Manganês (mg)":0.41, + "Fósforo (mg)":276, + "Ferro (mg)":3.3, + "Sódio (mg)":85, + "Potássio (mg)":458, + "Cobre (mg)":0.43, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":498, + "Descrição dos alimentos":"Chocolate, meio amargo", + "Umidade (%)":1.0, + "Energia (Kcal)":475, + "Energia (KJ)":1987, + "Proteína (g)":4.9, + "Lipídeos (g)":29.9, + "Colesterol (mg)":2, + "Carboidrato (g)":62.4, + "Fibra Alimentar (g)":4.9, + "Cinzas (g)":1.8, + "Cálcio (mg)":45, + "Magnésio (mg)":107, + "Manganês (mg)":0.83, + "Fósforo (mg)":220, + "Ferro (mg)":3.6, + "Sódio (mg)":9, + "Potássio (mg)":432, + "Cobre (mg)":0.77, + "Zinco (mg)":1.5 + }, + { + "Número do Alimento":499, + "Descrição dos alimentos":"Cocada branca", + "Umidade (%)":3.4, + "Energia (Kcal)":449, + "Energia (KJ)":1878, + "Proteína (g)":1.1, + "Lipídeos (g)":13.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":81.4, + "Fibra Alimentar (g)":3.6, + "Cinzas (g)":0.5, + "Cálcio (mg)":7, + "Magnésio (mg)":17, + "Manganês (mg)":0.36, + "Fósforo (mg)":396, + "Ferro (mg)":1.2, + "Sódio (mg)":29, + "Potássio (mg)":183, + "Cobre (mg)":0.20, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":500, + "Descrição dos alimentos":"Doce, de abóbora, cremoso", + "Umidade (%)":43.9, + "Energia (Kcal)":199, + "Energia (KJ)":832, + "Proteína (g)":0.9, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":54.6, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.4, + "Cálcio (mg)":13, + "Magnésio (mg)":6, + "Manganês (mg)":0.01, + "Fósforo (mg)":14, + "Ferro (mg)":0.9, + "Sódio (mg)":"Tr", + "Potássio (mg)":137, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":501, + "Descrição dos alimentos":"Doce, de leite, cremoso", + "Umidade (%)":27.5, + "Energia (Kcal)":306, + "Energia (KJ)":1282, + "Proteína (g)":5.5, + "Lipídeos (g)":6.0, + "Colesterol (mg)":20, + "Carboidrato (g)":59.5, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.5, + "Cálcio (mg)":195, + "Magnésio (mg)":16, + "Manganês (mg)":0.01, + "Fósforo (mg)":141, + "Ferro (mg)":0.1, + "Sódio (mg)":120, + "Potássio (mg)":259, + "Cobre (mg)":0.02, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":502, + "Descrição dos alimentos":"Geléia, mocotó, natural", + "Umidade (%)":73.5, + "Energia (Kcal)":106, + "Energia (KJ)":444, + "Proteína (g)":2.1, + "Lipídeos (g)":0.1, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":24.2, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.1, + "Cálcio (mg)":4, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":"Tr", + "Ferro (mg)":0.1, + "Sódio (mg)":43, + "Potássio (mg)":2, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":503, + "Descrição dos alimentos":"Glicose de milho", + "Umidade (%)":20.4, + "Energia (Kcal)":292, + "Energia (KJ)":1222, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":79.4, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.2, + "Cálcio (mg)":6, + "Magnésio (mg)":2, + "Manganês (mg)":"Tr", + "Fósforo (mg)":5, + "Ferro (mg)":0.1, + "Sódio (mg)":59, + "Potássio (mg)":5, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":504, + "Descrição dos alimentos":"Maria mole", + "Umidade (%)":21.6, + "Energia (Kcal)":301, + "Energia (KJ)":1260, + "Proteína (g)":3.8, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":73.6, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":0.9, + "Cálcio (mg)":13, + "Magnésio (mg)":7, + "Manganês (mg)":0.06, + "Fósforo (mg)":4, + "Ferro (mg)":0.4, + "Sódio (mg)":15, + "Potássio (mg)":24, + "Cobre (mg)":0.20, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":505, + "Descrição dos alimentos":"Maria mole, coco queimado", + "Umidade (%)":20.7, + "Energia (Kcal)":307, + "Energia (KJ)":1283, + "Proteína (g)":3.9, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":75.1, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":0.2, + "Cálcio (mg)":19, + "Magnésio (mg)":6, + "Manganês (mg)":0.09, + "Fósforo (mg)":5, + "Ferro (mg)":0.5, + "Sódio (mg)":14, + "Potássio (mg)":36, + "Cobre (mg)":0.03, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":506, + "Descrição dos alimentos":"Marmelada", + "Umidade (%)":28.5, + "Energia (Kcal)":257, + "Energia (KJ)":1076, + "Proteína (g)":0.4, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":70.8, + "Fibra Alimentar (g)":4.1, + "Cinzas (g)":0.2, + "Cálcio (mg)":11, + "Magnésio (mg)":6, + "Manganês (mg)":0.06, + "Fósforo (mg)":20, + "Ferro (mg)":0.7, + "Sódio (mg)":11, + "Potássio (mg)":83, + "Cobre (mg)":0.09, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":507, + "Descrição dos alimentos":"Mel, de abelha", + "Umidade (%)":15.8, + "Energia (Kcal)":309, + "Energia (KJ)":1294, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":84.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.1, + "Cálcio (mg)":10, + "Magnésio (mg)":6, + "Manganês (mg)":0.38, + "Fósforo (mg)":4, + "Ferro (mg)":0.3, + "Sódio (mg)":6, + "Potássio (mg)":99, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":508, + "Descrição dos alimentos":"Melado", + "Umidade (%)":22.1, + "Energia (Kcal)":297, + "Energia (KJ)":1241, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":76.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.3, + "Cálcio (mg)":102, + "Magnésio (mg)":115, + "Manganês (mg)":2.62, + "Fósforo (mg)":74, + "Ferro (mg)":5.4, + "Sódio (mg)":4, + "Potássio (mg)":395, + "Cobre (mg)":0.84, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":509, + "Descrição dos alimentos":"Quindim", + "Umidade (%)":23.9, + "Energia (Kcal)":411, + "Energia (KJ)":1721, + "Proteína (g)":4.7, + "Lipídeos (g)":24.4, + "Colesterol (mg)":271, + "Carboidrato (g)":46.3, + "Fibra Alimentar (g)":3.2, + "Cinzas (g)":0.6, + "Cálcio (mg)":37, + "Magnésio (mg)":15, + "Manganês (mg)":0.25, + "Fósforo (mg)":168, + "Ferro (mg)":1.4, + "Sódio (mg)":27, + "Potássio (mg)":111, + "Cobre (mg)":0.10, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":510, + "Descrição dos alimentos":"Rapadura", + "Umidade (%)":7.1, + "Energia (Kcal)":352, + "Energia (KJ)":1473, + "Proteína (g)":1.0, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":90.8, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":30, + "Magnésio (mg)":47, + "Manganês (mg)":1.66, + "Fósforo (mg)":21, + "Ferro (mg)":4.4, + "Sódio (mg)":22, + "Potássio (mg)":459, + "Cobre (mg)":0.17, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":511, + "Descrição dos alimentos":"Café, pó, torrado", + "Umidade (%)":2.9, + "Energia (Kcal)":419, + "Energia (KJ)":1752, + "Proteína (g)":14.7, + "Lipídeos (g)":11.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":65.8, + "Fibra Alimentar (g)":51.2, + "Cinzas (g)":4.7, + "Cálcio (mg)":107, + "Magnésio (mg)":165, + "Manganês (mg)":2.58, + "Fósforo (mg)":169, + "Ferro (mg)":8.1, + "Sódio (mg)":1, + "Potássio (mg)":1609, + "Cobre (mg)":1.30, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":512, + "Descrição dos alimentos":"Capuccino, pó", + "Umidade (%)":2.6, + "Energia (Kcal)":417, + "Energia (KJ)":1746, + "Proteína (g)":11.3, + "Lipídeos (g)":8.6, + "Colesterol (mg)":29, + "Carboidrato (g)":73.6, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":3.8, + "Cálcio (mg)":467, + "Magnésio (mg)":71, + "Manganês (mg)":0.17, + "Fósforo (mg)":358, + "Ferro (mg)":2.3, + "Sódio (mg)":382, + "Potássio (mg)":886, + "Cobre (mg)":"Tr", + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":513, + "Descrição dos alimentos":"Fermento em pó, químico", + "Umidade (%)":7.1, + "Energia (Kcal)":90, + "Energia (KJ)":375, + "Proteína (g)":0.5, + "Lipídeos (g)":0.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":43.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":48.5, + "Cálcio (mg)":" ", + "Magnésio (mg)":" ", + "Manganês (mg)":" ", + "Fósforo (mg)":" ", + "Ferro (mg)":" ", + "Sódio (mg)":10052, + "Potássio (mg)":" ", + "Cobre (mg)":" ", + "Zinco (mg)":" " + }, + { + "Número do Alimento":514, + "Descrição dos alimentos":"Fermento, biológico, levedura, tablete", + "Umidade (%)":71.9, + "Energia (Kcal)":90, + "Energia (KJ)":376, + "Proteína (g)":17.0, + "Lipídeos (g)":1.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.7, + "Fibra Alimentar (g)":4.2, + "Cinzas (g)":1.9, + "Cálcio (mg)":18, + "Magnésio (mg)":38, + "Manganês (mg)":0.20, + "Fósforo (mg)":419, + "Ferro (mg)":2.6, + "Sódio (mg)":40, + "Potássio (mg)":576, + "Cobre (mg)":0.29, + "Zinco (mg)":11.0 + }, + { + "Número do Alimento":515, + "Descrição dos alimentos":"Gelatina, sabores variados, pó", + "Umidade (%)":1.2, + "Energia (Kcal)":380, + "Energia (KJ)":1591, + "Proteína (g)":8.9, + "Lipídeos (g)":"Tr", + "Colesterol (mg)":0.0, + "Carboidrato (g)":89.2, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.6, + "Cálcio (mg)":27, + "Magnésio (mg)":2, + "Manganês (mg)":0.03, + "Fósforo (mg)":2, + "Ferro (mg)":0.3, + "Sódio (mg)":235, + "Potássio (mg)":7, + "Cobre (mg)":"Tr", + "Zinco (mg)":"Tr" + }, + { + "Número do Alimento":516, + "Descrição dos alimentos":"Sal, dietético", + "Umidade (%)":0.6, + "Energia (Kcal) (KJ)":0.0, + "Unnamed: 4":0.0, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":99.4, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":23432, + "Potássio (mg)":20468, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":517, + "Descrição dos alimentos":"Sal, grosso", + "Umidade (%)":0.4, + "Energia (Kcal) (KJ)":0.0, + "Unnamed: 4":0.0, + "Proteína (g)":0.0, + "Lipídeos (g)":0.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.0, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":39943, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":518, + "Descrição dos alimentos":"Shoyu", + "Umidade (%)":70.6, + "Energia (Kcal)":61, + "Energia (KJ)":255, + "Proteína (g)":3.3, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":14.1, + "Cálcio (mg)":15, + "Magnésio (mg)":24, + "Manganês (mg)":0.07, + "Fósforo (mg)":47, + "Ferro (mg)":0.5, + "Sódio (mg)":5024, + "Potássio (mg)":165, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":519, + "Descrição dos alimentos":"Tempero a base de sal", + "Umidade (%)":7.7, + "Energia (Kcal)":21, + "Energia (KJ)":89, + "Proteína (g)":2.7, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.1, + "Fibra Alimentar (g)":0.6, + "Cinzas (g)":87.3, + "Cálcio (mg)":0.0, + "Magnésio (mg)":0.0, + "Manganês (mg)":0.0, + "Fósforo (mg)":0.0, + "Ferro (mg)":0.0, + "Sódio (mg)":32560, + "Potássio (mg)":0.0, + "Cobre (mg)":0.0, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":520, + "Descrição dos alimentos":"Azeitona, preta, conserva", + "Umidade (%)":68.5, + "Energia (Kcal)":194, + "Energia (KJ)":812, + "Proteína (g)":1.2, + "Lipídeos (g)":20.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":5.5, + "Fibra Alimentar (g)":4.6, + "Cinzas (g)":4.5, + "Cálcio (mg)":59, + "Magnésio (mg)":5, + "Manganês (mg)":0.06, + "Fósforo (mg)":16, + "Ferro (mg)":5.5, + "Sódio (mg)":1567, + "Potássio (mg)":79, + "Cobre (mg)":0.25, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":521, + "Descrição dos alimentos":"Azeitona, verde, conserva", + "Umidade (%)":76.3, + "Energia (Kcal)":137, + "Energia (KJ)":573, + "Proteína (g)":0.9, + "Lipídeos (g)":14.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.1, + "Fibra Alimentar (g)":3.8, + "Cinzas (g)":4.5, + "Cálcio (mg)":46, + "Magnésio (mg)":4, + "Manganês (mg)":0.03, + "Fósforo (mg)":5, + "Ferro (mg)":0.2, + "Sódio (mg)":1347, + "Potássio (mg)":20, + "Cobre (mg)":0.14, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":522, + "Descrição dos alimentos":"Chantilly, spray, com gordura vegetal", + "Umidade (%)":55.1, + "Energia (Kcal)":315, + "Energia (KJ)":1318, + "Proteína (g)":0.5, + "Lipídeos (g)":27.3, + "Colesterol (mg)":"Tr", + "Carboidrato (g)":16.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.2, + "Cálcio (mg)":2, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":16, + "Ferro (mg)":"Tr", + "Sódio (mg)":110, + "Potássio (mg)":5, + "Cobre (mg)":0.01, + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":523, + "Descrição dos alimentos":"Leite, de coco", + "Umidade (%)":78.0, + "Energia (Kcal)":166, + "Energia (KJ)":695, + "Proteína (g)":1.0, + "Lipídeos (g)":18.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.2, + "Fibra Alimentar (g)":0.7, + "Cinzas (g)":0.4, + "Cálcio (mg)":6, + "Magnésio (mg)":17, + "Manganês (mg)":0.24, + "Fósforo (mg)":26, + "Ferro (mg)":0.5, + "Sódio (mg)":44, + "Potássio (mg)":144, + "Cobre (mg)":0.16, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":524, + "Descrição dos alimentos":"Maionese, tradicional com ovos", + "Umidade (%)":58.4, + "Energia (Kcal)":302, + "Energia (KJ)":1264, + "Proteína (g)":0.6, + "Lipídeos (g)":30.5, + "Colesterol (mg)":42, + "Carboidrato (g)":7.9, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":2.6, + "Cálcio (mg)":3, + "Magnésio (mg)":1, + "Manganês (mg)":"Tr", + "Fósforo (mg)":14, + "Ferro (mg)":0.1, + "Sódio (mg)":787, + "Potássio (mg)":16, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.1 + }, + { + "Número do Alimento":525, + "Descrição dos alimentos":"Acarajé", + "Umidade (%)":50.5, + "Energia (Kcal)":289, + "Energia (KJ)":1210, + "Proteína (g)":8.3, + "Lipídeos (g)":19.9, + "Colesterol (mg)":25, + "Carboidrato (g)":19.1, + "Fibra Alimentar (g)":9.4, + "Cinzas (g)":2.1, + "Cálcio (mg)":124, + "Magnésio (mg)":51, + "Manganês (mg)":0.59, + "Fósforo (mg)":142, + "Ferro (mg)":1.9, + "Sódio (mg)":305, + "Potássio (mg)":354, + "Cobre (mg)":0.23, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":526, + "Descrição dos alimentos":"Arroz carreteiro", + "Umidade (%)":68.0, + "Energia (Kcal)":154, + "Energia (KJ)":643, + "Proteína (g)":10.8, + "Lipídeos (g)":7.1, + "Colesterol (mg)":36, + "Carboidrato (g)":11.6, + "Fibra Alimentar (g)":1.5, + "Cinzas (g)":2.4, + "Cálcio (mg)":13, + "Magnésio (mg)":9, + "Manganês (mg)":0.18, + "Fósforo (mg)":48, + "Ferro (mg)":1.0, + "Sódio (mg)":1622, + "Potássio (mg)":87, + "Cobre (mg)":0.08, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":527, + "Descrição dos alimentos":"Baião de dois, arroz e feijão-de-corda", + "Umidade (%)":69.1, + "Energia (Kcal)":136, + "Energia (KJ)":568, + "Proteína (g)":6.2, + "Lipídeos (g)":3.2, + "Colesterol (mg)":4, + "Carboidrato (g)":20.4, + "Fibra Alimentar (g)":5.1, + "Cinzas (g)":1.1, + "Cálcio (mg)":33, + "Magnésio (mg)":19, + "Manganês (mg)":0.27, + "Fósforo (mg)":72, + "Ferro (mg)":0.6, + "Sódio (mg)":93, + "Potássio (mg)":157, + "Cobre (mg)":0.08, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":528, + "Descrição dos alimentos":"Barreado", + "Umidade (%)":71.2, + "Energia (Kcal)":165, + "Energia (KJ)":690, + "Proteína (g)":18.3, + "Lipídeos (g)":9.5, + "Colesterol (mg)":60, + "Carboidrato (g)":0.2, + "Fibra Alimentar (g)":0.1, + "Cinzas (g)":0.8, + "Cálcio (mg)":15, + "Magnésio (mg)":21, + "Manganês (mg)":0.05, + "Fósforo (mg)":169, + "Ferro (mg)":2.4, + "Sódio (mg)":48, + "Potássio (mg)":295, + "Cobre (mg)":0.17, + "Zinco (mg)":4.8 + }, + { + "Número do Alimento":529, + "Descrição dos alimentos":"Bife à cavalo, com contra filé", + "Umidade (%)":54.2, + "Energia (Kcal)":291, + "Energia (KJ)":1219, + "Proteína (g)":23.7, + "Lipídeos (g)":21.1, + "Colesterol (mg)":257, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":26, + "Magnésio (mg)":19, + "Manganês (mg)":0.02, + "Fósforo (mg)":216, + "Ferro (mg)":2.1, + "Sódio (mg)":83, + "Potássio (mg)":272, + "Cobre (mg)":0.06, + "Zinco (mg)":3.2 + }, + { + "Número do Alimento":530, + "Descrição dos alimentos":"Bolinho de arroz", + "Umidade (%)":41.5, + "Energia (Kcal)":274, + "Energia (KJ)":1144, + "Proteína (g)":8.0, + "Lipídeos (g)":8.3, + "Colesterol (mg)":70, + "Carboidrato (g)":41.7, + "Fibra Alimentar (g)":2.7, + "Cinzas (g)":0.5, + "Cálcio (mg)":24, + "Magnésio (mg)":13, + "Manganês (mg)":0.42, + "Fósforo (mg)":87, + "Ferro (mg)":2.1, + "Sódio (mg)":59, + "Potássio (mg)":96, + "Cobre (mg)":0.13, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":531, + "Descrição dos alimentos":"Camarão à baiana", + "Umidade (%)":82.0, + "Energia (Kcal)":101, + "Energia (KJ)":422, + "Proteína (g)":7.9, + "Lipídeos (g)":6.0, + "Colesterol (mg)":117, + "Carboidrato (g)":3.2, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":0.9, + "Cálcio (mg)":43, + "Magnésio (mg)":15, + "Manganês (mg)":0.11, + "Fósforo (mg)":244, + "Ferro (mg)":1.4, + "Sódio (mg)":85, + "Potássio (mg)":139, + "Cobre (mg)":0.07, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":532, + "Descrição dos alimentos":"Charuto, de repolho", + "Umidade (%)":81.5, + "Energia (Kcal)":78, + "Energia (KJ)":327, + "Proteína (g)":6.8, + "Lipídeos (g)":1.1, + "Colesterol (mg)":21, + "Carboidrato (g)":10.1, + "Fibra Alimentar (g)":1.5, + "Cinzas (g)":0.4, + "Cálcio (mg)":23, + "Magnésio (mg)":13, + "Manganês (mg)":0.22, + "Fósforo (mg)":68, + "Ferro (mg)":0.9, + "Sódio (mg)":12, + "Potássio (mg)":184, + "Cobre (mg)":1.45, + "Zinco (mg)":1.8 + }, + { + "Número do Alimento":533, + "Descrição dos alimentos":"Cuscuz, de milho, cozido com sal", + "Umidade (%)":71.1, + "Energia (Kcal)":113, + "Energia (KJ)":475, + "Proteína (g)":2.2, + "Lipídeos (g)":0.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":25.3, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":0.7, + "Cálcio (mg)":2, + "Magnésio (mg)":3, + "Manganês (mg)":0.02, + "Fósforo (mg)":23, + "Ferro (mg)":0.2, + "Sódio (mg)":248, + "Potássio (mg)":11, + "Cobre (mg)":"Tr", + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":534, + "Descrição dos alimentos":"Cuscuz, paulista", + "Umidade (%)":68.9, + "Energia (Kcal)":142, + "Energia (KJ)":595, + "Proteína (g)":2.6, + "Lipídeos (g)":4.6, + "Colesterol (mg)":15, + "Carboidrato (g)":22.5, + "Fibra Alimentar (g)":2.4, + "Cinzas (g)":1.3, + "Cálcio (mg)":14, + "Magnésio (mg)":5, + "Manganês (mg)":0.06, + "Fósforo (mg)":26, + "Ferro (mg)":0.3, + "Sódio (mg)":236, + "Potássio (mg)":53, + "Cobre (mg)":0.05, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":535, + "Descrição dos alimentos":"Cuxá, molho", + "Umidade (%)":81.0, + "Energia (Kcal)":80, + "Energia (KJ)":335, + "Proteína (g)":5.6, + "Lipídeos (g)":3.6, + "Colesterol (mg)":58, + "Carboidrato (g)":5.7, + "Fibra Alimentar (g)":3.0, + "Cinzas (g)":4.0, + "Cálcio (mg)":105, + "Magnésio (mg)":34, + "Manganês (mg)":0.23, + "Fósforo (mg)":111, + "Ferro (mg)":0.9, + "Sódio (mg)":1344, + "Potássio (mg)":124, + "Cobre (mg)":0.17, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":536, + "Descrição dos alimentos":"Dobradinha", + "Umidade (%)":75.3, + "Energia (Kcal)":125, + "Energia (KJ)":521, + "Proteína (g)":19.8, + "Lipídeos (g)":4.4, + "Colesterol (mg)":144, + "Carboidrato (g)":0.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":0.3, + "Cálcio (mg)":11, + "Magnésio (mg)":8, + "Manganês (mg)":0.11, + "Fósforo (mg)":57, + "Ferro (mg)":1.0, + "Sódio (mg)":29, + "Potássio (mg)":58, + "Cobre (mg)":0.06, + "Zinco (mg)":2.7 + }, + { + "Número do Alimento":537, + "Descrição dos alimentos":"Estrogonofe de carne", + "Umidade (%)":70.1, + "Energia (Kcal)":173, + "Energia (KJ)":724, + "Proteína (g)":15.0, + "Lipídeos (g)":10.8, + "Colesterol (mg)":66, + "Carboidrato (g)":3.0, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":28, + "Magnésio (mg)":22, + "Manganês (mg)":0.03, + "Fósforo (mg)":186, + "Ferro (mg)":2.7, + "Sódio (mg)":123, + "Potássio (mg)":322, + "Cobre (mg)":0.14, + "Zinco (mg)":2.0 + }, + { + "Número do Alimento":538, + "Descrição dos alimentos":"Estrogonofe de frango", + "Umidade (%)":70.9, + "Energia (Kcal)":157, + "Energia (KJ)":656, + "Proteína (g)":17.6, + "Lipídeos (g)":8.0, + "Colesterol (mg)":80, + "Carboidrato (g)":2.6, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.0, + "Cálcio (mg)":26, + "Magnésio (mg)":25, + "Manganês (mg)":0.03, + "Fósforo (mg)":195, + "Ferro (mg)":1.5, + "Sódio (mg)":99, + "Potássio (mg)":307, + "Cobre (mg)":0.12, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":539, + "Descrição dos alimentos":"Feijão tropeiro mineiro", + "Umidade (%)":61.7, + "Energia (Kcal)":152, + "Energia (KJ)":634, + "Proteína (g)":10.2, + "Lipídeos (g)":6.8, + "Colesterol (mg)":68, + "Carboidrato (g)":19.6, + "Fibra Alimentar (g)":3.6, + "Cinzas (g)":1.8, + "Cálcio (mg)":41, + "Magnésio (mg)":36, + "Manganês (mg)":0.38, + "Fósforo (mg)":199, + "Ferro (mg)":2.2, + "Sódio (mg)":365, + "Potássio (mg)":349, + "Cobre (mg)":0.22, + "Zinco (mg)":1.4 + }, + { + "Número do Alimento":540, + "Descrição dos alimentos":"L", + "Umidade (%)":71.8, + "Energia (Kcal)":117, + "Energia (KJ)":489, + "Proteína (g)":8.7, + "Lipídeos (g)":6.5, + "Colesterol (mg)":22, + "Carboidrato (g)":11.6, + "Fibra Alimentar (g)":5.1, + "Cinzas (g)":1.4, + "Cálcio (mg)":32, + "Magnésio (mg)":32, + "Manganês (mg)":0.24, + "Fósforo (mg)":105, + "Ferro (mg)":1.3, + "Sódio (mg)":278, + "Potássio (mg)":303, + "Cobre (mg)":0.15, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":541, + "Descrição dos alimentos":"Frango, com açafrão", + "Umidade (%)":79.5, + "Energia (Kcal)":113, + "Energia (KJ)":472, + "Proteína (g)":9.7, + "Lipídeos (g)":6.2, + "Colesterol (mg)":50, + "Carboidrato (g)":4.1, + "Fibra Alimentar (g)":0.2, + "Cinzas (g)":0.5, + "Cálcio (mg)":13, + "Magnésio (mg)":16, + "Manganês (mg)":0.09, + "Fósforo (mg)":167, + "Ferro (mg)":0.8, + "Sódio (mg)":29, + "Potássio (mg)":256, + "Cobre (mg)":0.02, + "Zinco (mg)":0.5 + }, + { + "Número do Alimento":542, + "Descrição dos alimentos":"Macarrão, molho bolognesa", + "Umidade (%)":71.4, + "Energia (Kcal)":120, + "Energia (KJ)":500, + "Proteína (g)":4.9, + "Lipídeos (g)":0.9, + "Colesterol (mg)":7, + "Carboidrato (g)":22.5, + "Fibra Alimentar (g)":0.8, + "Cinzas (g)":0.2, + "Cálcio (mg)":11, + "Magnésio (mg)":10, + "Manganês (mg)":0.22, + "Fósforo (mg)":54, + "Ferro (mg)":1.4, + "Sódio (mg)":9, + "Potássio (mg)":84, + "Cobre (mg)":0.09, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":543, + "Descrição dos alimentos":"Maniçoba", + "Umidade (%)":76.4, + "Energia (Kcal)":134, + "Energia (KJ)":562, + "Proteína (g)":10.0, + "Lipídeos (g)":8.7, + "Colesterol (mg)":43, + "Carboidrato (g)":3.4, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":1.5, + "Cálcio (mg)":66, + "Magnésio (mg)":24, + "Manganês (mg)":0.60, + "Fósforo (mg)":55, + "Ferro (mg)":3.2, + "Sódio (mg)":407, + "Potássio (mg)":148, + "Cobre (mg)":0.16, + "Zinco (mg)":2.0 + }, + { + "Número do Alimento":544, + "Descrição dos alimentos":"Quibebe", + "Umidade (%)":81.1, + "Energia (Kcal)":86, + "Energia (KJ)":361, + "Proteína (g)":8.6, + "Lipídeos (g)":2.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":6.6, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":1.0, + "Cálcio (mg)":8, + "Magnésio (mg)":10, + "Manganês (mg)":0.05, + "Fósforo (mg)":43, + "Ferro (mg)":0.8, + "Sódio (mg)":247, + "Potássio (mg)":153, + "Cobre (mg)":0.61, + "Zinco (mg)":1.6 + }, + { + "Número do Alimento":545, + "Descrição dos alimentos":"Salada, de legumes, com maionese", + "Umidade (%)":82.0, + "Energia (Kcal)":96, + "Energia (KJ)":402, + "Proteína (g)":1.1, + "Lipídeos (g)":7.0, + "Colesterol (mg)":7, + "Carboidrato (g)":8.9, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":0.9, + "Cálcio (mg)":12, + "Magnésio (mg)":9, + "Manganês (mg)":0.10, + "Fósforo (mg)":22, + "Ferro (mg)":0.2, + "Sódio (mg)":228, + "Potássio (mg)":141, + "Cobre (mg)":0.04, + "Zinco (mg)":0.2 + }, + { + "Número do Alimento":546, + "Descrição dos alimentos":"Salada, de legumes, cozida no vapor", + "Umidade (%)":90.0, + "Energia (Kcal)":35, + "Energia (KJ)":148, + "Proteína (g)":2.0, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":7.1, + "Fibra Alimentar (g)":2.5, + "Cinzas (g)":0.6, + "Cálcio (mg)":33, + "Magnésio (mg)":19, + "Manganês (mg)":0.24, + "Fósforo (mg)":45, + "Ferro (mg)":0.4, + "Sódio (mg)":3, + "Potássio (mg)":244, + "Cobre (mg)":0.17, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":547, + "Descrição dos alimentos":"Salpicão, de frango", + "Umidade (%)":72.5, + "Energia (Kcal)":148, + "Energia (KJ)":619, + "Proteína (g)":13.9, + "Lipídeos (g)":7.8, + "Colesterol (mg)":53, + "Carboidrato (g)":4.6, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":1.1, + "Cálcio (mg)":9, + "Magnésio (mg)":13, + "Manganês (mg)":0.03, + "Fósforo (mg)":103, + "Ferro (mg)":0.3, + "Sódio (mg)":248, + "Potássio (mg)":149, + "Cobre (mg)":0.08, + "Zinco (mg)":0.4 + }, + { + "Número do Alimento":548, + "Descrição dos alimentos":"Sarapatel", + "Umidade (%)":75.0, + "Energia (Kcal)":123, + "Energia (KJ)":515, + "Proteína (g)":18.5, + "Lipídeos (g)":4.4, + "Colesterol (mg)":315, + "Carboidrato (g)":1.1, + "Fibra Alimentar (g)":0.0, + "Cinzas (g)":1.1, + "Cálcio (mg)":12, + "Magnésio (mg)":13, + "Manganês (mg)":0.10, + "Fósforo (mg)":164, + "Ferro (mg)":7.2, + "Sódio (mg)":216, + "Potássio (mg)":199, + "Cobre (mg)":1.48, + "Zinco (mg)":1.8 + }, + { + "Número do Alimento":549, + "Descrição dos alimentos":"Tabule", + "Umidade (%)":85.8, + "Energia (Kcal)":57, + "Energia (KJ)":240, + "Proteína (g)":2.0, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.6, + "Fibra Alimentar (g)":2.1, + "Cinzas (g)":0.4, + "Cálcio (mg)":19, + "Magnésio (mg)":18, + "Manganês (mg)":0.37, + "Fósforo (mg)":35, + "Ferro (mg)":0.6, + "Sódio (mg)":1, + "Potássio (mg)":188, + "Cobre (mg)":0.12, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":550, + "Descrição dos alimentos":"Tacacá", + "Umidade (%)":85.2, + "Energia (Kcal)":47, + "Energia (KJ)":196, + "Proteína (g)":7.0, + "Lipídeos (g)":0.4, + "Colesterol (mg)":71, + "Carboidrato (g)":3.4, + "Fibra Alimentar (g)":0.2, + "Cinzas (g)":4.1, + "Cálcio (mg)":45, + "Magnésio (mg)":30, + "Manganês (mg)":0.12, + "Fósforo (mg)":89, + "Ferro (mg)":0.9, + "Sódio (mg)":1349, + "Potássio (mg)":240, + "Cobre (mg)":0.22, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":551, + "Descrição dos alimentos":"Tapioca, com manteiga", + "Umidade (%)":24.9, + "Energia (Kcal)":348, + "Energia (KJ)":1455, + "Proteína (g)":0.1, + "Lipídeos (g)":10.9, + "Colesterol (mg)":31, + "Carboidrato (g)":63.6, + "Fibra Alimentar (g)":"Tr", + "Cinzas (g)":0.5, + "Cálcio (mg)":30, + "Magnésio (mg)":3, + "Manganês (mg)":0.06, + "Fósforo (mg)":8, + "Ferro (mg)":0.2, + "Sódio (mg)":158, + "Potássio (mg)":19, + "Cobre (mg)":0.01, + "Zinco (mg)":0.0 + }, + { + "Número do Alimento":552, + "Descrição dos alimentos":"Tucupi, com pimenta-de-cheiro", + "Umidade (%)":91.9, + "Energia (Kcal)":27, + "Energia (KJ)":114, + "Proteína (g)":2.1, + "Lipídeos (g)":0.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.7, + "Fibra Alimentar (g)":0.2, + "Cinzas (g)":1.0, + "Cálcio (mg)":28, + "Magnésio (mg)":42, + "Manganês (mg)":0.52, + "Fósforo (mg)":31, + "Ferro (mg)":1.1, + "Sódio (mg)":5, + "Potássio (mg)":391, + "Cobre (mg)":0.12, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":553, + "Descrição dos alimentos":"Vaca atolada", + "Umidade (%)":75.0, + "Energia (Kcal)":145, + "Energia (KJ)":606, + "Proteína (g)":5.1, + "Lipídeos (g)":9.3, + "Colesterol (mg)":19, + "Carboidrato (g)":10.1, + "Fibra Alimentar (g)":2.3, + "Cinzas (g)":0.5, + "Cálcio (mg)":63, + "Magnésio (mg)":16, + "Manganês (mg)":0.04, + "Fósforo (mg)":72, + "Ferro (mg)":0.7, + "Sódio (mg)":26, + "Potássio (mg)":220, + "Cobre (mg)":0.12, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":554, + "Descrição dos alimentos":"Vatapá", + "Umidade (%)":58.4, + "Energia (Kcal)":255, + "Energia (KJ)":1066, + "Proteína (g)":6.0, + "Lipídeos (g)":23.2, + "Colesterol (mg)":44, + "Carboidrato (g)":9.7, + "Fibra Alimentar (g)":1.7, + "Cinzas (g)":2.7, + "Cálcio (mg)":47, + "Magnésio (mg)":39, + "Manganês (mg)":0.48, + "Fósforo (mg)":108, + "Ferro (mg)":1.4, + "Sódio (mg)":880, + "Potássio (mg)":209, + "Cobre (mg)":0.28, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":555, + "Descrição dos alimentos":"Virado à paulista", + "Umidade (%)":48.6, + "Energia (Kcal)":307, + "Energia (KJ)":1284, + "Proteína (g)":10.2, + "Lipídeos (g)":25.6, + "Colesterol (mg)":66, + "Carboidrato (g)":14.1, + "Fibra Alimentar (g)":2.2, + "Cinzas (g)":1.5, + "Cálcio (mg)":41, + "Magnésio (mg)":22, + "Manganês (mg)":0.15, + "Fósforo (mg)":135, + "Ferro (mg)":1.1, + "Sódio (mg)":346, + "Potássio (mg)":237, + "Cobre (mg)":0.07, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":556, + "Descrição dos alimentos":"Yakisoba", + "Umidade (%)":69.4, + "Energia (Kcal)":113, + "Energia (KJ)":472, + "Proteína (g)":7.5, + "Lipídeos (g)":2.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.3, + "Fibra Alimentar (g)":1.1, + "Cinzas (g)":2.2, + "Cálcio (mg)":14, + "Magnésio (mg)":13, + "Manganês (mg)":0.15, + "Fósforo (mg)":83, + "Ferro (mg)":0.6, + "Sódio (mg)":794, + "Potássio (mg)":159, + "Cobre (mg)":0.06, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":557, + "Descrição dos alimentos":"Amendoim, grão, cru", + "Umidade (%)":6.4, + "Energia (Kcal)":544, + "Energia (KJ)":2276, + "Proteína (g)":27.2, + "Lipídeos (g)":43.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":20.3, + "Fibra Alimentar (g)":8.0, + "Cinzas (g)":2.2, + "Cálcio (mg)":"Tr", + "Magnésio (mg)":171, + "Manganês (mg)":1.96, + "Fósforo (mg)":407, + "Ferro (mg)":2.5, + "Sódio (mg)":"Tr", + "Potássio (mg)":580, + "Cobre (mg)":0.78, + "Zinco (mg)":3.2 + }, + { + "Número do Alimento":558, + "Descrição dos alimentos":"Amendoim, torrado, salgado", + "Umidade (%)":1.7, + "Energia (Kcal)":606, + "Energia (KJ)":2535, + "Proteína (g)":22.5, + "Lipídeos (g)":54.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.7, + "Fibra Alimentar (g)":7.8, + "Cinzas (g)":3.2, + "Cálcio (mg)":39, + "Magnésio (mg)":159, + "Manganês (mg)":1.70, + "Fósforo (mg)":261, + "Ferro (mg)":1.3, + "Sódio (mg)":376, + "Potássio (mg)":496, + "Cobre (mg)":0.68, + "Zinco (mg)":2.1 + }, + { + "Número do Alimento":559, + "Descrição dos alimentos":"Ervilha, em vagem", + "Umidade (%)":76.8, + "Energia (Kcal)":88, + "Energia (KJ)":367, + "Proteína (g)":7.5, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.2, + "Fibra Alimentar (g)":9.7, + "Cinzas (g)":1.0, + "Cálcio (mg)":24, + "Magnésio (mg)":42, + "Manganês (mg)":0.40, + "Fósforo (mg)":152, + "Ferro (mg)":1.4, + "Sódio (mg)":"Tr", + "Potássio (mg)":311, + "Cobre (mg)":0.20, + "Zinco (mg)":1.2 + }, + { + "Número do Alimento":560, + "Descrição dos alimentos":"Ervilha, enlatada, drenada", + "Umidade (%)":80.1, + "Energia (Kcal)":74, + "Energia (KJ)":309, + "Proteína (g)":4.6, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.4, + "Fibra Alimentar (g)":5.1, + "Cinzas (g)":1.4, + "Cálcio (mg)":22, + "Magnésio (mg)":23, + "Manganês (mg)":0.46, + "Fósforo (mg)":79, + "Ferro (mg)":1.4, + "Sódio (mg)":372, + "Potássio (mg)":147, + "Cobre (mg)":0.14, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":561, + "Descrição dos alimentos":"Feijão, carioca, cozido", + "Umidade (%)":80.4, + "Energia (Kcal)":76, + "Energia (KJ)":320, + "Proteína (g)":4.8, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.6, + "Fibra Alimentar (g)":8.5, + "Cinzas (g)":0.7, + "Cálcio (mg)":27, + "Magnésio (mg)":42, + "Manganês (mg)":0.28, + "Fósforo (mg)":87, + "Ferro (mg)":1.3, + "Sódio (mg)":2, + "Potássio (mg)":255, + "Cobre (mg)":0.19, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":562, + "Descrição dos alimentos":"Feijão, carioca, cru", + "Umidade (%)":14.0, + "Energia (Kcal)":329, + "Energia (KJ)":1377, + "Proteína (g)":20.0, + "Lipídeos (g)":1.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":61.2, + "Fibra Alimentar (g)":18.4, + "Cinzas (g)":3.5, + "Cálcio (mg)":123, + "Magnésio (mg)":210, + "Manganês (mg)":1.02, + "Fósforo (mg)":385, + "Ferro (mg)":8.0, + "Sódio (mg)":"Tr", + "Potássio (mg)":1352, + "Cobre (mg)":0.79, + "Zinco (mg)":2.9 + }, + { + "Número do Alimento":563, + "Descrição dos alimentos":"Feijão, fradinho, cozido", + "Umidade (%)":80.0, + "Energia (Kcal)":78, + "Energia (KJ)":326, + "Proteína (g)":5.1, + "Lipídeos (g)":0.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":13.5, + "Fibra Alimentar (g)":7.5, + "Cinzas (g)":0.8, + "Cálcio (mg)":17, + "Magnésio (mg)":38, + "Manganês (mg)":0.53, + "Fósforo (mg)":85, + "Ferro (mg)":1.1, + "Sódio (mg)":1, + "Potássio (mg)":253, + "Cobre (mg)":0.10, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":564, + "Descrição dos alimentos":"Feijão, fradinho, cru", + "Umidade (%)":12.7, + "Energia (Kcal)":339, + "Energia (KJ)":1419, + "Proteína (g)":20.2, + "Lipídeos (g)":2.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":61.2, + "Fibra Alimentar (g)":23.6, + "Cinzas (g)":3.5, + "Cálcio (mg)":78, + "Magnésio (mg)":178, + "Manganês (mg)":1.43, + "Fósforo (mg)":355, + "Ferro (mg)":5.1, + "Sódio (mg)":10, + "Potássio (mg)":1083, + "Cobre (mg)":0.70, + "Zinco (mg)":3.9 + }, + { + "Número do Alimento":565, + "Descrição dos alimentos":"Feijão, jalo, cozido", + "Umidade (%)":75.8, + "Energia (Kcal)":93, + "Energia (KJ)":388, + "Proteína (g)":6.1, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":16.5, + "Fibra Alimentar (g)":13.9, + "Cinzas (g)":1.0, + "Cálcio (mg)":29, + "Magnésio (mg)":44, + "Manganês (mg)":0.32, + "Fósforo (mg)":121, + "Ferro (mg)":1.9, + "Sódio (mg)":1, + "Potássio (mg)":348, + "Cobre (mg)":0.24, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":566, + "Descrição dos alimentos":"Feijão, jalo, cru", + "Umidade (%)":13.5, + "Energia (Kcal)":328, + "Energia (KJ)":1372, + "Proteína (g)":20.1, + "Lipídeos (g)":0.9, + "Colesterol (mg)":0.0, + "Carboidrato (g)":61.5, + "Fibra Alimentar (g)":30.3, + "Cinzas (g)":3.9, + "Cálcio (mg)":98, + "Magnésio (mg)":170, + "Manganês (mg)":0.99, + "Fósforo (mg)":427, + "Ferro (mg)":7.0, + "Sódio (mg)":25, + "Potássio (mg)":1276, + "Cobre (mg)":0.95, + "Zinco (mg)":3.0 + }, + { + "Número do Alimento":567, + "Descrição dos alimentos":"Feijão, preto, cozido", + "Umidade (%)":80.2, + "Energia (Kcal)":77, + "Energia (KJ)":322, + "Proteína (g)":4.5, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":14.0, + "Fibra Alimentar (g)":8.4, + "Cinzas (g)":0.8, + "Cálcio (mg)":29, + "Magnésio (mg)":40, + "Manganês (mg)":0.37, + "Fósforo (mg)":88, + "Ferro (mg)":1.5, + "Sódio (mg)":2, + "Potássio (mg)":256, + "Cobre (mg)":0.20, + "Zinco (mg)":0.7 + }, + { + "Número do Alimento":568, + "Descrição dos alimentos":"Feijão, preto, cru", + "Umidade (%)":14.9, + "Energia (Kcal)":324, + "Energia (KJ)":1354, + "Proteína (g)":21.3, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":58.8, + "Fibra Alimentar (g)":21.8, + "Cinzas (g)":3.8, + "Cálcio (mg)":111, + "Magnésio (mg)":188, + "Manganês (mg)":1.32, + "Fósforo (mg)":471, + "Ferro (mg)":6.5, + "Sódio (mg)":"Tr", + "Potássio (mg)":1416, + "Cobre (mg)":0.83, + "Zinco (mg)":2.9 + }, + { + "Número do Alimento":569, + "Descrição dos alimentos":"Feijão, rajado, cozido", + "Umidade (%)":77.9, + "Energia (Kcal)":85, + "Energia (KJ)":354, + "Proteína (g)":5.5, + "Lipídeos (g)":0.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":15.3, + "Fibra Alimentar (g)":9.3, + "Cinzas (g)":0.9, + "Cálcio (mg)":29, + "Magnésio (mg)":42, + "Manganês (mg)":0.29, + "Fósforo (mg)":113, + "Ferro (mg)":1.4, + "Sódio (mg)":1, + "Potássio (mg)":315, + "Cobre (mg)":0.23, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":570, + "Descrição dos alimentos":"Feijão, rajado, cru", + "Umidade (%)":15.0, + "Energia (Kcal)":326, + "Energia (KJ)":1363, + "Proteína (g)":17.3, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":62.9, + "Fibra Alimentar (g)":24.0, + "Cinzas (g)":3.7, + "Cálcio (mg)":111, + "Magnésio (mg)":170, + "Manganês (mg)":1.17, + "Fósforo (mg)":335, + "Ferro (mg)":18.6, + "Sódio (mg)":14, + "Potássio (mg)":1135, + "Cobre (mg)":0.84, + "Zinco (mg)":2.6 + }, + { + "Número do Alimento":571, + "Descrição dos alimentos":"Feijão, rosinha, cozido", + "Umidade (%)":82.6, + "Energia (Kcal)":68, + "Energia (KJ)":284, + "Proteína (g)":4.5, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":11.8, + "Fibra Alimentar (g)":4.8, + "Cinzas (g)":0.6, + "Cálcio (mg)":19, + "Magnésio (mg)":43, + "Manganês (mg)":0.46, + "Fósforo (mg)":90, + "Ferro (mg)":1.2, + "Sódio (mg)":2, + "Potássio (mg)":241, + "Cobre (mg)":0.09, + "Zinco (mg)":1.3 + }, + { + "Número do Alimento":572, + "Descrição dos alimentos":"Feijão, rosinha, cru", + "Umidade (%)":12.0, + "Energia (Kcal)":337, + "Energia (KJ)":1410, + "Proteína (g)":20.9, + "Lipídeos (g)":1.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":62.2, + "Fibra Alimentar (g)":20.6, + "Cinzas (g)":3.6, + "Cálcio (mg)":68, + "Magnésio (mg)":184, + "Manganês (mg)":1.08, + "Fósforo (mg)":394, + "Ferro (mg)":5.3, + "Sódio (mg)":24, + "Potássio (mg)":1109, + "Cobre (mg)":0.60, + "Zinco (mg)":4.0 + }, + { + "Número do Alimento":573, + "Descrição dos alimentos":"Feijão, roxo, cozido", + "Umidade (%)":80.0, + "Energia (Kcal)":77, + "Energia (KJ)":322, + "Proteína (g)":5.7, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.9, + "Fibra Alimentar (g)":11.5, + "Cinzas (g)":0.8, + "Cálcio (mg)":23, + "Magnésio (mg)":34, + "Manganês (mg)":0.32, + "Fósforo (mg)":106, + "Ferro (mg)":1.4, + "Sódio (mg)":1, + "Potássio (mg)":268, + "Cobre (mg)":0.22, + "Zinco (mg)":1.0 + }, + { + "Número do Alimento":574, + "Descrição dos alimentos":"Feijão, roxo, cru", + "Umidade (%)":12.6, + "Energia (Kcal)":331, + "Energia (KJ)":1387, + "Proteína (g)":22.2, + "Lipídeos (g)":1.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":60.0, + "Fibra Alimentar (g)":33.8, + "Cinzas (g)":4.0, + "Cálcio (mg)":120, + "Magnésio (mg)":162, + "Manganês (mg)":1.34, + "Fósforo (mg)":394, + "Ferro (mg)":6.9, + "Sódio (mg)":10, + "Potássio (mg)":1221, + "Cobre (mg)":1.04, + "Zinco (mg)":3.3 + }, + { + "Número do Alimento":575, + "Descrição dos alimentos":"Grão-de-bico, cru", + "Umidade (%)":12.3, + "Energia (Kcal)":355, + "Energia (KJ)":1484, + "Proteína (g)":21.2, + "Lipídeos (g)":5.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":57.9, + "Fibra Alimentar (g)":12.4, + "Cinzas (g)":3.2, + "Cálcio (mg)":114, + "Magnésio (mg)":146, + "Manganês (mg)":3.16, + "Fósforo (mg)":342, + "Ferro (mg)":5.4, + "Sódio (mg)":5, + "Potássio (mg)":1116, + "Cobre (mg)":0.67, + "Zinco (mg)":3.2 + }, + { + "Número do Alimento":576, + "Descrição dos alimentos":"Guandu, cru", + "Umidade (%)":11.4, + "Energia (Kcal)":344, + "Energia (KJ)":1440, + "Proteína (g)":19.0, + "Lipídeos (g)":2.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":64.0, + "Fibra Alimentar (g)":21.3, + "Cinzas (g)":3.5, + "Cálcio (mg)":129, + "Magnésio (mg)":166, + "Manganês (mg)":1.02, + "Fósforo (mg)":269, + "Ferro (mg)":1.9, + "Sódio (mg)":2, + "Potássio (mg)":1215, + "Cobre (mg)":0.57, + "Zinco (mg)":2.0 + }, + { + "Número do Alimento":577, + "Descrição dos alimentos":"Lentilha, cozida", + "Umidade (%)":76.3, + "Energia (Kcal)":93, + "Energia (KJ)":388, + "Proteína (g)":6.3, + "Lipídeos (g)":0.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":16.3, + "Fibra Alimentar (g)":7.9, + "Cinzas (g)":0.6, + "Cálcio (mg)":16, + "Magnésio (mg)":22, + "Manganês (mg)":0.29, + "Fósforo (mg)":104, + "Ferro (mg)":1.5, + "Sódio (mg)":1, + "Potássio (mg)":220, + "Cobre (mg)":0.17, + "Zinco (mg)":1.1 + }, + { + "Número do Alimento":578, + "Descrição dos alimentos":"Lentilha, crua", + "Umidade (%)":11.5, + "Energia (Kcal)":339, + "Energia (KJ)":1419, + "Proteína (g)":23.2, + "Lipídeos (g)":0.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":62.0, + "Fibra Alimentar (g)":16.9, + "Cinzas (g)":2.6, + "Cálcio (mg)":54, + "Magnésio (mg)":94, + "Manganês (mg)":1.08, + "Fósforo (mg)":368, + "Ferro (mg)":7.0, + "Sódio (mg)":"Tr", + "Potássio (mg)":887, + "Cobre (mg)":0.83, + "Zinco (mg)":3.5 + }, + { + "Número do Alimento":579, + "Descrição dos alimentos":"Paçoca, amendoim", + "Umidade (%)":1.8, + "Energia (Kcal)":487, + "Energia (KJ)":2037, + "Proteína (g)":16.0, + "Lipídeos (g)":26.1, + "Colesterol (mg)":0.0, + "Carboidrato (g)":52.4, + "Fibra Alimentar (g)":7.3, + "Cinzas (g)":3.8, + "Cálcio (mg)":22, + "Magnésio (mg)":101, + "Manganês (mg)":1.06, + "Fósforo (mg)":198, + "Ferro (mg)":1.1, + "Sódio (mg)":167, + "Potássio (mg)":348, + "Cobre (mg)":0.38, + "Zinco (mg)":1.6 + }, + { + "Número do Alimento":580, + "Descrição dos alimentos":"Pé-de-moleque, amendoim", + "Umidade (%)":2.9, + "Energia (Kcal)":503, + "Energia (KJ)":2105, + "Proteína (g)":13.2, + "Lipídeos (g)":28.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":54.7, + "Fibra Alimentar (g)":3.4, + "Cinzas (g)":1.1, + "Cálcio (mg)":27, + "Magnésio (mg)":108, + "Manganês (mg)":1.09, + "Fósforo (mg)":171, + "Ferro (mg)":1.3, + "Sódio (mg)":16, + "Potássio (mg)":355, + "Cobre (mg)":0.43, + "Zinco (mg)":1.4 + }, + { + "Número do Alimento":581, + "Descrição dos alimentos":"Soja, farinha", + "Umidade (%)":5.8, + "Energia (Kcal)":404, + "Energia (KJ)":1690, + "Proteína (g)":36.0, + "Lipídeos (g)":14.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":38.4, + "Fibra Alimentar (g)":20.2, + "Cinzas (g)":5.1, + "Cálcio (mg)":206, + "Magnésio (mg)":242, + "Manganês (mg)":2.87, + "Fósforo (mg)":539, + "Ferro (mg)":13.1, + "Sódio (mg)":6, + "Potássio (mg)":1922, + "Cobre (mg)":1.29, + "Zinco (mg)":4.5 + }, + { + "Número do Alimento":582, + "Descrição dos alimentos":"Soja, extrato solúvel, natural, fluido", + "Umidade (%)":91.3, + "Energia (Kcal)":39, + "Energia (KJ)":164, + "Proteína (g)":2.4, + "Lipídeos (g)":1.6, + "Colesterol (mg)":0.0, + "Carboidrato (g)":4.3, + "Fibra Alimentar (g)":0.4, + "Cinzas (g)":0.5, + "Cálcio (mg)":17, + "Magnésio (mg)":15, + "Manganês (mg)":0.15, + "Fósforo (mg)":53, + "Ferro (mg)":0.4, + "Sódio (mg)":57, + "Potássio (mg)":121, + "Cobre (mg)":0.08, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":583, + "Descrição dos alimentos":"Soja, extrato solúvel, pó", + "Umidade (%)":4.5, + "Energia (Kcal)":459, + "Energia (KJ)":1920, + "Proteína (g)":35.7, + "Lipídeos (g)":26.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":28.5, + "Fibra Alimentar (g)":7.3, + "Cinzas (g)":5.2, + "Cálcio (mg)":359, + "Magnésio (mg)":216, + "Manganês (mg)":2.68, + "Fósforo (mg)":647, + "Ferro (mg)":7.0, + "Sódio (mg)":83, + "Potássio (mg)":1607, + "Cobre (mg)":1.19, + "Zinco (mg)":5.8 + }, + { + "Número do Alimento":584, + "Descrição dos alimentos":"Soja, queijo (tofu)", + "Umidade (%)":86.6, + "Energia (Kcal)":64, + "Energia (KJ)":270, + "Proteína (g)":6.6, + "Lipídeos (g)":4.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":2.1, + "Fibra Alimentar (g)":0.8, + "Cinzas (g)":0.7, + "Cálcio (mg)":81, + "Magnésio (mg)":38, + "Manganês (mg)":0.33, + "Fósforo (mg)":130, + "Ferro (mg)":1.4, + "Sódio (mg)":1, + "Potássio (mg)":182, + "Cobre (mg)":0.18, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":585, + "Descrição dos alimentos":"Tremoço, cru", + "Umidade (%)":9.7, + "Energia (Kcal)":381, + "Energia (KJ)":1595, + "Proteína (g)":33.6, + "Lipídeos (g)":10.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":43.8, + "Fibra Alimentar (g)":32.3, + "Cinzas (g)":2.6, + "Cálcio (mg)":177, + "Magnésio (mg)":121, + "Manganês (mg)":"*", + "Fósforo (mg)":265, + "Ferro (mg)":2.8, + "Sódio (mg)":3, + "Potássio (mg)":708, + "Cobre (mg)":0.79, + "Zinco (mg)":4.2 + }, + { + "Número do Alimento":586, + "Descrição dos alimentos":"Tremoço, em conserva", + "Umidade (%)":67.7, + "Energia (Kcal)":121, + "Energia (KJ)":505, + "Proteína (g)":11.1, + "Lipídeos (g)":3.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":12.4, + "Fibra Alimentar (g)":14.4, + "Cinzas (g)":5.0, + "Cálcio (mg)":16, + "Magnésio (mg)":4, + "Manganês (mg)":"*", + "Fósforo (mg)":40, + "Ferro (mg)":0.3, + "Sódio (mg)":1809, + "Potássio (mg)":5, + "Cobre (mg)":0.27, + "Zinco (mg)":0.6 + }, + { + "Número do Alimento":587, + "Descrição dos alimentos":"Amêndoa, torrada, salgada", + "Umidade (%)":3.1, + "Energia (Kcal)":581, + "Energia (KJ)":2430, + "Proteína (g)":18.6, + "Lipídeos (g)":47.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":29.5, + "Fibra Alimentar (g)":11.6, + "Cinzas (g)":1.5, + "Cálcio (mg)":237, + "Magnésio (mg)":222, + "Manganês (mg)":1.95, + "Fósforo (mg)":493, + "Ferro (mg)":3.1, + "Sódio (mg)":279, + "Potássio (mg)":640, + "Cobre (mg)":0.93, + "Zinco (mg)":2.6 + }, + { + "Número do Alimento":588, + "Descrição dos alimentos":"Castanha-de-caju, torrada, salgada", + "Umidade (%)":3.5, + "Energia (Kcal)":570, + "Energia (KJ)":2386, + "Proteína (g)":18.5, + "Lipídeos (g)":46.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":29.1, + "Fibra Alimentar (g)":3.7, + "Cinzas (g)":2.6, + "Cálcio (mg)":33, + "Magnésio (mg)":237, + "Manganês (mg)":1.59, + "Fósforo (mg)":594, + "Ferro (mg)":5.2, + "Sódio (mg)":125, + "Potássio (mg)":671, + "Cobre (mg)":1.92, + "Zinco (mg)":4.7 + }, + { + "Número do Alimento":589, + "Descrição dos alimentos":"Castanha-do-Brasil, crua", + "Umidade (%)":3.5, + "Energia (Kcal)":643, + "Energia (KJ)":2690, + "Proteína (g)":14.5, + "Lipídeos (g)":63.5, + "Colesterol (mg)":0.0, + "Carboidrato (g)":15.1, + "Fibra Alimentar (g)":7.9, + "Cinzas (g)":3.4, + "Cálcio (mg)":146, + "Magnésio (mg)":365, + "Manganês (mg)":1.10, + "Fósforo (mg)":853, + "Ferro (mg)":2.3, + "Sódio (mg)":1, + "Potássio (mg)":651, + "Cobre (mg)":1.79, + "Zinco (mg)":4.2 + }, + { + "Número do Alimento":590, + "Descrição dos alimentos":"Coco, cru", + "Umidade (%)":43.0, + "Energia (Kcal)":406, + "Energia (KJ)":1701, + "Proteína (g)":3.7, + "Lipídeos (g)":42.0, + "Colesterol (mg)":0.0, + "Carboidrato (g)":10.4, + "Fibra Alimentar (g)":5.4, + "Cinzas (g)":1.0, + "Cálcio (mg)":6, + "Magnésio (mg)":51, + "Manganês (mg)":1.00, + "Fósforo (mg)":118, + "Ferro (mg)":1.8, + "Sódio (mg)":15, + "Potássio (mg)":354, + "Cobre (mg)":0.45, + "Zinco (mg)":0.9 + }, + { + "Número do Alimento":591, + "Descrição dos alimentos":"Coco, verde, cru", + "Umidade (%)":"*", + "Energia (Kcal)":"*", + "Energia (KJ)":"*", + "Proteína (g)":"*", + "Lipídeos (g)":"*", + "Colesterol (mg)":"*", + "Carboidrato (g)":"*", + "Fibra Alimentar (g)":"*", + "Cinzas (g)":"*", + "Cálcio (mg)":"*", + "Magnésio (mg)":"*", + "Manganês (mg)":"*", + "Fósforo (mg)":"*", + "Ferro (mg)":"*", + "Sódio (mg)":"*", + "Potássio (mg)":"*", + "Cobre (mg)":"*", + "Zinco (mg)":"*" + }, + { + "Número do Alimento":592, + "Descrição dos alimentos":"Farinha, de mesocarpo de babaçu, crua", + "Umidade (%)":15.8, + "Energia (Kcal)":329, + "Energia (KJ)":1376, + "Proteína (g)":1.4, + "Lipídeos (g)":0.2, + "Colesterol (mg)":0.0, + "Carboidrato (g)":79.2, + "Fibra Alimentar (g)":17.9, + "Cinzas (g)":3.4, + "Cálcio (mg)":61, + "Magnésio (mg)":39, + "Manganês (mg)":0.38, + "Fósforo (mg)":26, + "Ferro (mg)":18.3, + "Sódio (mg)":12, + "Potássio (mg)":362, + "Cobre (mg)":0.22, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":593, + "Descrição dos alimentos":"Gergelim, semente", + "Umidade (%)":3.9, + "Energia (Kcal)":584, + "Energia (KJ)":2442, + "Proteína (g)":21.2, + "Lipídeos (g)":50.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":21.6, + "Fibra Alimentar (g)":11.9, + "Cinzas (g)":2.9, + "Cálcio (mg)":825, + "Magnésio (mg)":361, + "Manganês (mg)":2.67, + "Fósforo (mg)":741, + "Ferro (mg)":5.4, + "Sódio (mg)":3, + "Potássio (mg)":546, + "Cobre (mg)":1.51, + "Zinco (mg)":5.2 + }, + { + "Número do Alimento":594, + "Descrição dos alimentos":"Linhaça, semente", + "Umidade (%)":6.7, + "Energia (Kcal)":495, + "Energia (KJ)":2072, + "Proteína (g)":14.1, + "Lipídeos (g)":32.3, + "Colesterol (mg)":0.0, + "Carboidrato (g)":43.3, + "Fibra Alimentar (g)":33.5, + "Cinzas (g)":3.7, + "Cálcio (mg)":211, + "Magnésio (mg)":347, + "Manganês (mg)":2.81, + "Fósforo (mg)":615, + "Ferro (mg)":4.7, + "Sódio (mg)":9, + "Potássio (mg)":869, + "Cobre (mg)":1.09, + "Zinco (mg)":4.4 + }, + { + "Número do Alimento":595, + "Descrição dos alimentos":"Pinhão, cozido", + "Umidade (%)":50.5, + "Energia (Kcal)":174, + "Energia (KJ)":730, + "Proteína (g)":3.0, + "Lipídeos (g)":0.7, + "Colesterol (mg)":0.0, + "Carboidrato (g)":43.9, + "Fibra Alimentar (g)":15.6, + "Cinzas (g)":1.8, + "Cálcio (mg)":16, + "Magnésio (mg)":53, + "Manganês (mg)":0.41, + "Fósforo (mg)":166, + "Ferro (mg)":0.8, + "Sódio (mg)":1, + "Potássio (mg)":727, + "Cobre (mg)":0.18, + "Zinco (mg)":0.8 + }, + { + "Número do Alimento":596, + "Descrição dos alimentos":"Pupunha, cozida", + "Umidade (%)":54.5, + "Energia (Kcal)":219, + "Energia (KJ)":914, + "Proteína (g)":2.5, + "Lipídeos (g)":12.8, + "Colesterol (mg)":0.0, + "Carboidrato (g)":29.6, + "Fibra Alimentar (g)":4.3, + "Cinzas (g)":0.7, + "Cálcio (mg)":28, + "Magnésio (mg)":25, + "Manganês (mg)":0.13, + "Fósforo (mg)":49, + "Ferro (mg)":0.5, + "Sódio (mg)":1, + "Potássio (mg)":303, + "Cobre (mg)":0.28, + "Zinco (mg)":0.3 + }, + { + "Número do Alimento":597, + "Descrição dos alimentos":"Noz, crua", + "Umidade (%)":6.2, + "Energia (Kcal)":620, + "Energia (KJ)":2594, + "Proteína (g)":14.0, + "Lipídeos (g)":59.4, + "Colesterol (mg)":0.0, + "Carboidrato (g)":18.4, + "Fibra Alimentar (g)":7.2, + "Cinzas (g)":2.1, + "Cálcio (mg)":105, + "Magnésio (mg)":153, + "Manganês (mg)":4.05, + "Fósforo (mg)":396, + "Ferro (mg)":2.0, + "Sódio (mg)":5, + "Potássio (mg)":533, + "Cobre (mg)":0.75, + "Zinco (mg)":2.1 + } +] \ No newline at end of file From bc56892c5dad22ab2fce0570b8d422b25b99d962 Mon Sep 17 00:00:00 2001 From: Iury Filho Date: Tue, 21 Jan 2025 03:49:02 -0300 Subject: [PATCH 47/47] atualizando workflows --- .github/workflows/api.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml index 3118ceb..84e4707 100644 --- a/.github/workflows/api.yml +++ b/.github/workflows/api.yml @@ -1,7 +1,7 @@ # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs -name: DEV - Start & Test (API) +name: Start & Test (API) on: push: @@ -24,17 +24,17 @@ jobs: - name: Create .env file working-directory: backend run: | - echo "TYPE=${{ secrets.TYPE }}" > .env + echo "TYPE=${{ vars.TYPE }}" > .env echo "PROJECT_ID=${{ secrets.PROJECT_ID }}" >> .env echo "PRIVATE_KEY_ID=${{ secrets.PRIVATE_KEY_ID }}" >> .env echo 'PRIVATE_KEY="${{ secrets.PRIVATE_KEY }}"' >> .env echo "CLIENT_EMAIL=${{ secrets.CLIENT_EMAIL }}" >> .env echo "CLIENT_ID=${{ secrets.CLIENT_ID }}" >> .env - echo "AUTH_URI=${{ secrets.AUTH_URI }}" >> .env - echo "TOKEN_URI=${{ secrets.TOKEN_URI }}" >> .env - echo "AUTH_PROVIDER_X509_CERT_URL=${{ secrets.AUTH_PROVIDER_X509_CERT_URL }}" >> .env + echo "AUTH_URI=${{ vars.AUTH_URI }}" >> .env + echo "TOKEN_URI=${{ vars.TOKEN_URI }}" >> .env + echo "AUTH_PROVIDER_X509_CERT_URL=${{ vars.AUTH_PROVIDER_X509_CERT_URL }}" >> .env echo "CLIENT_X509_CERT_URL=${{ secrets.CLIENT_X509_CERT_URL }}" >> .env - echo "UNIVERSE_DOMAIN=${{ secrets.UNIVERSE_DOMAIN }}" >> .env + echo "UNIVERSE_DOMAIN=${{ vars.UNIVERSE_DOMAIN }}" >> .env - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: