Merge pull request 'welcome' (#2) from welcome into main

Reviewed-on: #2
feature/chart-progress-page
Bogdan Kotikov 2023-05-31 23:27:40 +02:00
commit b0ca2ada88
60 changed files with 1713 additions and 427 deletions

View File

@ -1,8 +0,0 @@
// Flutter web plugin registrant file.
//
// Generated file. Do not edit.
//
// ignore_for_file: type=lint
void registerPlugins() {}

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
{"inputs":["/Users/bogdan/IdeaProjects/ernaehrung/.dart_tool/flutter_build/c27655c010e9dca425e442f7862f55d5/app.dill","/usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart","/usr/local/Caskroom/flutter/3.7.7/flutter/bin/internal/engine.version","/usr/local/Caskroom/flutter/3.7.7/flutter/bin/internal/engine.version","/usr/local/Caskroom/flutter/3.7.7/flutter/bin/internal/engine.version","/usr/local/Caskroom/flutter/3.7.7/flutter/bin/internal/engine.version","/Users/bogdan/IdeaProjects/ernaehrung/pubspec.yaml","/Users/bogdan/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.5/assets/CupertinoIcons.ttf","/usr/local/Caskroom/flutter/3.7.7/flutter/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf","/usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/lib/src/material/shaders/ink_sparkle.frag","/Users/bogdan/.pub-cache/hosted/pub.dev/async-2.10.0/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/boolean_selector-2.1.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/characters-1.2.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/clock-1.1.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/collection-1.17.0/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.5/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/fake_async-1.3.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/js-0.6.5/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/lints-2.0.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/matcher-0.12.13/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/meta-1.8.0/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/path-1.8.2/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/source_span-1.9.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/string_scanner-1.2.0/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/test_api-0.4.16/LICENSE","/Users/bogdan/.pub-cache/hosted/pub.dev/vector_math-2.1.4/LICENSE","/usr/local/Caskroom/flutter/3.7.7/flutter/bin/cache/pkg/sky_engine/LICENSE","/usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/LICENSE"],"outputs":["/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/vm_snapshot_data","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/isolate_snapshot_data","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/kernel_blob.bin","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/fonts/MaterialIcons-Regular.otf","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/shaders/ink_sparkle.frag","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/AssetManifest.json","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/FontManifest.json","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/NOTICES.Z"]}

View File

@ -1 +0,0 @@
/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf /Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/fonts/MaterialIcons-Regular.otf /Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/shaders/ink_sparkle.frag /Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/AssetManifest.json /Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/FontManifest.json /Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/NOTICES.Z: /Users/bogdan/IdeaProjects/ernaehrung/pubspec.yaml /Users/bogdan/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.5/assets/CupertinoIcons.ttf /usr/local/Caskroom/flutter/3.7.7/flutter/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf /usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/lib/src/material/shaders/ink_sparkle.frag /Users/bogdan/.pub-cache/hosted/pub.dev/async-2.10.0/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/boolean_selector-2.1.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/characters-1.2.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/clock-1.1.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/collection-1.17.0/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.5/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/fake_async-1.3.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/js-0.6.5/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/lints-2.0.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/matcher-0.12.13/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/meta-1.8.0/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/path-1.8.2/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/source_span-1.9.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/string_scanner-1.2.0/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/test_api-0.4.16/LICENSE /Users/bogdan/.pub-cache/hosted/pub.dev/vector_math-2.1.4/LICENSE /usr/local/Caskroom/flutter/3.7.7/flutter/bin/cache/pkg/sky_engine/LICENSE /usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/LICENSE

View File

@ -1 +0,0 @@
{"inputs":["/Users/bogdan/IdeaProjects/ernaehrung/.dart_tool/package_config_subset"],"outputs":[]}

View File

@ -1 +0,0 @@
{"inputs":[],"outputs":[]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
["/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/vm_snapshot_data","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/isolate_snapshot_data","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/kernel_blob.bin","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/fonts/MaterialIcons-Regular.otf","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/shaders/ink_sparkle.frag","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/AssetManifest.json","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/FontManifest.json","/Users/bogdan/IdeaProjects/ernaehrung/build/app/intermediates/flutter/debug/flutter_assets/NOTICES.Z"]

View File

@ -37,6 +37,12 @@
"packageUri": "lib/",
"languageVersion": "2.18"
},
{
"name": "basic_utils",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/basic_utils-5.5.4",
"packageUri": "lib/",
"languageVersion": "2.18"
},
{
"name": "boolean_selector",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/boolean_selector-2.1.1",
@ -157,6 +163,12 @@
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "equatable",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/equatable-2.0.5",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "fake_async",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/fake_async-1.3.1",
@ -181,6 +193,12 @@
"packageUri": "lib/",
"languageVersion": "2.19"
},
{
"name": "fl_chart",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/fl_chart-0.62.0",
"packageUri": "lib/",
"languageVersion": "2.17"
},
{
"name": "flutter",
"rootUri": "file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter",
@ -193,18 +211,36 @@
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "flutter_form_builder",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_form_builder-8.0.0",
"packageUri": "lib/",
"languageVersion": "2.19"
},
{
"name": "flutter_lints",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1",
"packageUri": "lib/",
"languageVersion": "2.17"
},
{
"name": "flutter_localizations",
"rootUri": "file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_localizations",
"packageUri": "lib/",
"languageVersion": "2.17"
},
{
"name": "flutter_test",
"rootUri": "file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_test",
"packageUri": "lib/",
"languageVersion": "2.17"
},
{
"name": "form_builder_validators",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/form_builder_validators-8.6.1",
"packageUri": "lib/",
"languageVersion": "2.19"
},
{
"name": "frontend_server_client",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/frontend_server_client-3.2.0",
@ -241,6 +277,12 @@
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "http",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/http-0.13.6",
"packageUri": "lib/",
"languageVersion": "2.19"
},
{
"name": "http_multi_server",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/http_multi_server-3.2.1",
@ -253,6 +295,12 @@
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "intl",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/intl-0.17.0",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "io",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/io-1.0.4",
@ -379,6 +427,12 @@
"packageUri": "lib/",
"languageVersion": "2.17"
},
{
"name": "pointycastle",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/pointycastle-3.7.3",
"packageUri": "lib/",
"languageVersion": "2.14"
},
{
"name": "pool",
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/pool-1.5.1",
@ -554,7 +608,7 @@
"languageVersion": "2.19"
}
],
"generated": "2023-05-10T21:58:20.353562Z",
"generated": "2023-05-30T21:33:05.140346Z",
"generator": "pub",
"generatorVersion": "2.19.6"
}

View File

@ -22,6 +22,10 @@ async
2.18
file:///Users/bogdan/.pub-cache/hosted/pub.dev/async-2.10.0/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/async-2.10.0/lib/
basic_utils
2.18
file:///Users/bogdan/.pub-cache/hosted/pub.dev/basic_utils-5.5.4/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/basic_utils-5.5.4/lib/
boolean_selector
2.17
file:///Users/bogdan/.pub-cache/hosted/pub.dev/boolean_selector-2.1.1/
@ -102,6 +106,10 @@ empty_widget
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/empty_widget-0.0.5/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/empty_widget-0.0.5/lib/
equatable
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/equatable-2.0.5/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/equatable-2.0.5/lib/
fake_async
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/fake_async-1.3.1/
@ -118,14 +126,26 @@ fixnum
2.19
file:///Users/bogdan/.pub-cache/hosted/pub.dev/fixnum-1.1.0/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/fixnum-1.1.0/lib/
fl_chart
2.17
file:///Users/bogdan/.pub-cache/hosted/pub.dev/fl_chart-0.62.0/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/fl_chart-0.62.0/lib/
flutter_dotenv
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_dotenv-5.0.2/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_dotenv-5.0.2/lib/
flutter_form_builder
2.19
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_form_builder-8.0.0/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_form_builder-8.0.0/lib/
flutter_lints
2.17
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1/lib/
form_builder_validators
2.19
file:///Users/bogdan/.pub-cache/hosted/pub.dev/form_builder_validators-8.6.1/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/form_builder_validators-8.6.1/lib/
frontend_server_client
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/frontend_server_client-3.2.0/
@ -150,6 +170,10 @@ hive_generator
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/hive_generator-2.0.0/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/hive_generator-2.0.0/lib/
http
2.19
file:///Users/bogdan/.pub-cache/hosted/pub.dev/http-0.13.6/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/http-0.13.6/lib/
http_multi_server
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/http_multi_server-3.2.1/
@ -158,6 +182,10 @@ http_parser
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/http_parser-4.0.2/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/http_parser-4.0.2/lib/
intl
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/intl-0.17.0/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/intl-0.17.0/lib/
io
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/io-1.0.4/
@ -242,6 +270,10 @@ plugin_platform_interface
2.17
file:///Users/bogdan/.pub-cache/hosted/pub.dev/plugin_platform_interface-2.1.4/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/plugin_platform_interface-2.1.4/lib/
pointycastle
2.14
file:///Users/bogdan/.pub-cache/hosted/pub.dev/pointycastle-3.7.3/
file:///Users/bogdan/.pub-cache/hosted/pub.dev/pointycastle-3.7.3/lib/
pool
2.12
file:///Users/bogdan/.pub-cache/hosted/pub.dev/pool-1.5.1/
@ -362,6 +394,10 @@ flutter
2.17
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/lib/
flutter_localizations
2.17
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_localizations/
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_localizations/lib/
flutter_test
2.17
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_test/

