import 'package:cdb_ui/api.dart'; import 'package:cdb_ui/pages/consume.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qr_bar_code/qr/qr.dart'; class TransactionPage extends StatelessWidget { final Transaction transaction; final Function? refresh; const TransactionPage(this.transaction, {this.refresh, super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Text("UUID: ${transaction.uuid}"), QRCode( data: transaction.uuid, size: 22, semanticsLabel: "Transaction UUID", ), Text("${transaction.item} - ${transaction.variant}"), Text("Added: ${tsFormat(transaction.timestamp)}"), if (transaction.expired) const Text("Transaction is Expired!"), IconText(Icons.money, transaction.price.format(), color: Colors.green), IconText(Icons.store, transaction.origin!, color: Colors.blue), IconText(Icons.location_city, transaction.location!), if (transaction.note != null) Text(transaction.note!), if (transaction.consumed != null) ...[ const Divider(), Text("Consumed on: ${tsFormat(transaction.consumed!.timestamp)}"), IconText(Icons.store, transaction.consumed!.destination, color: Colors.blue), IconText(Icons.money, transaction.consumed!.price.format(), color: Colors.green), ] // todo : chart with price history ], ), floatingActionButton: FloatingActionButton( onPressed: () { Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (context) { return ConsumePage(transaction, refresh ?? () {}); }, )); }, child: const Icon(Icons.receipt_long)), ); } } class TransactionCard extends StatelessWidget { final Transaction t; final Function refresh; const 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, refresh); }, )); }, onLongPress: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) { return TransactionPage(t); }, )); }, child: Card( color: t.expired ? Colors.red[100] : Colors.black, margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), elevation: 4, child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Text( t.item, style: const TextStyle(fontSize: 16), ), const 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]), ), ], ), const SizedBox( height: 10, ), if ((t.note ?? "").isNotEmpty) ...[ const SizedBox(height: 8), Text(t.note!), const SizedBox( height: 10, ) ], IconText(Icons.money, "${t.price.value.toStringAsFixed(2)} ${t.price.currency}", color: Colors.green), if (t.origin != null) ...[ const SizedBox(height: 8), IconText(Icons.store, t.origin!, color: Colors.blue) ], if (t.location != null) ...[ const SizedBox( height: 8, ), IconText(Icons.location_city, t.location!) ] ], ), ), ), ); } } String tsFormat(int ts) { DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(ts * 1000); return DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); } class IconText extends StatelessWidget { final IconData icon; final String text; final Color? color; const IconText(this.icon, this.text, {super.key, this.color}); @override Widget build(BuildContext context) { return Row( children: [ Icon(icon, size: 18, color: color), const SizedBox(width: 6), Text( text, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ], ); } }