From e9b0e93f43f845597cfc6cee2a28a1f238ed08ae Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 20 Sep 2024 09:18:06 +0200 Subject: [PATCH] update --- lib/main.dart | 126 +-------------------------------------- lib/pages/items.dart | 47 +++++++++++++++ lib/pages/locations.dart | 87 +++++++++++++++++++++++++++ lib/pages/stats.dart | 72 ++++++++++++++++++++++ pubspec.lock | 16 +++++ pubspec.yaml | 1 + 6 files changed, 226 insertions(+), 123 deletions(-) create mode 100644 lib/pages/items.dart create mode 100644 lib/pages/locations.dart create mode 100644 lib/pages/stats.dart diff --git a/lib/main.dart b/lib/main.dart index 2ee0ade..8e647f5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,9 @@ import 'package:cdb_ui/api.dart'; import 'package:cdb_ui/pages/flow.dart'; -import 'package:cdb_ui/pages/itemview.dart'; +import 'package:cdb_ui/pages/items.dart'; +import 'package:cdb_ui/pages/locations.dart'; import 'package:cdb_ui/pages/setup.dart'; +import 'package:cdb_ui/pages/stats.dart'; import 'package:flutter/material.dart'; Future main() async { @@ -26,111 +28,6 @@ class MyApp extends StatelessWidget { } } -class StatsPage extends StatelessWidget { - const StatsPage({super.key}); - - Future<(List, List, GlobalItemStat)> - _fetchData() async { - return ( - await API().getItemsUnderMin(), - await API().getExpiredItems(), - await API().getGlobalItemStat() - ); - } - - @override - Widget build(BuildContext context) { - // todo : add global statistics - // todo : demand stat - // todo : stat on origin + destination - - return Scaffold( - body: FutureBuilder( - future: _fetchData(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const CircularProgressIndicator(); - } - - var data = snapshot.data!; - var min = data.$1; - var expired = data.$2; - var global_stat = data.$3; - - return Column( - children: [ - Card( - child: Column( - children: [ - Text("Items: ${global_stat.item_count}"), - Text("Inventory: ${global_stat.total_transactions}"), - Text("Price: ${global_stat.total_price} €") - ], - )), - - if (min.isNotEmpty) - const ListTile(title: Text("Items under Minimum")), - ...min.map((item) { - return ListTile( - title: Text( - "Item ${item.itemVariant} under minimum. Needs ${item.need} more."), - ); - }).toList(), - - if (expired.isNotEmpty) - const ListTile(title: Text("Expired Items")), - - // Mapping expired list to widgets - ...expired.map((item) { - return ListTile( - title: TransactionCard(item, () {}), - ); - }).toList(), - ], - ); - }, - ), - ); - } -} - -class LocationsPage extends StatelessWidget { - const LocationsPage({super.key}); - - @override - Widget build(BuildContext context) { - // todo : add locations tree view - return const Scaffold(); - } -} - -class ItemsPage extends StatelessWidget { - const ItemsPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text("Items"), - ), - body: FutureBuilder( - future: API().getItems(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const CircularProgressIndicator(); - } - - var items = snapshot.data!; - - return ListView( - children: items.map((x) { - return ItemTile(x); - }).toList()); - }), - ); - } -} - class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @@ -173,20 +70,3 @@ class _MyHomePageState extends State { ); } } - -class ItemTile extends StatelessWidget { - final String item; - - const ItemTile(this.item, {super.key}); - - @override - Widget build(BuildContext context) { - return ListTile( - onTap: () { - API().getItem(item).then((itemInfo) => Navigator.push(context, - MaterialPageRoute(builder: (context) => ItemView(item: itemInfo)))); - }, - title: Text(item), - ); - } -} diff --git a/lib/pages/items.dart b/lib/pages/items.dart new file mode 100644 index 0000000..217f427 --- /dev/null +++ b/lib/pages/items.dart @@ -0,0 +1,47 @@ +import 'package:cdb_ui/api.dart'; +import 'package:cdb_ui/pages/itemview.dart'; +import 'package:flutter/material.dart'; + +class ItemsPage extends StatelessWidget { + const ItemsPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Items"), + ), + body: FutureBuilder( + future: API().getItems(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const CircularProgressIndicator(); + } + + var items = snapshot.data!; + + return ListView( + children: items.map((x) { + return ItemTile(x); + }).toList()); + }), + ); + } +} + +class ItemTile extends StatelessWidget { + final String item; + + const ItemTile(this.item, {super.key}); + + @override + Widget build(BuildContext context) { + return ListTile( + onTap: () { + API().getItem(item).then((itemInfo) => Navigator.push(context, + MaterialPageRoute(builder: (context) => ItemView(item: itemInfo)))); + }, + title: Text(item), + ); + } +} diff --git a/lib/pages/locations.dart b/lib/pages/locations.dart new file mode 100644 index 0000000..2a0d945 --- /dev/null +++ b/lib/pages/locations.dart @@ -0,0 +1,87 @@ +import 'package:cdb_ui/api.dart'; +import 'package:cdb_ui/pages/itemview.dart'; +import 'package:flutter/material.dart'; + +class LocationsPage extends StatelessWidget { + const LocationsPage({super.key}); + + @override + Widget build(BuildContext context) { + // todo : add locations tree view + return const Scaffold(); + } +} + +class LocationView extends StatefulWidget { + final Location location; + + const LocationView(this.location, {super.key}); + + @override + State createState() => _LocationViewState(); +} + +class _LocationViewState extends State { + bool recursive = true; + + void refresh() { + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.location.name), + ), + body: Column( + children: [ + Card( + child: Column( + children: [ + if (widget.location.parent != null) + Text("Inside: ${widget.location.parent!}"), + if (widget.location.conditions?.temperature != null) + Text( + "Temperature: ${widget.location.conditions!.temperature} C°") + ], + ), + ), + Row( + children: [ + Checkbox( + value: !recursive, + onChanged: (bool? newValue) { + setState(() { + recursive = !(newValue ?? false); + }); + }, + ), + const Expanded( + child: Text( + 'Show only exact matches with location', + style: TextStyle(fontSize: 16), + ), + ), + ], + ), + FutureBuilder( + future: API().getTransactionsOfLocation(widget.location.id, + recursive: recursive), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const CircularProgressIndicator(); + } + + var data = snapshot.data!; + + return ListView( + children: + data.map((x) => TransactionCard(x, refresh)).toList()); + }, + ) + ], + ), + ); + } +} diff --git a/lib/pages/stats.dart b/lib/pages/stats.dart new file mode 100644 index 0000000..85efb2f --- /dev/null +++ b/lib/pages/stats.dart @@ -0,0 +1,72 @@ +import 'package:cdb_ui/api.dart'; +import 'package:cdb_ui/pages/itemview.dart'; +import 'package:flutter/material.dart'; + +class StatsPage extends StatelessWidget { + const StatsPage({super.key}); + + Future<(List, List, GlobalItemStat)> + _fetchData() async { + return ( + await API().getItemsUnderMin(), + await API().getExpiredItems(), + await API().getGlobalItemStat() + ); + } + + @override + Widget build(BuildContext context) { + // todo : add global statistics + // todo : demand stat + // todo : stat on origin + destination + // todo : add btn for scanning transaction + + return Scaffold( + body: FutureBuilder( + future: _fetchData(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const CircularProgressIndicator(); + } + + var data = snapshot.data!; + var min = data.$1; + var expired = data.$2; + var globalStat = data.$3; + + return Column( + children: [ + Card( + child: Column( + children: [ + Text("Items: ${globalStat.item_count}"), + Text("Inventory: ${globalStat.total_transactions}"), + Text("Price: ${globalStat.total_price} €") + ], + )), + + if (min.isNotEmpty) + const ListTile(title: Text("Items under Minimum")), + ...min.map((item) { + return ListTile( + title: Text( + "Item ${item.itemVariant} under minimum. Needs ${item.need} more."), + ); + }).toList(), + + if (expired.isNotEmpty) + const ListTile(title: Text("Expired Items")), + + // Mapping expired list to widgets + ...expired.map((item) { + return ListTile( + title: TransactionCard(item, () {}), + ); + }).toList(), + ], + ); + }, + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 8e39663..18a3532 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -73,6 +73,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.1" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -105,6 +113,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: "94307bef3a324a0d329d3ab77b2f0c6e5ed739185ffc029ed28c0f9b019ea7ef" + url: "https://pub.dev" + source: hosted + version: "0.69.0" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index e4cc3a3..f58703c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ dependencies: qr_bar_code_scanner_dialog: ^0.0.5 intl: ^0.18.0 shared_preferences: ^2.1.0 + fl_chart: ^0.69.0 # The following adds the Cupertino Icons font to your application.