View File

@ -1 +0,0 @@
3.7.9

3
.env
View File

@ -1,11 +1,10 @@
USER_BOX=USER
FIRST_NAME_FIELD=FIRST_NAME
SECOND_NAME_FIELD=SECOND_NAME
AGE_FIELD=AGE
WEIGHT_FIELD=WEIGHT
HEIGHT_FIELD=HEIGHT
CALORIES_FIELD=CALORIES
FIRST_NAME_FIELD=FIRST_NAME
FIRST_NAME_FIELD=FIRST_NAME
TODAY_BOX=TODAY
DATE_FIELD=DATE # datum
BREAKFAST_FIELD=FRÜHSTÜCK # frühstück

View File

@ -1,6 +0,0 @@
# This is a generated file; do not edit or check into version control.
path_provider=/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider-2.0.14/
path_provider_android=/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_android-2.0.27/
path_provider_foundation=/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.2/
path_provider_linux=/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.10/
path_provider_windows=/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_windows-2.1.6/

View File

@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.2/","native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_android-2.0.27/","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.2/","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.10/","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_windows-2.1.6/","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2023-05-12 23:04:16.870373","version":"3.7.9"}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.2/","native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_android-2.0.27/","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.2/","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.10/","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_windows-2.1.6/","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2023-05-31 22:57:37.224562","version":"3.7.9"}

5
.gitignore vendored
View File

@ -647,3 +647,8 @@ lib/generated_plugin_registrant.dart
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
# Windows
**/windows/flutter/generated_plugin_registrant.cc
**/windows/flutter/generated_plugin_registrant.h
**/windows/flutter/generated_plugins.cmake

View File

@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View File

@ -1,20 +1,25 @@
import 'package:ernaehrung/android/pages/nav_pages/main_page.dart';
import 'package:ernaehrung/android/views/navigation/navigation_screen.dart';
import 'package:ernaehrung/android/pages/welcome.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'models/user.dart';
class AndroidApp extends StatelessWidget {
const AndroidApp({super.key});
@override
Widget build(BuildContext context) {
final box = Hive.box<User>('USER_BOX');
print("got it ${box.get("USER")}");
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: Colors.grey.shade100, //<-- SEE
),
home: const MainPage(),
home: box.get("USER") == null ? const OnboardingPage() : const MainPage(),
routes: {
'/navigation': (context) => const NavigationScreen(),
'/navigation': (context) => const MainPage(),
},
);
}

View File

@ -0,0 +1,27 @@
import 'package:ernaehrung/android/components/food_list_component.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'meal_page_text/title_component.dart';
class MealPageStatisticsFoodComponent extends StatelessWidget {
const MealPageStatisticsFoodComponent({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
color: Colors.white
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 24,
),
const TitleComponent("Nahrung"),
FoodComponent(box: Hive.box('STATISTICS_REDUCED'),)
],
),
);
}
}

View File

@ -0,0 +1,83 @@
import 'package:ernaehrung/android/components/card/card_data_food_component.dart';
import 'package:ernaehrung/android/components/card/card_title_component.dart';
import 'package:flutter/material.dart';
import '../../models/food.dart';
import '../../pages/nav_pages/search_food.dart';
class CardComponent extends StatelessWidget {
final String title;
final List<dynamic> foods;
const CardComponent(this.title, this.foods, {super.key});
List<Food> castDynamicToListFood(List<dynamic> dynamicList) {
List<Food> foodList = [];
for (Food element in dynamicList) {
foodList.add(element);
}
return foodList;
}
Route createRoute(String cardName) {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) =>
SearchFoodPage(cardName),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
@override
Widget build(BuildContext context) {
return Container(
height: 300,
decoration: BoxDecoration(
color: const Color(0xFF6E7BFB),
borderRadius: const BorderRadius.all(Radius.circular(16)),
border: Border.all(
color: Colors.black,
),
),
margin: const EdgeInsets.fromLTRB(0, 16, 0, 16),
child: Column(
children: [
CardTitleComponent(
title, "${castDynamicToListFood(foods).length} Kalorien"),
CardDataFoodComponent(
castDynamicToListFood(foods)
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: Container(
margin: const EdgeInsets.fromLTRB(0, 8, 0, 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40), //
backgroundColor: const Color(0xFFffffff),
foregroundColor: const Color(0xFF6E7BFB),
shape: const StadiumBorder(),
),
onPressed: () async {
Navigator.of(context).push(createRoute(title));
},
child: Text('Text Of Button'),
),
),
)
],
));
}
}

View File

@ -0,0 +1,35 @@
import 'package:ernaehrung/android/components/card/card_food_item_component.dart';
import 'package:ernaehrung/android/models/food.dart';
import 'package:flutter/material.dart';
class CardDataFoodComponent extends StatelessWidget {
final List<Food> foods;
const CardDataFoodComponent(this.foods, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 180,
decoration: const BoxDecoration(
color: Colors.pink,
borderRadius: BorderRadius.all(Radius.circular(16))),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: foods.length,
itemBuilder: (context, i) {
return CardFoodItemComponent(foods[i]);
})
],
),
)),
);
}
}

View File

@ -0,0 +1,42 @@
import 'package:ernaehrung/android/models/food.dart';
import 'package:flutter/material.dart';
class CardFoodItemComponent extends StatelessWidget {
final Food food;
const CardFoodItemComponent(this.food, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.fromLTRB(0, 8, 0, 4),
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 6,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
food.name.toString(),
style: const TextStyle(color: Colors.white),
softWrap: true,
),
Text(
food.calories.toString(),
style: const TextStyle(color: Colors.white),
),
],
),
),
Expanded(
flex: 1, child: TextButton(onPressed: () {}, child: Text("+")))
],
),
);
}
}

View File

@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
class CardTitleComponent extends StatelessWidget {
final String title;
final String calories;
const CardTitleComponent(this.title, this.calories, {super.key});
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16))
),
child: Padding(
padding:
const EdgeInsets
.symmetric(
vertical: 16,
horizontal: 8
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text(title), Text(calories)],
),
),
);
}
}

View File

