feature/optimize-search-page #5
|
@ -201,7 +201,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "flutter",
|
"name": "flutter",
|
||||||
"rootUri": "file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter",
|
"rootUri": "file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter",
|
||||||
"packageUri": "lib/",
|
"packageUri": "lib/",
|
||||||
"languageVersion": "2.17"
|
"languageVersion": "2.17"
|
||||||
},
|
},
|
||||||
|
@ -225,7 +225,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "flutter_localizations",
|
"name": "flutter_localizations",
|
||||||
"rootUri": "file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_localizations",
|
"rootUri": "file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_localizations",
|
||||||
"packageUri": "lib/",
|
"packageUri": "lib/",
|
||||||
"languageVersion": "2.17"
|
"languageVersion": "2.17"
|
||||||
},
|
},
|
||||||
|
@ -237,10 +237,22 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "flutter_test",
|
"name": "flutter_test",
|
||||||
"rootUri": "file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_test",
|
"rootUri": "file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_test",
|
||||||
"packageUri": "lib/",
|
"packageUri": "lib/",
|
||||||
"languageVersion": "2.17"
|
"languageVersion": "2.17"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "flutter_web_plugins",
|
||||||
|
"rootUri": "file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_web_plugins",
|
||||||
|
"packageUri": "lib/",
|
||||||
|
"languageVersion": "2.17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fluttertoast",
|
||||||
|
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2",
|
||||||
|
"packageUri": "lib/",
|
||||||
|
"languageVersion": "2.12"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "form_builder_validators",
|
"name": "form_builder_validators",
|
||||||
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/form_builder_validators-8.6.1",
|
"rootUri": "file:///Users/bogdan/.pub-cache/hosted/pub.dev/form_builder_validators-8.6.1",
|
||||||
|
@ -495,7 +507,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sky_engine",
|
"name": "sky_engine",
|
||||||
"rootUri": "file:///usr/local/Caskroom/flutter/3.7.7/flutter/bin/cache/pkg/sky_engine",
|
"rootUri": "file:///Users/bogdan/fvm/versions/3.7.9/bin/cache/pkg/sky_engine",
|
||||||
"packageUri": "lib/",
|
"packageUri": "lib/",
|
||||||
"languageVersion": "2.12"
|
"languageVersion": "2.12"
|
||||||
},
|
},
|
||||||
|
@ -614,7 +626,7 @@
|
||||||
"languageVersion": "2.19"
|
"languageVersion": "2.19"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"generated": "2023-06-02T11:38:29.193689Z",
|
"generated": "2023-06-02T22:45:16.476426Z",
|
||||||
"generator": "pub",
|
"generator": "pub",
|
||||||
"generatorVersion": "2.19.6"
|
"generatorVersion": "2.19.6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,10 @@ flutter_profile_picture
|
||||||
2.12
|
2.12
|
||||||
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_profile_picture-2.0.0/
|
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_profile_picture-2.0.0/
|
||||||
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_profile_picture-2.0.0/lib/
|
file:///Users/bogdan/.pub-cache/hosted/pub.dev/flutter_profile_picture-2.0.0/lib/
|
||||||
|
fluttertoast
|
||||||
|
2.12
|
||||||
|
file:///Users/bogdan/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/
|
||||||
|
file:///Users/bogdan/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/lib/
|
||||||
form_builder_validators
|
form_builder_validators
|
||||||
2.19
|
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/
|
||||||
|
@ -392,18 +396,22 @@ file:///Users/bogdan/IdeaProjects/ernaehrung/
|
||||||
file:///Users/bogdan/IdeaProjects/ernaehrung/lib/
|
file:///Users/bogdan/IdeaProjects/ernaehrung/lib/
|
||||||
sky_engine
|
sky_engine
|
||||||
2.12
|
2.12
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/bin/cache/pkg/sky_engine/
|
file:///Users/bogdan/fvm/versions/3.7.9/bin/cache/pkg/sky_engine/
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/bin/cache/pkg/sky_engine/lib/
|
file:///Users/bogdan/fvm/versions/3.7.9/bin/cache/pkg/sky_engine/lib/
|
||||||
flutter
|
flutter
|
||||||
2.17
|
2.17
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter/
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter/lib/
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter/lib/
|
||||||
flutter_localizations
|
flutter_localizations
|
||||||
2.17
|
2.17
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_localizations/
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_localizations/
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_localizations/lib/
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_localizations/lib/
|
||||||
flutter_test
|
flutter_test
|
||||||
2.17
|
2.17
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_test/
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_test/
|
||||||
file:///usr/local/Caskroom/flutter/3.7.7/flutter/packages/flutter_test/lib/
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_test/lib/
|
||||||
|
flutter_web_plugins
|
||||||
|
2.17
|
||||||
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_web_plugins/
|
||||||
|
file:///Users/bogdan/fvm/versions/3.7.9/packages/flutter_web_plugins/lib/
|
||||||
2
|
2
|
||||||
|
|
|
@ -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-06-02 13:45:10.283479","version":"3.7.9"}
|
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"fluttertoast","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.2/","native_build":true,"dependencies":[]}],"android":[{"name":"fluttertoast","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/","native_build":true,"dependencies":[]},{"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":[{"name":"fluttertoast","path":"/Users/bogdan/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/","dependencies":[]}]},"dependencyGraph":[{"name":"fluttertoast","dependencies":[]},{"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-06-03 00:48:24.365407","version":"3.7.9"}
|
|
@ -8,9 +8,11 @@ import '../../pages/nav_pages/search_food.dart';
|
||||||
|
|
||||||
class CardComponent extends StatelessWidget {
|
class CardComponent extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final List<dynamic> foods;
|
final Color color;
|
||||||
|
final List<Food> foods;
|
||||||
|
|
||||||
const CardComponent(this.title, this.foods, {super.key});
|
const CardComponent(this.title, this.foods, {super.key, Color? color})
|
||||||
|
: color = color ?? Colors.black;
|
||||||
|
|
||||||
Route createRoute(String cardName) {
|
Route createRoute(String cardName) {
|
||||||
return PageRouteBuilder(
|
return PageRouteBuilder(
|
||||||
|
@ -44,38 +46,47 @@ class CardComponent extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 300,
|
decoration: BoxDecoration(
|
||||||
decoration: const BoxDecoration(
|
color: color,
|
||||||
color: Color(0xFF6E7BFB),
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
|
||||||
),
|
),
|
||||||
margin: const EdgeInsets.fromLTRB(0, 16, 0, 16),
|
margin: const EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
CardTitleComponent(
|
CardTitleComponent(
|
||||||
StringUtils.capitalize(title), "${countCalories(castDynamicToListFood(foods))} Kalorien"),
|
StringUtils.capitalize(title),
|
||||||
|
"${countCalories(castDynamicToListFood(foods))} Kalorien",
|
||||||
|
),
|
||||||
CardDataFoodComponent(
|
CardDataFoodComponent(
|
||||||
castDynamicToListFood(foods)
|
foods,
|
||||||
|
color,
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),
|
padding: const EdgeInsets.only(left: 8, right: 8,bottom: 8),
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.fromLTRB(0, 8, 0, 0),
|
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
minimumSize: const Size.fromHeight(40), //
|
minimumSize: const Size.fromHeight(40),
|
||||||
backgroundColor: const Color(0xFFffffff),
|
backgroundColor: const Color(0xFFffffff),
|
||||||
foregroundColor: const Color(0xFF6E7BFB),
|
foregroundColor: color,
|
||||||
shape: const StadiumBorder(),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.of(context).push(createRoute(title));
|
Navigator.of(context).push(createRoute(title));
|
||||||
},
|
},
|
||||||
child: Text('Gericht zum ${StringUtils.capitalize(title)} hinzufügen'),
|
child: const Text(
|
||||||
|
'+ Gericht hinzufügen',
|
||||||
|
style:TextStyle(
|
||||||
|
fontSize: 17
|
||||||
|
) ,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,38 @@ import 'package:ernaehrung/android/components/card/card_food_item_component.dart
|
||||||
import 'package:ernaehrung/android/models/food.dart';
|
import 'package:ernaehrung/android/models/food.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../config/format_helper.dart';
|
||||||
|
|
||||||
class CardDataFoodComponent extends StatelessWidget {
|
class CardDataFoodComponent extends StatelessWidget {
|
||||||
final List<Food> foods;
|
final List<Food> foods;
|
||||||
|
final Color color;
|
||||||
|
|
||||||
const CardDataFoodComponent(this.foods, {Key? key}) : super(key: key);
|
const CardDataFoodComponent(this.foods,this.color, {Key? key,}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return Padding(
|
||||||
height: 180,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||||
child: foods.isNotEmpty
|
child: foods.isNotEmpty ?
|
||||||
? SingleChildScrollView(
|
Column(
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ListView.builder(
|
ListView.builder(
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: foods.length,
|
itemCount: getMapOfDistinctElementsWithCounterAndCalories(
|
||||||
|
foods)
|
||||||
|
.keys
|
||||||
|
.length,
|
||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
|
Map<String, List<int>> map =
|
||||||
|
getMapOfDistinctElementsWithCounterAndCalories(
|
||||||
|
foods);
|
||||||
|
String foodName = map.keys.elementAt(i);
|
||||||
|
List<int> values = map.values.elementAt(i);
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
CardFoodItemComponent(foods[i]),
|
CardFoodItemComponent(foodName,values),
|
||||||
Divider(
|
Divider(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
thickness: 1.2,
|
thickness: 1.2,
|
||||||
|
@ -34,12 +42,15 @@ class CardDataFoodComponent extends StatelessWidget {
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const Center(
|
: const Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"Die Liste ist momentan leer, aber Sie können sie ändern!"),
|
"Füge jetzt neue Gerichte hinzu!",
|
||||||
)),
|
style: TextStyle(
|
||||||
);
|
fontSize: 14,
|
||||||
|
color: Colors.white
|
||||||
|
),
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import 'package:ernaehrung/android/models/food.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class CardFoodItemComponent extends StatelessWidget {
|
class CardFoodItemComponent extends StatelessWidget {
|
||||||
final Food food;
|
final String foodName;
|
||||||
|
final List<int> countAndCalories; // [count, calories]
|
||||||
|
|
||||||
const CardFoodItemComponent(this.food, {Key? key}) : super(key: key);
|
const CardFoodItemComponent(this.foodName,this.countAndCalories, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -16,12 +16,17 @@ class CardFoodItemComponent extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
food.name.toString(),
|
"$foodName - ${countAndCalories[0] * 100}g",
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
|
maxLines: 2,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
food.calories.toString(),
|
"\n${countAndCalories[1]} kcal | 100g",
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -11,18 +11,26 @@ class CardTitleComponent extends StatelessWidget {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16))
|
borderRadius: BorderRadius.all(Radius.circular(12))
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets
|
const EdgeInsets.symmetric(vertical: 16,horizontal: 16),
|
||||||
.symmetric(
|
|
||||||
vertical: 16,
|
|
||||||
horizontal: 8
|
|
||||||
),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [Text(title), Text(calories)],
|
children: [
|
||||||
|
Text(title,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 20
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
calories,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 17
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -90,7 +90,6 @@ class _FormBuilderComponentState extends State<FormBuilderComponent> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
print("widget enable ${widget.lockTextFields}");
|
|
||||||
return FormBuilder(
|
return FormBuilder(
|
||||||
key: formKey,
|
key: formKey,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
@ -103,7 +102,6 @@ class _FormBuilderComponentState extends State<FormBuilderComponent> {
|
||||||
itemCount: listOfTextField.length,
|
itemCount: listOfTextField.length,
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
print(listOfTextField[index]);
|
|
||||||
return FormBuilderTextFieldComponent(
|
return FormBuilderTextFieldComponent(
|
||||||
true, listOfTextField[index]);
|
true, listOfTextField[index]);
|
||||||
}),
|
}),
|
||||||
|
@ -134,8 +132,6 @@ class _FormBuilderComponentState extends State<FormBuilderComponent> {
|
||||||
int.parse(formKey
|
int.parse(formKey
|
||||||
.currentState?.fields['kalorien']?.value)));
|
.currentState?.fields['kalorien']?.value)));
|
||||||
|
|
||||||
print(box.get("USER"));
|
|
||||||
|
|
||||||
Navigator.of(context).pushReplacement(MaterialPageRoute(
|
Navigator.of(context).pushReplacement(MaterialPageRoute(
|
||||||
builder: (BuildContext context) => const MainPage()));
|
builder: (BuildContext context) => const MainPage()));
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import 'package:assorted_layout_widgets/assorted_layout_widgets.dart';
|
import 'package:assorted_layout_widgets/assorted_layout_widgets.dart';
|
||||||
|
import 'package:basic_utils/basic_utils.dart';
|
||||||
import 'package:ernaehrung/android/config/cast_helper.dart';
|
import 'package:ernaehrung/android/config/cast_helper.dart';
|
||||||
import 'package:ernaehrung/android/config/statistics.dart';
|
import 'package:ernaehrung/android/config/statistics.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import '../config/format_helper.dart';
|
||||||
import '../models/food.dart';
|
import '../models/food.dart';
|
||||||
|
|
||||||
class SearchedFoodComponent extends StatefulWidget {
|
class SearchedFoodComponent extends StatefulWidget {
|
||||||
|
@ -16,15 +19,29 @@ class SearchedFoodComponent extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SearchFoodComponentState extends State<SearchedFoodComponent> {
|
class _SearchFoodComponentState extends State<SearchedFoodComponent> {
|
||||||
|
int counter = 1;
|
||||||
void storeFood() async {
|
void storeFood(int counter) async {
|
||||||
StatisticsService.instance.addItemToMainBox(widget.food, widget.cardName);
|
|
||||||
final mealplanBox = Hive.box(dotenv.env['MEALPLAN_BOX']!);
|
final mealplanBox = Hive.box(dotenv.env['MEALPLAN_BOX']!);
|
||||||
if (!mealplanBox.isOpen){
|
if (!mealplanBox.isOpen){
|
||||||
Hive.openBox(dotenv.env['MEALPLAN_BOX']!);
|
Hive.openBox(dotenv.env['MEALPLAN_BOX']!);
|
||||||
}
|
}
|
||||||
|
for(int i = 0; i < counter; i++){
|
||||||
|
StatisticsService.instance.addItemToMainBox(widget.food, widget.cardName);
|
||||||
addValuesToList(mealplanBox, widget.cardName, [widget.food]);
|
addValuesToList(mealplanBox, widget.cardName, [widget.food]);
|
||||||
}
|
}
|
||||||
|
showSuccessToast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showSuccessToast(){
|
||||||
|
Fluttertoast.showToast(
|
||||||
|
msg: "${getToastFoodNameString(widget.food)} erfolgreich zu ${StringUtils.capitalize(widget.cardName)} hinzugefügt",
|
||||||
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
|
gravity: ToastGravity.BOTTOM,
|
||||||
|
timeInSecForIosWeb: 5,
|
||||||
|
backgroundColor: Colors.green,
|
||||||
|
textColor: Colors.black,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void addValuesToList(box, String key, List<Food> newValues){
|
void addValuesToList(box, String key, List<Food> newValues){
|
||||||
List<Food> existingList = castDynamicToListFood(box.get(key));
|
List<Food> existingList = castDynamicToListFood(box.get(key));
|
||||||
|
@ -38,10 +55,14 @@ class _SearchFoodComponentState extends State<SearchedFoodComponent> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
decoration:
|
margin: const EdgeInsets.only(top: 8),
|
||||||
const BoxDecoration(color: Color.fromARGB(234, 234, 123, 5)),
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.lightGreen,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
child: WrapSuper(
|
child: WrapSuper(
|
||||||
spacing: 32,
|
spacing: 32,
|
||||||
wrapType: WrapType.balanced,
|
wrapType: WrapType.balanced,
|
||||||
|
@ -54,35 +75,104 @@ class _SearchFoodComponentState extends State<SearchedFoodComponent> {
|
||||||
width: MediaQuery.of(context).size.width * 0.6,
|
width: MediaQuery.of(context).size.width * 0.6,
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.food.name,
|
widget.food.name,
|
||||||
maxLines: 1,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 20.0),
|
fontSize: 20.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.of(context).size.width * 0.6,
|
width: MediaQuery.of(context).size.width * 0.6,
|
||||||
child: Text(
|
child: Text(
|
||||||
"${widget.food.fatg} 100g "
|
"${widget.food.calories} kcal | 100g",
|
||||||
"${widget.food.calories} 100g "
|
|
||||||
"${widget.food.carbohydrateg.toString()} 100g",
|
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 20.0),
|
fontSize: 20.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top:12),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right :12),
|
||||||
|
child: Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
border: Border.all(color: Colors.white),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
counter = counter > 1 ? counter - 1 : 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Center(
|
||||||
|
child: Text(
|
||||||
|
"-",
|
||||||
|
style: TextStyle(fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(
|
||||||
|
width: 20,
|
||||||
|
child: Text(
|
||||||
|
counter.toString(),
|
||||||
|
style: const TextStyle(fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left:12),
|
||||||
|
child: Container(
|
||||||
|
width: 40,
|
||||||
|
height: 38,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
border: Border.all(color: Colors.white),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
counter++;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Center(
|
||||||
|
child: Text(
|
||||||
|
"+",
|
||||||
|
style: TextStyle(fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top:12),
|
||||||
|
child: ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
storeFood();
|
storeFood(counter);
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
|
@ -90,13 +180,23 @@ class _SearchFoodComponentState extends State<SearchedFoodComponent> {
|
||||||
shadowColor: Colors.greenAccent,
|
shadowColor: Colors.greenAccent,
|
||||||
elevation: 3,
|
elevation: 3,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(32.0)),
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
maximumSize: Size(
|
),
|
||||||
MediaQuery.of(context).size.width * 0.2, 36), //////// HERE
|
),
|
||||||
|
child: const Text(
|
||||||
|
'+',
|
||||||
|
style: TextStyle(fontSize: 25),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: const Text('+'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
],
|
],
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,17 +27,20 @@ class _SearchComponentState extends State<SearchComponent> {
|
||||||
return Container(
|
return Container(
|
||||||
constraints: const BoxConstraints.expand(),
|
constraints: const BoxConstraints.expand(),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(0, 16, 0, 0),
|
padding: const EdgeInsets.fromLTRB(16, 16, 16, 0), // Add padding on the X-axis
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16), // Add padding on the X-axis for text input
|
||||||
prefix: const Icon(Icons.search),
|
prefix: const Icon(Icons.search),
|
||||||
hintText: 'Suche nach Gericht',
|
hintText: 'Suche nach Gericht',
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: const BorderSide(color: Colors.blue))),
|
borderSide: const BorderSide(color: Colors.blue),
|
||||||
|
),
|
||||||
|
),
|
||||||
onChanged: findOnChanged,
|
onChanged: findOnChanged,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -47,12 +50,29 @@ class _SearchComponentState extends State<SearchComponent> {
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final food = foundedFood[index];
|
final food = foundedFood[index];
|
||||||
return SearchedFoodComponent(food, widget.cardName);
|
return SearchedFoodComponent(food, widget.cardName);
|
||||||
})
|
},
|
||||||
: EmptyWidget())
|
)
|
||||||
|
: EmptyWidget(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)));
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void findOnChanged(String searchedFood) async{
|
||||||
|
foundedFood =
|
||||||
|
allFoods
|
||||||
|
.where((food) => food.name
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.startsWith(searchedFood.toLowerCase()))
|
||||||
|
.toList();
|
||||||
|
setState(() {
|
||||||
|
foundedFood;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/*
|
||||||
void findOnChanged(String searchedFood) async {
|
void findOnChanged(String searchedFood) async {
|
||||||
foundedFood.clear();
|
foundedFood.clear();
|
||||||
if(searchedFood.isEmpty){
|
if(searchedFood.isEmpty){
|
||||||
|
@ -67,4 +87,5 @@ class _SearchComponentState extends State<SearchComponent> {
|
||||||
setState(() => {foundedFood});
|
setState(() => {foundedFood});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,12 @@ String getWeeklyRankingString(String foodName){
|
||||||
return limitedText;
|
return limitedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getToastFoodNameString(Food food){
|
||||||
|
int maxWidth = 25;
|
||||||
|
String limitedText = food.name.length > maxWidth ? "${food.name.substring(0, maxWidth - 3)} ... " : food.name;
|
||||||
|
return limitedText;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String,List<int>> getMapOfDistinctElementsWithCounterAndCalories(List<Food> foods){
|
Map<String,List<int>> getMapOfDistinctElementsWithCounterAndCalories(List<Food> foods){
|
||||||
Map<String,List<int>> resultMap = <String,List<int>>{};
|
Map<String,List<int>> resultMap = <String,List<int>>{};
|
||||||
for(int i = 0; i < foods.length;i++){
|
for(int i = 0; i < foods.length;i++){
|
||||||
|
@ -24,6 +30,7 @@ Map<String,List<int>> getMapOfDistinctElementsWithCounterAndCalories(List<Food>
|
||||||
return resultMap;
|
return resultMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<Food> getListOfDistinctElements(List<Food> foods){
|
List<Food> getListOfDistinctElements(List<Food> foods){
|
||||||
List<Food> result = [];
|
List<Food> result = [];
|
||||||
for(int i = 0; i < foods.length;i++){
|
for(int i = 0; i < foods.length;i++){
|
||||||
|
|
|
@ -12,7 +12,6 @@ mockDataForWholeWeek(){
|
||||||
int timestamp = statisticsService.getTimestampFromNow();
|
int timestamp = statisticsService.getTimestampFromNow();
|
||||||
List<int> currentWeek = statisticsService.getTimestampsByTimestampAndTimespan(TimeSpan.week, timestamp);
|
List<int> currentWeek = statisticsService.getTimestampsByTimestampAndTimespan(TimeSpan.week, timestamp);
|
||||||
for(int i = 0;i < currentWeek.length;i++){
|
for(int i = 0;i < currentWeek.length;i++){
|
||||||
print(mockFood(i));
|
|
||||||
box.put(currentWeek[i], mockFood(i));
|
box.put(currentWeek[i], mockFood(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,6 +214,11 @@ class StatisticsService {
|
||||||
return sum as int;
|
return sum as int;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double getCaloryTargetForOneDay(){
|
||||||
|
final Box userBox = Hive.box<User>("USER_BOX");
|
||||||
|
return userBox.get("USER").kalorien.toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
List<double> getAllEatenIngredientsForTodayStatistics(double dayLen){
|
List<double> getAllEatenIngredientsForTodayStatistics(double dayLen){
|
||||||
Box box = Hive.box(todayStatisticsBoxName);
|
Box box = Hive.box(todayStatisticsBoxName);
|
||||||
final Box userBox = Hive.box<User>("USER_BOX");
|
final Box userBox = Hive.box<User>("USER_BOX");
|
||||||
|
|
|
@ -18,9 +18,9 @@ class MainPage extends StatefulWidget {
|
||||||
|
|
||||||
class MainPageState extends State<MainPage> {
|
class MainPageState extends State<MainPage> {
|
||||||
List pages = [
|
List pages = [
|
||||||
const TodayPage(title: 'Today'),
|
const TodayPage(title: 'Essensplan'),
|
||||||
const MealPlanPage(title: 'Meal Plan'),
|
const MealPlanPage(title: 'Gesamtübersicht'),
|
||||||
const ProgressPage(title: 'Progress')
|
const ProgressPage(title: 'Statistiken')
|
||||||
];
|
];
|
||||||
|
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
|
@ -47,7 +47,12 @@ class MainPageState extends State<MainPage> {
|
||||||
title: Row(
|
title: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(pages[currentIndex].title),
|
Text(
|
||||||
|
pages[currentIndex].title,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.black
|
||||||
|
),
|
||||||
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|
|
@ -169,6 +169,20 @@ class ProgressPage extends StatelessWidget {
|
||||||
barGroups: value,
|
barGroups: value,
|
||||||
gridData: FlGridData(show: false),
|
gridData: FlGridData(show: false),
|
||||||
alignment: BarChartAlignment.spaceAround,
|
alignment: BarChartAlignment.spaceAround,
|
||||||
|
extraLinesData: ExtraLinesData(
|
||||||
|
horizontalLines: [
|
||||||
|
HorizontalLine(
|
||||||
|
y: StatisticsService.instance.getCaloryTargetForOneDay(), // Specify the y-value where you want the line to be positioned
|
||||||
|
color: Colors.black, // Change the color as per your requirement
|
||||||
|
strokeWidth: 2, // Adjust the width as needed
|
||||||
|
dashArray: [3, 2],
|
||||||
|
label: HorizontalLineLabel(
|
||||||
|
show: true,
|
||||||
|
labelResolver: (x) => "Zielwert"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -28,8 +28,11 @@ class _SearchFoodPageState extends State<SearchFoodPage> {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
return SearchComponent(snapshot.data!, widget.cardName);
|
return SearchComponent(snapshot.data!, widget.cardName);
|
||||||
}else {
|
}else {
|
||||||
return const Placeholder();
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(), // Loading animation
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})));
|
})
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import 'package:hive_flutter/adapters.dart';
|
||||||
class TodayPage extends StatefulWidget {
|
class TodayPage extends StatefulWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final Color backgroundColor = const Color(0xff47a44b);
|
final Color backgroundColor = const Color(0xff47a44b);
|
||||||
|
|
||||||
const TodayPage({Key? key, required this.title}) : super(key: key);
|
const TodayPage({Key? key, required this.title}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -15,6 +14,8 @@ class TodayPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TodayPageState extends State<TodayPage> {
|
class _TodayPageState extends State<TodayPage> {
|
||||||
|
final List<Color> colors = [Colors.teal,Colors.red,Colors.green];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -30,7 +31,8 @@ class _TodayPageState extends State<TodayPage> {
|
||||||
String mealTypeAsString = box.keyAt(i).toString();
|
String mealTypeAsString = box.keyAt(i).toString();
|
||||||
return CardComponent(
|
return CardComponent(
|
||||||
mealTypeAsString,
|
mealTypeAsString,
|
||||||
StatisticsService.instance.getMealsOfTodayByMealtype(mealTypeAsString)
|
StatisticsService.instance.getMealsOfTodayByMealtype(mealTypeAsString),
|
||||||
|
color: colors[i],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
})));
|
})));
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'package:ernaehrung/web/web_app.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'android/andoird_app.dart';
|
import 'android/android_app.dart';
|
||||||
import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb;
|
import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb;
|
||||||
import 'android/config/setup_todaybox_config.dart';
|
import 'android/config/setup_todaybox_config.dart';
|
||||||
|
|
||||||
|
|
13
pubspec.lock
13
pubspec.lock
|
@ -312,6 +312,19 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
fluttertoast:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: fluttertoast
|
||||||
|
sha256: "474f7d506230897a3cd28c965ec21c5328ae5605fc9c400cd330e9e9d6ac175c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "8.2.2"
|
||||||
form_builder_validators:
|
form_builder_validators:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -49,6 +49,7 @@ dependencies:
|
||||||
basic_utils: ^5.5.4
|
basic_utils: ^5.5.4
|
||||||
flutter_form_builder: ^8.0.0
|
flutter_form_builder: ^8.0.0
|
||||||
form_builder_validators: ^8.0.0
|
form_builder_validators: ^8.0.0
|
||||||
|
fluttertoast: ^8.0.7
|
||||||
flutter_profile_picture: ^2.0.0
|
flutter_profile_picture: ^2.0.0
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue