diff --git a/lib/services/database.dart b/lib/services/database.dart index 16b9477..f0de22b 100644 --- a/lib/services/database.dart +++ b/lib/services/database.dart @@ -712,6 +712,41 @@ class Database { return inventory; } + + static Future modifyInventory(firebase.IdTokenResult idToken, + String barcodeId, String? newStatus, String? newLocation, BuildContext context) async { + var client = http.Client(); + + Map data = { + 'endpoint': 'modify-inventory', + 'auth': idToken.token, + 'barcodeId': barcodeId, + 'status': newStatus, + 'location': newLocation + }; + + var body = json.encode(data); + + var result = await client.post(Uri.parse(Constants.SERVER_URL), + headers: {"Content-Type": "application/json"}, body: body); + + if (result.statusCode != 200) { + Alert.showAlert(context, jsonDecode(result.body)['err']); + return null; + } + + if (jsonDecode(result.body)['inventory'] == null) { + Alert.showAlert(context, "Inventoried tool does not exist!"); + return null; + } + + final parsed = + jsonDecode(result.body)['inventory']; + + var inventory = Inventory.fromJson(parsed); + + return inventory; + } } final Map deliveryMap = { diff --git a/lib/ui/BarcodeResultPage.dart b/lib/ui/BarcodeResultPage.dart index aa375a3..0fa74b4 100644 --- a/lib/ui/BarcodeResultPage.dart +++ b/lib/ui/BarcodeResultPage.dart @@ -15,7 +15,7 @@ class BarcodeResultPage extends StatelessWidget { title: Center( child: Text( 'Barcode Result', - style: TextStyle(fontSize: 30, fontWeight: FontWeight.w800, color: Colors.black), + style: TextStyle(fontSize: 30, fontWeight: FontWeight.w800, color: Color.fromARGB(255, 255, 255, 255)), ), ), backgroundColor: Colors.blue, diff --git a/lib/ui/tools/BarcodeResultPage.dart b/lib/ui/tools/BarcodeResultPage.dart new file mode 100644 index 0000000..6f87926 --- /dev/null +++ b/lib/ui/tools/BarcodeResultPage.dart @@ -0,0 +1,204 @@ +import 'package:firebase_auth/firebase_auth.dart' as firebase; +import 'package:flutter/material.dart'; +import 'package:OptixToolkit/services/database.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:provider/provider.dart'; + +class BarcodeResultPage extends StatefulWidget { + final String barcodeValue; + final Inventory inventory; + + const BarcodeResultPage( + {Key? key, required this.barcodeValue, required this.inventory}) + : super(key: key); + + @override + State createState() => _BarcodeResultPageState(); +} + +class _BarcodeResultPageState extends State { + Inventory? inventory; + + @override + void initState() { + super.initState(); + inventory = widget.inventory; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color(0xff26292c), + appBar: AppBar( + centerTitle: true, + title: Text( + "BARCODE RESULT", + style: GoogleFonts.rubik(fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + ), + backgroundColor: Color(0xff159deb), + ), + body: Container( + margin: EdgeInsets.only(left: 12, top: 20, right: 12, bottom: 0), + width: 400, + height: MediaQuery.of(context).size.height * 0.75, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Color(0xff3a3d41), + ), + child: Padding( + padding: EdgeInsets.all(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + //Tool Name + 'Tool Name: ${inventory!.name}', + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + Text( + //Barcode Value + 'Barcode ID: ${widget.barcodeValue}', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + color: Colors.white), + ), + + SizedBox(height: 30), + + Text( + // Tool Description + 'Tool Description: ${inventory!.description}', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.normal, + color: Colors.white), + ), + SizedBox(height: 10), + Text( + // Tool Count + 'Tool Count: ${inventory!.count}', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.normal, + color: Colors.white), + ), + // Tool Status + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Tool Status: ${inventory!.status}', + style: TextStyle(fontSize: 18, color: Colors.white), + ), + ElevatedButton( + onPressed: () { + _handleChange( + 'Tool Status', widget.inventory.status, context); + }, + child: + Text('Change', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: + Colors.blue, // Set the button color to blue + ), + ), + ], + ), + + // Tool Location + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Tool Location: ${inventory!.location}', + style: TextStyle(fontSize: 18, color: Colors.white), + ), + ElevatedButton( + onPressed: () { + _handleChange('Tool Location', + widget.inventory.location, context); + }, + child: + Text('Change', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: + Colors.blue, // Set the button color to blue + ), + ), + ], + ), + ], + ), + ), + )); + } + + //This is the function to handle changing tool attributes + void _handleChange( + String attributeName, String currentValue, BuildContext context) async { + TextEditingController inputController = TextEditingController(); + + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Change $attributeName'), + content: TextField( + controller: inputController, + keyboardType: TextInputType.text, + decoration: InputDecoration(labelText: 'Enter new $attributeName'), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + TextButton( + onPressed: () async { + String newValue = inputController.text.trim(); + if (newValue.isNotEmpty) { + Inventory? newInventory; + + if (attributeName == "Tool Status") { + newInventory = await Database.modifyInventory( + Provider.of(context, listen: false), + widget.barcodeValue, + newValue, + null, + context); + } + if (attributeName == "Tool Location") { + newInventory = await Database.modifyInventory( + Provider.of(context, listen: false), + widget.barcodeValue, + null, + newValue, + context); + } + + if (newInventory != null) { + setState(() { + inventory = newInventory; + }); + } + + Navigator.of(context).pop(); + } else { + print("Please enter a valid $attributeName"); + } + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } +} diff --git a/lib/ui/tools/ToolModal.dart b/lib/ui/tools/ToolModal.dart deleted file mode 100644 index f8c201d..0000000 --- a/lib/ui/tools/ToolModal.dart +++ /dev/null @@ -1,106 +0,0 @@ -// Flutter imports: -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:firebase_auth/firebase_auth.dart' as firebase; -import 'package:OptixToolkit/services/database.dart'; - -// Package imports: -import 'package:google_fonts/google_fonts.dart'; - -class ToolModal extends StatelessWidget { - final Inventory inventory; - const ToolModal({Key? key, required this.inventory}) : super(key: key); - - @override - Widget build(BuildContext context) { - final Color blue = Color(0xff159deb); - final Color green = Color(0xff15ee07); - final Color yellow = Color(0xffebe712); - final Color red = Color(0xffd5212c); - final Color orange = Color(0xffff9415); - - final ButtonStyle buttonStyle = ElevatedButton.styleFrom( - textStyle: const TextStyle(fontSize: 20), - ); - - Widget doneButton = TextButton( - child: Text( - "Done", - style: GoogleFonts.rubik( - fontWeight: FontWeight.bold, - color: Color(0xff159deb), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ); - - return AlertDialog( - title: Text( - 'Tool: ${inventory.name}', - style: GoogleFonts.rubik( - fontSize: 25.0, - fontWeight: FontWeight.bold, - color: Color(0xff159deb), - ), - ), - backgroundColor: Color(0xff26292c), - content: SingleChildScrollView( - child: ListBody( - children: [ - RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'Count: ${inventory.count}', - style: GoogleFonts.rubik( - fontWeight: FontWeight.bold, - color: Colors.white, - fontSize: 20.0, - ), - ), - ], - ), - ), - if (inventory.description != null) - RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'Description: ${inventory.description}', - style: GoogleFonts.rubik( - fontWeight: FontWeight.bold, - color: Colors.white, - fontSize: 15.0, - ), - ), - ], - ), - ), - const SizedBox(height: 20), - ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xff159deb), - ), - onPressed: () async {}, - child: RichText( - text: TextSpan( - text: 'Use Tool', - style: GoogleFonts.rubik( - color: Colors.white, - fontSize: 18.0, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ), - ), - actions: [ - doneButton, - ], - ); - } -} diff --git a/lib/ui/tools/ToolsPage.dart b/lib/ui/tools/ToolsPage.dart index fc19470..c4a2925 100644 --- a/lib/ui/tools/ToolsPage.dart +++ b/lib/ui/tools/ToolsPage.dart @@ -1,6 +1,5 @@ // Flutter imports: -import 'package:OptixToolkit/ui/BarcodeResultPage.dart'; -import 'package:OptixToolkit/ui/tools/ToolModal.dart'; +import 'package:OptixToolkit/ui/tools/BarcodeResultPage.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:OptixToolkit/ui/tools/ToolCard.dart'; @@ -226,23 +225,19 @@ class _toolState extends State with RouteAware { backgroundColor: Color(0xff159deb), ), ), - ElevatedButton( - onPressed: () { - _showManualEntryDialog(context); - }, - child: Text( - 'Manual Entry' , - style: GoogleFonts.rubik( - fontWeight: FontWeight.bold, - fontSize: 20.0, - color: Colors.white - ) - ), - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xff159deb), - ) - ) - // ButtonTheme( + ElevatedButton( + onPressed: () { + _showManualEntryDialog(context); + }, + child: Text('Manual Entry', + style: GoogleFonts.rubik( + fontWeight: FontWeight.bold, + fontSize: 20.0, + color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xff159deb), + )) + // ButtonTheme( // minWidth: MediaQuery.of(context).size.width * 0.43, // height: 55, // shape: RoundedRectangleBorder( @@ -330,31 +325,36 @@ class _toolState extends State with RouteAware { // Function to handle barcode scanning Future _scanBarcode(BuildContext context) async { - try { - String barcodeValue = (await BarcodeScanner.scan()).rawContent; + try { + String barcodeValue = (await BarcodeScanner.scan()).rawContent; - Inventory? inv = await Database.getInventory(idToken, barcodeValue, context); + // remove first and last digit of barcode + barcodeValue = barcodeValue.substring(1, barcodeValue.length - 1); - if (inv != null) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => BarcodeResultPage(barcodeValue: barcodeValue, inventory: inv), - ), - ); - } - } on PlatformException catch (e) { - if (e.code == BarcodeScanner.cameraAccessDenied) { - print('Camera permission not granted'); - } else { + Inventory? inv = + await Database.getInventory(idToken, barcodeValue, context); + + if (inv != null) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + BarcodeResultPage(barcodeValue: barcodeValue, inventory: inv), + ), + ); + } + } on PlatformException catch (e) { + if (e.code == BarcodeScanner.cameraAccessDenied) { + print('Camera permission not granted'); + } else { + print('Unknown Error: $e'); + } + } on FormatException catch (e) { + print('User pressed back button before scanning'); + } catch (e) { print('Unknown Error: $e'); } - } on FormatException catch (e) { - print('User pressed back button before scanning'); - } catch (e) { - print('Unknown Error: $e'); } -} void _showManualEntryDialog(BuildContext context) { TextEditingController barcodeController = TextEditingController(); @@ -393,28 +393,22 @@ class _toolState extends State with RouteAware { ); } -Future _handleManualBarcodeEntry(BuildContext context, String enteredBarcode) async{ + Future _handleManualBarcodeEntry( + BuildContext context, String enteredBarcode) async { + String barcodeValue = enteredBarcode; + Inventory? inv = + await Database.getInventory(idToken, barcodeValue, context); - String barcodeValue = enteredBarcode; - Inventory? inv = await Database.getInventory(idToken, barcodeValue, context); - - if (inv != null) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => BarcodeResultPage(barcodeValue: barcodeValue, inventory: inv), - ), - ); - } -} - // Function to show a modal - void _showBarcodeModal(BuildContext context, Inventory inv) { - showDialog( - context: context, //tells flutter the context, or where we are in the app - builder: (BuildContext context) { - // return object of type Dialog - return ToolModal(inventory: inv); - }, - ); + if (inv != null) { + Navigator.of(context).pop(); // Close the dialog + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + BarcodeResultPage(barcodeValue: barcodeValue, inventory: inv), + ), + ); + } } }