@ -1,15 +1,15 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import '../models/food.dart';
import '../pages/nav_pages/search_food.dart';
class CardComponent extends StatefulWidget {
final String eatingMealName;
final List<Food> selectedMeal;
final bool addButtonVisible;
const CardComponent(
{Key? key, required this.eatingMealName, required this.selectedMeal})
{Key? key, required this.eatingMealName, required this.selectedMeal, this.addButtonVisible = true})
: super(key: key);
@override
@ -38,11 +38,11 @@ class _CardComponentState extends State<CardComponent> {
}
getImageOfMeal() {
if (widget.eatingMealName == dotenv.env['BREAKFAST_FIELD']!) {
if (widget.eatingMealName.toLowerCase() == dotenv.env['BREAKFAST_FIELD']!.toLowerCase()) {
return const Image(image: AssetImage('assets/images/tea.png'));
} else if (widget.eatingMealName == dotenv.env['LUNCH_FIELD']!) {
} else if (widget.eatingMealName.toLowerCase() == dotenv.env['LUNCH_FIELD']!.toLowerCase()) {
return const Image(image: AssetImage('assets/images/fries.png'));
} else if (widget.eatingMealName == dotenv.env['DINNER_FIELD']!) {
} else if (widget.eatingMealName.toLowerCase() == dotenv.env['DINNER_FIELD']!.toLowerCase()) {
return const Image(image: AssetImage('assets/images/ice.png'));
}
}
@ -58,19 +58,24 @@ class _CardComponentState extends State<CardComponent> {
}
Widget getElevatedButton() {
return ElevatedButton(
onPressed: () async {
Navigator.of(context).push(createRoute(widget.eatingMealName));
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(8),
),
child: const Text(
'+',
style: TextStyle(fontSize: 28),
),
);
if(widget.addButtonVisible){
return ElevatedButton(
onPressed: () async {
Navigator.of(context).push(createRoute(widget.eatingMealName));
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(0),
),
child: const Text(
'+',
style: TextStyle(fontSize: 28),
),
);
}else{
return const SizedBox.shrink();
}
}
int getCountedCalories() {
@ -85,6 +90,24 @@ class _CardComponentState extends State<CardComponent> {
return calories.round();
}
Map<String,List<int>> getMapOfDistinctElementsWithCounterAndCalories(List<Food> foods){
Map<String,List<int>> resultMap = <String,List<int>>{};
for(int i = 0; i < foods.length;i++){
if(!resultMap.keys.contains(foods[i].name)){
resultMap.putIfAbsent(foods[i].name, () => [1,foods[i].calories]);
}else{
resultMap[foods[i].name]![0] = resultMap[foods[i].name]![0] + 1;
}
}
return resultMap;
}
String getFoodListStringByFood(String foodName, int count, int calories){
int maxWidth = 35;
String limitedText = foodName.length > maxWidth ? "${foodName.substring(0, maxWidth - 3)} ... $count x $calories kcal" : "$foodName $count x $calories kcal";
return limitedText;
}
@override
Widget build(BuildContext context) {
return Card(
@ -113,21 +136,6 @@ class _CardComponentState extends State<CardComponent> {
fontSize: 14),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.6,
child: Text(
widget.selectedMeal.isNotEmpty
? listFoodAsString()
: "Empfohlen: 123",
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: const TextStyle(
color: Colors.black26,
fontWeight: FontWeight.w500,
fontSize: 10),
),
),
],
)
],
@ -135,6 +143,22 @@ class _CardComponentState extends State<CardComponent> {
getElevatedButton(),
],
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.8,
child:ListView.builder(
primary: false,
shrinkWrap: true,
itemCount: getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal).keys.length,
itemBuilder: (context, i) {
Map<String,List<int>> map = getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal);
String foodName = map.keys.elementAt(i);
List<int> values = map.values.elementAt(i);
return Text(
getFoodListStringByFood(foodName, values[0], values[1])
);
}
),
),
widget.selectedMeal.isNotEmpty
? const Divider()
: const SizedBox.shrink(),

View File

@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
class CircularLoadingComponent extends StatelessWidget {
final int eatenCalories;
const CircularLoadingComponent(this.eatenCalories, {Key? key}) : super(key: key);
final int targetCaolries = 3500; // TODO get from user data
@override
Widget build(BuildContext context) {
double progress = double.parse((eatenCalories/targetCaolries).toStringAsFixed(1));
return CircularPercentIndicator(
animation: true,
radius: 60.0,
lineWidth: 5.0,
percent: progress,
center: Text("${progress*100} %"),
progressColor: Colors.lightGreen,
);
}
}

View File

@ -0,0 +1,38 @@
import 'package:ernaehrung/android/components/meal_page_text/statistics_text_component.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
class LineCircularWiTextComponent extends StatelessWidget {
final Color progressColor;
final double percent;
final int left;
final int total;
final String textName;
const LineCircularWiTextComponent(
this.progressColor, this.percent, this.left, this.total, this.textName,
{super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StaticsTextComponent(left.toString(), true),
const SizedBox(height: 4,),
LinearPercentIndicator(
padding: EdgeInsets.zero,
lineHeight: 8.0,
percent: 0.9,
progressColor: progressColor,
),
const SizedBox(height: 4,),
StaticsTextComponent(textName, false),
],
),
);
}
}

View File

@ -1,10 +0,0 @@
import 'package:flutter/cupertino.dart';
class EmptySearchComponent extends StatelessWidget {
const EmptySearchComponent({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}

View File

@ -0,0 +1,35 @@
import 'package:ernaehrung/android/config/cast_helper.dart';
import 'package:flutter/cupertino.dart';
import 'package:hive_flutter/adapters.dart';
import 'card_component.dart';
class FoodComponent extends StatelessWidget {
final Box box;
const FoodComponent({super.key, required this.box});
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: box.listenable(),
builder: (context, box, widget) {
return ListView.builder(
primary: false,
shrinkWrap: true,
itemCount: box.keys.length,
itemBuilder: (context, i) {
if (box.keyAt(i).toString() == "DATE") {
return const SizedBox.shrink();
} else {
return CardComponent(
eatingMealName: box.keyAt(i).toString(),
selectedMeal: castDynamicToListFood(box.getAt(i)),
addButtonVisible: box.name != 'statistics_reduced',
);
}
});
});
}
}

View File

@ -1,8 +1,9 @@
import 'package:assorted_layout_widgets/assorted_layout_widgets.dart';
import 'package:ernaehrung/android/config/cast_helper.dart';
import 'package:ernaehrung/android/config/statistics.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:hive/hive.dart';
import '../config/setup_todaybox_config.dart';
import '../models/food.dart';
class SearchedFoodComponent extends StatefulWidget {
@ -15,36 +16,25 @@ class SearchedFoodComponent extends StatefulWidget {
}
class _SearchFoodComponentState extends State<SearchedFoodComponent> {
StatisticsService statisticsService = StatisticsService();
void storeFood() async {
statisticsService.addItemToMainBox(widget.food, widget.cardName);
final todayBox = Hive.box(dotenv.env['TODAY_BOX']!);
if (!todayBox.isOpen){
Hive.openBox(dotenv.env['TODAY_BOX']!);
}
addValuesToList(todayBox, widget.cardName, [widget.food]);
}
final todayBoxDateField = todayBox.containsKey(dotenv.env['DATE_FIELD']!.toString());
final todayBoxEatingField = todayBox.containsKey(widget.cardName.toUpperCase().toString());
if (todayBoxDateField && todayBoxEatingField){
updateFoodInStorage(todayBox);
}else{
addFoodToStorage(todayBox);
void addValuesToList(box, String key, List<Food> newValues){
List<Food> existingList = castDynamicToListFood(box.get(key));
for(int i = 0; i < newValues.length;i++){
if(!existingList.contains(newValues[i])){
existingList.add(newValues[i]);
}
}
}
void updateFoodInStorage(dynamic todayBox) async {
final values = todayBox.get(widget.cardName.toUpperCase());
values.add(widget.food);
await todayBox.put(widget.cardName.toUpperCase(), values);
}
void addFoodToStorage(dynamic todayBox) async{
List<Food> foods = [];
foods.add(widget.food);
todayBox.put(widget.cardName.toUpperCase(), foods);
todayBox.put(dotenv.env['DATE_FIELD']!, getFormatedTodayDate());
box.put(key, existingList);
}
@override

View File

@ -0,0 +1,73 @@
import 'package:ernaehrung/android/components/meal_page_text/days_text_component.dart';
import 'package:ernaehrung/android/config/statistics.dart';
import 'package:flutter/material.dart';
enum TimeSpan {
day,
week,
month
}
class DaysMealPageComponent extends StatefulWidget {
const DaysMealPageComponent({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _DaysMealPageState();
}
class _DaysMealPageState extends State<DaysMealPageComponent> {
int activatedIndex = 0;
StatisticsService statisticsService = StatisticsService();
void updateValue(int index) {
setState(() {
activatedIndex = index;
if(activatedIndex == 0){
statisticsService.updateReducedBoxByTimespan(TimeSpan.day);
}else if(activatedIndex == 1){
statisticsService.updateReducedBoxByTimespan(TimeSpan.week);
}else if(activatedIndex == 2){
statisticsService.updateReducedBoxByTimespan(TimeSpan.month);
}
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
DaysTextComponent(
timeSpan: TimeSpan.day,
textColor: activatedIndex == 0
? const Color(0xff47a44b)
: const Color(0xff000000),
onPressed: updateValue,
index: 0
),
DaysTextComponent(
timeSpan: TimeSpan.week,
textColor: activatedIndex == 1
? const Color(0xff47a44b)
: const Color(0xff000000),
onPressed: updateValue,
index: 1
),
DaysTextComponent(
timeSpan: TimeSpan.month,
textColor: activatedIndex == 2
? const Color(0xff47a44b)
: const Color(0xff000000),
onPressed: updateValue,
index: 2
),
],
),
);
}
}

View File

@ -0,0 +1,42 @@
import 'package:ernaehrung/android/components/meal_page_text/days_component.dart';
import 'package:ernaehrung/android/config/statistics.dart';
import 'package:flutter/material.dart';
class DaysTextComponent extends StatelessWidget {
late final String timeSpan;
late final TimeSpan timespan;
Function(int i) onPressed;
int index;
Color textColor;
late StatisticsService statisticsService;
DaysTextComponent({super.key, required TimeSpan timeSpan, required this.textColor, required this.onPressed, required this.index}){
timespan = timeSpan;
switch(timeSpan){
case TimeSpan.day:
this.timeSpan = 'Tag';
break;
case TimeSpan.week:
this.timeSpan = 'Woche';
break;
case TimeSpan.month:
this.timeSpan = 'Monat';
break;
}
}
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () {
onPressed(index);
},
child: Text(
timeSpan,
style: TextStyle(
color: textColor,
fontSize: 14,
),
));
}
}

View File

@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
class SecondaryBigTextComponent extends StatelessWidget {
final String title;
const SecondaryBigTextComponent(this.title, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
title.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 30,
fontWeight: FontWeight.w600),
textAlign: TextAlign.left,
);
}
}

