2024-09-04 18:05:04 +00:00
|
|
|
import 'package:cdb_ui/api.dart';
|
2024-09-19 06:46:48 +00:00
|
|
|
import 'package:cdb_ui/pages/flow.dart';
|
2024-09-07 21:56:52 +00:00
|
|
|
import 'package:cdb_ui/pages/itemview.dart';
|
2024-09-08 15:45:48 +00:00
|
|
|
import 'package:cdb_ui/pages/setup.dart';
|
2024-09-04 18:05:04 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
2024-09-08 15:45:48 +00:00
|
|
|
Future<void> main() async {
|
|
|
|
await API().init();
|
2024-09-04 18:05:04 +00:00
|
|
|
runApp(const MyApp());
|
|
|
|
}
|
|
|
|
|
|
|
|
class MyApp extends StatelessWidget {
|
|
|
|
const MyApp({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return MaterialApp(
|
|
|
|
title: 'CDB',
|
|
|
|
theme: ThemeData(
|
2024-09-07 22:51:18 +00:00
|
|
|
colorScheme: ColorScheme.fromSeed(
|
|
|
|
seedColor: Colors.deepPurple, brightness: Brightness.dark),
|
2024-09-04 18:05:04 +00:00
|
|
|
useMaterial3: true,
|
|
|
|
),
|
2024-09-16 07:42:55 +00:00
|
|
|
home: API().isInit() ? const MyHomePage() : const SetupPage(),
|
2024-09-04 18:05:04 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-05 10:03:47 +00:00
|
|
|
class StatsPage extends StatelessWidget {
|
|
|
|
const StatsPage({super.key});
|
|
|
|
|
2024-09-20 06:52:56 +00:00
|
|
|
Future<(List<MinItem>, List<Transaction>, GlobalItemStat)>
|
|
|
|
_fetchData() async {
|
|
|
|
return (
|
|
|
|
await API().getItemsUnderMin(),
|
|
|
|
await API().getExpiredItems(),
|
|
|
|
await API().getGlobalItemStat()
|
|
|
|
);
|
2024-09-15 13:15:46 +00:00
|
|
|
}
|
|
|
|
|
2024-09-05 10:03:47 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2024-09-07 21:56:52 +00:00
|
|
|
// todo : add global statistics
|
2024-09-18 06:09:08 +00:00
|
|
|
// todo : demand stat
|
|
|
|
// todo : stat on origin + destination
|
|
|
|
|
2024-09-15 13:15:46 +00:00
|
|
|
return Scaffold(
|
|
|
|
body: FutureBuilder(
|
|
|
|
future: _fetchData(),
|
|
|
|
builder: (context, snapshot) {
|
|
|
|
if (!snapshot.hasData) {
|
2024-09-16 07:42:55 +00:00
|
|
|
return const CircularProgressIndicator();
|
2024-09-15 13:15:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var data = snapshot.data!;
|
|
|
|
var min = data.$1;
|
|
|
|
var expired = data.$2;
|
2024-09-20 06:52:56 +00:00
|
|
|
var global_stat = data.$3;
|
2024-09-15 13:15:46 +00:00
|
|
|
|
|
|
|
return Column(
|
|
|
|
children: [
|
2024-09-20 06:52:56 +00:00
|
|
|
Card(
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Text("Items: ${global_stat.item_count}"),
|
|
|
|
Text("Inventory: ${global_stat.total_transactions}"),
|
|
|
|
Text("Price: ${global_stat.total_price} €")
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
|
2024-09-16 07:42:55 +00:00
|
|
|
if (min.isNotEmpty)
|
|
|
|
const ListTile(title: Text("Items under Minimum")),
|
2024-09-15 13:15:46 +00:00
|
|
|
...min.map((item) {
|
|
|
|
return ListTile(
|
|
|
|
title: Text(
|
2024-09-16 07:42:55 +00:00
|
|
|
"Item ${item.itemVariant} under minimum. Needs ${item.need} more."),
|
2024-09-15 13:15:46 +00:00
|
|
|
);
|
|
|
|
}).toList(),
|
|
|
|
|
2024-09-16 07:42:55 +00:00
|
|
|
if (expired.isNotEmpty)
|
|
|
|
const ListTile(title: Text("Expired Items")),
|
2024-09-15 13:15:46 +00:00
|
|
|
|
|
|
|
// Mapping expired list to widgets
|
|
|
|
...expired.map((item) {
|
|
|
|
return ListTile(
|
|
|
|
title: TransactionCard(item, () {}),
|
|
|
|
);
|
|
|
|
}).toList(),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
);
|
2024-09-07 21:56:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-05 10:03:47 +00:00
|
|
|
class LocationsPage extends StatelessWidget {
|
|
|
|
const LocationsPage({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2024-09-07 21:56:52 +00:00
|
|
|
// todo : add locations tree view
|
2024-09-16 07:42:55 +00:00
|
|
|
return const Scaffold();
|
2024-09-05 10:03:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ItemsPage extends StatelessWidget {
|
|
|
|
const ItemsPage({super.key});
|
2024-09-05 08:12:56 +00:00
|
|
|
|
2024-09-04 18:05:04 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Scaffold(
|
2024-09-05 10:03:47 +00:00
|
|
|
appBar: AppBar(
|
|
|
|
title: const Text("Items"),
|
|
|
|
),
|
|
|
|
body: FutureBuilder(
|
|
|
|
future: API().getItems(),
|
|
|
|
builder: (context, snapshot) {
|
|
|
|
if (!snapshot.hasData) {
|
|
|
|
return const CircularProgressIndicator();
|
|
|
|
}
|
|
|
|
|
|
|
|
var items = snapshot.data!;
|
|
|
|
|
2024-09-18 06:09:08 +00:00
|
|
|
return ListView(
|
|
|
|
children: items.map((x) {
|
|
|
|
return ItemTile(x);
|
|
|
|
}).toList());
|
2024-09-05 10:03:47 +00:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class MyHomePage extends StatefulWidget {
|
|
|
|
const MyHomePage({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<MyHomePage> createState() => _MyHomePageState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _MyHomePageState extends State<MyHomePage> {
|
|
|
|
int pageIndex = 0;
|
|
|
|
|
2024-09-16 07:42:55 +00:00
|
|
|
List<Widget> pages = [
|
|
|
|
const StatsPage(),
|
|
|
|
const ItemsPage(),
|
|
|
|
const FlowsPage(),
|
|
|
|
const LocationsPage()
|
|
|
|
];
|
2024-09-05 10:03:47 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Scaffold(
|
|
|
|
bottomNavigationBar: BottomNavigationBar(
|
2024-09-15 13:15:46 +00:00
|
|
|
fixedColor: Colors.white,
|
|
|
|
unselectedItemColor: Colors.white70,
|
2024-09-05 10:03:47 +00:00
|
|
|
items: const [
|
|
|
|
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
|
|
|
|
BottomNavigationBarItem(
|
|
|
|
icon: Icon(Icons.data_object), label: "Items"),
|
2024-09-07 21:56:52 +00:00
|
|
|
BottomNavigationBarItem(icon: Icon(Icons.receipt), label: "Flows"),
|
2024-09-05 10:03:47 +00:00
|
|
|
BottomNavigationBarItem(
|
|
|
|
icon: Icon(Icons.location_city), label: "Locations"),
|
|
|
|
],
|
|
|
|
currentIndex: pageIndex,
|
|
|
|
onTap: (value) {
|
|
|
|
setState(() {
|
|
|
|
pageIndex = value;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
body: pages[pageIndex],
|
2024-09-04 18:05:04 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-18 06:09:08 +00:00
|
|
|
class ItemTile extends StatelessWidget {
|
2024-09-05 08:12:56 +00:00
|
|
|
final String item;
|
2024-09-04 18:05:04 +00:00
|
|
|
|
2024-09-18 06:09:08 +00:00
|
|
|
const ItemTile(this.item, {super.key});
|
2024-09-04 18:05:04 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2024-09-18 06:09:08 +00:00
|
|
|
return ListTile(
|
2024-09-16 07:42:55 +00:00
|
|
|
onTap: () {
|
|
|
|
API().getItem(item).then((itemInfo) => Navigator.push(context,
|
|
|
|
MaterialPageRoute(builder: (context) => ItemView(item: itemInfo))));
|
2024-09-04 18:05:04 +00:00
|
|
|
},
|
2024-09-18 06:09:08 +00:00
|
|
|
title: Text(item),
|
2024-09-04 18:05:04 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|