import 'package:cdb_ui/api.dart'; import 'package:cdb_ui/pages/consume.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'supply.dart'; class ItemView extends StatefulWidget { final Item item; @override State createState() => _ItemViewState(); const ItemView({super.key, required this.item}); } class _ItemViewState extends State { void refresh() { setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.item.name), ), body: Column(children: [ Padding( padding: EdgeInsets.symmetric(horizontal: 28), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ const Align( alignment: Alignment.centerLeft, child: Placeholder( fallbackWidth: 100, fallbackHeight: 100, ), ), // todo SizedBox( width: 16.0, ), Column( children: [ Text( widget.item.name, style: const TextStyle(fontWeight: FontWeight.bold), ), Text(widget.item.category), ], ) ], ), const SizedBox(height: 18), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: widget.item.variants.entries.map((entry) { return Column(children: [ Text( entry.value.name, style: TextStyle(fontWeight: FontWeight.bold), ), FutureBuilder( future: API().getStat(widget.item.id, entry.key), builder: (context, snapshot) { if (!snapshot.hasData) { return CircularProgressIndicator(); } var stat = snapshot.data!; return Column( children: [ Text("Amount: ${stat.amount}"), Text( "Total Cost: ${stat.total_price.toStringAsFixed(2)}") ], ); }, ) ]); }).toList()), SizedBox( height: 12, ) ], ), ), FutureBuilder( future: API().getInventory(widget.item.id), builder: (context, snapshot) { if (!snapshot.hasData) { return const CircularProgressIndicator(); } var data = snapshot.data!; return Expanded( child: ListView( children: data.map((x) => TransactionCard(x, refresh)).toList())); }, ) ]), floatingActionButton: FloatingActionButton( onPressed: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => SupplyPage(widget.item, refresh))); }, child: const Icon(Icons.add)), ); } } class TransactionCard extends StatelessWidget { final Transaction t; Function refresh; TransactionCard(this.t, this.refresh, {super.key}); @override Widget build(BuildContext context) { return InkWell( onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) { return ConsumePage(t.uuid, t.item, t.variant, this.refresh); }, )); }, child: Card( color: t.expired ? Colors.red[100] : Colors.black, margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), elevation: 4, child: Padding( padding: EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Text( t.item, style: TextStyle(fontSize: 16), ), SizedBox( width: 4, ), Text( t.variant, style: TextStyle(fontSize: 14, color: Colors.grey[400]), ), ], ), Text( tsFormat(t.timestamp), style: TextStyle(fontSize: 14, color: Colors.grey[700]), ), ], ), SizedBox( height: 10, ), Row( children: [ Icon(Icons.money, size: 18, color: Colors.green), SizedBox(width: 6), Text( "${t.price.value.toStringAsFixed(2)} ${t.price.currency}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ], ), if (t.origin != null) ...[ SizedBox(height: 8), Row( children: [ Icon(Icons.store, size: 18, color: Colors.blue), SizedBox(width: 6), Text( t.origin!, style: TextStyle(fontSize: 14, color: Colors.grey[700]), ), ], ), ], ], ), ), ), ); } } String tsFormat(int ts) { DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(ts * 1000); return DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); }