View File

@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
class SecondaryTextComponent extends StatelessWidget {
final String title;
const SecondaryTextComponent(this.title, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
title.toString(),
style: TextStyle(
color: Colors.grey.shade500,
fontSize: 14,
fontWeight: FontWeight.w500),
textAlign: TextAlign.left,
);
}
}

View File

@ -0,0 +1,19 @@
import 'package:flutter/cupertino.dart';
class StaticsTextComponent extends StatelessWidget {
final String name;
final bool titleOrSecondary;
const StaticsTextComponent(this.name, this.titleOrSecondary, {super.key});
@override
Widget build(BuildContext context) {
return Text(name,
textAlign: TextAlign.left,
style: TextStyle(
color: const Color.fromARGB(255, 211, 211, 211),
fontSize: titleOrSecondary ? 14 : 10,
fontWeight: titleOrSecondary ? FontWeight.w600 : FontWeight.w400
));
}
}

View File

@ -0,0 +1,51 @@
import 'package:ernaehrung/android/components/circular/circular_component.dart';
import 'package:ernaehrung/android/components/circular/line_circular_with_text_component.dart';
import 'package:ernaehrung/android/config/statistics.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class StatisticsPercentage extends StatelessWidget {
final double heightStatisticsContainer = 220.0;
final double widthStatisticsContainer = double.infinity;
const StatisticsPercentage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
StatisticsService statisticsService = StatisticsService();
return Container(
decoration:
BoxDecoration(border: Border.all(width: 2.0, color: Colors.black)),
height: heightStatisticsContainer,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: SizedBox(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: FittedBox(
child: CircularLoadingComponent(statisticsService.getAllEatenCaloriesForTodayStatistics()),
),
),
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
LineCircularWiTextComponent(
Colors.green.shade400, 1.0, 1000, 2000, "Konsumiert"),
LineCircularWiTextComponent(
Colors.green.shade400, 1.0, 1000, 2000, "Konsumiert"),
LineCircularWiTextComponent(
Colors.green.shade400, 1.0, 1000, 2000, "Konsumiert"),
],
),
)
],
),
);
}
}

View File

@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
class TitleComponent extends StatelessWidget {
final String title;
const TitleComponent(this.title, {super.key});
@override
Widget build(BuildContext context) {
return Text(
title.toString(),
style: TextStyle(
color: Colors.orange.shade400,
fontSize: 18,
fontWeight: FontWeight.w500),
textAlign: TextAlign.left,
);
}
}

View File

@ -1,16 +1,12 @@
import 'package:ernaehrung/android/components/circular/circular_component.dart';
import 'package:flutter/material.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
class StatisticsPercentComponent extends StatelessWidget {
late String eaten, calorienBurned, calorienLeft, calorienLeftPercent;
late int eaten, calorienBurned, calorienLeft, calorienLeftPercent;
StatisticsPercentComponent(int eaten, int calorienBurned, int calorienLeft, {super.key}){
this.eaten = '$eaten Gegessen';
this.calorienBurned = '$calorienBurned Verbrannt';
this.calorienLeft = '$calorienLeft Kcal Übrig';
}
StatisticsPercentComponent(this.eaten, this.calorienBurned, this.calorienLeft, {super.key});
String get getEaten => eaten;
int get getEaten => eaten;
get getCalorienBurned => calorienBurned;
get getCalorienLeft => calorienLeft;
get getCalorienLeftPercent => calorienLeftPercent;
@ -21,15 +17,9 @@ class StatisticsPercentComponent extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(eaten),
CircularPercentIndicator(
radius: 60.0,
lineWidth: 5.0,
percent: 0.5,
center: const Text("100%"), //TODO: anpassen
progressColor: Colors.lightGreen,
),
Text(calorienBurned),
Text("$eaten gegessen"),
CircularLoadingComponent(eaten),
Text("$calorienBurned verbrannt"),
],
);
}

View File

@ -1,7 +1,6 @@
import 'package:ernaehrung/android/pages/nav_pages/main_page.dart';
import 'package:flutter/material.dart';
import '../views/navigation/navigation_screen.dart';
class WelcomePageStateTextFieldState extends StatefulWidget {
const WelcomePageStateTextFieldState({super.key});
@ -183,7 +182,7 @@ class _WelcomePageStateTextFieldState
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => const NavigationScreen()),
builder: (context) => const MainPage()),
(r) => false);
},
child: const Text('Bestätigen'))

View File

@ -0,0 +1,23 @@
import '../models/food.dart';
List<Food> castDynamicToListFood(dynamic dynamicList) {
List<Food> foodList = [];
if(dynamicList == null){
return foodList;
}
for (Food element in dynamicList) {
foodList.add(element);
}
return foodList;
}
Map<String,List<Food>> castDynamicMap(dynamic dynamicMap){
Map<String,List<Food>> foodMap = {};
if(dynamicMap == null){
return foodMap;
}
for(dynamic key in dynamicMap.keys){
foodMap.putIfAbsent(key as String , () => castDynamicToListFood(dynamicMap[key]));
}
return foodMap;
}

View File

