added editing entries and deleting them
This commit is contained in:
		
							parent
							
								
									fa9a0569fb
								
							
						
					
					
						commit
						955c506b92
					
				
					 9 changed files with 369 additions and 101 deletions
				
			
		| 
						 | 
				
			
			@ -76,7 +76,7 @@ class ApiClient {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Future<Map<String, dynamic>> delete(String path) async {
 | 
			
		||||
  Future<void> delete(String path) async {
 | 
			
		||||
    final response = await httpClient.delete(
 | 
			
		||||
      Uri.parse('$baseUrl$path'),
 | 
			
		||||
      headers: headers(),
 | 
			
		||||
| 
						 | 
				
			
			@ -85,8 +85,6 @@ class ApiClient {
 | 
			
		|||
    if (response.statusCode != 200) {
 | 
			
		||||
      throw Exception('Response returned status code: ${response.statusCode}');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return _jsonDecode(response);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<Map<String, dynamic>> patch(String path, Map<String, dynamic> body) async {
 | 
			
		||||
| 
						 | 
				
			
			@ -182,4 +180,22 @@ class ApiClient {
 | 
			
		|||
    };
 | 
			
		||||
    await post("/entry", entry);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> deleteEntry(int id) async {
 | 
			
		||||
    await delete("/entry/$id");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> updateEntry(int id, {
 | 
			
		||||
    required double grams,
 | 
			
		||||
    required int productId,
 | 
			
		||||
    required int mealId,
 | 
			
		||||
  }
 | 
			
		||||
  ) async {
 | 
			
		||||
    var entry = {
 | 
			
		||||
      "grams": grams,
 | 
			
		||||
      "product_id": productId,
 | 
			
		||||
      "meal_id": mealId,
 | 
			
		||||
    };
 | 
			
		||||
    await patch("/entry/$id", entry);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,6 @@ class _AddEntryScreen extends State<AddEntryScreen> {
 | 
			
		|||
    try {
 | 
			
		||||
      double.parse(gramsController.text);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print(e);
 | 
			
		||||
      showError("Grams must be a number");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										146
									
								
								lib/screens/edit_entry.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								lib/screens/edit_entry.dart
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,146 @@
 | 
			
		|||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:fooder_web/screens/based.dart';
 | 
			
		||||
import 'package:fooder_web/models/product.dart';
 | 
			
		||||
import 'package:fooder_web/models/entry.dart';
 | 
			
		||||
import 'package:fooder_web/widgets/product.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EditEntryScreen extends BasedScreen {
 | 
			
		||||
  final Entry entry;
 | 
			
		||||
 | 
			
		||||
  const EditEntryScreen({super.key, required super.apiClient, required this.entry});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<EditEntryScreen> createState() => _EditEntryScreen();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _EditEntryScreen extends State<EditEntryScreen> {
 | 
			
		||||
  final gramsController = TextEditingController();
 | 
			
		||||
  final productNameController = TextEditingController();
 | 
			
		||||
  List<Product> products = [];
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void dispose() {
 | 
			
		||||
    gramsController.dispose();
 | 
			
		||||
    productNameController.dispose();
 | 
			
		||||
    super.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void popMeDady() {
 | 
			
		||||
    Navigator.pop(context);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState () {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    setState(() {
 | 
			
		||||
      gramsController.text = widget.entry.grams.toString();
 | 
			
		||||
      productNameController.text = widget.entry.product.name;
 | 
			
		||||
      products = [widget.entry.product];
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _getProducts() async {
 | 
			
		||||
    var productsMap = await widget.apiClient.getProducts(productNameController.text);
 | 
			
		||||
    setState(() {
 | 
			
		||||
      products = (productsMap['products'] as List<dynamic>).map((e) => Product.fromJson(e as Map<String, dynamic>)).toList();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void showError(String message)
 | 
			
		||||
  {
 | 
			
		||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
			
		||||
      SnackBar(
 | 
			
		||||
        content: Text(message, textAlign: TextAlign.center),
 | 
			
		||||
        backgroundColor: Theme.of(context).colorScheme.error,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _saveEntry() async {
 | 
			
		||||
    if (products.length != 1) {
 | 
			
		||||
      showError("Pick product first");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      double.parse(gramsController.text);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      showError("Grams must be a number");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await widget.apiClient.updateEntry(
 | 
			
		||||
      widget.entry.id,
 | 
			
		||||
      grams: double.parse(gramsController.text),
 | 
			
		||||
      productId: products[0].id,
 | 
			
		||||
      mealId: widget.entry.mealId,
 | 
			
		||||
    );
 | 
			
		||||
    popMeDady();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _deleteEntry() async {
 | 
			
		||||
    await widget.apiClient.deleteEntry(widget.entry.id);
 | 
			
		||||
    popMeDady();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
 | 
			
		||||
        title: const Text("🅵🅾🅾🅳🅴🆁"),
 | 
			
		||||
      ),
 | 
			
		||||
      body: Center(
 | 
			
		||||
        child: Container(
 | 
			
		||||
          constraints: const BoxConstraints(maxWidth: 720),
 | 
			
		||||
          padding: const EdgeInsets.all(10),
 | 
			
		||||
          child: ListView(
 | 
			
		||||
            children: <Widget>[
 | 
			
		||||
              TextFormField(
 | 
			
		||||
                decoration: const InputDecoration(
 | 
			
		||||
                  labelText: 'Grams',
 | 
			
		||||
                ),
 | 
			
		||||
                controller: gramsController,
 | 
			
		||||
              ),
 | 
			
		||||
              TextFormField(
 | 
			
		||||
                decoration: const InputDecoration(
 | 
			
		||||
                  labelText: 'Product name',
 | 
			
		||||
                ),
 | 
			
		||||
                controller: productNameController,
 | 
			
		||||
                onChanged: (_) => _getProducts(),
 | 
			
		||||
              ),
 | 
			
		||||
              for (var product in products)
 | 
			
		||||
                ListTile(
 | 
			
		||||
                onTap: () {
 | 
			
		||||
                  setState(() {
 | 
			
		||||
                    products = [product];
 | 
			
		||||
                    });
 | 
			
		||||
                },
 | 
			
		||||
                title: ProductWidget(
 | 
			
		||||
                  product: product,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ]
 | 
			
		||||
          )
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
      floatingActionButton: Row(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.end,
 | 
			
		||||
        children: <Widget>[
 | 
			
		||||
          FloatingActionButton(
 | 
			
		||||
            onPressed: _deleteEntry,
 | 
			
		||||
            heroTag: null,
 | 
			
		||||
            child: const Icon(Icons.delete),
 | 
			
		||||
          ),
 | 
			
		||||
          FloatingActionButton(
 | 
			
		||||
            onPressed: _saveEntry,
 | 
			
		||||
            heroTag: null,
 | 
			
		||||
            child: const Icon(Icons.save),
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ class _MainScreen extends State<MainScreen> {
 | 
			
		|||
      content = Container(
 | 
			
		||||
        constraints: const BoxConstraints(maxWidth: 720),
 | 
			
		||||
        padding: const EdgeInsets.all(10),
 | 
			
		||||
        child: DiaryWidget(diary: diary!),
 | 
			
		||||
        child: DiaryWidget(diary: diary!, apiClient: widget.apiClient, refreshParent: _asyncInitState),
 | 
			
		||||
      );
 | 
			
		||||
      title = Row(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,55 +1,67 @@
 | 
			
		|||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:fooder_web/models/diary.dart';
 | 
			
		||||
import 'package:fooder_web/widgets/meal.dart';
 | 
			
		||||
import 'package:fooder_web/widgets/macro.dart';
 | 
			
		||||
import 'package:fooder_web/client.dart';
 | 
			
		||||
import 'dart:core';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DiaryWidget extends StatelessWidget {
 | 
			
		||||
  final Diary diary;
 | 
			
		||||
  final ApiClient apiClient;
 | 
			
		||||
  final Function() refreshParent;
 | 
			
		||||
 | 
			
		||||
  const DiaryWidget({super.key, required this.diary});
 | 
			
		||||
  const DiaryWidget({super.key, required this.diary, required this.apiClient, required this.refreshParent});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Container(
 | 
			
		||||
      padding: const EdgeInsets.all(8),
 | 
			
		||||
      child: ListView(
 | 
			
		||||
        padding: const EdgeInsets.all(8),
 | 
			
		||||
      child: CustomScrollView(
 | 
			
		||||
        slivers: <Widget>[
 | 
			
		||||
          SliverAppBar(
 | 
			
		||||
            title: Row(
 | 
			
		||||
              children: <Widget>[
 | 
			
		||||
                const Spacer(),
 | 
			
		||||
                Text(
 | 
			
		||||
                  "${diary.calories.toStringAsFixed(1)} kcal",
 | 
			
		||||
                  style: Theme.of(context).textTheme.headlineLarge!.copyWith(
 | 
			
		||||
                    color: Theme.of(context).colorScheme.onSecondary,
 | 
			
		||||
                    fontWeight: FontWeight.bold,
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ]
 | 
			
		||||
            ),
 | 
			
		||||
            expandedHeight: 128,
 | 
			
		||||
            backgroundColor: Theme.of(context).colorScheme.secondary,
 | 
			
		||||
            shape: RoundedRectangleBorder(
 | 
			
		||||
              borderRadius: BorderRadius.circular(8),
 | 
			
		||||
            ),
 | 
			
		||||
            floating: true,
 | 
			
		||||
            flexibleSpace: FlexibleSpaceBar(
 | 
			
		||||
              title: MacroWidget(
 | 
			
		||||
                protein: diary.protein,
 | 
			
		||||
                carb: diary.carb,
 | 
			
		||||
                fat: diary.fat,
 | 
			
		||||
                style: Theme.of(context).textTheme.bodyMedium!.copyWith(
 | 
			
		||||
                  color: Theme.of(context).colorScheme.onSecondary,
 | 
			
		||||
                  fontWeight: FontWeight.bold,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
          SliverList(
 | 
			
		||||
            delegate: SliverChildListDelegate(
 | 
			
		||||
              [
 | 
			
		||||
                for (var meal in diary.meals)
 | 
			
		||||
                  MealWidget(
 | 
			
		||||
                    meal: meal,
 | 
			
		||||
              ),
 | 
			
		||||
          Card(
 | 
			
		||||
            child: Padding(
 | 
			
		||||
              padding: const EdgeInsets.all(8.0),
 | 
			
		||||
              child: Column(
 | 
			
		||||
                children: <Widget>[
 | 
			
		||||
                  Row(
 | 
			
		||||
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
                    children: <Widget>[
 | 
			
		||||
                      Text(
 | 
			
		||||
                        "carb: ${diary.carb.toStringAsFixed(2)}",
 | 
			
		||||
                        style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
                      ),
 | 
			
		||||
                      Text(
 | 
			
		||||
                        "fat: ${diary.fat.toStringAsFixed(2)}",
 | 
			
		||||
                        style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
                      ),
 | 
			
		||||
                      Text(
 | 
			
		||||
                        "protein: ${diary.protein.toStringAsFixed(2)}",
 | 
			
		||||
                        style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
                      ),
 | 
			
		||||
                      Text(
 | 
			
		||||
                        "calories: ${diary.calories.toStringAsFixed(2)}",
 | 
			
		||||
                        style: TextStyle(color: Theme.of(context).colorScheme.primary),
 | 
			
		||||
                    apiClient: apiClient,
 | 
			
		||||
                    refreshParent: refreshParent,
 | 
			
		||||
                    ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
                ],
 | 
			
		||||
          ),
 | 
			
		||||
            ),
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:fooder_web/models/entry.dart';
 | 
			
		||||
import 'package:fooder_web/widgets/macro.dart';
 | 
			
		||||
import 'dart:core';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,29 +23,17 @@ class EntryWidget extends StatelessWidget {
 | 
			
		|||
                  style: Theme.of(context).textTheme.titleLarge,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              Text("${entry.calories.toStringAsFixed(2)} kcal"),
 | 
			
		||||
              Text("${entry.calories.toStringAsFixed(1)} kcal"),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
          Row(
 | 
			
		||||
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
            children: <Widget>[
 | 
			
		||||
              Text(
 | 
			
		||||
                "carb: ${entry.carb.toStringAsFixed(2)}",
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
          MacroWidget(
 | 
			
		||||
            protein: entry.protein,
 | 
			
		||||
            carb: entry.carb,
 | 
			
		||||
            fat: entry.fat,
 | 
			
		||||
            amount: entry.grams,
 | 
			
		||||
            style: Theme.of(context).textTheme.bodyMedium!.copyWith(
 | 
			
		||||
              color: Theme.of(context).colorScheme.secondary,
 | 
			
		||||
            ),
 | 
			
		||||
              Text(
 | 
			
		||||
                "fat: ${entry.fat.toStringAsFixed(2)}",
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
              ),
 | 
			
		||||
              Text(
 | 
			
		||||
                "protein: ${entry.protein.toStringAsFixed(2)}",
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
              ),
 | 
			
		||||
              Text(
 | 
			
		||||
                "amount: ${entry.grams.toStringAsFixed(2)}",
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										102
									
								
								lib/widgets/macro.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								lib/widgets/macro.dart
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,102 @@
 | 
			
		|||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MacroWidget extends StatelessWidget {
 | 
			
		||||
  final double? amount;
 | 
			
		||||
  final double? calories;
 | 
			
		||||
  final double protein;
 | 
			
		||||
  final double carb;
 | 
			
		||||
  final double fat;
 | 
			
		||||
  final TextStyle style;
 | 
			
		||||
 | 
			
		||||
  const MacroWidget({
 | 
			
		||||
    Key? key,
 | 
			
		||||
    this.calories,
 | 
			
		||||
    this.amount,
 | 
			
		||||
    required this.protein,
 | 
			
		||||
    required this.carb,
 | 
			
		||||
    required this.fat,
 | 
			
		||||
    required this.style,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    var elements = <Widget>[
 | 
			
		||||
    Expanded(
 | 
			
		||||
      flex: 1,
 | 
			
		||||
      child: Text(
 | 
			
		||||
        "C: ${carb.toStringAsFixed(1)} g",
 | 
			
		||||
        style: style,
 | 
			
		||||
        textAlign: TextAlign.center,
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    Expanded(
 | 
			
		||||
      flex: 1,
 | 
			
		||||
      child: Text(
 | 
			
		||||
        "F: ${fat.toStringAsFixed(1)} g",
 | 
			
		||||
        style: style,
 | 
			
		||||
        textAlign: TextAlign.center,
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    Expanded(
 | 
			
		||||
      flex: 1,
 | 
			
		||||
      child: Text(
 | 
			
		||||
        "P: ${protein.toStringAsFixed(1)} g",
 | 
			
		||||
        style: style,
 | 
			
		||||
        textAlign: TextAlign.center,
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    if (calories != null) {
 | 
			
		||||
      elements.add(
 | 
			
		||||
        Expanded(
 | 
			
		||||
          flex: 1,
 | 
			
		||||
          child: Text(
 | 
			
		||||
            "${calories!.toStringAsFixed(1)} kcal",
 | 
			
		||||
            style: style,
 | 
			
		||||
            textAlign: TextAlign.center,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (amount != null) {
 | 
			
		||||
      elements.add(
 | 
			
		||||
        Expanded(
 | 
			
		||||
          flex: 1,
 | 
			
		||||
          child: Text(
 | 
			
		||||
            "${amount!.toStringAsFixed(1)} g",
 | 
			
		||||
            style: style,
 | 
			
		||||
            textAlign: TextAlign.center,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (amount == null && calories == null) {
 | 
			
		||||
      elements.add(
 | 
			
		||||
        Expanded(
 | 
			
		||||
          flex: 1,
 | 
			
		||||
          child: Text(
 | 
			
		||||
            "",
 | 
			
		||||
            style: style,
 | 
			
		||||
            textAlign: TextAlign.center,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Padding(
 | 
			
		||||
      padding: const EdgeInsets.only(
 | 
			
		||||
        top: 4.0,
 | 
			
		||||
        bottom: 4.0,
 | 
			
		||||
        left: 8.0,
 | 
			
		||||
        right: 8.0,
 | 
			
		||||
      ),
 | 
			
		||||
      child: Row(
 | 
			
		||||
        children: elements,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +1,18 @@
 | 
			
		|||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:fooder_web/models/meal.dart';
 | 
			
		||||
import 'package:fooder_web/widgets/entry.dart';
 | 
			
		||||
import 'package:fooder_web/widgets/macro.dart';
 | 
			
		||||
import 'package:fooder_web/screens/edit_entry.dart';
 | 
			
		||||
import 'package:fooder_web/client.dart';
 | 
			
		||||
import 'dart:core';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MealWidget extends StatelessWidget {
 | 
			
		||||
  final Meal meal;
 | 
			
		||||
  final ApiClient apiClient;
 | 
			
		||||
  final Function() refreshParent;
 | 
			
		||||
 | 
			
		||||
  const MealWidget({super.key, required this.meal});
 | 
			
		||||
  const MealWidget({super.key, required this.meal, required this.apiClient, required this.refreshParent});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
| 
						 | 
				
			
			@ -26,33 +31,39 @@ class MealWidget extends StatelessWidget {
 | 
			
		|||
                        style: Theme.of(context).textTheme.titleLarge,
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    Text("${meal.calories.toStringAsFixed(2)} kcal"),
 | 
			
		||||
                    Text("${meal.calories.toStringAsFixed(1)} kcal"),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
                Row(
 | 
			
		||||
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
                  children: <Widget>[
 | 
			
		||||
                    Text(
 | 
			
		||||
                      "carb: ${meal.carb.toStringAsFixed(2)}",
 | 
			
		||||
                      style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
                MacroWidget(
 | 
			
		||||
                  protein: meal.protein,
 | 
			
		||||
                  carb: meal.carb,
 | 
			
		||||
                  fat: meal.fat,
 | 
			
		||||
                  style: Theme.of(context).textTheme.bodyMedium!.copyWith(
 | 
			
		||||
                    color: Theme.of(context).colorScheme.secondary,
 | 
			
		||||
                  ),
 | 
			
		||||
                    Text(
 | 
			
		||||
                      "fat: ${meal.fat.toStringAsFixed(2)}",
 | 
			
		||||
                      style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
                    ),
 | 
			
		||||
                    Text(
 | 
			
		||||
                      "protein: ${meal.protein.toStringAsFixed(2)}",
 | 
			
		||||
                      style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
            children: <Widget>[
 | 
			
		||||
              for (var entry in meal.entries)
 | 
			
		||||
                EntryWidget(
 | 
			
		||||
                ListTile(
 | 
			
		||||
                  title: EntryWidget(
 | 
			
		||||
                    entry: entry,
 | 
			
		||||
                  ),
 | 
			
		||||
                onTap: () {
 | 
			
		||||
                  Navigator.push(
 | 
			
		||||
                    context,
 | 
			
		||||
                    MaterialPageRoute(
 | 
			
		||||
                      builder: (context) => EditEntryScreen(
 | 
			
		||||
                        apiClient: apiClient,
 | 
			
		||||
                        entry: entry,
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ).then((_) {
 | 
			
		||||
                    refreshParent();
 | 
			
		||||
                  });
 | 
			
		||||
                },
 | 
			
		||||
                )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:fooder_web/models/product.dart';
 | 
			
		||||
import 'package:fooder_web/widgets/macro.dart';
 | 
			
		||||
import 'dart:core';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,25 +23,17 @@ class ProductWidget extends StatelessWidget {
 | 
			
		|||
                  style: Theme.of(context).textTheme.titleLarge,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              Text("${product.calories.toStringAsFixed(2)} kcal"),
 | 
			
		||||
              Text("${product.calories.toStringAsFixed(1)} kcal"),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
          Row(
 | 
			
		||||
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
            children: <Widget>[
 | 
			
		||||
              Text(
 | 
			
		||||
                "carb: ${product.carb.toStringAsFixed(2)}",
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
          MacroWidget(
 | 
			
		||||
            protein: product.protein,
 | 
			
		||||
            carb: product.carb,
 | 
			
		||||
            fat: product.fat,
 | 
			
		||||
            style: Theme.of(context).textTheme.bodyMedium!.copyWith(
 | 
			
		||||
              color: Theme.of(context).colorScheme.secondary,
 | 
			
		||||
              fontWeight: FontWeight.bold,
 | 
			
		||||
            ),
 | 
			
		||||
              Text(
 | 
			
		||||
                "fat: ${product.fat.toStringAsFixed(2)}",
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
              ),
 | 
			
		||||
              Text(
 | 
			
		||||
                "protein: ${product.protein.toStringAsFixed(2)}",
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).colorScheme.secondary),
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue