From a9b98566edbe28cf74c8f09a5c1f046accf7ae39 Mon Sep 17 00:00:00 2001 From: rivindulahiruka Date: Sat, 21 Jun 2025 13:31:13 +0530 Subject: [PATCH 1/4] feature: add-account --- .../add-account/models/account_model.dart | 43 +++ .../add-account/models/factory_model.dart | 24 ++ .../add-account/models/transporter_model.dart | 24 ++ .../screens/add_account_screen.dart | 259 ++++++++++++++++++ .../service/addaccount_service.dart | 59 ++++ .../add-account/widgets/form_widgets.dart | 68 +++++ 6 files changed, 477 insertions(+) create mode 100644 lib/feature/add-account/models/account_model.dart create mode 100644 lib/feature/add-account/models/factory_model.dart create mode 100644 lib/feature/add-account/models/transporter_model.dart create mode 100644 lib/feature/add-account/screens/add_account_screen.dart create mode 100644 lib/feature/add-account/service/addaccount_service.dart create mode 100644 lib/feature/add-account/widgets/form_widgets.dart diff --git a/lib/feature/add-account/models/account_model.dart b/lib/feature/add-account/models/account_model.dart new file mode 100644 index 0000000..5da1aa2 --- /dev/null +++ b/lib/feature/add-account/models/account_model.dart @@ -0,0 +1,43 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +class AccountModel { + final String? id; + final String factoryName; + final String transporterName; + final String accountNumber; + final String route; + final DateTime createdAt; + final bool isActive; + + AccountModel({ + this.id, + required this.factoryName, + required this.transporterName, + required this.accountNumber, + required this.route, + required this.createdAt, + this.isActive = true, + }); + + factory AccountModel.fromFirestore(DocumentSnapshot doc){ + Mapdata=doc.data() as Map; + return AccountModel(factoryName: data['factoryName'] ?? '', + transporterName: data['transporterName'] ?? '', + accountNumber: data['accountNumber'] ?? '', + route: data['route'] ?? '', + createdAt: (data['createdAt'] ?? '' as Timestamp?)?.ToDate() ?? DateTime.now(), + isActive: data['isActive'] ?? true, + + ); + } + Map toFirestore(){ + return{ + 'factoryName': factoryName, + 'transporterName': transporterName, + 'accountNumber': accountNumber, + 'route': route, + 'createdAt': FieldValue.serverTimestamp(), + 'isActive': isActive, + }; + } +} diff --git a/lib/feature/add-account/models/factory_model.dart b/lib/feature/add-account/models/factory_model.dart new file mode 100644 index 0000000..0583da6 --- /dev/null +++ b/lib/feature/add-account/models/factory_model.dart @@ -0,0 +1,24 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +class FactoryModel { + final String id; + final String name; + final String location; + final String contactNumber; + +FactoryModel({ + required this.id, + required this.name, + required this.location, + required this.contactNumber, +}); + +factory FactoryModel.fromFirestore(String id, Map data){ + return FactoryModel( + id: id, + name: data['name'] ?? '', + location: data['location'] ?? '', + contactNumber: data['contactNumber'] ?? '', + ); +} +} diff --git a/lib/feature/add-account/models/transporter_model.dart b/lib/feature/add-account/models/transporter_model.dart new file mode 100644 index 0000000..18d414d --- /dev/null +++ b/lib/feature/add-account/models/transporter_model.dart @@ -0,0 +1,24 @@ + +class TransporterModel { + final String id; + final String name; + final String assignedFactoryId; + final List routes; + + TransporterModel({ + required this.id, + required this.name, + required this.assignedFactoryId, + required this.routes, + }); + + + factory TransporterModel.fromFirestore(String id, Map data) { + return TransporterModel( + id: id, + name: data['name'] ?? '', + assignedFactoryId: data['assignedFactoryId'] ?? '', + routes: List.from(data['routes'] ?? []), + ); + } +} diff --git a/lib/feature/add-account/screens/add_account_screen.dart b/lib/feature/add-account/screens/add_account_screen.dart new file mode 100644 index 0000000..0c97299 --- /dev/null +++ b/lib/feature/add-account/screens/add_account_screen.dart @@ -0,0 +1,259 @@ +import 'package:flutter/material.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:harvest_manager/shared/widgets/background_template.dart'; +import 'package:harvest_manager/feature/add-account/models/factory_model.dart'; +import 'package:harvest_manager/feature/add-account/models/transporter_model.dart'; +import 'package:harvest_manager/feature/add-account/widgets/form_widgets.dart'; +import 'package:harvest_manager/feature/add-account/service/addaccount_service.dart'; + +class AddAccountScreen extends StatefulWidget { + const AddAccountScreen({super.key}); + + @override + State createState() => _AddAccountScreenState(); +} + +class _AddAccountScreenState extends State { + final AddAccountService _addAccountService = AddAccountService(); + + String? selectedFactoryId; + String? selectedTransporterId; + String? selectedRoute; + + final TextEditingController accountNoController = TextEditingController(); + + List factories = []; + List transporters = []; + List availableRoutes = []; + + bool isLoadingFactories = true; + bool isLoadingTransporters = false; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) async { + await fetchFactories(); + }); + } + + Future fetchFactories() async { + setState(() { + isLoadingFactories = true; + }); + + try { + final fetchedFactories = await _addAccountService.getFactories(); + setState(() { + factories = fetchedFactories; + isLoadingFactories = false; + }); + } catch (e) { + print('Error fetching factories: $e'); + setState(() { + isLoadingFactories = false; + }); + } + } + + Future fetchTransportersForFactory(String factoryId) async { + setState(() { + isLoadingTransporters = true; + transporters = []; + selectedTransporterId = null; + availableRoutes = []; + }); + + try { + final fetchedTransporters = + await _addAccountService.getTransportersForFactory(factoryId); + setState(() { + transporters = fetchedTransporters; + isLoadingTransporters = false; + }); + } catch (e) { + print('Error fetching transporters: $e'); + setState(() { + isLoadingTransporters = false; + }); + } + } + + Future handleAddAccount() async { + if (selectedFactoryId != null && + selectedTransporterId != null && + selectedRoute != null && + accountNoController.text.isNotEmpty) { + try { + await _addAccountService.addAccount( + factoryId: selectedFactoryId!, + transporterId: selectedTransporterId!, + accountNo: accountNoController.text, + route: selectedRoute!, + ); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Account successfully added!')), + ); + + accountNoController.clear(); + setState(() { + selectedFactoryId = null; + selectedTransporterId = null; + selectedRoute = null; + transporters = []; + availableRoutes = []; + }); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Failed to add account.')), + ); + } + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Please complete all fields')), + ); + } + } + + @override + Widget build(BuildContext context) { + return BackgroundTemplate( + child: Padding( + padding: const EdgeInsets.only(bottom: 100.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset("assets/images/teacup.png", height: 60, width: 60), + Expanded( + child: Center( + child: Text( + "Add Accounts", + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Color.fromRGBO(33, 33, 33, 1), + ), + ), + ), + ), + IconButton( + icon: Icon(Icons.notifications_none, color: Colors.black), + onPressed: () {}, + ), + ], + ), + const SizedBox(height: 20), + + buildLabel('Name of the Factory'), + isLoadingFactories + ? const Center(child: CircularProgressIndicator()) + : buildDropdown( + value: selectedFactoryId, + hint: 'Select Factory', + items: factories.map((factory) { + return DropdownMenuItem( + value: factory.id, + child: Text(factory.name), + ); + }).toList(), + onChanged: (value) { + setState(() { + selectedFactoryId = value; + }); + if (value != null) { + fetchTransportersForFactory(value); + } + }, + ), + const SizedBox(height: 16), + + buildLabel('Transporter Name'), + isLoadingTransporters + ? const Center(child: CircularProgressIndicator()) + : buildDropdown( + value: selectedTransporterId, + hint: 'Select Transporter', + items: transporters.map((transporter) { + return DropdownMenuItem( + value: transporter.id, + child: Text(transporter.name), + ); + }).toList(), + onChanged: (value) { + setState(() { + selectedTransporterId = value; + final selected = transporters.firstWhere( + (t) => t.id == value, + orElse: () => TransporterModel( + id: '', + name: '', + assignedFactoryId: '', + routes: [], + ), + ); + availableRoutes = selected.routes; + selectedRoute = null; + }); + }, + ), + const SizedBox(height: 16), + + buildLabel('Account No.'), + buildTextField( + hint: 'Enter Account No', + controller: accountNoController, + ), + const SizedBox(height: 16), + + buildLabel('Routes'), + buildDropdown( + value: selectedRoute, + hint: 'Select Route', + items: availableRoutes.map((route) { + return DropdownMenuItem( + value: route, + child: Text(route), + ); + }).toList(), + onChanged: (value) { + setState(() { + selectedRoute = value; + }); + }, + ), + + const SizedBox(height: 48), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: handleAddAccount, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + padding: const EdgeInsets.symmetric(vertical: 15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: const Text( + "Add Account", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/feature/add-account/service/addaccount_service.dart b/lib/feature/add-account/service/addaccount_service.dart new file mode 100644 index 0000000..89d82b8 --- /dev/null +++ b/lib/feature/add-account/service/addaccount_service.dart @@ -0,0 +1,59 @@ +// lib/services/addaccount_service.dart +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:harvest_manager/feature/add-account/models/factory_model.dart'; +import 'package:harvest_manager/feature/add-account/models/transporter_model.dart'; + +class AddAccountService { + final FirebaseFirestore _firestore = FirebaseFirestore.instance; + + /// Fetch all factories from Firestore + Future> getFactories() async { + try { + final snapshot = await _firestore.collection('factories').get(); + return snapshot.docs + .map((doc) => FactoryModel.fromFirestore(doc.id, doc.data())) + .toList(); + } catch (e) { + print('Error fetching factories: $e'); + rethrow; + } + } + + /// Fetch transporters assigned to a specific factory + Future> getTransportersForFactory(String factoryId) async { + try { + final snapshot = await _firestore + .collection('transporters') + .where('assignedFactoryId', isEqualTo: factoryId) + .get(); + + return snapshot.docs + .map((doc) => TransporterModel.fromFirestore(doc.id, doc.data())) + .toList(); + } catch (e) { + print('Error fetching transporters: $e'); + rethrow; + } + } + + // Save a new account document to Firestore + Future addAccount({ + required String factoryId, + required String transporterId, + required String accountNo, + required String route, + }) async { + try { + await _firestore.collection('accounts').add({ + 'factoryId': factoryId, + 'transporterId': transporterId, + 'accountNo': accountNo, + 'route': route, + 'createdAt': FieldValue.serverTimestamp(), + }); + } catch (e) { + print('Error adding account: $e'); + rethrow; + } + } +} diff --git a/lib/feature/add-account/widgets/form_widgets.dart b/lib/feature/add-account/widgets/form_widgets.dart new file mode 100644 index 0000000..11ec23d --- /dev/null +++ b/lib/feature/add-account/widgets/form_widgets.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; + +/// Label builder +Widget buildLabel(String text) => Padding( + padding: const EdgeInsets.only(top: 12.0, bottom: 6), + child: Text( + text, + style: const TextStyle(fontWeight: FontWeight.w600), + ), + ); + +/// Generic Dropdown builder using DropdownMenuItem +Widget buildDropdown({ + required T? value, + required List> items, + required String hint, + required void Function(T?) onChanged, +}) { + return DropdownButtonFormField( + value: value, + decoration: InputDecoration( + filled: true, + fillColor: Colors.white.withOpacity(0.7), + contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + hint: Text(hint), + items: items, + onChanged: onChanged, + ); +} + +/// Dropdown builder from List +Widget buildDropdownFromList({ + required String? value, + required List items, + required String hint, + required void Function(String?) onChanged, +}) { + return buildDropdown( + value: value, + items: items + .map((item) => DropdownMenuItem( + value: item, + child: Text(item), + )) + .toList(), + hint: hint, + onChanged: onChanged, + ); +} + +/// Text field builder +Widget buildTextField({ + required String hint, + required TextEditingController controller, +}) { + return TextFormField( + controller: controller, + decoration: InputDecoration( + hintText: hint, + filled: true, + fillColor: Colors.white.withOpacity(0.7), + contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + ); +} From af82cab9eb852831ec05a9e5794305ca5c7347ed Mon Sep 17 00:00:00 2001 From: rivindulahiruka Date: Tue, 24 Jun 2025 12:48:20 +0530 Subject: [PATCH 2/4] feature: forgot password --- .../screens/forgot_password_screen.dart | 118 ++++++++++++++++++ .../sign-in/screens/sign_in_screen.dart | 28 +++-- .../sign-in/services/auth_service.dart | 7 ++ 3 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 lib/feature/sign-in/screens/forgot_password_screen.dart diff --git a/lib/feature/sign-in/screens/forgot_password_screen.dart b/lib/feature/sign-in/screens/forgot_password_screen.dart new file mode 100644 index 0000000..d92cd52 --- /dev/null +++ b/lib/feature/sign-in/screens/forgot_password_screen.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:harvest_manager/shared/widgets/background_template.dart'; +import 'package:harvest_manager/feature/sign-in/services/auth_service.dart'; +import 'package:harvest_manager/feature/sign-up/models/signup_exceptions.dart'; + +class ForgotPasswordScreen extends StatefulWidget { + const ForgotPasswordScreen({super.key}); + + @override + State createState() => _ForgotPasswordScreenState(); +} + +class _ForgotPasswordScreenState extends State { + final _emailController = TextEditingController(); + final _formKey = GlobalKey(); + final authService = AuthService(); + + @override + Widget build(BuildContext context) { + return BackgroundTemplate( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 40), + const Center( + child: Text( + "Forgot Password", + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Color(0xff2E7D32), + ), + ), + ), + const SizedBox(height: 30), + const Text( + "Enter your email address and we’ll send you a link to reset your password.", + style: TextStyle( + fontSize: 16, + color: Color(0xFF424242), + ), + ), + const SizedBox(height: 30), + Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + controller: _emailController, + decoration: InputDecoration( + labelText: 'Email Address', + hintText: 'Enter your Gmail address', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + ), + prefixIcon: const Icon(Icons.email), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Email is required'; + } + if (!RegExp(r'^[\w-\.]+@gmail\.com$').hasMatch(value)) { + return 'Enter a valid Gmail address'; + } + return null; + }, + ), + const SizedBox(height: 30), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () async { + if (_formKey.currentState!.validate()) { + try { + await authService + .sendPasswordResetEmail(_emailController.text.trim()); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Reset link sent to your email."), + backgroundColor: Colors.green, + ), + ); + } on SignupException catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(e.message), + backgroundColor: Colors.red, + ), + ); + } + } + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xff2E7D32), + padding: const EdgeInsets.symmetric(vertical: 15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: const Text( + 'Send Reset Link', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/feature/sign-in/screens/sign_in_screen.dart b/lib/feature/sign-in/screens/sign_in_screen.dart index cfe7735..8a79862 100644 --- a/lib/feature/sign-in/screens/sign_in_screen.dart +++ b/lib/feature/sign-in/screens/sign_in_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:harvest_manager/feature/sign-in/screens/forgot_password_screen.dart'; import 'package:harvest_manager/feature/sign-in/widgets/sign_in_textfield.dart'; import 'package:harvest_manager/feature/sign-in/services/auth_service.dart'; import 'package:harvest_manager/shared/widgets/background_template.dart'; @@ -164,18 +165,25 @@ class _SignInFormScreenState extends State { ], ), const SizedBox(height: 10), - TextButton( - onPressed: () {}, - child: const Text( - "Forget Password", - style: TextStyle( - fontSize: 12, - fontFamily: 'Inter', - color: Color(0xFF000000), - decoration: TextDecoration.underline, + // SignInFormScreen.dart -> in your "Forget Password" button + TextButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (_) => const ForgotPasswordScreen()), + ); + }, + child: const Text( + "Forget Password", + style: TextStyle( + fontSize: 12, + fontFamily: 'Inter', + color: Color(0xFF000000), + decoration: TextDecoration.underline, + ), ), ), - ), + ], ), ), diff --git a/lib/feature/sign-in/services/auth_service.dart b/lib/feature/sign-in/services/auth_service.dart index fa69c70..8263cdc 100644 --- a/lib/feature/sign-in/services/auth_service.dart +++ b/lib/feature/sign-in/services/auth_service.dart @@ -31,6 +31,13 @@ else{ } } + Future sendPasswordResetEmail(String email) async{ + try { + await _auth.sendPasswordResetEmail(email: email); + } on FirebaseAuthException catch (e) { + throw SignupException(e.message ?? "Failed to send password reset email."); + } +} } From 61e392c6d8d1c15a1e3f93ad6b9e5c66a7fd1f78 Mon Sep 17 00:00:00 2001 From: rivindulahiruka Date: Mon, 23 Jun 2025 01:52:12 +0530 Subject: [PATCH 3/4] chore: modify Add Account logic --- android/app/build.gradle.kts | 2 +- .../add-account/models/account_model.dart | 3 ++ .../add-account/models/transporter_model.dart | 6 +-- .../screens/add_account_screen.dart | 11 +++++- .../service/addaccount_service.dart | 38 +++++++++++++++---- lib/feature/navbar/bottom_navbar.dart | 8 +++- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 247fa5f..1db0d32 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -12,7 +12,7 @@ android { compileSdk = 35 buildToolsVersion = "35.0.1" namespace = "edu.BitaZoft.harvest_manager" - compileSdk = flutter.compileSdkVersion + compileSdk = 35 ndkVersion = flutter.ndkVersion ndkVersion = "29.0.13113456" diff --git a/lib/feature/add-account/models/account_model.dart b/lib/feature/add-account/models/account_model.dart index 5da1aa2..43973c0 100644 --- a/lib/feature/add-account/models/account_model.dart +++ b/lib/feature/add-account/models/account_model.dart @@ -6,6 +6,7 @@ class AccountModel { final String transporterName; final String accountNumber; final String route; + final String userId; final DateTime createdAt; final bool isActive; @@ -17,6 +18,7 @@ class AccountModel { required this.route, required this.createdAt, this.isActive = true, + required this.userId }); factory AccountModel.fromFirestore(DocumentSnapshot doc){ @@ -25,6 +27,7 @@ class AccountModel { transporterName: data['transporterName'] ?? '', accountNumber: data['accountNumber'] ?? '', route: data['route'] ?? '', + userId: data['supplierId'] ?? '', createdAt: (data['createdAt'] ?? '' as Timestamp?)?.ToDate() ?? DateTime.now(), isActive: data['isActive'] ?? true, diff --git a/lib/feature/add-account/models/transporter_model.dart b/lib/feature/add-account/models/transporter_model.dart index 18d414d..a1dd656 100644 --- a/lib/feature/add-account/models/transporter_model.dart +++ b/lib/feature/add-account/models/transporter_model.dart @@ -16,9 +16,9 @@ class TransporterModel { factory TransporterModel.fromFirestore(String id, Map data) { return TransporterModel( id: id, - name: data['name'] ?? '', - assignedFactoryId: data['assignedFactoryId'] ?? '', - routes: List.from(data['routes'] ?? []), + name: data['fullName'] ?? '', + assignedFactoryId: data['facId'] ?? '', + routes: List.from(data['route'] ?? []), ); } } diff --git a/lib/feature/add-account/screens/add_account_screen.dart b/lib/feature/add-account/screens/add_account_screen.dart index 0c97299..ff487fe 100644 --- a/lib/feature/add-account/screens/add_account_screen.dart +++ b/lib/feature/add-account/screens/add_account_screen.dart @@ -5,6 +5,7 @@ import 'package:harvest_manager/feature/add-account/models/factory_model.dart'; import 'package:harvest_manager/feature/add-account/models/transporter_model.dart'; import 'package:harvest_manager/feature/add-account/widgets/form_widgets.dart'; import 'package:harvest_manager/feature/add-account/service/addaccount_service.dart'; +import 'package:firebase_auth/firebase_auth.dart'; class AddAccountScreen extends StatefulWidget { const AddAccountScreen({super.key}); @@ -20,6 +21,8 @@ class _AddAccountScreenState extends State { String? selectedTransporterId; String? selectedRoute; + + final TextEditingController accountNoController = TextEditingController(); List factories = []; @@ -83,13 +86,19 @@ class _AddAccountScreenState extends State { if (selectedFactoryId != null && selectedTransporterId != null && selectedRoute != null && - accountNoController.text.isNotEmpty) { + accountNoController.text.isNotEmpty + ) { try { + +final String supplierId = FirebaseAuth.instance.currentUser!.uid; + await _addAccountService.addAccount( factoryId: selectedFactoryId!, transporterId: selectedTransporterId!, accountNo: accountNoController.text, route: selectedRoute!, + userId: supplierId, + ); ScaffoldMessenger.of(context).showSnackBar( diff --git a/lib/feature/add-account/service/addaccount_service.dart b/lib/feature/add-account/service/addaccount_service.dart index 89d82b8..24731e5 100644 --- a/lib/feature/add-account/service/addaccount_service.dart +++ b/lib/feature/add-account/service/addaccount_service.dart @@ -1,5 +1,7 @@ // lib/services/addaccount_service.dart import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:harvest_manager/feature/add-account/models/factory_model.dart'; import 'package:harvest_manager/feature/add-account/models/transporter_model.dart'; @@ -24,7 +26,7 @@ class AddAccountService { try { final snapshot = await _firestore .collection('transporters') - .where('assignedFactoryId', isEqualTo: factoryId) + .where('facId', isEqualTo: factoryId) .get(); return snapshot.docs @@ -42,15 +44,35 @@ class AddAccountService { required String transporterId, required String accountNo, required String route, + required String userId }) async { try { - await _firestore.collection('accounts').add({ - 'factoryId': factoryId, - 'transporterId': transporterId, - 'accountNo': accountNo, - 'route': route, - 'createdAt': FieldValue.serverTimestamp(), - }); + final batch =_firestore.batch(); + + + final accountRef=_firestore.collection('account').doc(); + final supplierRef = _firestore.collection('supplier').doc(userId); + final transporterRef = _firestore.collection('transporters').doc(transporterId); + + batch.set(accountRef, { + 'factoryId': factoryId, + 'transporterId': transporterId, + 'accountNo': accountNo, + 'route': route, + 'supplierId': userId, + 'createdAt': FieldValue.serverTimestamp(), + 'isActive': true, + }); + + batch.update(supplierRef, { + 'facAccId': factoryId, + }); + batch.update(transporterRef, { + 'assignedSuppliers': FieldValue.arrayUnion([userId]), + }); + await batch.commit(); + print('Account has been added, supplier and transporter have been updated'); + } catch (e) { print('Error adding account: $e'); rethrow; diff --git a/lib/feature/navbar/bottom_navbar.dart b/lib/feature/navbar/bottom_navbar.dart index 0dab2a5..9654aee 100644 --- a/lib/feature/navbar/bottom_navbar.dart +++ b/lib/feature/navbar/bottom_navbar.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:harvest_manager/core/theme/theme.dart'; +import 'package:harvest_manager/feature/add-account/screens/add_account_screen.dart'; import 'package:harvest_manager/feature/drawer/app_drawer.dart'; import '../home/screens/home_screen.dart'; @@ -15,11 +16,14 @@ class _BottomNavbarState extends State { int _selectedIndex = 0; static final List _screens = [ - HomeScreen(), // index 0 - Your home screen + const HomeScreen(), + const AddAccountScreen() , + // index 0 - Your home screen //const AnalyticsPage(), // index 1 - Analytics page //const AddPage(), // index 2 - Add page //const NotificationsPage(), // index 3 - Notifications page - const Center(child: Text('Menu Screen')), // index 4 - Keep as is since menu is in drawer + // const Center(child: Text('Menu Screen')), + // index 4 - Keep as is since menu is in drawer ]; void _onItemTapped(int index) { From a1bd7bf98cffee8ca2dd6c3ce91eca7722420f63 Mon Sep 17 00:00:00 2001 From: rivindulahiruka Date: Mon, 30 Jun 2025 17:54:05 +0530 Subject: [PATCH 4/4] change compilesdk --- android/app/build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 1db0d32..4a196ea 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -9,10 +9,9 @@ plugins { } android { - compileSdk = 35 + compileSdk = flutter.compileSdkVersion buildToolsVersion = "35.0.1" namespace = "edu.BitaZoft.harvest_manager" - compileSdk = 35 ndkVersion = flutter.ndkVersion ndkVersion = "29.0.13113456"