@ -4,51 +4,22 @@ import '../models/food.dart';
final List<Food> emptyList = [];
Future<void> setupTodayBox() async {
final todayBoxExist = await Hive.boxExists(dotenv.env['TODAY_BOX']!);
final todayBoxOpened = Hive.isBoxOpen(dotenv.env['TODAY_BOX']!);
if (!todayBoxOpened && !todayBoxExist){
Hive.openBox(dotenv.env['TODAY_BOX']!);
}
setupEatingKeys();
}
void setupEatingKeys() async {
void setupTodayBox() async{
final todayBox = Hive.box(dotenv.env['TODAY_BOX']!);
final breakfastExist = todayBox.containsKey(dotenv.env['BREAKFAST_FIELD']!);
final lunchExist = todayBox.containsKey(dotenv.env['LUNCH_FIELD']!);
final dinnerExist = todayBox.containsKey(dotenv.env['DINNER_FIELD']!);
if (!breakfastExist){
todayBox.put(dotenv.env['BREAKFAST_FIELD']!, emptyList);
}
if (!lunchExist){
todayBox.put(dotenv.env['LUNCH_FIELD']!, emptyList);
}
if (!dinnerExist){
todayBox.put(dotenv.env['DINNER_FIELD']!, emptyList);
}
setupDateField();
}
void setupDateField() async{
final todayBox = Hive.box(dotenv.env['TODAY_BOX']!);
final dateExist = todayBox.containsKey(dotenv.env['DATE_FIELD']!);
if (!dateExist){
todayBox.put(dotenv.env['DATE_FIELD']!, getFormatedTodayDate());
}
}
void moveTodayBoxDataToYesterdayAndBefore() async{
putIfKeyNotExists(todayBox, 'FRÜHSTÜCK', []);
putIfKeyNotExists(todayBox, 'MITTAGESSEN', []);
putIfKeyNotExists(todayBox, 'ABENDESSEN', []);
}
void putIfKeyNotExists(Box box, String key, List<Food> value) {
if (!box.containsKey(key)) {
box.put(key, value);
}
}
String getFormatedTodayDate(){
return DateTime.now().toString().substring(0,10);
}

View File

@ -0,0 +1,217 @@
import 'dart:math';
import 'package:ernaehrung/android/components/meal_page_text/days_component.dart';
import 'package:ernaehrung/android/config/cast_helper.dart';
import 'package:hive/hive.dart';
import '../models/food.dart';
class StatisticsService {
final String reducedStatisticsBoxName = 'STATISTICS_REDUCED';
final String mainStatisticsBoxName = 'STATISTICS_MAIN';
StatisticsService() {
initBoxes();
}
initBoxes()async{
Box reducedBox = Hive.box(reducedStatisticsBoxName);
putIfKeyNotExists(reducedBox, 'FRÜHSTÜCK', []);
putIfKeyNotExists(reducedBox, 'MITTAGESSEN', []);
putIfKeyNotExists(reducedBox, 'ABENDESSEN', []);
updateReducedBoxByTimespan(TimeSpan.day);
}
void putIfKeyNotExists(Box box, String key, dynamic value) {
if (!box.containsKey(key)) {
box.put(key, value);
}
}
updateReducedBoxByTimespan(TimeSpan timeSpan){
clearReducedBoxBeforeUpdate();
DateTime now = DateTime.now();
int timestamp = now.millisecondsSinceEpoch.toInt() ~/ 1000;
switch(timeSpan){
case TimeSpan.day:
getNewFoodAndUpdateReducedBoxByTimestamp(timestamp);
break;
case TimeSpan.week:
List<int> currentWeek = getTimestampsByTimestampAndTimespan(TimeSpan.week,timestamp);
for(int i = 0;i < currentWeek.length;i++){
getNewFoodAndUpdateReducedBoxByTimestamp(currentWeek[i]);
}
break;
case TimeSpan.month:
List<int> currentMonth = getTimestampsByTimestampAndTimespan(TimeSpan.month,timestamp);
for(int i = 0;i < currentMonth.length;i++){
getNewFoodAndUpdateReducedBoxByTimestamp(currentMonth[i]);
}
break;
}
}
void getNewFoodAndUpdateReducedBoxByTimestamp(int timestamp){
Map<String,List<Food>> newFood = getFoodMapForGivenTimestampFromMainBox(timestamp);
if(newFood.keys.isNotEmpty){
setElementsOfReducedBox(newFood);
}
}
List<int> getTimestampsByTimestampAndTimespan(TimeSpan timespan, int timestamp) {
int range = timespan == TimeSpan.week ? 7 : 31;
int targetWeekday = DateTime.monday; // Example target weekday (Monday)
DateTime currentDateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
int currentWeekday = currentDateTime.weekday;
int daysToAdd = targetWeekday - currentWeekday;
DateTime targetDateTime = currentDateTime.add(Duration(days: daysToAdd));
List<int> timestampsForWeekdays = [];
for (int i = 0; i < range; i++) {
timestampsForWeekdays.add(targetDateTime.millisecondsSinceEpoch ~/ 1000);
targetDateTime = targetDateTime.add(const Duration(days: 1));
}
return timestampsForWeekdays;
}
clearReducedBoxBeforeUpdate(){
Box box = Hive.box(reducedStatisticsBoxName);
for(int i = 0; i < box.keys.length;i++){
box.put(box.keys.elementAt(i), []);
}
}
setElementsOfReducedBox(Map<String,List<Food>> newFood){
Box box = Hive.box(reducedStatisticsBoxName);
Iterable<String> keys = newFood.keys;
for(int i = 0; i < keys.length;i++){
box.put(keys.elementAt(i), newFood[keys.elementAt(i)] ?? []);
}
}
getDayAsIntFromTimestamp(int timestamp){
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
return dateTime.day;
}
Map<String,List<Food>> getFoodMapForGivenTimestampFromMainBox(int timestamp){
Box box = Hive.box(mainStatisticsBoxName);
dynamic matchingTimestamp = getMatchingTimeStamp(box, timestamp);
if(matchingTimestamp != null){
return castDynamicMap(box.get(matchingTimestamp));
}
return <String,List<Food>>{};
}
getMatchingTimeStamp(Box box,int newTimestamp){
if(box.keys.isNotEmpty){
for(int i = 0; i < box.keys.length;i++){
int timestamp = box.keys.elementAt(i);
if(isDateEqual(newTimestamp, timestamp)){
return timestamp;
}
}
return null;
}
}
getMonthAsIntFromTimestamp(int timestamp){
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
return dateTime.month;
}
getYearAsIntFromTimestamp(int timestamp){
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
return dateTime.year;
}
isDateEqual(int timestamp1, int timestamp2){
return
getDayAsIntFromTimestamp(timestamp1) == getDayAsIntFromTimestamp(timestamp2) &&
getMonthAsIntFromTimestamp(timestamp1) == getMonthAsIntFromTimestamp(timestamp2) &&
getYearAsIntFromTimestamp(timestamp1) == getYearAsIntFromTimestamp(timestamp2);
}
addItemToMainBox(Food value, String mealType){
// Hive.deleteFromDisk();
Box box = Hive.box(mainStatisticsBoxName);
DateTime dateTime = DateTime.now();
// DEBUG
//DateTime dateTime = getRandomTimestampForTesting();
int newTimestamp = dateTime.millisecondsSinceEpoch.toInt() ~/ 1000;
dynamic matchingTimestamp = getMatchingTimeStamp(box, newTimestamp);
if(matchingTimestamp != null){
newTimestamp = matchingTimestamp;
}
Map<String, List<Food>> valueMap = castDynamicMap(box.get(newTimestamp));
List<Food> values = [];
if(valueMap.containsKey(mealType)){
values = valueMap[mealType]!;
}
values.add(value);
valueMap[mealType] = values;
box.put(newTimestamp, valueMap);
}
getRandomTimestampForTesting(){
DateTime now = DateTime.now();
DateTime startOfWeek = now.subtract(Duration(days: now.weekday - 1));
DateTime endOfWeek = startOfWeek.add(const Duration(days: 6));
Random random = Random();
int randomMilliseconds = random.nextInt(endOfWeek.millisecondsSinceEpoch - startOfWeek.millisecondsSinceEpoch);
DateTime randomTimestamp = startOfWeek.add(Duration(milliseconds: randomMilliseconds));
return randomTimestamp;
}
int getAllEatenCaloriesForTodayStatistics(){
Box box = Hive.box(reducedStatisticsBoxName);
num sum = 0;
for(int i = 0; i < box.keys.length;i++){
for(Food food in box.get(box.keys.elementAt(i))){
sum += food.calories;
}
}
return sum as int;
}
num getAllCaloriesByBoxAndTimestamp(Box box,int timestamp){
Map<String, List<Food>> valueMap = castDynamicMap(box.get(timestamp));
num sum = 0;
for(var mealType in valueMap.keys){
if(valueMap.containsKey(mealType)){
List<Food> values = valueMap[mealType]!;
for(var value in values){
sum += value.calories;
}
}
}
return sum;
}
num getCaloriesByTimestampAndMealTypeAndBox(Box box,DateTime date, String mealType){
int timestamp = date.millisecondsSinceEpoch.toInt() ~/ 1000;
Map<String, List<Food>> valueMap = castDynamicMap(box.get(timestamp));
num sum = 0;
if(valueMap.containsKey(mealType)){
List<Food> values = valueMap[mealType]!;
for(var value in values){
sum += value.calories;
}
}
return sum;
}
showItems(){
print("Statistics.dart - showItems() - ITEMS");
//Hive.box(boxName).clear();
print(Hive.box(mainStatisticsBoxName).keys.length);
for(int i = 0; i < Hive.box(mainStatisticsBoxName).keys.length; i++){
print(Hive.box(mainStatisticsBoxName).keys.elementAt(i));
print(Hive.box(mainStatisticsBoxName).values.elementAt(i));
//print(Hive.box(boxName).keys.elementAt(i) + " " + Hive.box(boxName).values.elementAt(i));
}
}
}

View File

@ -1,7 +1,7 @@
import 'package:hive/hive.dart';
part 'food.g.dart';
@HiveType(typeId: 1)
@HiveType(typeId: 0)
class Food {
Food(this.id, this.name, this.foodGroup, this.calories, this.fatg,
this.proteing, this.carbohydrateg, this.sugarsg, this.fiberg);

View File

@ -8,7 +8,7 @@ part of 'food.dart';
class FoodAdapter extends TypeAdapter<Food> {
@override
final int typeId = 1;
final int typeId = 0;
@override
Food read(BinaryReader reader) {

View File

@ -0,0 +1,26 @@
import 'package:hive/hive.dart';
part 'user.g.dart';
@HiveType(typeId: 1)
class User {
@HiveField(0)
final String vorname;
@HiveField(1)
final String nachname;
@HiveField(2)
final int gewicht;
@HiveField(3)
final int groesse;
@HiveField(4)
final int alter;
@HiveField(5)
final int kalorien;
User(this.vorname, this.nachname, this.gewicht, this.groesse, this.alter,
this.kalorien);
@override
String toString() {
return 'User{vorname: $vorname, nachname: $nachname, gewicht: $gewicht, groesse: $groesse, alter: $alter, kalorien: $kalorien}';
}
}

View File

@ -0,0 +1,56 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class UserAdapter extends TypeAdapter<User> {
@override
final int typeId = 1;
@override
User read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return User(
fields[0] as String,
fields[1] as String,
fields[2] as int,
fields[3] as int,
fields[4] as int,
fields[5] as int,
);
}
@override
void write(BinaryWriter writer, User obj) {
writer
..writeByte(6)
..writeByte(0)
..write(obj.vorname)
..writeByte(1)
..write(obj.nachname)
..writeByte(2)
..write(obj.gewicht)
..writeByte(3)
..write(obj.groesse)
..writeByte(4)
..write(obj.alter)
..writeByte(5)
..write(obj.kalorien);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is UserAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@ -12,39 +12,31 @@ class MainPage extends StatefulWidget {
class MainPageState extends State<MainPage> {
List pages = [
const TodayPage(title: 'Today',),
const TodayPage(title: 'Today'),
const MealPlanPage(title: 'Meal Plan'),
const ProgressPage(title: 'Progress',)
const ProgressPage(title: 'Progress')
];
int currentIndex = 0;
void onTap(int index){
void onTap(int index) {
setState(() {
currentIndex = index;
getPageWithOrOutPadding();
pages[currentIndex];
});
}
Widget getPageWithOrOutPadding(){
if (pages[currentIndex] is TodayPage){
return Placeholder(
child: pages[currentIndex],
);
}else{
return Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: pages[currentIndex],
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
title: Text(pages[currentIndex].title),
backgroundColor: Colors.grey.shade100,
),
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),
child: pages[currentIndex],
),
body: getPageWithOrOutPadding(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: currentIndex,
selectedItemColor: Colors.black54,
@ -54,18 +46,10 @@ class MainPageState extends State<MainPage> {
elevation: 0,
onTap: onTap,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.today), label: 'Today'),
BottomNavigationBarItem(
icon: Icon(Icons.today),
label: 'Today'
),
BottomNavigationBarItem(
icon: Icon(Icons.area_chart),
label: 'Progress'
),
BottomNavigationBarItem(
icon: Icon(Icons.apple),
label: 'Meal Plan'
),
icon: Icon(Icons.area_chart), label: 'Progress'),
BottomNavigationBarItem(icon: Icon(Icons.apple), label: 'Meal Plan'),
],
),
);

View File

@ -1,7 +1,12 @@
import 'package:flutter/cupertino.dart';
import 'package:ernaehrung/android/components/MealPageFoodComponent.dart';
import 'package:ernaehrung/android/components/meal_page_text/days_component.dart';
import 'package:ernaehrung/android/components/meal_page_text/statistics_today_component.dart';
import 'package:flutter/material.dart';
class MealPlanPage extends StatelessWidget {
class MealPlanPage extends StatefulWidget {
final String title;
final Color backgroundColor = const Color(0xff47a44b);
const MealPlanPage({Key? key, required this.title}) : super(key: key);
String get getTitle => title;
@ -11,8 +16,26 @@ class MealPlanPage extends StatelessWidget {
return getTitle;
}
@override
State<StatefulWidget> createState() => _MealPlanState();
}
class _MealPlanState extends State<MealPlanPage> {
@override
Widget build(BuildContext context) {
return const Placeholder();
return Scaffold(
body: Container(
margin: const EdgeInsets.all(8),
width: double.infinity,
height: double.infinity,
child: SingleChildScrollView(
child: Column(
children: const [
DaysMealPageComponent(),
StatisticsPercentage(),
MealPageStatisticsFoodComponent(),
],
),
)));
}
}

View File

@ -1,7 +1,13 @@
import 'package:flutter/cupertino.dart';
import 'package:ernaehrung/android/components/meal_page_text/secondary_big_text_component.dart';
import 'package:ernaehrung/android/components/meal_page_text/secondary_text_component.dart';
import 'package:ernaehrung/android/components/meal_page_text/title_component.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class ProgressPage extends StatelessWidget {
final String title;
final Color backgroundColor = const Color(0xff47a44b);
const ProgressPage({Key? key, required this.title}) : super(key: key);
String get getTitle => title;
@ -11,10 +17,288 @@ class ProgressPage extends StatelessWidget {
return getTitle;
}
/*
* TODO: in versch. Dateien auslagern, damit der Code nicht voll gemüllt wird
* */
@override
Widget build(BuildContext context) {
return Container(
return Scaffold(
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
child: Column(
children: [
Container(
height: 284,
decoration: BoxDecoration(
border: Border.all(),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const TitleComponent("Kalorien"),
const SizedBox(
height: 16,
),
const SecondaryTextComponent("Durchschnittlich"),
SecondaryBigTextComponent(1235.toString()),
SizedBox(
height: 200,
child: BarChart(
BarChartData(
barTouchData: barTouchData,
titlesData: titlesData,
borderData: borderData,
barGroups: barGroups,
gridData: FlGridData(show: false),
alignment: BarChartAlignment.spaceAround,
maxY: 200,
),
),
)
],
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16, horizontal: 0),
child: Column(
//TODO: Aussortieren und mit einer Schleife drüber gehen
//bzw. die Daten aus der Hivebox ziehen und sortieren
children: [
const TitleComponent(
"Lebensmittel mit dem höchsten Kaloriengehalt"),
const SizedBox(height: 24,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SecondaryTextComponent("Haferflocker"),
SecondaryTextComponent("670 Kalorien"),
],
),
const SizedBox(height: 24,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SecondaryTextComponent("Haferflocker"),
SecondaryTextComponent("670 Kalorien"),
],
),
const SizedBox(height: 24,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SecondaryTextComponent("Haferflocker"),
SecondaryTextComponent("670 Kalorien"),
],
),
const SizedBox(height: 24,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SecondaryTextComponent("Haferflocker"),
SecondaryTextComponent("670 Kalorien"),
],
),
const SizedBox(height: 24,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SecondaryTextComponent("Haferflocker"),
SecondaryTextComponent("670 Kalorien"),
],
),
const SizedBox(height: 24,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SecondaryTextComponent("Haferflocker"),
SecondaryTextComponent("670 Kalorien"),
],
),
const SizedBox(height: 24,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SecondaryTextComponent("Haferflocker"),
SecondaryTextComponent("670 Kalorien"),
],
)
],
),
)
],
),
),
),
);
}
BarTouchData get barTouchData => BarTouchData(
enabled: false,
touchTooltipData: BarTouchTooltipData(
tooltipBgColor: Colors.transparent,
tooltipPadding: EdgeInsets.zero,
tooltipMargin: 4,
getTooltipItem: (
BarChartGroupData group,
int groupIndex,
BarChartRodData rod,
int rodIndex,
) {
return BarTooltipItem(
rod.toY.round().toString(),
const TextStyle(
color: Colors.orange,
fontWeight: FontWeight.bold,
),
);
},
),
);
Widget getTitles(double value, TitleMeta meta) {
const style = TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold,
fontSize: 14,
);
String text;
switch (value.toInt()) {
case 0:
text = 'Mn';
break;
case 1:
text = 'Te';
break;
case 2:
text = 'Wd';
break;
case 3:
text = 'Tu';
break;
case 4:
text = 'Fr';
break;
case 5:
text = 'St';
break;
case 6:
text = 'Sn';
break;
default:
text = '';
break;
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 4,
child: Text(text, style: style),
);
}
FlTitlesData get titlesData => FlTitlesData(
show: true,
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 30,
getTitlesWidget: getTitles,
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
);
FlBorderData get borderData => FlBorderData(
show: false,
);
LinearGradient get _barsGradient => const LinearGradient(
colors: [
Colors.cyan,
Colors.deepPurple,
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
);
List<BarChartGroupData> get barGroups => [
BarChartGroupData(
x: 0,
barRods: [
BarChartRodData(
toY: 8,
gradient: _barsGradient,
)
],
showingTooltipIndicators: [0],
),
BarChartGroupData(
x: 1,
barRods: [
BarChartRodData(
toY: 10,
gradient: _barsGradient,
)
],
showingTooltipIndicators: [0],
),
BarChartGroupData(
x: 2,
barRods: [
BarChartRodData(
toY: 14,
gradient: _barsGradient,
)
],
showingTooltipIndicators: [0],
),
BarChartGroupData(
x: 3,
barRods: [
BarChartRodData(
toY: 150,
gradient: _barsGradient,
)
],
showingTooltipIndicators: [0],
),
BarChartGroupData(
x: 4,
barRods: [
BarChartRodData(
toY: 13,
gradient: _barsGradient,
)
],
showingTooltipIndicators: [0],
),
BarChartGroupData(
x: 5,
barRods: [
BarChartRodData(
toY: 10,
gradient: _barsGradient,
)
],
showingTooltipIndicators: [0],
),
BarChartGroupData(
x: 6,
barRods: [
BarChartRodData(
toY: 16,
gradient: _barsGradient,
)
],
showingTooltipIndicators: [0],
),
];
}

