diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index c5219ab..6a72c01 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mobile/repos/cart.dart'; import 'package:mobile/repos/product.dart'; +import 'package:mobile/repos/receipt.dart'; import 'package:provider/provider.dart'; import 'pages/landing_page.dart'; import 'package:mobile/repos/bottom_navigation_bar.dart'; @@ -19,6 +20,7 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => BottomNavigationBarRepo()), ChangeNotifierProvider(create: (_) => ProductRepo()), ChangeNotifierProvider(create: (_) => CartRepo()), + ChangeNotifierProvider(create: (_) => ReceiptRepo()), ], child: MaterialApp( title: 'Fresh Plaza', diff --git a/mobile/lib/pages/all_products_page.dart b/mobile/lib/pages/all_products_page.dart index fa91ca0..0f525a6 100644 --- a/mobile/lib/pages/all_products_page.dart +++ b/mobile/lib/pages/all_products_page.dart @@ -19,14 +19,9 @@ class ProductListItem extends StatelessWidget { @override Widget build(BuildContext context) { return PrimaryCard( - child: ElevatedButton( - style: ButtonStyle( - backgroundColor: WidgetStateProperty.all(Colors.transparent), - elevation: WidgetStateProperty.all(0), - shape: WidgetStateProperty.all(const RoundedRectangleBorder()), - padding: WidgetStateProperty.all(EdgeInsets.zero), - splashFactory: NoSplash.splashFactory), - onPressed: () { + child: InkWell( + borderRadius: const BorderRadius.all(Radius.circular(10)), + onTap: () { Navigator.of(context) .push(MaterialPageRoute(builder: (context) => productPage)); }, @@ -49,7 +44,7 @@ class ProductListItem extends StatelessWidget { borderRadius: const BorderRadius.only( topRight: Radius.circular(10), bottomRight: Radius.circular(10)), - child: Image( + child: Ink.image( image: AssetImage(imagePath), fit: BoxFit.contain, width: 100, diff --git a/mobile/lib/pages/all_receipts_page.dart b/mobile/lib/pages/all_receipts_page.dart new file mode 100644 index 0000000..f697189 --- /dev/null +++ b/mobile/lib/pages/all_receipts_page.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:mobile/repos/receipt.dart'; +import 'package:provider/provider.dart'; + +class ReceiptsListItem extends StatelessWidget { + final String dateFormatted; + final int totalPrice; + const ReceiptsListItem( + {super.key, required this.dateFormatted, required this.totalPrice}); + + @override + Widget build(BuildContext context) { + return Card( + child: InkWell( + borderRadius: const BorderRadius.all(Radius.circular(10)), + onTap: () {}, + child: Container( + padding: const EdgeInsets.all(20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [Text(dateFormatted), Text("$totalPrice kr")], + ), + ), + ), + ); + } +} + +class AllReceiptsPage extends StatelessWidget { + const AllReceiptsPage({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded(child: Consumer( + builder: (_, cartRepo, __) { + final allReceipts = cartRepo.allReceipts(); + return ListView.builder( + shrinkWrap: true, + itemBuilder: (_, idx) { + return ReceiptsListItem( + dateFormatted: allReceipts[idx].dateFormatted(), + totalPrice: allReceipts[idx].totalPrice()); + }, + itemCount: allReceipts.length, + ); + }, + )), + ], + ); + } +} diff --git a/mobile/lib/pages/cart_page.dart b/mobile/lib/pages/cart_page.dart index e596f42..ac1869f 100644 --- a/mobile/lib/pages/cart_page.dart +++ b/mobile/lib/pages/cart_page.dart @@ -150,7 +150,7 @@ class CartPage extends StatelessWidget { context, MaterialPageRoute( builder: (context) => - FinishShoppingPage())); + const FinishShoppingPage())); }, child: const Text("Afslut indkøb")), ), diff --git a/mobile/lib/pages/dashboard.dart b/mobile/lib/pages/dashboard.dart index e41715a..bf27e57 100644 --- a/mobile/lib/pages/dashboard.dart +++ b/mobile/lib/pages/dashboard.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mobile/pages/all_products_page.dart'; import 'package:mobile/pages/cart_page.dart'; -import 'package:mobile/pages/receipts_page.dart'; +import 'package:mobile/pages/all_receipts_page.dart'; import 'package:mobile/repos/bottom_navigation_bar.dart'; import 'package:mobile/repos/cart.dart'; import 'package:provider/provider.dart'; @@ -10,7 +10,7 @@ class Dashboard extends StatelessWidget { final List pages = [ const AllProductsPage(), const CartPage(), - const ReceiptsPage(), + const AllReceiptsPage(), ]; Dashboard({super.key}); @@ -48,17 +48,3 @@ class Dashboard extends StatelessWidget { ); } } - -//Consumer(builder: (_, productRepo, __) { -// final products = productRepo.allProducts(); -// return ListView.builder( -// shrinkWrap: true, -// itemBuilder: (_, idx) => ProductListItem( -// name: products[idx].name, -// price: products[idx].price, -// imagePath: "assets/${products[idx].name}.png", -// productPage: ProductPage(product: products[idx]), -// ), -// itemCount: products.length, -// ); -// }) diff --git a/mobile/lib/pages/finish_shopping_page.dart b/mobile/lib/pages/finish_shopping_page.dart index 9d00598..df84cc1 100644 --- a/mobile/lib/pages/finish_shopping_page.dart +++ b/mobile/lib/pages/finish_shopping_page.dart @@ -1,48 +1,9 @@ import 'package:flutter/material.dart'; import 'package:mobile/repos/cart.dart'; import 'package:mobile/widgets/primary_button.dart'; +import 'package:mobile/widgets/receipt_item.dart'; import 'package:provider/provider.dart'; -class ReceiptItem extends StatelessWidget { - final int pricePerAmount; - final String name; - final int amount; - - const ReceiptItem( - {super.key, - required this.pricePerAmount, - required this.name, - required this.amount}); - - @override - Widget build(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(name), - Row( - children: [ - SizedBox( - width: 60, - child: Text( - "$amount stk", - textAlign: TextAlign.end, - overflow: TextOverflow.ellipsis, - )), - SizedBox( - width: 60, - child: Text( - "${pricePerAmount * amount} kr", - textAlign: TextAlign.end, - overflow: TextOverflow.ellipsis, - )) - ], - ), - ], - ); - } -} - class FinishShoppingPage extends StatelessWidget { const FinishShoppingPage({super.key}); @@ -65,7 +26,7 @@ class FinishShoppingPage extends StatelessWidget { child: Expanded( child: ListView.builder( shrinkWrap: true, - itemBuilder: (_, idx) => ReceiptItem( + itemBuilder: (_, idx) => ReceiptItemView( pricePerAmount: cart[idx].product.price, name: cart[idx].product.name, amount: cart[idx].amount), diff --git a/mobile/lib/pages/product_page.dart b/mobile/lib/pages/product_page.dart index 3c82bae..fb79c6f 100644 --- a/mobile/lib/pages/product_page.dart +++ b/mobile/lib/pages/product_page.dart @@ -12,76 +12,74 @@ class ProductPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: Container( + body: Card( margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(10)), - color: const Color(0xFFFFFFFF), - border: Border.all(color: const Color(0xFF666666)), - ), - child: Column(children: [ - Row( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const BackButton(), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - product.name, - style: const TextStyle( - fontSize: 20, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Column(children: [ + Row( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const BackButton(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + product.name, + style: const TextStyle( + fontSize: 20, + ), ), - ), - Text( - "${product.price} kr", - style: const TextStyle( - fontSize: 16, - ), - ) - ]) - ], - ), - ], - ), - Expanded( - child: Container( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Image( - image: AssetImage("assets/${product.name}.png"), - height: 250, - fit: BoxFit.fitHeight, - ), - Text( - product.name, - style: Theme.of(context).textTheme.bodyLarge, - ), - Text( - "${product.price} kr", - style: Theme.of(context).textTheme.bodyLarge, - ), - Padding( - padding: const EdgeInsets.only(top: 20, bottom: 20), - child: Text(product.description), - ), - PrimaryButton( - onPressed: () {}, child: const Text("Find i butik")), - PrimaryButton( - onPressed: () { - var cartRepo = context.read(); - cartRepo.addToCart(product); - }, - child: const Text("Tilføj til indkøbskurv")), - ], - ), + Text( + "${product.price} kr", + style: const TextStyle( + fontSize: 16, + ), + ) + ]) + ], + ), + ], ), - ) - ]), + Expanded( + child: Container( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Image( + image: AssetImage("assets/${product.name}.png"), + height: 250, + fit: BoxFit.fitHeight, + ), + Text( + product.name, + style: Theme.of(context).textTheme.bodyLarge, + ), + Text( + "${product.price} kr", + style: Theme.of(context).textTheme.bodyLarge, + ), + Padding( + padding: const EdgeInsets.only(top: 20, bottom: 20), + child: Text(product.description), + ), + PrimaryButton( + onPressed: () {}, child: const Text("Find i butik")), + PrimaryButton( + onPressed: () { + var cartRepo = context.read(); + cartRepo.addToCart(product); + }, + child: const Text("Tilføj til indkøbskurv")), + ], + ), + ), + ) + ]), + ), ), ); } diff --git a/mobile/lib/pages/receipts_page.dart b/mobile/lib/pages/receipts_page.dart deleted file mode 100644 index a126369..0000000 --- a/mobile/lib/pages/receipts_page.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/material.dart'; - -class ReceiptsPage extends StatelessWidget { - const ReceiptsPage({super.key}); - - @override - Widget build(BuildContext context) { - return const Row(); - } -} diff --git a/mobile/lib/repos/receipt.dart b/mobile/lib/repos/receipt.dart new file mode 100644 index 0000000..f97d734 --- /dev/null +++ b/mobile/lib/repos/receipt.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:mobile/repos/product.dart'; + +class ReceiptRepo extends ChangeNotifier { + final List receipts = [ + Receipt( + id: 0, + date: DateTime.fromMillisecondsSinceEpoch(1730031200000), + receiptItems: [ + ReceiptItem( + product: Product( + id: 1, + name: "Letmælk", + price: 13, + description: "Konventionel minimælk med fedtprocent på 0,4%"), + amount: 1), + ReceiptItem( + product: Product( + id: 0, + name: "Minimælk", + price: 12, + description: "Konventionel minimælk med fedtprocent på 0,4%"), + amount: 3), + ]), + Receipt(id: 1, date: DateTime.now(), receiptItems: [ + ReceiptItem( + product: Product( + id: 1, + name: "Letmælk", + price: 13, + description: "Konventionel minimælk med fedtprocent på 0,4%"), + amount: 3), + ReceiptItem( + product: Product( + id: 0, + name: "Minimælk", + price: 12, + description: "Konventionel minimælk med fedtprocent på 0,4%"), + amount: 1), + ]) + ]; + + List allReceipts() { + return receipts; + } + + Receipt? receiptWithId(int id) { + for (var i = 0; i < receipts.length; i++) { + if (receipts[i].id == id) { + return receipts[i]; + } + } + return null; + } +} + +class Receipt { + final int id; + final DateTime date; + final List receiptItems; + + Receipt({required this.date, required this.receiptItems, required this.id}); + + ReceiptItem? withProductId(int productId) { + for (var i = 0; i < receiptItems.length; i++) { + if (receiptItems[i].product.id == productId) { + return receiptItems[i]; + } + } + return null; + } + + int totalPrice() { + var result = 0; + for (var i = 0; i < receiptItems.length; i++) { + result += receiptItems[i].totalPrice(); + } + return result; + } + + String dateFormatted() { + return "${date.day}-${date.month}-${date.year}"; + } +} + +class ReceiptItem { + final Product product; + final int amount; + ReceiptItem({required this.product, required this.amount}); + + int totalPrice() { + return product.price * amount; + } +} diff --git a/mobile/lib/widgets/receipt_item.dart b/mobile/lib/widgets/receipt_item.dart new file mode 100644 index 0000000..8b7ad78 --- /dev/null +++ b/mobile/lib/widgets/receipt_item.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +class ReceiptItemView extends StatelessWidget { + final int pricePerAmount; + final String name; + final int amount; + + const ReceiptItemView( + {super.key, + required this.pricePerAmount, + required this.name, + required this.amount}); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(name), + Row( + children: [ + SizedBox( + width: 60, + child: Text( + "$amount stk", + textAlign: TextAlign.end, + overflow: TextOverflow.ellipsis, + )), + SizedBox( + width: 60, + child: Text( + "${pricePerAmount * amount} kr", + textAlign: TextAlign.end, + overflow: TextOverflow.ellipsis, + )) + ], + ), + ], + ); + } +}