diff --git a/lib/main.dart b/lib/main.dart index 2df9cda..c32dcbf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -75,7 +75,7 @@ class MyApp extends StatelessWidget { class MainApp extends StatelessWidget { @override Widget build(BuildContext context) { - if (Provider.of(context) == null) return FormPage(); + if (Provider.of(context) == null) return ToolReservationPage(); if (Provider.of(context) == null) return Loading(); return MyStatefulWidget(); } diff --git a/lib/services/firebase.dart b/lib/services/firebase.dart index c3b3d97..7f8ae76 100644 --- a/lib/services/firebase.dart +++ b/lib/services/firebase.dart @@ -11,12 +11,33 @@ class Auth { static bool isInProcess = false; static firebase.FirebaseAuth _auth = firebase.FirebaseAuth.instance; - static Future signIn( + static Future signUp( String email, String password, BuildContext context) async { if (isInProcess) return; isInProcess = true; - //do login try { + // Create a new user + await _auth.createUserWithEmailAndPassword( + email: email, + password: password, + ); + // Show a success message + Alert.showAlert(context, "Account created successfully!"); + Navigator.pop(context); // Navigate back to the login page + } on firebase.FirebaseAuthException catch (e) { + // Handle authentication errors + Alert.showAlert(context, e.message ?? "Unknown authentication error"); + } finally { + isInProcess = false; + } + } + + static Future signIn( + String email, String password, BuildContext context) async { + if (isInProcess) return; + isInProcess = true; + try { + // Log in the user await _auth.signInWithEmailAndPassword(email: email, password: password); } on firebase.FirebaseAuthException catch (e) { Alert.showAlert(context, e.message ?? "Unknown authentication error"); @@ -24,7 +45,7 @@ class Auth { isInProcess = false; } - static Future signOut() async { + static Future signOut() async { await _auth.signOut(); } @@ -37,8 +58,7 @@ class Auth { try { await _auth.sendPasswordResetEmail(email: email); } on firebase.FirebaseAuthException catch (e) { - Alert.showAlert(context, e.message ?? "Unknown Authentication error"); - print(e); + Alert.showAlert(context, e.message ?? "Unknown authentication error"); } } diff --git a/lib/ui/BarcodeScanner.dart b/lib/ui/BarcodeScanner.dart index 9497775..24c0522 100644 --- a/lib/ui/BarcodeScanner.dart +++ b/lib/ui/BarcodeScanner.dart @@ -1,213 +1,187 @@ import 'package:flutter/material.dart'; import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; +import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; -class BarcodeScannerPage extends StatefulWidget { +// Define the backend base URL here +const String backendBaseUrl = "https://optixtoolkit-backend-production-abcd.up.railway.app/"; + +class ToolReservationPage extends StatefulWidget { @override - _BarcodeScannerPageState createState() => _BarcodeScannerPageState(); + _ToolReservationPageState createState() => _ToolReservationPageState(); } -class _BarcodeScannerPageState extends State { - String barcode = ''; - Map inventoryEntry = {}; - List tools = []; - String userID = "deltameters"; // Replace with actual user ID - String baseUrl = "https://optixtoolkit-backend-production-abcd.up.railway.app/"; // Replace this variable later with the actual base URL +class _ToolReservationPageState extends State { + final Color background = const Color(0xff26292c); + final Color lightBackground = const Color(0xff3a3d41); + final Color blue = const Color(0xff159deb); + final Color white = const Color(0xffffffff); + + String reserverID = "user123"; // Example reserver ID, replace with actual ID + List checkedInTools = []; @override void initState() { super.initState(); - _fetchTools(); + fetchCheckedInTools(); } - // Step 3: Function to scan the barcode - Future _scanBarcode() async { - try { - var scanResult = await FlutterBarcodeScanner.scanBarcode( - '#ff6666', - 'Cancel', - true, - ScanMode.BARCODE, - ); - - // Check if scan was cancelled (returns '-1') - if (scanResult != '-1' && scanResult.isNotEmpty) { - setState(() { - barcode = scanResult; - }); + Future scanBarcode() async { + String barcode = await FlutterBarcodeScanner.scanBarcode( + "#ff6666", + "Cancel", + true, + ScanMode.BARCODE, + ); - await _postInventoryCheck(); - } else { - _showSnackBar('Scan was cancelled or invalid'); - } - } catch (e) { - print(e); - _showSnackBar('Failed to scan barcode'); + if (barcode != "-1") { + await checkInTool(barcode); } } - // Step 4: POST inventory check - Future _postInventoryCheck() async { - var url = Uri.parse('$baseUrl/inventory-check'); - + Future checkInTool(String barcode) async { try { - var response = await http.post( - url, - body: jsonEncode({ - "endpoint": "post-inventory-check-tool", - "barcodeId": barcode, - }), - headers: {"Content-Type": "application/json"}, + final response = await http.get( + Uri.parse('$backendBaseUrl/inventory/$barcode'), ); if (response.statusCode == 200) { - setState(() { - inventoryEntry = jsonDecode(response.body); - }); + final tool = json.decode(response.body); + await http.post( + Uri.parse('$backendBaseUrl/'), + headers: {"Content-Type": "application/json"}, + body: json.encode({ + "endpoint": "post-tool", + "reserverID": reserverID, + "name": tool["name"], + }), + ); - await _postInventoryDecreaseCount(); - await _postToolReservation(); + fetchCheckedInTools(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("${tool["name"]} checked in successfully")), + ); } else { - _showSnackBar('Failed to check inventory'); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Tool not found in inventory")), + ); } } catch (e) { - print(e); - _showSnackBar('Error checking inventory'); - } - } - - // Step 5: POST inventory decrease count - Future _postInventoryDecreaseCount() async { - var url = Uri.parse('$baseUrl/decrease-count'); - - try { - var response = await http.post( - url, - body: jsonEncode({ - "endpoint": "post-inventory-decrease-count-by-name", - "name": inventoryEntry['name'], - }), - headers: {"Content-Type": "application/json"}, + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Error: $e")), ); - - if (response.statusCode != 200) { - _showSnackBar('Failed to decrease inventory count'); - } - } catch (e) { - print(e); - _showSnackBar('Error decreasing inventory count'); } } - // Step 6: POST tool reservation - Future _postToolReservation() async { - var url = Uri.parse('$baseUrl/reserve-tool'); - + Future fetchCheckedInTools() async { try { - var response = await http.post( - url, - body: jsonEncode({ - "endpoint": "post-tool", - "name": inventoryEntry['name'], - "category": inventoryEntry['category'], - "reserverID": userID, - }), - headers: {"Content-Type": "application/json"}, + final response = await http.get( + Uri.parse('$backendBaseUrl/tools/$reserverID'), ); - if (response.statusCode != 200) { - _showSnackBar('Failed to reserve tool'); - } - } catch (e) { - print(e); - _showSnackBar('Error reserving tool'); - } - } - - // Step 7: Fetch tools - Future _fetchTools() async { - var url = Uri.parse('$baseUrl/tools'); - - try { - var response = await http.get(url); - if (response.statusCode == 200) { setState(() { - tools = jsonDecode(response.body); + checkedInTools = json.decode(response.body); }); } else { - _showSnackBar('Failed to fetch tools'); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Error fetching checked-in tools")), + ); } } catch (e) { - print(e); - _showSnackBar('Error fetching tools'); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Error: $e")), + ); } } - // Step 8: Check In function - Future _checkInTool(String toolName) async { - var deleteUrl = Uri.parse('$baseUrl/tools/$userID/$toolName'); - + Future checkOutTool(String name) async { try { - var deleteResponse = await http.delete(deleteUrl); + final response = await http.delete( + Uri.parse('$backendBaseUrl/tools/$reserverID/$name'), + ); - if (deleteResponse.statusCode == 200) { - var postUrl = Uri.parse('$baseUrl/increase-count'); - await http.post( - postUrl, - body: jsonEncode({ - "endpoint": "post-inventory-increase-count-by-name", - "name": toolName, - }), - headers: {"Content-Type": "application/json"}, + if (response.statusCode == 200) { + fetchCheckedInTools(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("$name checked out successfully")), ); - - // Refresh tool list - await _fetchTools(); } else { - _showSnackBar('Failed to check in tool'); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Error checking out tool")), + ); } } catch (e) { - print(e); - _showSnackBar('Error checking in tool'); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Error: $e")), + ); } } - // Function to show a SnackBar with a message - void _showSnackBar(String message) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message))); - } - @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Barcode Scanner'), + title: Text( + "Tool Reservation", + style: GoogleFonts.rubik(fontWeight: FontWeight.bold), + ), + backgroundColor: blue, ), - body: Column( - children: [ - ElevatedButton( - onPressed: _scanBarcode, - child: Text('Scan Barcode'), - ), - SizedBox(height: 20), - Expanded( - child: ListView.builder( - itemCount: tools.length, - itemBuilder: (context, index) { - var tool = tools[index]; - return ListTile( - title: Text(tool['name']), - trailing: ElevatedButton( - onPressed: () => _checkInTool(tool['name']), - child: Text('Check In'), - ), - ); - }, + backgroundColor: background, + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ElevatedButton( + onPressed: scanBarcode, + style: ElevatedButton.styleFrom( + backgroundColor: blue, + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15), + ), + child: Text( + "Scan Barcode to Check In", + style: GoogleFonts.rubik(color: white, fontWeight: FontWeight.bold), + ), + ), + const SizedBox(height: 20), + Text( + "Checked-In Tools:", + style: GoogleFonts.rubik(fontSize: 20, fontWeight: FontWeight.bold, color: white), + ), + const SizedBox(height: 10), + Expanded( + child: checkedInTools.isEmpty + ? Center( + child: Text( + "No tools checked in.", + style: GoogleFonts.rubik(color: white, fontSize: 16), + ), + ) + : ListView.builder( + itemCount: checkedInTools.length, + itemBuilder: (context, index) { + final tool = checkedInTools[index]; + return Card( + color: lightBackground, + child: ListTile( + title: Text( + tool["name"], + style: GoogleFonts.rubik(color: white), + ), + trailing: IconButton( + icon: Icon(Icons.delete, color: Colors.red), + onPressed: () => checkOutTool(tool["name"]), + ), + ), + ); + }, + ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/ui/CreateAccount.dart b/lib/ui/CreateAccount.dart new file mode 100644 index 0000000..3d21a4d --- /dev/null +++ b/lib/ui/CreateAccount.dart @@ -0,0 +1,200 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:OptixToolkit/services/NavigationService.dart'; +import 'package:OptixToolkit/services/firebase.dart'; + +class CreateAccount extends StatefulWidget { + CreateAccount({Key? key}) : super(key: key); + + @override + _CreateAccountState createState() => _CreateAccountState(); +} + +class _CreateAccountState extends State { + final _formKey = GlobalKey(); + + final emailController = TextEditingController(); + final passwordController = TextEditingController(); + final confirmPasswordController = TextEditingController(); + + final Color background = const Color(0xff26292c); + final Color blue = const Color(0xff159deb); + final Color white = const Color(0xffffffff); + final Color gray = const Color(0xff3A3D41); + final Color subtleGray = const Color(0xffcccccc); + bool _showPassword = false; + + @override + void dispose() { + emailController.dispose(); + passwordController.dispose(); + confirmPasswordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: background, + appBar: AppBar( + title: Center( + child: Text( + "CREATE ACCOUNT", + style: GoogleFonts.rubik(fontWeight: FontWeight.bold), + ), + ), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Form( + key: _formKey, + child: Column( + children: [ + const SizedBox(height: 10), + Container( + width: 300, + child: TextFormField( + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email.'; + } + return null; + }, + controller: emailController, + style: GoogleFonts.rubik(color: Colors.white), + textAlign: TextAlign.center, + decoration: InputDecoration( + filled: true, + fillColor: gray, + hintText: 'Email', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(9.0), + ), + hintStyle: GoogleFonts.rubik(color: subtleGray), + ), + ), + ), + const SizedBox(height: 10), + Container( + width: 300, + child: TextFormField( + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your password.'; + } + if (value.length < 6) { + return 'Password must be at least 6 characters long.'; + } + return null; + }, + controller: passwordController, + obscureText: !_showPassword, + style: GoogleFonts.rubik(color: Colors.white), + textAlign: TextAlign.center, + decoration: InputDecoration( + filled: true, + prefixIcon: const Icon(Icons.lock), + suffixIcon: IconButton( + icon: Icon( + Icons.remove_red_eye, + color: _showPassword ? Colors.blue : Colors.grey, + ), + onPressed: () { + setState(() => _showPassword = !_showPassword); + }, + ), + fillColor: gray, + hintText: 'Password', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(9.0), + ), + hintStyle: GoogleFonts.rubik(color: subtleGray), + ), + ), + ), + const SizedBox(height: 10), + Container( + width: 300, + child: TextFormField( + validator: (value) { + if (value != passwordController.text) { + return 'Passwords do not match.'; + } + return null; + }, + controller: confirmPasswordController, + obscureText: !_showPassword, + style: GoogleFonts.rubik(color: Colors.white), + textAlign: TextAlign.center, + decoration: InputDecoration( + filled: true, + prefixIcon: const Icon(Icons.lock), + fillColor: gray, + hintText: 'Confirm Password', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(9.0), + ), + hintStyle: GoogleFonts.rubik(color: subtleGray), + ), + ), + ), + const SizedBox(height: 20), + ButtonTheme( + minWidth: 300, + height: 50, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(7.0), + ), + child: ElevatedButton( + onPressed: () { + if (_formKey.currentState != null && + _formKey.currentState!.validate()) { + Auth.signUp( + emailController.text, + passwordController.text, + context, + ); + } + }, + child: Text( + 'CREATE ACCOUNT', + style: GoogleFonts.rubik( + fontWeight: FontWeight.bold, + color: white, + ), + ), + style: ElevatedButton.styleFrom(backgroundColor: blue), + ), + ), + const SizedBox(height: 20), + RichText( + text: TextSpan( + text: 'Already have an account? ', + style: GoogleFonts.rubik(color: subtleGray, fontSize: 15), + children: [ + TextSpan( + text: 'Log in.', + style: GoogleFonts.rubik( + color: blue, + fontWeight: FontWeight.bold, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.pop(context); + }, + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/ui/Form.dart b/lib/ui/Form.dart index d101185..0064c78 100644 --- a/lib/ui/Form.dart +++ b/lib/ui/Form.dart @@ -1,13 +1,9 @@ -// Flutter imports: import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; - -// Package imports: import 'package:google_fonts/google_fonts.dart'; import 'package:OptixToolkit/ui/ForgetPassword.dart'; +import 'package:OptixToolkit/ui/CreateAccount.dart'; import 'package:OptixToolkit/services/NavigationService.dart'; - -// Project imports: import 'package:OptixToolkit/services/firebase.dart'; class FormPage extends StatefulWidget { @@ -22,21 +18,19 @@ class _FormPageState extends State { final emailController = TextEditingController(); final passwordController = TextEditingController(); - final nameController = TextEditingController(); - final Color background = Color(0xff26292c); - final Color blue = Color(0xff159deb); - final Color white = Color(0xffffffff); - final Color gray = Color(0xff3A3D41); - final Color subtleGray = Color(0xffcccccc); - final Color divider = Color(0xff3a3d41); + final Color background = const Color(0xff26292c); + final Color blue = const Color(0xff159deb); + final Color white = const Color(0xffffffff); + final Color gray = const Color(0xff3A3D41); + final Color subtleGray = const Color(0xffcccccc); + final Color divider = const Color(0xff3a3d41); bool _showPassword = false; @override void dispose() { emailController.dispose(); passwordController.dispose(); - nameController.dispose(); super.dispose(); } @@ -46,130 +40,166 @@ class _FormPageState extends State { backgroundColor: background, appBar: AppBar( title: Center( - child: Text("LOGIN", - style: GoogleFonts.rubik(fontWeight: FontWeight.bold))), + child: Text( + "LOGIN", + style: GoogleFonts.rubik(fontWeight: FontWeight.bold), + ), + ), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Form( - key: _formKey, - child: Column( - children: [ - SizedBox(height: 10), - Container( - width: 300, - child: TextFormField( - validator: (value) { - if (value == null || value.isEmpty) { - return 'Email'; - } - return null; - }, - controller: emailController, - style: GoogleFonts.rubik(color: Colors.white), - textAlign: TextAlign.center, - decoration: InputDecoration( - filled: true, - fillColor: gray, - hintText: 'Email', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(9.0)), - hintStyle: GoogleFonts.rubik(color: subtleGray), + key: _formKey, + child: Column( + children: [ + const SizedBox(height: 10), + Container( + width: 300, + child: TextFormField( + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email.'; + } + return null; + }, + controller: emailController, + style: GoogleFonts.rubik(color: Colors.white), + textAlign: TextAlign.center, + decoration: InputDecoration( + filled: true, + fillColor: gray, + hintText: 'Email', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(9.0), ), + hintStyle: GoogleFonts.rubik(color: subtleGray), ), ), - SizedBox(height: 10), - Container( - width: 300, - child: TextFormField( - validator: (value) { - if (value == null || value.isEmpty) { - return 'Password'; - } - return null; - }, - controller: passwordController, - obscureText: !this._showPassword, - style: GoogleFonts.rubik(color: Colors.white), - textAlign: TextAlign.center, - decoration: InputDecoration( - filled: true, - prefixIcon: Icon(Icons.security), - suffixIcon: IconButton( - icon: Icon( - Icons.remove_red_eye, - color: this._showPassword - ? Colors.blue - : Colors.grey, - ), - onPressed: () { - setState(() => - this._showPassword = !this._showPassword); - }, + ), + const SizedBox(height: 10), + Container( + width: 300, + child: TextFormField( + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your password.'; + } + return null; + }, + controller: passwordController, + obscureText: !_showPassword, + style: GoogleFonts.rubik(color: Colors.white), + textAlign: TextAlign.center, + decoration: InputDecoration( + filled: true, + prefixIcon: const Icon(Icons.security), + suffixIcon: IconButton( + icon: Icon( + Icons.remove_red_eye, + color: _showPassword ? Colors.blue : Colors.grey, ), - fillColor: gray, - hintText: 'Password', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(9.0)), - hintStyle: GoogleFonts.rubik(color: subtleGray), + onPressed: () { + setState(() => _showPassword = !_showPassword); + }, ), + fillColor: gray, + hintText: 'Password', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(9.0), + ), + hintStyle: GoogleFonts.rubik(color: subtleGray), ), ), - SizedBox(height: 5), - Container( - width: 300, - child: Divider( - color: divider, - height: 20, - thickness: 2, - endIndent: 0, + ), + const SizedBox(height: 5), + Container( + width: 300, + child: Divider( + color: divider, + height: 20, + thickness: 2, + endIndent: 0, + ), + ), + const SizedBox(height: 5), + ButtonTheme( + minWidth: 300, + height: 50, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(7.0), + ), + child: ElevatedButton( + onPressed: () { + if (_formKey.currentState != null && + _formKey.currentState!.validate()) { + Auth.signIn( + emailController.text, + passwordController.text, + context, + ); + } + }, + child: Text( + 'LOG IN', + style: GoogleFonts.rubik( + fontWeight: FontWeight.bold, + color: white, + ), ), + style: ElevatedButton.styleFrom(backgroundColor: blue), ), - SizedBox(height: 5), - ButtonTheme( - minWidth: 300, - height: 50, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(7.0)), - child: ElevatedButton( - onPressed: () { - if (_formKey.currentState != null && - _formKey.currentState!.validate()) { - Auth.signIn(emailController.text, - passwordController.text, context); - } - }, - child: Text('LOG IN', - style: GoogleFonts.rubik( - fontWeight: FontWeight.bold, color: white)), - style: - ElevatedButton.styleFrom(backgroundColor: blue)), + ), + const SizedBox(height: 20), + RichText( + text: TextSpan( + text: 'Forgot Password?', + style: GoogleFonts.rubik(color: blue, fontSize: 15), + recognizer: TapGestureRecognizer() + ..onTap = () { + NavigationService.goTo( + PageRouteBuilder( + pageBuilder: (context, animation1, animation2) => + ForgetPassword(), + ), + ); + }, ), - SizedBox(height: 20), - RichText( - text: TextSpan( - text: 'Forgot Password', - style: GoogleFonts.rubik(color: blue, fontSize: 15), + ), + const SizedBox(height: 20), + RichText( + text: TextSpan( + text: 'New to Toolkit? ', + style: GoogleFonts.rubik(color: subtleGray, fontSize: 15), + children: [ + TextSpan( + text: 'Create account.', + style: GoogleFonts.rubik( + color: blue, + fontWeight: FontWeight.bold, + ), recognizer: TapGestureRecognizer() ..onTap = () { NavigationService.goTo( PageRouteBuilder( pageBuilder: (context, animation1, animation2) => - ForgetPassword(), + CreateAccount(), ), ); - }), + }, + ), + ], ), - SizedBox(height: 5), - SizedBox(height: 5), - ], - )), + ), + const SizedBox(height: 5), + ], + ), + ), ], ), ), ); } -} +} \ No newline at end of file diff --git a/lib/ui/Home.dart b/lib/ui/Home.dart index ccc06f8..554b81c 100644 --- a/lib/ui/Home.dart +++ b/lib/ui/Home.dart @@ -2,6 +2,7 @@ import 'dart:async'; // Flutter imports: +import 'package:OptixToolkit/ui/BarcodeScanner.dart'; import 'package:OptixToolkit/ui/HoursPage.dart'; import 'package:flutter/material.dart'; @@ -12,7 +13,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:OptixToolkit/Icons.dart'; import 'package:OptixToolkit/ui/HomePage.dart'; import 'package:OptixToolkit/ui/ProfilePage.dart'; -import 'package:OptixToolkit/ui/tools/ToolsPage.dart'; +// import 'package:OptixToolkit/ui/tools/ToolsPage.dart'; import 'package:OptixToolkit/services/firebase.dart'; import 'package:OptixToolkit/ui/parts/PartReimburse.dart'; @@ -58,7 +59,7 @@ class _MyStatefulWidgetState extends State { List _widgetOptions = [ homePage(changePage: changePage), hoursPage(), - toolsPage(uid: '',), + ToolReservationPage(), PartReimburse(), profilePage(key: null,), Container( diff --git a/lib/ui/HoursPage.dart b/lib/ui/HoursPage.dart index b8d2f78..5e7ff5d 100644 --- a/lib/ui/HoursPage.dart +++ b/lib/ui/HoursPage.dart @@ -20,7 +20,9 @@ class hoursPage extends StatelessWidget { Provider.of(context), context), initialData: null), FutureProvider.value( value: Database.getMeetingCount( - Provider.of(context), context), initialData: null) + Provider.of(context), context), + initialData: null, +) ], child: hoursPageLoaded()); } } @@ -73,12 +75,12 @@ class _hoursPageState extends State { if (time == null || lastCheckIn == null || meetingCount == null) { var timeProv = Provider.of(context); - var lastCheckInProv = Provider.of(context); - var meetingCountProv = Provider.of(context); + var lastCheckInProv = Provider.of(context); + var meetingCountProv = Provider.of(context); time = timeProv; - lastCheckIn = lastCheckInProv.getValue(); - meetingCount = meetingCountProv.getValue(); + lastCheckIn = lastCheckInProv?.getValue(); + meetingCount = meetingCountProv?.getValue() ?? 0; // Default to 0 if null } final Color formBackground = Color(0xff3A3D41); diff --git a/pubspec.lock b/pubspec.lock index a27f761..eb83e6d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -29,10 +29,10 @@ packages: dependency: "direct main" description: name: barcode_scan2 - sha256: "0b0625d27841a21e36e896195d86b2aada335e3c486f63647cce701495718e16" + sha256: a2ab566027cd57b2795ea42aa26835dbaa8fe70bcc1aff54942a14d3705dff97 url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "4.3.3" boolean_selector: dependency: transitive description: @@ -237,10 +237,10 @@ packages: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -572,10 +572,10 @@ packages: dependency: transitive description: name: protobuf - sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "3.1.0" provider: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index cfd5eaf..c6c92ee 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,8 +15,7 @@ dependencies: sdk: flutter permission_handler: - - barcode_scan2: + flutter_barcode_scanner: ^2.0.0 loading_animations: firebase_auth: @@ -32,6 +31,7 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: firebase_core: any + barcode_scan2: ^4.3.3 dev_dependencies: flutter_test: sdk: flutter