View File

@ -1,12 +1,11 @@
import 'package:basic_utils/basic_utils.dart';
import 'package:ernaehrung/android/components/card/card_component.dart';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import '../../components/card_component.dart';
import '../../components/diet_chart_component.dart';
import '../../components/statistics_circular_indicator_component.dart';
import '../../models/food.dart';
import 'package:hive_flutter/adapters.dart';
class TodayPage extends StatefulWidget {
final String title;
final Color backgroundColor = const Color(0xff47a44b);
const TodayPage({Key? key, required this.title}) : super(key: key);
@ -15,57 +14,27 @@ class TodayPage extends StatefulWidget {
}
class _TodayPageState extends State<TodayPage> {
List<Food> castDynamicToListFood(List<dynamic> dynamicList) {
List<Food> foodList = [];
for (Food element in dynamicList) {
foodList.add(element);
}
return foodList;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xff000000), Color(0xff47a44b)],
stops: [0.1, 5],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
)),
child: SingleChildScrollView(
child: Column(
children: [
StatisticsPercentComponent(300, 100, 400),
DietChatComponent(1500),
ValueListenableBuilder(
valueListenable: Hive.box("TODAY").listenable(),
builder: (context, box, widget) {
return ListView.builder(
primary: false,
shrinkWrap: true,
itemCount: box.keys.length,
itemBuilder: (context, i) {
if(box.keyAt(i).toString() == "DATE"){
return const SizedBox.shrink();
}else{
return CardComponent(
eatingMealName: box.keyAt(i).toString(),
selectedMeal: castDynamicToListFood(
box.getAt(i)));
}
}
body: SingleChildScrollView(
child: ValueListenableBuilder(
valueListenable: Hive.box("TODAY").listenable(),
builder: (context, box, widget) {
return ListView.builder(
primary: false,
shrinkWrap: true,
itemCount: box.keys.length,
itemBuilder: (context, i) {
if (box.keyAt(i).toString() == "DATE") {
return const SizedBox.shrink();
} else {
return CardComponent(
StringUtils.capitalize(box.keyAt(i).toString()),
box.getAt(i)
);
}),
],
),
)),
));
}
});
})));
}
}

