From 850391045e171a3b18f127136f0470b767e17be9 Mon Sep 17 00:00:00 2001 From: Mikkel Troels Kongsted Date: Thu, 6 Mar 2025 08:28:53 +0100 Subject: [PATCH] use product repo by server --- .../android/app/src/main/AndroidManifest.xml | 1 + mobile/lib/main.dart | 2 +- mobile/lib/models/product.dart | 12 +- mobile/lib/pages/all_products_page.dart | 7 +- mobile/lib/pages/cart_page.dart | 11 +- mobile/lib/pages/finish_shopping_page.dart | 2 +- mobile/lib/pages/product_page.dart | 4 +- mobile/lib/pages/receipt_page.dart | 2 +- mobile/lib/repos/cart.dart | 8 +- mobile/lib/repos/product.dart | 114 +++++++++++++----- mobile/lib/repos/receipt.dart | 10 +- mobile/pubspec.lock | 2 +- mobile/pubspec.yaml | 1 + 13 files changed, 116 insertions(+), 60 deletions(-) diff --git a/mobile/android/app/src/main/AndroidManifest.xml b/mobile/android/app/src/main/AndroidManifest.xml index a82bc28..58284db 100644 --- a/mobile/android/app/src/main/AndroidManifest.xml +++ b/mobile/android/app/src/main/AndroidManifest.xml @@ -43,4 +43,5 @@ + diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 6b14f45..d293389 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -23,7 +23,7 @@ class MyApp extends StatelessWidget { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => Routing()), - ChangeNotifierProvider(create: (_) => ProductRepoByMemory()), + ChangeNotifierProvider(create: (_) => ProductRepo()), ChangeNotifierProvider(create: (_) => CartRepo()), ChangeNotifierProvider(create: (_) => ReceiptRepo()), ChangeNotifierProvider(create: (_) => PayingStateRepo()), diff --git a/mobile/lib/models/product.dart b/mobile/lib/models/product.dart index faefcd0..e14a0a9 100644 --- a/mobile/lib/models/product.dart +++ b/mobile/lib/models/product.dart @@ -4,16 +4,24 @@ class Product { final int id; final String name; final String description; - final int priceInDkkCent; + final int priceInDkkCents; final Coordinate? location; final String? barcode; Product({ required this.id, required this.name, - required this.priceInDkkCent, + required this.priceInDkkCents, required this.description, this.location, this.barcode, }); + + Product.fromJson(Map json) + : id = json["id"], + name = json["name"], + description = json["description"], + priceInDkkCents = json["priceInDkkCents"], + location = null, + barcode = null; } diff --git a/mobile/lib/pages/all_products_page.dart b/mobile/lib/pages/all_products_page.dart index 3bf8de5..18104d2 100644 --- a/mobile/lib/pages/all_products_page.dart +++ b/mobile/lib/pages/all_products_page.dart @@ -99,7 +99,7 @@ class AllProductsPage extends StatelessWidget { @override Widget build(BuildContext context) { - final productRepo = Provider.of(context); + final productRepo = Provider.of(context); return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -122,15 +122,14 @@ class AllProductsPage extends StatelessWidget { ], ), Expanded( - child: - Consumer(builder: (_, productRepo, __) { + child: Consumer(builder: (_, productRepo, __) { final products = productRepo.filteredProducts; return ListView.builder( shrinkWrap: true, itemBuilder: (_, idx) => ProductListItem( productId: products[idx].id, name: products[idx].name, - price: products[idx].priceInDkkCent, + price: products[idx].priceInDkkCents, productPage: ProductPage(product: products[idx]), product: products[idx], ), diff --git a/mobile/lib/pages/cart_page.dart b/mobile/lib/pages/cart_page.dart index 7f64b48..8100fe9 100644 --- a/mobile/lib/pages/cart_page.dart +++ b/mobile/lib/pages/cart_page.dart @@ -162,7 +162,7 @@ class CartPage extends StatelessWidget { cartRepo: cartRepo, productId: cart[idx].product.id, name: cart[idx].product.name, - price: cart[idx].product.priceInDkkCent, + price: cart[idx].product.priceInDkkCents, amount: cart[idx].amount), itemCount: cart.length, ); @@ -205,9 +205,8 @@ class CartPage extends StatelessWidget { child: const Text("Cancel")), TextButton( onPressed: () { - final ProductRepoByMemory - productRepo = context.read< - ProductRepoByMemory>(); + final productRepo = + context.read(); final CartRepo cartRepo = context.read(); final productResult = @@ -271,8 +270,8 @@ class CartPage extends StatelessWidget { } final CartRepo cartRepo = context.read(); - final ProductRepoByMemory productRepo = - context.read(); + final productRepo = + context.read(); final productResult = productRepo .productWithBarcode(result.rawContent); switch (productResult) { diff --git a/mobile/lib/pages/finish_shopping_page.dart b/mobile/lib/pages/finish_shopping_page.dart index b04548f..cb15a05 100644 --- a/mobile/lib/pages/finish_shopping_page.dart +++ b/mobile/lib/pages/finish_shopping_page.dart @@ -36,7 +36,7 @@ class FinishShoppingPage extends StatelessWidget { child: ListView.builder( shrinkWrap: true, itemBuilder: (_, idx) => ReceiptItemView( - pricePerAmount: cart[idx].product.priceInDkkCent, + pricePerAmount: cart[idx].product.priceInDkkCents, name: cart[idx].product.name, amount: cart[idx].amount), itemCount: cart.length)), diff --git a/mobile/lib/pages/product_page.dart b/mobile/lib/pages/product_page.dart index 6861f95..e9ea9ef 100644 --- a/mobile/lib/pages/product_page.dart +++ b/mobile/lib/pages/product_page.dart @@ -39,7 +39,7 @@ class ProductPage extends StatelessWidget { ), ), Text( - formatDkkCents(product.priceInDkkCent), + formatDkkCents(product.priceInDkkCents), style: const TextStyle( fontSize: 16, ), @@ -67,7 +67,7 @@ class ProductPage extends StatelessWidget { style: Theme.of(context).textTheme.bodyLarge, ), Text( - formatDkkCents(product.priceInDkkCent), + formatDkkCents(product.priceInDkkCents), style: Theme.of(context).textTheme.bodyLarge, ), Padding( diff --git a/mobile/lib/pages/receipt_page.dart b/mobile/lib/pages/receipt_page.dart index 5f4a66b..b3a2fce 100644 --- a/mobile/lib/pages/receipt_page.dart +++ b/mobile/lib/pages/receipt_page.dart @@ -29,7 +29,7 @@ class ReceiptView extends StatelessWidget { shrinkWrap: true, itemBuilder: (_, idx) => ReceiptItemView( pricePerAmount: - receiptItems[idx].product.priceInDkkCent, + receiptItems[idx].product.priceInDkkCents, name: receiptItems[idx].product.name, amount: receiptItems[idx].amount), itemCount: receiptItems.length), diff --git a/mobile/lib/repos/cart.dart b/mobile/lib/repos/cart.dart index 5a6e483..a261293 100644 --- a/mobile/lib/repos/cart.dart +++ b/mobile/lib/repos/cart.dart @@ -9,14 +9,14 @@ class CartRepo extends ChangeNotifier { product: Product( id: 1, name: "Letmælk", - priceInDkkCent: 1295, + priceInDkkCents: 1295, description: "Konventionel letmælk med fedtprocent på 1,5%"), amount: 1), CartItem( product: Product( id: 2, name: "Frilands Øko Supermælk", - priceInDkkCent: 1995, + priceInDkkCents: 1995, description: "Økologisk mælk af frilandskøer med fedtprocent på 3,5%. Ikke homogeniseret eller pasteuriseret. Skaber store muskler og styrker knoglerne 💪"), amount: 6), @@ -24,7 +24,7 @@ class CartRepo extends ChangeNotifier { product: Product( id: 3, name: "Minimælk", - priceInDkkCent: 1195, + priceInDkkCents: 1195, description: "Konventionel minimælk med fedtprocent på 0,4%"), amount: 1), ]; @@ -98,7 +98,7 @@ class CartRepo extends ChangeNotifier { return cart.fold( 0, (prev, cartItem) => - prev + cartItem.amount * cartItem.product.priceInDkkCent); + prev + cartItem.amount * cartItem.product.priceInDkkCents); } void clearCart() { diff --git a/mobile/lib/repos/product.dart b/mobile/lib/repos/product.dart index 839ad64..1159825 100644 --- a/mobile/lib/repos/product.dart +++ b/mobile/lib/repos/product.dart @@ -1,38 +1,39 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; import 'package:mobile/models/coordinate.dart'; import 'package:mobile/models/product.dart'; import 'package:mobile/results.dart'; -class ProductRepoByMemory extends ChangeNotifier { +class ProductRepo extends ChangeNotifier { int _nextId = 0; List products = []; - late List filteredProducts; - ProductRepoByMemory() { + String query = ""; + ProductRepo() { _addAllProducts(); - filteredProducts = products; } int getNextId() { return _nextId++; } - List allProducts() { - return products; + get filteredProducts { + if (query.trim().isEmpty) { + return products; + } + return products.where((product) { + final nameLower = product.name.toLowerCase(); + final descriptionLower = product.description.toLowerCase(); + final searchLower = query.toLowerCase(); + + return nameLower.contains(searchLower) || + descriptionLower.contains(searchLower); + }).toList(); } void searchProducts(String query) { - if (query.trim().isEmpty) { - filteredProducts = products; - } else { - filteredProducts = products.where((product) { - final nameLower = product.name.toLowerCase(); - final descriptionLower = product.description.toLowerCase(); - final searchLower = query.toLowerCase(); - - return nameLower.contains(searchLower) || - descriptionLower.contains(searchLower); - }).toList(); - } + this.query = query; notifyListeners(); } @@ -50,78 +51,125 @@ class ProductRepoByMemory extends ChangeNotifier { Product( id: _nextId++, name: "Minimælk", - priceInDkkCent: 1200, + priceInDkkCents: 1200, description: "Konventionel minimælk med fedtprocent på 0,4%"), Product( id: _nextId++, name: "Letmælk", - priceInDkkCent: 1300, + priceInDkkCents: 1300, description: "Konventionel letmælk med fedtprocent på 1,5%", location: Coordinate(x: 1800, y: 100)), Product( id: _nextId++, name: "Frilands Øko Supermælk", - priceInDkkCent: 2000, + priceInDkkCents: 2000, description: "Økologisk mælk af frilandskøer med fedtprocent på 3,5%. Ikke homogeniseret eller pasteuriseret. Skaber store muskler og styrker knoglerne 💪"), Product( id: _nextId++, name: "Øko Gulerødder 1 kg", - priceInDkkCent: 1000, + priceInDkkCents: 1000, description: ""), Product( id: _nextId++, name: "Øko Agurk", - priceInDkkCent: 1000, + priceInDkkCents: 1000, description: ""), Product( id: _nextId++, name: "Æbler 1 kg", - priceInDkkCent: 1000, + priceInDkkCents: 1000, description: ""), Product( id: _nextId++, name: "Basmati Ris", - priceInDkkCent: 2000, + priceInDkkCents: 2000, description: ""), Product( id: _nextId++, name: "Haribo Mix", - priceInDkkCent: 3000, + priceInDkkCents: 3000, description: ""), Product( - id: _nextId++, name: "Smør", priceInDkkCent: 3000, description: ""), + id: _nextId++, name: "Smør", priceInDkkCents: 3000, description: ""), Product( id: _nextId++, name: "Harboe Cola", - priceInDkkCent: 500, + priceInDkkCents: 500, description: ""), Product( id: _nextId++, name: "Monster Energi Drik", - priceInDkkCent: 2000, + priceInDkkCents: 2000, description: ""), Product( id: _nextId++, name: "Spaghetti", - priceInDkkCent: 1000, + priceInDkkCents: 1000, description: ""), Product( id: _nextId++, name: "Rød Cecil", - priceInDkkCent: 6000, + priceInDkkCents: 6000, description: ""), Product( id: _nextId++, name: "Jägermeister 750 ml", - priceInDkkCent: 12000, + priceInDkkCents: 12000, description: ""), Product( id: _nextId++, barcode: "5711953068881", name: "Protein Chokoladedrik", - priceInDkkCent: 1500, + priceInDkkCents: 1500, description: "Arla's protein chokolade drik der giver store muskler"), ]; } } + +class ProductRepoByServer extends ChangeNotifier { + String apiUrl = "http://127.0.0.1:8080/products.json"; + List products = []; + String query = ""; + ProductRepoByServer() { + fetchProductsFromServer(); + } + + Future fetchProductsFromServer() async { + final res = await http.get( + Uri.parse(apiUrl), + ); + final productsJson = List>.from(jsonDecode(res.body)); + products = + productsJson.map(((product) => Product.fromJson(product))).toList(); + notifyListeners(); + } + + get filteredProducts { + if (query.trim().isEmpty) { + return products; + } + return products.where((product) { + final nameLower = product.name.toLowerCase(); + final descriptionLower = product.description.toLowerCase(); + final searchLower = query.toLowerCase(); + + return nameLower.contains(searchLower) || + descriptionLower.contains(searchLower); + }).toList(); + } + + void searchProducts(String query) { + this.query = query; + notifyListeners(); + } + + Result productWithBarcode(String barcode) { + for (var i = 0; i < products.length; i++) { + if (products[i].barcode == barcode) { + return Ok(products[i]); + } + } + return Err("Product with barcode $barcode doesn't exist"); + } +} diff --git a/mobile/lib/repos/receipt.dart b/mobile/lib/repos/receipt.dart index b89c5d2..5e07871 100644 --- a/mobile/lib/repos/receipt.dart +++ b/mobile/lib/repos/receipt.dart @@ -13,14 +13,14 @@ class ReceiptRepo extends ChangeNotifier { product: Product( id: 1243, name: "Letmælk", - priceInDkkCent: 13, + priceInDkkCents: 13, description: "Konventionel minimælk med fedtprocent på 0,4%"), amount: 1), ReceiptItem( product: Product( id: 340, name: "Minimælk", - priceInDkkCent: 12, + priceInDkkCents: 12, description: "Konventionel minimælk med fedtprocent på 0,4%"), amount: 3), ]), @@ -32,14 +32,14 @@ class ReceiptRepo extends ChangeNotifier { product: Product( id: 12341, name: "Letmælk", - priceInDkkCent: 13, + priceInDkkCents: 13, description: "Konventionel minimælk med fedtprocent på 0,4%"), amount: 3), ReceiptItem( product: Product( id: 1234443, name: "Minimælk", - priceInDkkCent: 12, + priceInDkkCents: 12, description: "Konventionel minimælk med fedtprocent på 0,4%"), amount: 1), ]) @@ -119,6 +119,6 @@ class ReceiptItem { ReceiptItem({required this.product, required this.amount}); int totalPrice() { - return product.priceInDkkCent * amount; + return product.priceInDkkCents * amount; } } diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 7b7bee1..d2029a6 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -116,7 +116,7 @@ packages: source: hosted version: "6.2.1" http: - dependency: transitive + dependency: "direct main" description: name: http sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index ca31f93..44b64b4 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: barcode_scan2: ^4.4.0 google_fonts: ^6.2.1 intl: ^0.20.2 + http: ^1.3.0 dev_dependencies: flutter_test: