From 2d393a9885d519cefe33b22bdebd430402525818 Mon Sep 17 00:00:00 2001 From: kratikpal Date: Fri, 6 Sep 2024 10:08:19 +0530 Subject: [PATCH] Visit RD/PD and update sales task --- lib/models/user_model.dart | 7 +- lib/provider/task_provider.dart | 1 - lib/provider/visit_pdrd_provider.dart | 36 ++++++++ lib/screens/Visit_Dealers_screen.dart | 111 +++++++++++++++--------- lib/screens/assign_tasks_screen.dart | 8 +- lib/screens/confirm_task_screen.dart | 3 +- lib/screens/home_screen.dart | 37 ++++---- lib/screens/product_sales_data.dart | 58 +++++++------ lib/screens/profile_screen.dart | 103 ++++++++++++++++++++++ lib/screens/task_management_screen.dart | 8 +- lib/services/api_urls.dart | 1 + lib/widgets/common_drawer.dart | 10 ++- 12 files changed, 279 insertions(+), 104 deletions(-) create mode 100644 lib/provider/visit_pdrd_provider.dart create mode 100644 lib/screens/profile_screen.dart diff --git a/lib/models/user_model.dart b/lib/models/user_model.dart index d77b39d..4281f8f 100644 --- a/lib/models/user_model.dart +++ b/lib/models/user_model.dart @@ -3,6 +3,8 @@ class UserModel { String name; String email; String uniqueId; + String mobileNumber; + String designation; bool isVerified; UserModel({ @@ -10,6 +12,8 @@ class UserModel { required this.name, required this.email, required this.uniqueId, + required this.mobileNumber, + required this.designation, required this.isVerified, }); @@ -19,8 +23,9 @@ class UserModel { name: json['name'], email: json['email'], uniqueId: json['uniqueId'], + mobileNumber: json['mobileNumber'], + designation: json['designation'], isVerified: json['isVerified'], ); } } - diff --git a/lib/provider/task_provider.dart b/lib/provider/task_provider.dart index 15d2b67..8b61b90 100644 --- a/lib/provider/task_provider.dart +++ b/lib/provider/task_provider.dart @@ -94,7 +94,6 @@ class TaskProvider extends ChangeNotifier { String? selectedDistributorType, }) async { setLoading(true); - print("addedFff:$selectedDistributorType"); try { final data = { diff --git a/lib/provider/visit_pdrd_provider.dart b/lib/provider/visit_pdrd_provider.dart new file mode 100644 index 0000000..28159b2 --- /dev/null +++ b/lib/provider/visit_pdrd_provider.dart @@ -0,0 +1,36 @@ +import 'package:cheminova/screens/data_submit_successfull.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import '../services/api_client.dart'; +import '../services/api_urls.dart'; + +class VisitPdRdProvider with ChangeNotifier { + final _apiClient = ApiClient(); + bool _isLoading = false; + + bool get isLoading => _isLoading; + + void setLoading(bool loading) { + _isLoading = loading; + notifyListeners(); + } + + Future submitVisitPdRd(BuildContext context, String id) async { + setLoading(true); + try { + Response response = + await _apiClient.put(ApiUrls.updateTaskInventoryUrl + id); + debugPrint('Response: $response'); + setLoading(false); + if (response.statusCode == 200) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const DataSubmitSuccessfull())); + } + } catch (e) { + setLoading(false); + debugPrint("Error: $e"); + } + } +} diff --git a/lib/screens/Visit_Dealers_screen.dart b/lib/screens/Visit_Dealers_screen.dart index 9b18276..33a41e4 100644 --- a/lib/screens/Visit_Dealers_screen.dart +++ b/lib/screens/Visit_Dealers_screen.dart @@ -1,20 +1,25 @@ +import 'package:cheminova/provider/visit_pdrd_provider.dart'; import 'package:cheminova/widgets/common_drawer.dart'; import 'package:flutter/material.dart'; import 'package:cheminova/widgets/common_background.dart'; import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; import '../widgets/common_app_bar.dart'; import '../widgets/common_elevated_button.dart'; import '../widgets/common_text_form_field.dart'; import 'package:image_picker/image_picker.dart'; class VisitDealersScreen extends StatefulWidget { - const VisitDealersScreen({super.key}); + final String? tradeName; + final String? id; + const VisitDealersScreen({super.key, this.tradeName, this.id}); @override State createState() => VisitDealersScreenState(); } class VisitDealersScreenState extends State { + late VisitPdRdProvider _visitPdRdProvider; final dateController = TextEditingController( text: DateFormat('dd/MM/yyyy').format(DateTime.now())); @@ -26,13 +31,10 @@ class VisitDealersScreenState extends State { final meetingSummaryController = TextEditingController(); final followUpActionsController = TextEditingController(); final nextVisitDateController = TextEditingController(); + late TextEditingController retailerController = TextEditingController(); - String selectedPurpose = 'Sales/Liquidation'; - List purposeOptions = [ - 'Sales/Liquidation', - 'Dues collection', - 'Others' - ]; + String selectedPurpose = 'Sales'; + List purposeOptions = ['Sales', 'Dues collection', 'Others']; Future _pickImage() async { final ImagePicker picker = ImagePicker(); @@ -40,34 +42,52 @@ class VisitDealersScreenState extends State { // Handle the picked image } + @override + void initState() { + _visitPdRdProvider = VisitPdRdProvider(); + super.initState(); + } + @override Widget build(BuildContext context) { - return CommonBackground( - child: Scaffold( - backgroundColor: Colors.transparent, - appBar: CommonAppBar( - actions: [ - IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: Image.asset('assets/Back_attendance.png'), - padding: const EdgeInsets.only(right: 20), - ), - ], - title: const Text('Visit Retailers', - style: TextStyle( - fontSize: 20, - color: Colors.black, - fontWeight: FontWeight.w400, - fontFamily: 'Anek')), + retailerController = TextEditingController(text: widget.tradeName); + + return ChangeNotifierProvider( + create: (context) => _visitPdRdProvider, + child: CommonBackground( + child: Scaffold( backgroundColor: Colors.transparent, - elevation: 0, - ), - drawer: const CommonDrawer(), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: SingleChildScrollView( + appBar: CommonAppBar( + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Image.asset('assets/Back_attendance.png'), + padding: const EdgeInsets.only(right: 20), + ), + ], + title: Column( + children: [ + const Text('Visit Retailers', + style: TextStyle( + fontSize: 20, + color: Colors.black, + fontWeight: FontWeight.w400, + fontFamily: 'Anek')), + Text(widget.tradeName ?? '', + style: const TextStyle( + fontSize: 20, + color: Colors.black, + fontWeight: FontWeight.w400, + fontFamily: 'Anek')), + ], + ), + backgroundColor: Colors.transparent, + elevation: 0, + ), + drawer: const CommonDrawer(), + body: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -77,7 +97,7 @@ class VisitDealersScreenState extends State { Container( padding: const EdgeInsets.all(20.0).copyWith(top: 30, bottom: 30), - // margin: const EdgeInsets.symmetric(horizontal: 30.0), + margin: const EdgeInsets.symmetric(horizontal: 16.0), decoration: BoxDecoration( border: Border.all(color: Colors.white), color: const Color(0xffB4D1E5).withOpacity(0.9), @@ -86,9 +106,10 @@ class VisitDealersScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ CommonTextFormField( + readOnly: true, title: 'Select Retailer', fillColor: Colors.white, - controller: dealerController), + controller: retailerController), const SizedBox(height: 15), CommonTextFormField( title: 'Visit date', @@ -155,15 +176,19 @@ class VisitDealersScreenState extends State { ], ), const SizedBox(height: 15), - Align( - alignment: Alignment.center, - child: CommonElevatedButton( - borderRadius: 30, - width: double.infinity, - height: kToolbarHeight - 10, - text: 'SUBMIT', - backgroundColor: const Color(0xff004791), - onPressed: () {}, + Consumer( + builder: (context, value, child) => Align( + alignment: Alignment.center, + child: CommonElevatedButton( + borderRadius: 30, + width: double.infinity, + height: kToolbarHeight - 10, + text: 'SUBMIT', + backgroundColor: const Color(0xff004791), + onPressed: () { + value.submitVisitPdRd(context, widget.id ?? ''); + }, + ), ), ), ], diff --git a/lib/screens/assign_tasks_screen.dart b/lib/screens/assign_tasks_screen.dart index 7767ded..628c773 100644 --- a/lib/screens/assign_tasks_screen.dart +++ b/lib/screens/assign_tasks_screen.dart @@ -49,8 +49,7 @@ class _AssignTasksScreenState extends State { } // Validate Distributor - if ((taskProvider.selectedTask == 'Update Inventory Data' || - taskProvider.selectedTask == 'Visit RD/PD') && + if ((taskProvider.selectedTask != 'Collect KYC') && (taskProvider.selectedDistributor == null || selectedDistributorType == null)) { _isDistributorValid = false; @@ -267,7 +266,7 @@ class _AssignTasksScreenState extends State { taskProvider.setSelectedTask(value); }, title: const Text( - "Update Sales Data", + "Update Sales Data Data", ), ), ), @@ -345,7 +344,8 @@ class _AssignTasksScreenState extends State { }, if (taskProvider.selectedTask == 'Update Inventory Data' || - taskProvider.selectedTask == 'Visit RD/PD') ...{ + taskProvider.selectedTask == 'Visit RD/PD' || + taskProvider.selectedTask == 'Update Sales Data') ...{ Padding( padding: const EdgeInsets.symmetric( horizontal: 15.0, diff --git a/lib/screens/confirm_task_screen.dart b/lib/screens/confirm_task_screen.dart index 3357d51..6d1c0be 100644 --- a/lib/screens/confirm_task_screen.dart +++ b/lib/screens/confirm_task_screen.dart @@ -165,8 +165,7 @@ class _ConfirmTaskScreenState extends State { ), ), const SizedBox(height: 20), - if (taskProvider.selectedTask == 'Update Inventory Data' || - taskProvider.selectedTask == 'Visit RD/PD') ...{ + if (taskProvider.selectedTask != 'Collect KYC') ...{ _customContainer( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 2578470..980fb4e 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -1,5 +1,6 @@ import 'package:cheminova/notification_service.dart'; import 'package:cheminova/provider/user_provider.dart'; +import 'package:cheminova/screens/Visit_Dealers_screen.dart'; import 'package:cheminova/screens/assign_task_dash_board_screen.dart'; import 'package:cheminova/screens/calendar_screen.dart'; import 'package:cheminova/screens/collect_kyc_screen.dart'; @@ -7,14 +8,12 @@ import 'package:cheminova/screens/mark_attendence_screen.dart'; import 'package:cheminova/screens/notification_screen.dart'; import 'package:cheminova/screens/products_manual_screen.dart'; import 'package:cheminova/screens/rejected_application_screen.dart'; -import 'package:cheminova/screens/summary_screen.dart'; import 'package:cheminova/screens/product_sales_data.dart'; import 'package:cheminova/screens/update_inventory_screen.dart'; import 'package:cheminova/screens/display_sales_screen.dart'; import 'package:cheminova/widgets/common_drawer.dart'; import 'package:flutter/material.dart'; import 'package:cheminova/widgets/common_background.dart'; -import 'package:cheminova/screens/daily_tasks_screen.dart'; import 'package:provider/provider.dart'; class HomePage extends StatefulWidget { @@ -106,17 +105,7 @@ class _HomePageState extends State { const SizedBox( height: 5, ), - _buildCustomCard('Daily Tasks', 'Dashboard', onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const DailyTasksScreen(), - )); - }), - const SizedBox( - height: 5, - ), - _buildCustomCard('Assign Tasks', '', onTap: () { + _buildCustomCard('Assign Tasks', 'Dashboard', onTap: () { Navigator.push( context, MaterialPageRoute( @@ -130,9 +119,8 @@ class _HomePageState extends State { Row( children: [ Expanded( - child: _buildCustomCard( - 'Display\nSales data', 'Quickly display Sales', - onTap: () { + child: _buildCustomCard('Display\nSales data', + 'Quickly display Sales\n', onTap: () { Navigator.push( context, MaterialPageRoute( @@ -163,14 +151,19 @@ class _HomePageState extends State { Row( children: [ Expanded( - child: - _buildCustomCard('Summary', '\n\n', onTap: () { - Navigator.push( + child: _buildCustomCard( + 'Visit RD/PD', + '\n\n', + onTap: () { + Navigator.push( context, MaterialPageRoute( - builder: (context) => const SummaryScreen(), - )); - }), + builder: (context) => + const VisitDealersScreen(), + ), + ); + }, + ), ), const SizedBox( width: 12, diff --git a/lib/screens/product_sales_data.dart b/lib/screens/product_sales_data.dart index 3945af0..08cef61 100644 --- a/lib/screens/product_sales_data.dart +++ b/lib/screens/product_sales_data.dart @@ -19,7 +19,7 @@ class ProductSalesDataState extends State { text: DateFormat('dd/MM/yyyy').format(DateTime.now())); final timeController = - TextEditingController(text: DateFormat('hh:mm a').format(DateTime.now())); + TextEditingController(text: DateFormat('hh:mm a').format(DateTime.now())); final locationController = TextEditingController(); final notesController = TextEditingController(); @@ -29,19 +29,19 @@ class ProductSalesDataState extends State { final salesController = TextEditingController(); final commentController = TextEditingController(); - @override Widget build(BuildContext context) { return CommonBackground( - child: Scaffold(backgroundColor: Colors.transparent, + child: Scaffold( + backgroundColor: Colors.transparent, appBar: CommonAppBar( actions: [ IconButton( - onPressed: () - { + onPressed: () { Navigator.pop(context); }, - icon: Image.asset('assets/Back_attendance.png'), padding: const EdgeInsets.only(right: 20), + icon: Image.asset('assets/Back_attendance.png'), + padding: const EdgeInsets.only(right: 20), ), ], title: const Text('Product Sales Data', @@ -49,7 +49,9 @@ class ProductSalesDataState extends State { fontSize: 20, color: Colors.black, fontWeight: FontWeight.w400, - fontFamily: 'Anek')), backgroundColor: Colors.transparent, elevation: 0, + fontFamily: 'Anek')), + backgroundColor: Colors.transparent, + elevation: 0, ), drawer: const CommonDrawer(), body: Padding( @@ -63,7 +65,7 @@ class ProductSalesDataState extends State { const SizedBox(height: 16), Container( padding: - const EdgeInsets.all(20.0).copyWith(top: 30, bottom: 30), + const EdgeInsets.all(20.0).copyWith(top: 30, bottom: 30), // margin: const EdgeInsets.symmetric(horizontal: 30.0), decoration: BoxDecoration( border: Border.all(color: Colors.white), @@ -77,42 +79,42 @@ class ProductSalesDataState extends State { fillColor: Colors.white, controller: dealercontroller), const SizedBox(height: 15), - CommonTextFormField( title: 'Select Product: Product A', fillColor: Colors.white, controller: productController), const SizedBox(height: 15), - CommonTextFormField( title: 'Date Range: 10-06 to 20-06', readOnly: true, fillColor: Colors.white, controller: dateController), const SizedBox(height: 15), - Align( - alignment: Alignment.center, - child: CommonElevatedButton( - borderRadius: 30, - width: double.infinity, - height: kToolbarHeight - 10, - text: 'VIEW DATA', - backgroundColor: const Color(0xff004791), - onPressed: () { - Navigator.push(context, MaterialPageRoute(builder: (context) => const DataSubmitSuccessfull(),)); - }, - - ) - - ), - ], + alignment: Alignment.center, + child: CommonElevatedButton( + borderRadius: 30, + width: double.infinity, + height: kToolbarHeight - 10, + text: 'VIEW DATA', + backgroundColor: const Color(0xff004791), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + const DataSubmitSuccessfull(), + )); + }, + )), + ], ), ), ], ), ), - ),), + ), + ), ); } -} \ No newline at end of file +} diff --git a/lib/screens/profile_screen.dart b/lib/screens/profile_screen.dart new file mode 100644 index 0000000..00e6c59 --- /dev/null +++ b/lib/screens/profile_screen.dart @@ -0,0 +1,103 @@ +import 'package:cheminova/provider/user_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:cheminova/widgets/common_app_bar.dart'; +import 'package:cheminova/widgets/common_background.dart'; +import 'package:cheminova/widgets/common_drawer.dart'; + +class ProfileScreen extends StatelessWidget { + const ProfileScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + CommonBackground( + isFullWidth: true, + child: Scaffold( + drawer: const CommonDrawer(), + backgroundColor: Colors.transparent, + appBar: CommonAppBar( + title: const Text('Profile'), + backgroundColor: Colors.transparent, + elevation: 0, + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Image.asset('assets/Back_attendance.png'), + padding: const EdgeInsets.only(right: 20), + ), + ], + ), + body: Consumer( + builder: (context, userProvider, child) { + final profileData = userProvider.user; + return SingleChildScrollView( + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(20.0) + .copyWith(top: 15, bottom: 30), + margin: const EdgeInsets.symmetric( + horizontal: 30.0, vertical: 20.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.white), + color: const Color(0xffB4D1E5).withOpacity(0.9), + borderRadius: BorderRadius.circular(26.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + _buildProfileItem('Name', profileData?.name ?? ''), + _buildProfileItem('ID', profileData?.uniqueId ?? ''), + _buildProfileItem( + 'Email ID', profileData?.email ?? ''), + _buildProfileItem('Mobile Number', + profileData?.mobileNumber ?? ''), + _buildProfileItem( + 'Designation', profileData?.designation ?? ''), + ], + ), + ), + ], + ), + ); + }, + ), + ), + ), + ], + ); + } + + Widget _buildProfileItem(String label, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + label, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xff004791), + ), + ), + const SizedBox(height: 5), + Text( + value, + style: const TextStyle( + fontSize: 18, + color: Colors.black, + ), + ), + const Divider(color: Colors.grey), + ], + ), + ); + } +} diff --git a/lib/screens/task_management_screen.dart b/lib/screens/task_management_screen.dart index c475eb2..71a223e 100644 --- a/lib/screens/task_management_screen.dart +++ b/lib/screens/task_management_screen.dart @@ -18,7 +18,7 @@ class TaskManagementScreen extends StatefulWidget { class _TaskManagementScreenState extends State { final TextEditingController _searchController = TextEditingController(); List _filteredTaskList = []; - String? _selectedChip; // State to track the selected chip + String? _selectedChip = 'New'; // State to track the selected chip void _filterTaskList(String query) { if (query.isEmpty || query == '' || query == ' ') { @@ -165,7 +165,11 @@ class _TaskManagementScreenState extends State { : ListView.builder( itemCount: _filteredTaskList.length, itemBuilder: (context, index) => _taskView( - task: _filteredTaskList[index], + task: _filteredTaskList[ + _selectedChip == 'Completed' + ? index + : ((_filteredTaskList.length - 1) - + index)], ), ), ), diff --git a/lib/services/api_urls.dart b/lib/services/api_urls.dart index a150ac7..9aaa933 100644 --- a/lib/services/api_urls.dart +++ b/lib/services/api_urls.dart @@ -19,4 +19,5 @@ class ApiUrls { static const String assignTask = 'task/assign-task'; static const String getProductsManual = 'productmanual/getall'; static const String getAllTasks = 'task/alltasks/'; + static const String updateTaskInventoryUrl = ''; } diff --git a/lib/widgets/common_drawer.dart b/lib/widgets/common_drawer.dart index 41b204c..2115caa 100644 --- a/lib/widgets/common_drawer.dart +++ b/lib/widgets/common_drawer.dart @@ -2,6 +2,7 @@ import 'package:cheminova/provider/user_provider.dart'; import 'package:cheminova/screens/change_password_screen.dart'; import 'package:cheminova/screens/home_screen.dart'; import 'package:cheminova/screens/login_screen.dart'; +import 'package:cheminova/screens/profile_screen.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -72,7 +73,14 @@ class CommonDrawer extends StatelessWidget { leading: const Icon(Icons.account_circle), title: const Text('Profile'), onTap: () { - Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return const ProfileScreen(); + }, + ), + ); }, ), ListTile(