View File

@ -1,4 +1,10 @@
import 'package:flutter/cupertino.dart';
import 'package:ernaehrung/android/pages/nav_pages/main_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:hive_flutter/hive_flutter.dart';
import '../models/user.dart';
class OnboardingPage extends StatefulWidget {
const OnboardingPage({Key? key}) : super(key: key);
@ -8,9 +14,195 @@ class OnboardingPage extends StatefulWidget {
}
class _OnboardingPageState extends State<OnboardingPage> {
InputDecoration decoration(String hintText) {
return InputDecoration(
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))),
filled: true,
hintStyle: TextStyle(color: Colors.grey.shade400),
hintText: hintText,
labelText: hintText,
fillColor: Colors.white70);
}
@override
Widget build(BuildContext context) {
return const Placeholder();
final _formKey = GlobalKey<FormBuilderState>();
return Scaffold(
appBar: AppBar(
title: const Text("Welcome"),
backgroundColor: Colors.grey.shade100,
),
body: FormBuilder(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(8),
child: SingleChildScrollView(
child: Column(
children: [
Container(
margin:
const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: FormBuilderTextField(
name: 'vorname',
decoration: decoration("Vorname"),
keyboardType: TextInputType.text,
maxLength: 30,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.minLength(2,
errorText:
"Die Name sollte mindestens 2 Zeichen lang sein"),
FormBuilderValidators.maxLength(30,
errorText:
"Die Name sollte maximal 30 Zeichen lang sein")
]),
),
),
Container(
margin:
const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: FormBuilderTextField(
name: 'nachname',
decoration: decoration("Nachname"),
keyboardType: TextInputType.text,
maxLength: 30,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.minLength(2,
errorText:
"Die Nachname sollte mindestens 2 Zeichen lang sein"),
FormBuilderValidators.maxLength(30,
errorText:
"Die Nachname sollte maximal 30 Zeichen lang sein")
]),
),
),
Container(
margin:
const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: FormBuilderTextField(
name: 'gewicht',
decoration: decoration("Gewicht"),
keyboardType: TextInputType.number,
maxLength: 7,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.numeric(
errorText:
"Der Gewicht sollte mindestens 10 kg sein"),
FormBuilderValidators.max(200,
errorText:
"Der Gewicht sollte maximal 200 kg sein"),
FormBuilderValidators.min(10,
errorText:
"Der Gewicht sollte mindestens 10 kg sein")
]),
),
),
Container(
margin:
const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: FormBuilderTextField(
name: 'groesse',
decoration: decoration("Größe"),
keyboardType: TextInputType.number,
maxLength: 7,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.numeric(
errorText: "Die Größe sollte mindestens 60cm sein"),
FormBuilderValidators.max(230,
errorText: "Die Größe sollte maximal 230cm sein"),
FormBuilderValidators.min(60,
errorText: "Die Größe sollte mindestens 60cm sein")
]),
),
),
Container(
margin:
const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: FormBuilderTextField(
name: 'alter',
decoration: decoration("Alter"),
keyboardType: TextInputType.number,
maxLength: 7,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.numeric(
errorText:
"Das Alter sollte mindestens 6 Jahre alt sein"),
FormBuilderValidators.max(99,
errorText:
"Das Alter sollte maximal 99 Jahre alt sein"),
FormBuilderValidators.min(6,
errorText:
"Das Alter sollte mindestens 6 Jahre alt sein")
]),
),
),
Container(
margin:
const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: FormBuilderTextField(
name: 'kalorien',
decoration:
decoration("gewünschte Kalorienzufuhr: min. 1000"),
keyboardType: TextInputType.number,
maxLength: 7,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.numeric(
errorText:
"Die Kalorienanzahl sollte mindestens 1000 Kcal sein"),
FormBuilderValidators.max(30000),
FormBuilderValidators.min(1000,
errorText:
"Die Kalorienanzahl sollte mindestens 1000 Kcal sein")
]),
),
),
Container(
margin: const EdgeInsets.symmetric(
vertical: 8, horizontal: 0),
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40), //
backgroundColor: const Color(0xFF6E7BFB),
foregroundColor: const Color(0xFFffffff),
shape: const StadiumBorder(),
),
onPressed: () {
final Box box = Hive.box<User>("USER_BOX");
box.put("USER", User(
_formKey.currentState?.fields['vorname']?.value,
_formKey.currentState?.fields['nachname']?.value,
int.parse(_formKey.currentState?.fields['gewicht']?.value),
int.parse(_formKey.currentState?.fields['groesse']?.value),
int.parse(_formKey.currentState?.fields['alter']?.value),
int.parse(_formKey.currentState?.fields['kalorien']?.value)
));
print(box.get("USER"));
Navigator
.of(context)
.pushReplacement(MaterialPageRoute(builder: (BuildContext context) => const MainPage()));
},
child: const Text("Eingaben bestätigen"),
)),
],
),
),
)),
);
}
}

