diff --git a/lib/models/select_task_response.dart b/lib/models/select_task_response.dart new file mode 100644 index 0000000..9b398e2 --- /dev/null +++ b/lib/models/select_task_response.dart @@ -0,0 +1,86 @@ +class SelectTaskKycResponse { + bool? success; + List? tasks; + + SelectTaskKycResponse({this.success, this.tasks}); + + SelectTaskKycResponse.fromJson(Map json) { + success = json['success']; + if (json['tasks'] != null) { + tasks = []; + json['tasks'].forEach((v) { + tasks!.add(new Tasks.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['success'] = this.success; + if (this.tasks != null) { + data['tasks'] = this.tasks!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Tasks { + String? sId; + String? taskId; + String? task; + String? note; + String? taskStatus; + String? taskPriority; + String? taskDueDate; + String? taskAssignedTo; + String? taskAssignedBy; + String? createdAt; + String? updatedAt; + int? iV; + + Tasks( + {this.sId, + this.taskId, + this.task, + this.note, + this.taskStatus, + this.taskPriority, + this.taskDueDate, + this.taskAssignedTo, + this.taskAssignedBy, + this.createdAt, + this.updatedAt, + this.iV}); + + Tasks.fromJson(Map json) { + sId = json['_id']; + taskId = json['taskId']; + task = json['task']; + note = json['note']; + taskStatus = json['taskStatus']; + taskPriority = json['taskPriority']; + taskDueDate = json['taskDueDate']; + taskAssignedTo = json['taskAssignedTo']; + taskAssignedBy = json['taskAssignedBy']; + createdAt = json['createdAt']; + updatedAt = json['updatedAt']; + iV = json['__v']; + } + + Map toJson() { + final Map data = new Map(); + data['_id'] = this.sId; + data['taskId'] = this.taskId; + data['task'] = this.task; + data['note'] = this.note; + data['taskStatus'] = this.taskStatus; + data['taskPriority'] = this.taskPriority; + data['taskDueDate'] = this.taskDueDate; + data['taskAssignedTo'] = this.taskAssignedTo; + data['taskAssignedBy'] = this.taskAssignedBy; + data['createdAt'] = this.createdAt; + data['updatedAt'] = this.updatedAt; + data['__v'] = this.iV; + return data; + } +} diff --git a/lib/provider/rejected_provider.dart b/lib/provider/rejected_provider.dart index c0d6402..a23f828 100644 --- a/lib/provider/rejected_provider.dart +++ b/lib/provider/rejected_provider.dart @@ -14,7 +14,6 @@ class RejectedProvider extends ChangeNotifier { List rejectedApplicationList = []; bool _isLoading = false; - bool get isLoading => _isLoading; void setLoading(bool loading) { diff --git a/lib/provider/select_task_provider.dart b/lib/provider/select_task_provider.dart new file mode 100644 index 0000000..2c65e30 --- /dev/null +++ b/lib/provider/select_task_provider.dart @@ -0,0 +1,43 @@ +import 'package:cheminova/models/select_task_response.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import '../services/api_client.dart'; +import '../services/api_urls.dart'; + +class SelectTaskProvider extends ChangeNotifier { + SelectTaskProvider() { + getTask(); + } + + final _apiClient = ApiClient(); + List tasksList=[]; + + bool _isLoading = false; + + bool get isLoading => _isLoading; + + void setLoading(bool loading) { + _isLoading = loading; + notifyListeners(); + } + + Future getTask() async { + setLoading(true); + try { + Response response = await _apiClient.get(ApiUrls.selectTaskUrl); + setLoading(false); + if (response.statusCode == 200) { + final data = SelectTaskKycResponse.fromJson(response.data); + tasksList = data.tasks ?? []; + notifyListeners(); + } + } catch (e) { + setLoading(false); + if (kDebugMode) { + print("Error occurred while fetching notifications: $e"); + } + } + } +} diff --git a/lib/screens/collect_kyc_screen.dart b/lib/screens/collect_kyc_screen.dart index a82529d..518cb9b 100644 --- a/lib/screens/collect_kyc_screen.dart +++ b/lib/screens/collect_kyc_screen.dart @@ -11,7 +11,8 @@ import 'package:provider/provider.dart'; import '../widgets/common_app_bar.dart'; class CollectKycScreen extends StatefulWidget { - const CollectKycScreen({super.key}); + final String id; + const CollectKycScreen({super.key, required this.id}); @override State createState() => CollectKycScreenState(); diff --git a/lib/screens/daily_tasks_screen.dart b/lib/screens/daily_tasks_screen.dart index e2cd2ed..2e1d2b9 100644 --- a/lib/screens/daily_tasks_screen.dart +++ b/lib/screens/daily_tasks_screen.dart @@ -41,7 +41,7 @@ class _DailyTasksScreenState extends State { ); } - PreferredSizeWidget _buildAppBar() { + CommonAppBar _buildAppBar() { return CommonAppBar( backgroundColor: Colors.transparent, elevation: 0, @@ -219,9 +219,13 @@ class _DailyTasksScreenState extends State { } final List _newTasks = [ - KycTaskItem('Collect KYC Documents', const CollectKycScreen(), + KycTaskItem('Collect KYC Documents', const CollectKycScreen(id: '',), 'Collect KYC documents from ABC Trader', DateFormat('dd/MM/yyyy').format(DateTime.now()).toString(), 'Priority'), - TaskItem('Update Inventory Data', const UpdateInventoryScreen()), + KycTaskItem('REUPLOAD', const CollectKycScreen(id: '',), + 'Reupload Pan Car From Shiv Traders', DateFormat('dd/MM/yyyy').format(DateTime.now()).toString(), 'Priority'), + KycTaskItem('REUPLOAD', const CollectKycScreen(id: '',), + 'Reupload Pan Car From Shiv Traders', DateFormat('dd/MM/yyyy').format(DateTime.now()).toString(), 'Priority'), + // TaskItem('Update Inventory Data', const UpdateInventoryScreen()), ]; final List _pendingTasks = [ diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index bd21fc2..a151375 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -9,6 +9,7 @@ import 'package:cheminova/screens/mark_attendence_screen.dart'; import 'package:cheminova/screens/notification_screen.dart'; import 'package:cheminova/screens/product_sales_data.dart'; import 'package:cheminova/screens/products_manual_screen.dart'; +import 'package:cheminova/screens/select_taskkyc_screen.dart'; import 'package:cheminova/screens/summary_screen.dart'; import 'package:cheminova/screens/update_inventory_screen.dart'; import 'package:cheminova/widgets/common_app_bar.dart'; @@ -181,7 +182,7 @@ class _HomePageState extends State { context, MaterialPageRoute( builder: (context) => - const CollectKycScreen(), + const SelectTaskkycScreen(), )); }), ), diff --git a/lib/screens/notification_screen.dart b/lib/screens/notification_screen.dart index d6abc36..9503bca 100644 --- a/lib/screens/notification_screen.dart +++ b/lib/screens/notification_screen.dart @@ -72,7 +72,6 @@ Widget buildProductButton(String productName) { text: productName, backgroundColor: const Color(0xff004791), onPressed: () { - // Handle product button press debugPrint('$productName pressed'); }, ), @@ -86,7 +85,6 @@ class MyListView extends StatelessWidget { @override Widget build(BuildContext context) { - // Group notifications by date Map> groupedNotifications = {}; for (var notification in value.notificationList) { @@ -117,7 +115,6 @@ class MyListView extends StatelessWidget { style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), - // Display notifications for the date ...notificationsForDate.map((item) => Padding( padding: const EdgeInsets.only(bottom: 10), child: ExpansionTile( diff --git a/lib/screens/rejected_application_screen.dart b/lib/screens/rejected_application_screen.dart index abc96bb..43ecfbf 100644 --- a/lib/screens/rejected_application_screen.dart +++ b/lib/screens/rejected_application_screen.dart @@ -104,7 +104,7 @@ class MyListView extends StatelessWidget { subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text((DateFormat("dd/MMMM/yyyy") + Text((DateFormat("dd/MMMM /yyyy") .format(DateTime.parse(item.createdAt ?? '')))), Text(item.sId ?? ''), for (var note in item.notes!) Text(note.message ?? ''), diff --git a/lib/screens/retailer_details_screen.dart b/lib/screens/retailer_details_screen.dart index 89284a3..02c743e 100644 --- a/lib/screens/retailer_details_screen.dart +++ b/lib/screens/retailer_details_screen.dart @@ -43,213 +43,191 @@ class RetailerDetailsScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - DropdownButtonFormField( - decoration: InputDecoration( - fillColor: Colors.white, - filled: true, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - borderSide: BorderSide.none)), - hint: Text("Select a task"), - value: value.selectedTask, - onChanged: (String? newValue) { - value.setTask(newValue!); - }, - items:["task1", "task2", "task3"].map((String task) { - return DropdownMenuItem( - value: task, - child: Text(task), - ); - }).toList(), - ), - IgnorePointer( - ignoring: value.selectedTask == null, - child: Column( - children: [ - const SizedBox(height: 15), - CommonTextFormField( - title: 'Trade Name', - fillColor: Colors.white, - validator: (String? value) { - if (value!.isEmpty) { - return 'Trade Name cannot be empty'; - } - return null; - }, - controller: value.tradeNameController), - const SizedBox(height: 15), - CommonTextFormField( - title: 'Name', - fillColor: Colors.white, - validator: (String? value) { - if (value!.isEmpty) { - return 'Name cannot be empty'; - } - return null; - }, - controller: value.nameController), - const SizedBox(height: 15), - CommonTextFormField( - title: 'Address', - fillColor: Colors.white, - validator: (String? value) { - if (value!.isEmpty) { - return 'Address cannot be empty'; - } - return null; - }, - controller: value.addressController), - const SizedBox(height: 15), - CSCPicker( - defaultCountry: CscCountry.India, - disableCountry: true, - onCountryChanged: (val) { - setState(() { - value.country.text = val; - }); - }, - onStateChanged: (val) { - setState(() { - value.state.text = val ?? ''; - }); - }, - onCityChanged: (val) { - setState(() { - value.city.text = val ?? ''; - }); - }, - ), - const SizedBox(height: 15), - CommonTextFormField( - title: 'District', - fillColor: Colors.white, - validator: (String? value) { - if (value!.isEmpty) { - return 'District cannot be empty'; - } - return null; - }, - controller: value.districtController), - const SizedBox(height: 15), - CommonTextFormField( - maxLength: 6, - title: 'Pincode', - fillColor: Colors.white, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - validator: (String? value) { - if (value!.isEmpty) { - return 'Pincode cannot be empty'; - } - return null; - }, - controller: value.pinCodeController), - const SizedBox(height: 15), - CommonTextFormField( - maxLength: 10, - title: 'Mobile Number', - fillColor: Colors.white, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - validator: (String? value) { - if (value!.isEmpty) { - return 'Mobile Number cannot be empty'; - } - return null; - }, - controller: value.mobileNumberController), - const SizedBox(height: 15), - CommonTextFormField( - maxLength: 12, - title: 'Aadhar Number', - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - fillColor: Colors.white, - validator: (String? value) { - if (value!.isEmpty) { - return 'Aadhar Number cannot be empty'; - } - return null; - }, - controller: value.aadharNumberController), - const SizedBox(height: 15), - CommonTextFormField( - inputFormatters: [ - UpperCaseTextFormatter(), - ], - maxLength: 10, - title: 'PAN Number', - fillColor: Colors.white, - validator: (String? value) { - if (value!.isEmpty) { - return 'PAN Number cannot be empty'; - } - return null; - }, - controller: value.panNumberController), - const SizedBox(height: 15), - CommonTextFormField( - inputFormatters: [ - UpperCaseTextFormatter(), - ], - maxLength: 15, - title: 'GST Number', - fillColor: Colors.white, - validator: (String? value) { - if (value!.isEmpty) { - return 'GST Number cannot be empty'; - } - return null; - }, - controller: value.gstNumberController), - const SizedBox(height: 15), - DropdownButtonFormField( - decoration: InputDecoration( - fillColor: Colors.white, - filled: true, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - borderSide: BorderSide.none), - hintText: 'Mapped Principal Distributor'), - value: value.selectedDistributor, - items: value.pdList.map((GetPdResponse pd) { - return DropdownMenuItem( - value: pd.sId, child: Text(pd.name ?? '')); - }).toList(), - onChanged: (String? newValue) { - setState(() { - value.selectedDistributor = newValue; - }); - }, + Column( + children: [ + const SizedBox(height: 15), + CommonTextFormField( + title: 'Trade Name', + fillColor: Colors.white, validator: (String? value) { - if (value == null || value.isEmpty) { - return 'Mapped Principal Distributor cannot be empty'; + if (value!.isEmpty) { + return 'Trade Name cannot be empty'; } return null; }, + controller: value.tradeNameController), + const SizedBox(height: 15), + CommonTextFormField( + title: 'Name', + fillColor: Colors.white, + validator: (String? value) { + if (value!.isEmpty) { + return 'Name cannot be empty'; + } + return null; + }, + controller: value.nameController), + const SizedBox(height: 15), + CommonTextFormField( + title: 'Address', + fillColor: Colors.white, + validator: (String? value) { + if (value!.isEmpty) { + return 'Address cannot be empty'; + } + return null; + }, + controller: value.addressController), + const SizedBox(height: 15), + CSCPicker( + defaultCountry: CscCountry.India, + disableCountry: true, + onCountryChanged: (val) { + setState(() { + value.country.text = val; + }); + }, + onStateChanged: (val) { + setState(() { + value.state.text = val ?? ''; + }); + }, + onCityChanged: (val) { + setState(() { + value.city.text = val ?? ''; + }); + }, + ), + const SizedBox(height: 15), + CommonTextFormField( + title: 'District', + fillColor: Colors.white, + validator: (String? value) { + if (value!.isEmpty) { + return 'District cannot be empty'; + } + return null; + }, + controller: value.districtController), + const SizedBox(height: 15), + CommonTextFormField( + maxLength: 6, + title: 'Pincode', + fillColor: Colors.white, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + validator: (String? value) { + if (value!.isEmpty) { + return 'Pincode cannot be empty'; + } + return null; + }, + controller: value.pinCodeController), + const SizedBox(height: 15), + CommonTextFormField( + maxLength: 10, + title: 'Mobile Number', + fillColor: Colors.white, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + validator: (String? value) { + if (value!.isEmpty) { + return 'Mobile Number cannot be empty'; + } + return null; + }, + controller: value.mobileNumberController), + const SizedBox(height: 15), + CommonTextFormField( + maxLength: 12, + title: 'Aadhar Number', + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + fillColor: Colors.white, + validator: (String? value) { + if (value!.isEmpty) { + return 'Aadhar Number cannot be empty'; + } + return null; + }, + controller: value.aadharNumberController), + const SizedBox(height: 15), + CommonTextFormField( + inputFormatters: [ + UpperCaseTextFormatter(), + ], + maxLength: 10, + title: 'PAN Number', + fillColor: Colors.white, + validator: (String? value) { + if (value!.isEmpty) { + return 'PAN Number cannot be empty'; + } + return null; + }, + controller: value.panNumberController), + const SizedBox(height: 15), + CommonTextFormField( + inputFormatters: [ + UpperCaseTextFormatter(), + ], + maxLength: 15, + title: 'GST Number', + fillColor: Colors.white, + validator: (String? value) { + if (value!.isEmpty) { + return 'GST Number cannot be empty'; + } + return null; + }, + controller: value.gstNumberController), + const SizedBox(height: 15), + DropdownButtonFormField( + decoration: InputDecoration( + fillColor: Colors.white, + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: BorderSide.none), + hintText: 'Mapped Principal Distributor'), + value: value.selectedDistributor, + items: value.pdList.map((GetPdResponse pd) { + return DropdownMenuItem( + value: pd.sId, child: Text(pd.name ?? '')); + }).toList(), + onChanged: (String? newValue) { + setState(() { + value.selectedDistributor = newValue; + }); + }, + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Mapped Principal Distributor cannot be empty'; + } + return null; + }, + ), + const SizedBox(height: 30), + Align( + alignment: Alignment.center, + child: CommonElevatedButton( + borderRadius: 30, + width: double.infinity, + height: kToolbarHeight - 10, + text: 'CONTINUE', + backgroundColor: const Color(0xff004791), + onPressed: () { + if (value.retailerDetailsFormKey.currentState! + .validate()) { + value.tabController.animateTo(1); + } + }, ), - const SizedBox(height: 30), - Align( - alignment: Alignment.center, - child: CommonElevatedButton( - borderRadius: 30, - width: double.infinity, - height: kToolbarHeight - 10, - text: 'CONTINUE', - backgroundColor: const Color(0xff004791), - onPressed: () { - if (value.retailerDetailsFormKey.currentState! - .validate()) { - value.tabController.animateTo(1); - } - }, - ), - ), - ], - ), + ), + ], ), ], ), diff --git a/lib/screens/select_taskkyc_screen.dart b/lib/screens/select_taskkyc_screen.dart new file mode 100644 index 0000000..f2eff74 --- /dev/null +++ b/lib/screens/select_taskkyc_screen.dart @@ -0,0 +1,127 @@ +import 'package:cheminova/models/select_task_response.dart'; +import 'package:cheminova/provider/select_task_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:cheminova/screens/collect_kyc_screen.dart'; +import 'package:cheminova/widgets/common_app_bar.dart'; +import 'package:cheminova/widgets/common_drawer.dart'; +import 'package:cheminova/widgets/common_background.dart'; +import 'package:provider/provider.dart'; + +class SelectTaskkycScreen extends StatefulWidget { + const SelectTaskkycScreen({super.key}); + + @override + State createState() => SelectTaskkycScreenState(); +} + +class SelectTaskkycScreenState extends State { +late SelectTaskProvider _selectTaskProvider; +@override + void initState() { + _selectTaskProvider = SelectTaskProvider(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + + return ChangeNotifierProvider( + create: (context) => _selectTaskProvider, + child: CommonBackground( + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: CommonAppBar(title:const Text('Select Task'), + backgroundColor: Colors.transparent, + elevation: 0, + actions: [IconButton( + onPressed: () => Navigator.pop(context), + icon: Image.asset('assets/Back_attendance.png'), + padding: const EdgeInsets.only(right: 20), + ), + ]), + drawer: const CommonDrawer(), + body: Consumer( + builder: (context, value, child) => value.isLoading + ? const Center(child: CircularProgressIndicator()) + : _buildTaskList(), + ), + ), + )); + } + + Widget _buildTaskList() { + return Consumer( + builder: (context, value, child) { + if (value.tasksList.isEmpty) { + return const Center(child: Text('No tasks available')); + } + return ListView.builder( + itemCount: value.tasksList.length, + itemBuilder: (context, index) => + _buildTaskCard(value.tasksList[index]), + ); + }); + } + + +Widget _buildTaskCard(Tasks task) { + return Card( + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + color: Colors.white, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + leading: const Icon(Icons.task, color: Colors.blueAccent), + title: Text( + task.task??'', + style: const TextStyle( + color: Colors.black87, + fontWeight: FontWeight.w700, + fontSize: 16, + fontFamily: 'Anek', + ), + ), + trailing: + const Icon(Icons.arrow_forward_ios, color: Colors.black87), + onTap: () => Navigator.push(context, + MaterialPageRoute(builder: (context) => CollectKycScreen(id:task.taskId??''))), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Note: ${task.note}'), + Text('Date: ${task.taskDueDate}'), + Text('Priority: ${task.taskPriority}'), + ], + ), + ), + ], + ), + ); +} +} + +class TaskItem { + final String title; + final Widget screen; + + TaskItem({required this.title, required this.screen}); +} + +class KycTaskItem extends TaskItem { + final String note; + final String date; + final String priority; + + KycTaskItem({ + required String title, + required Widget screen, + required this.note, + required this.date, + required this.priority, + }) : super(title: title, screen: screen); +} diff --git a/lib/services/api_urls.dart b/lib/services/api_urls.dart index 47fb01d..aa28d97 100644 --- a/lib/services/api_urls.dart +++ b/lib/services/api_urls.dart @@ -16,4 +16,5 @@ class ApiUrls { static const String getProducts = '${baseUrl}product/getAll/user'; static const String getPdRdUrl = '${baseUrl}inventory/distributors-SC/'; static const String submitProductUrl = '${baseUrl}inventory/add-SC'; + static const String selectTaskUrl = '${baseUrl}task/tasks'; }