View File

@ -1,61 +0,0 @@
import 'package:flutter/material.dart';
class NavigationScreen extends StatefulWidget {
const NavigationScreen({super.key});
@override
NavigationScreenState createState() => NavigationScreenState();
}
class NavigationScreenState extends State<NavigationScreen> {
int _selectedIndex = 0;
final _pages = ["Page 1", "Page 2", "Page 3"];
String _selectedPage = "Page 1";
final PageController _pageController = PageController(initialPage: 0);
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
_selectedPage = _pages[index];
_pageController.animateToPage(index,
duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_selectedPage),
),
body: PageView(
controller: _pageController,
onPageChanged: (int index) {
setState(() {
_selectedPage = _pages[index];
_selectedIndex = index;
});
},
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Page 1',
),
BottomNavigationBarItem(
icon: Icon(Icons.work),
label: 'Page 2',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'Page 3',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
}

View File

@ -1,43 +0,0 @@
import 'package:flutter/material.dart';
import '../../components/welcome_text_field.dart';
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Welcome Screen',
home: WelcomeScreenPage(),
);
}
}
class WelcomeScreenPage extends StatefulWidget {
const WelcomeScreenPage({super.key});
@override
State<StatefulWidget> createState() => WelcomeScreenPageState();
}
class WelcomeScreenPageState extends State<WelcomeScreenPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Welcome Screen'),
),
body: const SizedBox(
height: double.infinity,
width: double.infinity,
child: SingleChildScrollView(
child: Form(
child: WelcomePageStateTextFieldState(),
)
),
)
);
}
}

View File

@ -1,27 +1,35 @@
import 'package:ernaehrung/android/models/food.dart';
import 'package:ernaehrung/android/models/user.dart';
import 'package:ernaehrung/web/web_app.dart';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'android/andoird_app.dart';
import 'android/config/setup_todaybox_config.dart';
import 'android/models/food.dart';
import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb;
import 'android/config/setup_todaybox_config.dart';
void main() async {
await dotenv.load(fileName: ".env");
await Hive.initFlutter();
if (! Hive.isAdapterRegistered(1)) {
if (!Hive.isAdapterRegistered(0)) {
Hive.registerAdapter(FoodAdapter());
}
await Hive.openBox(dotenv.env['TODAY_BOX']!);
await setupTodayBox();
if (!Hive.isAdapterRegistered(1)) {
Hive.registerAdapter(UserAdapter());
}
if(defaultTargetPlatform == TargetPlatform.android){
await Hive.openBox('STATISTICS_REDUCED');
await Hive.openBox('STATISTICS_MAIN');
await Hive.openBox('TODAY');
await Hive.openBox<User>('USER_BOX');
setupTodayBox();
if (defaultTargetPlatform == TargetPlatform.android) {
runApp(const AndroidApp());
}else if(kIsWeb){
} else if (kIsWeb) {
runApp(const WebApp());
}
}

View File

@ -1,23 +1,13 @@
import 'package:ernaehrung/android/components/statistics_circular_indicator_component.dart';
import 'package:ernaehrung/android/config/cast_helper.dart';
import 'package:flutter/cupertino.dart';
import 'package:hive_flutter/adapters.dart';
import '../../android/components/card_component.dart';
import '../../android/components/diet_chart_component.dart';
import '../../android/models/food.dart';
class SectionComponent extends StatelessWidget {
const SectionComponent({Key? key}) : super(key: key);
List<Food> castDynamicToListFood(List<dynamic> dynamicList) {
List<Food> foodList = [];
for (Food element in dynamicList) {
foodList.add(element);
}
return foodList;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
@ -38,8 +28,8 @@ class SectionComponent extends StatelessWidget {
}else{
return CardComponent(
eatingMealName: box.keyAt(i).toString(),
selectedMeal: castDynamicToListFood(
box.getAt(i)));
selectedMeal: castDynamicToListFood(box.getAt(i)),
);
}
}
);

View File

@ -49,6 +49,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.10.0"
basic_utils:
dependency: "direct main"
description:
name: basic_utils
sha256: "8815477fcf58499e42326bd858e391442425fa57db9a45e48e15224c62049262"
url: "https://pub.dev"
source: hosted
version: "5.5.4"
boolean_selector:
dependency: transitive
description:
@ -209,6 +217,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.0.5"
equatable:
dependency: transitive
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async:
dependency: transitive
description:
@ -241,6 +257,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
fl_chart:
dependency: "direct main"
description:
name: fl_chart
sha256: "48a1b69be9544e2b03d9a8e843affd89e43f3194c9248776222efcb4206bb1ec"
url: "https://pub.dev"
source: hosted
version: "0.62.0"
flutter:
dependency: "direct main"
description: flutter
@ -254,6 +278,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.2"
flutter_form_builder:
dependency: "direct main"
description:
name: flutter_form_builder
sha256: "236c96dad143a0e67c0f11522606d6b17b6510e97530cb73af355b018ded7c10"
url: "https://pub.dev"
source: hosted
version: "8.0.0"
flutter_lints:
dependency: "direct dev"
description:
@ -262,11 +294,24 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.1"
flutter_localizations:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
form_builder_validators:
dependency: "direct main"
description:
name: form_builder_validators
sha256: f2d90439c56345c23ad8d0c2912e4002cd02563d816f4387c9495051c10d3321
url: "https://pub.dev"
source: hosted
version: "8.6.1"
frontend_server_client:
dependency: transitive
description:
@ -315,6 +360,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
http:
dependency: transitive
description:
name: http
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
version: "0.13.6"
http_multi_server:
dependency: transitive
description:
@ -331,6 +384,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
intl:
dependency: transitive
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
url: "https://pub.dev"
source: hosted
version: "0.17.0"
io:
dependency: transitive
description:
@ -499,6 +560,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev"
source: hosted
version: "3.7.3"
pool:
dependency: transitive
description:
@ -722,4 +791,4 @@ packages:
version: "3.1.2"
sdks:
dart: ">=2.19.6 <3.0.0"
flutter: ">=3.3.0"
flutter: ">=3.7.0"

View File

@ -45,6 +45,10 @@ dependencies:
flutter_dotenv: ^5.0.2
responsive_framework: ^1.0.0
sizer: ^2.0.15
fl_chart: ^0.62.0
basic_utils: ^5.5.4
flutter_form_builder: ^8.0.0
form_builder_validators: ^8.6.1
dev_dependencies:
@ -60,6 +64,7 @@ dev_dependencies:
hive_generator: ^2.0.0
build_runner: ^2.3.3
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

View File

@ -1,11 +0,0 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void RegisterPlugins(flutter::PluginRegistry* registry) {
}

View File

@ -1,15 +0,0 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter/plugin_registry.h>
// Registers Flutter plugins.
void RegisterPlugins(flutter::PluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_

View File

@ -1,23 +0,0 @@
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)