Compare commits

..

No commits in common. "2d393a9885d519cefe33b22bdebd430402525818" and "96aa3e8549cc348816fddfe4f7f389cfbfdb46e5" have entirely different histories.

35 changed files with 666 additions and 2545 deletions

View File

@ -1,10 +1,7 @@
import 'dart:developer'; import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:cheminova/provider/collect_kyc_provider.dart'; import 'package:cheminova/provider/collect_kyc_provider.dart';
import 'package:cheminova/provider/pd_rd_provider.dart';
import 'package:cheminova/provider/product_manual_provider.dart';
import 'package:cheminova/provider/product_provider.dart'; import 'package:cheminova/provider/product_provider.dart';
import 'package:cheminova/provider/task_provider.dart';
import 'package:cheminova/provider/user_provider.dart'; import 'package:cheminova/provider/user_provider.dart';
import 'package:cheminova/screens/splash_screen.dart'; import 'package:cheminova/screens/splash_screen.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
@ -23,10 +20,8 @@ Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
} }
AndroidNotificationChannel channel = const AndroidNotificationChannel( AndroidNotificationChannel channel = const AndroidNotificationChannel(
'High Importance Channel', 'High Importance Channel', 'High Importance Notifications',
'High Importance Notifications', importance: Importance.high);
importance: Importance.high,
);
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
@ -103,9 +98,6 @@ Future<void> main() async {
ChangeNotifierProvider(create: (context) => CollectKycProvider()), ChangeNotifierProvider(create: (context) => CollectKycProvider()),
ChangeNotifierProvider(create: (_) => UserProvider()), ChangeNotifierProvider(create: (_) => UserProvider()),
ChangeNotifierProvider(create: (_) => ProductProvider()), ChangeNotifierProvider(create: (_) => ProductProvider()),
ChangeNotifierProvider(create: (_) => PdRdProvider()),
ChangeNotifierProvider(create: (_) => TaskProvider()),
ChangeNotifierProvider(create: (_) => ProductManualProvider()),
], ],
child: const MyApp(), child: const MyApp(),
), ),
@ -127,12 +119,8 @@ class _MyAppState extends State<MyApp> {
// scaffoldMessengerKey: SnackBarService().scaffoldMessengerKey, // scaffoldMessengerKey: SnackBarService().scaffoldMessengerKey,
title: 'cheminova', title: 'cheminova',
theme: ThemeData( theme: ThemeData(
colorScheme: ColorScheme.fromSeed( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
seedColor: const Color(0xff004791), useMaterial3: true),
), home: const SplashScreen());
useMaterial3: true,
),
home: const SplashScreen(),
);
} }
} }

View File

@ -1,72 +0,0 @@
class PdRdResponseModel {
String? id;
String? uniqueId;
String? name;
String? tradeNameRd;
ShippingAddress? shippingAddress;
String? salesCoordinator; // Nullable property for SalesCoordinator
PdRdResponseModel({
this.id,
this.uniqueId,
this.name,
this.tradeNameRd,
this.shippingAddress,
this.salesCoordinator, // Initialize SalesCoordinator
});
factory PdRdResponseModel.fromJson(Map<String, dynamic> json) =>
PdRdResponseModel(
id: json["_id"],
name: json["name"],
uniqueId: json["uniqueId"],
tradeNameRd: json["trade_name"],
shippingAddress: json['shippingAddress'] != null
? ShippingAddress.fromJson(json['shippingAddress'])
: null,
salesCoordinator: json.containsKey('salesCoordinator')
? json['salesCoordinator']
: null, // Handle missing field
);
}
class ShippingAddress {
final String id;
final String street;
final String city;
final String state;
final String postalCode;
final String country;
final String panNumber;
final String tradeName;
final String gstNumber;
final bool isDefault;
ShippingAddress({
required this.id,
required this.street,
required this.city,
required this.state,
required this.postalCode,
required this.country,
required this.panNumber,
required this.tradeName,
required this.gstNumber,
required this.isDefault,
});
factory ShippingAddress.fromJson(Map<String, dynamic> json) {
return ShippingAddress(
id: json['_id'] ?? '',
street: json['street'] ?? '',
city: json['city'] ?? '',
state: json['state'] ?? '',
postalCode: json['postalCode'] ?? '',
country: json['country'] ?? '',
panNumber: json['panNumber'] ?? '',
tradeName: json['tradeName'] ?? '',
gstNumber: json['gstNumber'] ?? '',
isDefault: json['isDefault'] ?? false,
);
}
}

View File

@ -1,48 +0,0 @@
class ProductManualModel {
final ProductManualDetail productManualDetail;
final String id;
final String title;
final String createdAt;
final String updatedAt;
final int version;
ProductManualModel({
required this.productManualDetail,
required this.id,
required this.title,
required this.createdAt,
required this.updatedAt,
required this.version,
});
factory ProductManualModel.fromJson(Map<String, dynamic> json) {
return ProductManualModel(
productManualDetail: ProductManualDetail.fromJson(json['product_manual']),
id: json['_id'],
title: json['title'],
createdAt: json['createdAt'],
updatedAt: json['updatedAt'],
version: json['__v'],
);
}
}
class ProductManualDetail {
final String publicId;
final String url;
final String filename;
ProductManualDetail({
required this.publicId,
required this.url,
required this.filename,
});
factory ProductManualDetail.fromJson(Map<String, dynamic> json) {
return ProductManualDetail(
publicId: json['public_id'],
url: json['url'],
filename: json['filename'],
);
}
}

View File

@ -2,13 +2,13 @@ class ProductResponse {
final bool success; final bool success;
final int totalData; final int totalData;
final int totalPages; final int totalPages;
final List<Product> products; final List<Product> product;
ProductResponse({ ProductResponse({
required this.success, required this.success,
required this.totalData, required this.totalData,
required this.totalPages, required this.totalPages,
required this.products, required this.product,
}); });
factory ProductResponse.fromJson(Map<String, dynamic> json) { factory ProductResponse.fromJson(Map<String, dynamic> json) {
@ -16,7 +16,7 @@ class ProductResponse {
success: json['success'], success: json['success'],
totalData: json['total_data'], totalData: json['total_data'],
totalPages: json['total_pages'], totalPages: json['total_pages'],
products: (json['products'] as List) product: (json['product'] as List)
.map((item) => Product.fromJson(item)) .map((item) => Product.fromJson(item))
.toList(), .toList(),
); );
@ -27,7 +27,7 @@ class ProductResponse {
'success': success, 'success': success,
'total_data': totalData, 'total_data': totalData,
'total_pages': totalPages, 'total_pages': totalPages,
'products': products.map((item) => item.toJson()).toList(), 'product': product.map((item) => item.toJson()).toList(),
}; };
} }
} }
@ -37,38 +37,32 @@ class Product {
final String SKU; final String SKU;
final String name; final String name;
final Category category; final Category category;
final Brand brand;
final double price; final double price;
final int GST; final GST gst;
final int HSNCode;
final String description; final String description;
final String specialInstructions;
final String productStatus; final String productStatus;
final AddedBy addedBy; final AddedBy addedBy;
final List<dynamic> image; final List<dynamic> image;
final DateTime createdAt; final DateTime createdAt;
final DateTime updatedAt; final DateTime updatedAt;
final int v; final int v;
int? sale;
int? inventory;
Product({ Product({
required this.id, required this.id,
required this.SKU, required this.SKU,
required this.name, required this.name,
required this.category, required this.category,
required this.brand,
required this.price, required this.price,
required this.GST, required this.gst,
required this.HSNCode,
required this.description, required this.description,
required this.specialInstructions,
required this.productStatus, required this.productStatus,
required this.addedBy, required this.addedBy,
required this.image, required this.image,
required this.createdAt, required this.createdAt,
required this.updatedAt, required this.updatedAt,
required this.v, required this.v,
this.sale,
this.inventory,
}); });
factory Product.fromJson(Map<String, dynamic> json) { factory Product.fromJson(Map<String, dynamic> json) {
@ -77,19 +71,16 @@ class Product {
SKU: json['SKU'], SKU: json['SKU'],
name: json['name'], name: json['name'],
category: Category.fromJson(json['category']), category: Category.fromJson(json['category']),
brand: Brand.fromJson(json['brand']),
price: (json['price'] as num).toDouble(), price: (json['price'] as num).toDouble(),
GST: json['GST'], gst: GST.fromJson(json['GST']),
HSNCode: json['HSN_Code'], description: json['description'],
description: json['description'] ?? '', specialInstructions: json['special_instructions'],
productStatus: json['product_Status'], productStatus: json['product_Status'],
addedBy: AddedBy.fromJson(json['addedBy']), addedBy: AddedBy.fromJson(json['addedBy']),
image: json['image'] as List<dynamic>, image: json['image'] as List<dynamic>,
createdAt: DateTime.parse(json['createdAt']), createdAt: DateTime.parse(json['createdAt']),
updatedAt: DateTime.parse(json['updatedAt']), updatedAt: DateTime.parse(json['updatedAt']),
v: json['__v'], v: json['__v'],
sale: json['sale'], // Nullable field
inventory: json['inventory'], // Nullable field
); );
} }
@ -99,19 +90,16 @@ class Product {
'SKU': SKU, 'SKU': SKU,
'name': name, 'name': name,
'category': category.toJson(), 'category': category.toJson(),
'brand': brand.toJson(),
'price': price, 'price': price,
'GST': GST, 'GST': gst.toJson(),
'HSN_Code': HSNCode,
'description': description, 'description': description,
'special_instructions': specialInstructions,
'product_Status': productStatus, 'product_Status': productStatus,
'addedBy': addedBy.toJson(), 'addedBy': addedBy.toJson(),
'image': image, 'image': image,
'createdAt': createdAt.toIso8601String(), 'createdAt': createdAt.toIso8601String(),
'updatedAt': updatedAt.toIso8601String(), 'updatedAt': updatedAt.toIso8601String(),
'__v': v, '__v': v,
'sale': sale, // Nullable field
'inventory': inventory, // Nullable field
}; };
} }
} }
@ -140,26 +128,30 @@ class Category {
} }
} }
class Brand { class GST {
final String id; final String id;
final String brandName; final String name;
final int tax;
Brand({ GST({
required this.id, required this.id,
required this.brandName, required this.name,
required this.tax,
}); });
factory Brand.fromJson(Map<String, dynamic> json) { factory GST.fromJson(Map<String, dynamic> json) {
return Brand( return GST(
id: json['_id'], id: json['_id'],
brandName: json['brandName'], name: json['name'],
tax: json['tax'],
); );
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
'_id': id, '_id': id,
'brandName': brandName, 'name': name,
'tax': tax,
}; };
} }
} }

View File

@ -1,78 +0,0 @@
class TaskModel {
final String id;
final String taskId;
final String task;
final String? note;
final String taskStatus;
final String? taskPriority;
final DateTime taskDueDate;
final TaskAssignedTo taskAssignedTo;
final String? taskAssignedBy;
final String? addedFor;
final String? addedForId;
final String? tradename;
final DateTime? createdAt;
final DateTime? updatedAt;
final int? version;
TaskModel({
required this.id,
required this.taskId,
required this.task,
this.note,
required this.taskStatus,
this.taskPriority,
required this.taskDueDate,
required this.taskAssignedTo,
this.taskAssignedBy,
this.addedFor,
this.addedForId,
this.tradename,
this.createdAt,
this.updatedAt,
this.version,
});
factory TaskModel.fromJson(Map<String, dynamic> json) {
return TaskModel(
id: json['_id'],
taskId: json['taskId'],
task: json['task'],
note: json['note'],
taskStatus: json['taskStatus'],
taskPriority: json['taskPriority'],
taskDueDate: DateTime.parse(json['taskDueDate']),
taskAssignedTo: TaskAssignedTo.fromJson(json['taskAssignedTo']),
taskAssignedBy: json['taskAssignedBy'],
addedFor: json['addedFor'],
addedForId: json['addedForId'],
tradename: json['tradename'],
createdAt: DateTime.parse(json['createdAt']),
updatedAt: DateTime.parse(json['updatedAt']),
version: json['__v'],
);
}
}
class TaskAssignedTo {
final String id;
final String name;
final String mobileNumber;
final String email;
TaskAssignedTo({
required this.id,
required this.name,
required this.mobileNumber,
required this.email,
});
factory TaskAssignedTo.fromJson(Map<String, dynamic> json) {
return TaskAssignedTo(
id: json['_id'],
name: json['name'],
mobileNumber: json['mobileNumber'],
email: json['email'],
);
}
}

View File

@ -3,8 +3,6 @@ class UserModel {
String name; String name;
String email; String email;
String uniqueId; String uniqueId;
String mobileNumber;
String designation;
bool isVerified; bool isVerified;
UserModel({ UserModel({
@ -12,8 +10,6 @@ class UserModel {
required this.name, required this.name,
required this.email, required this.email,
required this.uniqueId, required this.uniqueId,
required this.mobileNumber,
required this.designation,
required this.isVerified, required this.isVerified,
}); });
@ -23,9 +19,8 @@ class UserModel {
name: json['name'], name: json['name'],
email: json['email'], email: json['email'],
uniqueId: json['uniqueId'], uniqueId: json['uniqueId'],
mobileNumber: json['mobileNumber'],
designation: json['designation'],
isVerified: json['isVerified'], isVerified: json['isVerified'],
); );
} }
} }

View File

@ -1,68 +0,0 @@
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:cheminova/models/pd_rd_response_model.dart';
import 'package:cheminova/services/api_client.dart';
import 'package:cheminova/services/api_urls.dart';
class PdRdProvider extends ChangeNotifier {
bool _isLoading = false;
bool get isLoading => _isLoading;
List<PdRdResponseModel> _pdList = [];
List<PdRdResponseModel> get pdList => _pdList;
List<PdRdResponseModel> _rdList = [];
List<PdRdResponseModel> get rdList => _rdList;
final _apiClient = ApiClient();
void setLoading(bool loading) {
_isLoading = loading;
notifyListeners();
}
void clearLists() {
_pdList.clear();
_rdList.clear();
notifyListeners();
}
Future<void> getPd() async {
setLoading(true);
clearLists(); // Clear the list before fetching new data
try {
Response response = await _apiClient.get(ApiUrls.getPd);
if (response.statusCode == 200) {
List<PdRdResponseModel> data = (response.data as List)
.map((json) => PdRdResponseModel.fromJson(json))
.toList();
_pdList = data;
} else {
print("Failed to load data: ${response.statusCode}");
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
Future<void> getRd() async {
setLoading(true);
clearLists(); // Clear the list before fetching new data
try {
Response response = await _apiClient.get(ApiUrls.getRd);
if (response.statusCode == 200) {
List<PdRdResponseModel> data = (response.data as List)
.map((json) => PdRdResponseModel.fromJson(json))
.toList();
_rdList = data;
} else {
print("Failed to load data: ${response.statusCode}");
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
}

View File

@ -1,39 +0,0 @@
import 'package:cheminova/models/product_manual_model.dart';
import 'package:cheminova/services/api_urls.dart';
import 'package:cheminova/services/api_client.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
class ProductManualProvider extends ChangeNotifier {
bool _isLoading = false;
List<ProductManualModel> _productManualList = [];
final _apiClient = ApiClient();
List<ProductManualModel> get productManualList => _productManualList;
bool get isLoading => _isLoading;
void setLoading(bool loading) {
_isLoading = loading;
notifyListeners();
}
Future<void> getProductManualList() async {
setLoading(true);
try {
Response response = await _apiClient.get(ApiUrls.getProductsManual);
if (response.statusCode == 200) {
List<ProductManualModel> data =
(response.data['productManuals'] as List)
.map((json) => ProductManualModel.fromJson(json))
.toList();
_productManualList = data;
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
}

View File

@ -12,14 +12,11 @@ class ProductProvider extends ChangeNotifier {
final _apiClient = ApiClient(); final _apiClient = ApiClient();
ProductResponse? productResponse; ProductResponse? productResponse;
List<Product> productList = []; List<Product> productList = [];
final List<Product> _selectedProducts = [];
bool _isLoading = false; bool _isLoading = false;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
List<Product> get selectedProducts => _selectedProducts;
void setLoading(bool loading) { void setLoading(bool loading) {
_isLoading = loading; _isLoading = loading;
notifyListeners(); notifyListeners();
@ -32,7 +29,7 @@ class ProductProvider extends ChangeNotifier {
setLoading(false); setLoading(false);
if (response.statusCode == 200) { if (response.statusCode == 200) {
productResponse = ProductResponse.fromJson(response.data); productResponse = ProductResponse.fromJson(response.data);
productList = productResponse!.products; productList = productResponse!.product;
notifyListeners(); notifyListeners();
} }
} catch (e) { } catch (e) {
@ -40,36 +37,4 @@ class ProductProvider extends ChangeNotifier {
print("Error: $e"); print("Error: $e");
} }
} }
Future<bool> submitSelectedProducts(
String addedFor, String addedForId) async {
setLoading(true);
try {
final data = {
"products": selectedProducts.map((product) {
return {
"SKU": product.SKU,
"ProductName": product.name,
"Sale": product.sale,
"Inventory": product.inventory,
};
}).toList(),
"addedFor": addedFor,
"addedForId": addedForId,
};
Response response =
await _apiClient.post(ApiUrls.submitProducts, data: data);
setLoading(false);
if (response.statusCode == 201) {
return true;
} else {
return false;
}
} catch (e) {
setLoading(false);
print("Error: $e");
return false;
}
}
} }

View File

@ -1,248 +0,0 @@
import 'package:cheminova/models/pd_rd_response_model.dart';
import 'package:cheminova/models/task_model.dart';
import 'package:cheminova/screens/data_submit_successfull.dart';
import 'package:cheminova/services/api_client.dart';
import 'package:cheminova/services/api_urls.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class TaskProvider extends ChangeNotifier {
bool _isLoading = false;
PdRdResponseModel? _selectedSalesCoordinator;
String? _selectedTask;
String? _selectedPriority;
String _selectedDate = DateFormat('dd/MM/yyyy').format(DateTime.now());
List<PdRdResponseModel> _salesCoordinators = [];
List<PdRdResponseModel> _pdList = [];
List<PdRdResponseModel> _rdList = [];
List<TaskModel> _taskModelList = [];
PdRdResponseModel? _selectedDistributor;
final TextEditingController _noteController = TextEditingController();
final _apiClient = ApiClient();
bool get isLoading => _isLoading;
PdRdResponseModel? get selectedSalesCoordinator => _selectedSalesCoordinator;
String? get selectedTask => _selectedTask;
String? get selectedPriority => _selectedPriority;
String get selectedDate => _selectedDate;
List<PdRdResponseModel> get salesCoordinators => _salesCoordinators;
TextEditingController get noteController => _noteController;
List<PdRdResponseModel> get pdList => _pdList;
List<PdRdResponseModel> get rdList => _rdList;
List<TaskModel> get taskModelList => _taskModelList;
PdRdResponseModel? get selectedDistributor => _selectedDistributor;
void setLoading(bool loading) {
_isLoading = loading;
notifyListeners();
}
void setSelectedSalesCoordinator(PdRdResponseModel coordinator) {
_selectedSalesCoordinator = coordinator;
notifyListeners();
}
void setSelectedTask(String? task) {
_selectedTask = task;
notifyListeners();
}
void setSelectedPriority(String priority) {
_selectedPriority = priority;
notifyListeners();
}
void setDate(String date) {
_selectedDate = date;
notifyListeners();
}
void clear() {
_selectedSalesCoordinator = null;
_selectedTask = null;
_selectedPriority = null;
_selectedDate = DateFormat('dd/MM/yyyy').format(DateTime.now());
_noteController.clear();
_taskModelList.clear();
notifyListeners();
}
Future<void> getSalesCoordinators() async {
setLoading(true);
try {
Response response = await _apiClient.get(ApiUrls.getSalesCoordinators);
if (response.statusCode == 200) {
List<PdRdResponseModel> data =
(response.data['salesCoOrinators'] as List)
.map((json) => PdRdResponseModel.fromJson(json))
.toList();
_salesCoordinators = data;
} else {
print("Failed to load data: ${response.statusCode}");
}
} catch (e) {
print("Error occurred: $e");
setLoading(false);
} finally {
setLoading(false);
}
}
Future<void> assignTask({
required BuildContext context,
String? selectedDistributorType,
}) async {
setLoading(true);
try {
final data = {
'taskAssignedTo': _selectedSalesCoordinator!.id,
'task': _selectedTask,
'taskPriority': _selectedPriority,
'taskDueDate': _selectedDate,
if (_selectedTask == 'Collect KYC' || _selectedTask == 'Visit RD/PD')
'note': _noteController.text,
};
if (selectedDistributorType != null &&
selectedDistributorType.isNotEmpty) {
data.addAll({
'addedFor': selectedDistributorType,
'addedForId': _selectedDistributor!.id,
'tradename': selectedDistributorType == 'PrincipalDistributor'
? _selectedDistributor!.shippingAddress!.tradeName
: _selectedDistributor!.tradeNameRd,
});
}
Response response = await _apiClient.post(
ApiUrls.assignTask,
data: data,
);
if (response.statusCode == 201) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DataSubmitSuccessfull(),
),
);
} else {
print("Failed to assign task: ${response.statusCode}");
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
void clearLists() {
_pdList.clear();
_rdList.clear();
notifyListeners();
}
void setSelectedDistributor(PdRdResponseModel? distributor) {
_selectedDistributor = distributor;
notifyListeners();
}
Future<void> getPd() async {
setLoading(true);
clearLists(); // Clear the list before fetching new data
try {
Response response = await _apiClient.get(ApiUrls.getPd);
if (response.statusCode == 200) {
List<PdRdResponseModel> data = (response.data as List)
.map((json) => PdRdResponseModel.fromJson(json))
.toList();
_pdList = data;
print("PDTradeName ${data[0].shippingAddress!.tradeName}");
} else {
print("Failed to load data: ${response.statusCode}");
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
Future<void> getRd() async {
setLoading(true);
clearLists(); // Clear the list before fetching new data
try {
Response response = await _apiClient.get(ApiUrls.getRd);
if (response.statusCode == 200) {
List<PdRdResponseModel> data = (response.data as List)
.map((json) => PdRdResponseModel.fromJson(json))
.toList();
_rdList = data;
print("RDTradeName ${data[0].tradeNameRd}");
} else {
print("Failed to load data: ${response.statusCode}");
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
Future<void> getNewTasks() async {
setLoading(true);
clearLists();
try {
Response response = await _apiClient.get("${ApiUrls.getAllTasks}New");
if (response.statusCode == 200) {
List<TaskModel> data = (response.data['tasks'] as List)
.map((json) => TaskModel.fromJson(json))
.toList();
_taskModelList = data;
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
Future<void> getPendingTasks() async {
setLoading(true);
clearLists();
try {
Response response = await _apiClient.get("${ApiUrls.getAllTasks}Pending");
if (response.statusCode == 200) {
List<TaskModel> data = (response.data['tasks'] as List)
.map((json) => TaskModel.fromJson(json))
.toList();
_taskModelList = data;
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
Future<void> getCompletedTasks() async {
setLoading(true);
clearLists();
try {
Response response =
await _apiClient.get("${ApiUrls.getAllTasks}Completed");
if (response.statusCode == 200) {
List<TaskModel> data = (response.data['tasks'] as List)
.map((json) => TaskModel.fromJson(json))
.toList();
_taskModelList = data;
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
}

View File

@ -1,36 +0,0 @@
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<void> 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");
}
}
}

View File

@ -1,25 +1,20 @@
import 'package:cheminova/provider/visit_pdrd_provider.dart';
import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_drawer.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/widgets/common_background.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../widgets/common_app_bar.dart'; import '../widgets/common_app_bar.dart';
import '../widgets/common_elevated_button.dart'; import '../widgets/common_elevated_button.dart';
import '../widgets/common_text_form_field.dart'; import '../widgets/common_text_form_field.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
class VisitDealersScreen extends StatefulWidget { class VisitDealersScreen extends StatefulWidget {
final String? tradeName; const VisitDealersScreen({super.key});
final String? id;
const VisitDealersScreen({super.key, this.tradeName, this.id});
@override @override
State<VisitDealersScreen> createState() => VisitDealersScreenState(); State<VisitDealersScreen> createState() => VisitDealersScreenState();
} }
class VisitDealersScreenState extends State<VisitDealersScreen> { class VisitDealersScreenState extends State<VisitDealersScreen> {
late VisitPdRdProvider _visitPdRdProvider;
final dateController = TextEditingController( final dateController = TextEditingController(
text: DateFormat('dd/MM/yyyy').format(DateTime.now())); text: DateFormat('dd/MM/yyyy').format(DateTime.now()));
@ -31,10 +26,13 @@ class VisitDealersScreenState extends State<VisitDealersScreen> {
final meetingSummaryController = TextEditingController(); final meetingSummaryController = TextEditingController();
final followUpActionsController = TextEditingController(); final followUpActionsController = TextEditingController();
final nextVisitDateController = TextEditingController(); final nextVisitDateController = TextEditingController();
late TextEditingController retailerController = TextEditingController();
String selectedPurpose = 'Sales'; String selectedPurpose = 'Sales/Liquidation';
List<String> purposeOptions = ['Sales', 'Dues collection', 'Others']; List<String> purposeOptions = [
'Sales/Liquidation',
'Dues collection',
'Others'
];
Future<void> _pickImage() async { Future<void> _pickImage() async {
final ImagePicker picker = ImagePicker(); final ImagePicker picker = ImagePicker();
@ -42,19 +40,9 @@ class VisitDealersScreenState extends State<VisitDealersScreen> {
// Handle the picked image // Handle the picked image
} }
@override
void initState() {
_visitPdRdProvider = VisitPdRdProvider();
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
retailerController = TextEditingController(text: widget.tradeName); return CommonBackground(
return ChangeNotifierProvider(
create: (context) => _visitPdRdProvider,
child: CommonBackground(
child: Scaffold( child: Scaffold(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
appBar: CommonAppBar( appBar: CommonAppBar(
@ -67,27 +55,19 @@ class VisitDealersScreenState extends State<VisitDealersScreen> {
padding: const EdgeInsets.only(right: 20), padding: const EdgeInsets.only(right: 20),
), ),
], ],
title: Column( title: const Text('Visit Retailers',
children: [
const Text('Visit Retailers',
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
fontFamily: 'Anek')), fontFamily: 'Anek')),
Text(widget.tradeName ?? '',
style: const TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Anek')),
],
),
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
elevation: 0, elevation: 0,
), ),
drawer: const CommonDrawer(), drawer: const CommonDrawer(),
body: SingleChildScrollView( body: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -97,7 +77,7 @@ class VisitDealersScreenState extends State<VisitDealersScreen> {
Container( Container(
padding: 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: 16.0), // margin: const EdgeInsets.symmetric(horizontal: 30.0),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.white), border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.9), color: const Color(0xffB4D1E5).withOpacity(0.9),
@ -106,10 +86,9 @@ class VisitDealersScreenState extends State<VisitDealersScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
CommonTextFormField( CommonTextFormField(
readOnly: true,
title: 'Select Retailer', title: 'Select Retailer',
fillColor: Colors.white, fillColor: Colors.white,
controller: retailerController), controller: dealerController),
const SizedBox(height: 15), const SizedBox(height: 15),
CommonTextFormField( CommonTextFormField(
title: 'Visit date', title: 'Visit date',
@ -176,8 +155,7 @@ class VisitDealersScreenState extends State<VisitDealersScreen> {
], ],
), ),
const SizedBox(height: 15), const SizedBox(height: 15),
Consumer<VisitPdRdProvider>( Align(
builder: (context, value, child) => Align(
alignment: Alignment.center, alignment: Alignment.center,
child: CommonElevatedButton( child: CommonElevatedButton(
borderRadius: 30, borderRadius: 30,
@ -185,10 +163,7 @@ class VisitDealersScreenState extends State<VisitDealersScreen> {
height: kToolbarHeight - 10, height: kToolbarHeight - 10,
text: 'SUBMIT', text: 'SUBMIT',
backgroundColor: const Color(0xff004791), backgroundColor: const Color(0xff004791),
onPressed: () { onPressed: () {},
value.submitVisitPdRd(context, widget.id ?? '');
},
),
), ),
), ),
], ],

View File

@ -1,4 +1,3 @@
import 'package:cheminova/models/pd_rd_response_model.dart';
import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/provider/product_provider.dart'; import 'package:cheminova/provider/product_provider.dart';
import 'package:cheminova/screens/data_submit_successfull.dart'; import 'package:cheminova/screens/data_submit_successfull.dart';
@ -10,36 +9,20 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class AddProductsScreen extends StatefulWidget { class AddProductsScreen extends StatefulWidget {
final PdRdResponseModel distributor; const AddProductsScreen({super.key});
final String distributorType;
const AddProductsScreen({
super.key,
required this.distributor,
required this.distributorType,
});
@override @override
State<AddProductsScreen> createState() => _AddProductsScreenState(); State<AddProductsScreen> createState() => _AddProductsScreenState();
} }
class _AddProductsScreenState extends State<AddProductsScreen> { class _AddProductsScreenState extends State<AddProductsScreen> {
List<Product> selectedProducts = [];
List<Product> filteredProducts = []; List<Product> filteredProducts = [];
final searchController = TextEditingController(); final searchController = TextEditingController();
late ProductProvider provider;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
loadProducts();
}
Future<void> loadProducts() async {
provider = Provider.of<ProductProvider>(context, listen: false);
await provider.getProducts();
setState(() {
provider.selectedProducts.clear();
filteredProducts = provider.productList;
});
} }
void filterProducts(String query) { void filterProducts(String query) {
@ -71,15 +54,12 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
padding: const EdgeInsets.only(right: 20), padding: const EdgeInsets.only(right: 20),
), ),
], ],
title: Text( title: const Text('Add Products',
widget.distributor.name!, style: TextStyle(
style: const TextStyle(
fontSize: 20, fontSize: 20,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
fontFamily: 'Anek', fontFamily: 'Anek')),
),
),
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
elevation: 0, elevation: 0,
), ),
@ -90,23 +70,26 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} }
filteredProducts = provider.productList;
return Stack( return Stack(
children: [ children: [
Column( Column(
children: [ children: [
if (provider.selectedProducts.isNotEmpty) if (selectedProducts.isNotEmpty)
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
itemCount: provider.selectedProducts.length, itemCount: selectedProducts.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return ProductBlock(index: index); return ProductBlock(
product: selectedProducts[index]);
}, },
), ),
), ),
], ],
), ),
Align( Align(
alignment: provider.selectedProducts.isEmpty alignment: selectedProducts.isEmpty
? Alignment.center ? Alignment.center
: Alignment.bottomCenter, : Alignment.bottomCenter,
child: Padding( child: Padding(
@ -117,21 +100,14 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
FloatingActionButton.extended( FloatingActionButton.extended(
onPressed: () { onPressed: () {
showModalBottomSheet( showModalBottomSheet(
isScrollControlled: true,
constraints: BoxConstraints(
maxHeight:
MediaQuery.of(context).size.height * 0.9,
),
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return Consumer<ProductProvider>( return StatefulBuilder(
builder: (context, value, child) =>
StatefulBuilder(
builder: (context, setState) { builder: (context, setState) {
return Column( return Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(18.0), padding: const EdgeInsets.all(8.0),
child: TextField( child: TextField(
controller: searchController, controller: searchController,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -148,14 +124,11 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
), ),
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
itemCount: itemCount: filteredProducts.length,
filteredProducts.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
bool isAlreadySelected = bool isAlreadySelected =
provider.selectedProducts selectedProducts.contains(
.contains( filteredProducts[index]);
filteredProducts[
index]);
return Card( return Card(
child: ListTile( child: ListTile(
title: Text( title: Text(
@ -168,8 +141,7 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
), ),
), ),
subtitle: Text( subtitle: Text(
filteredProducts[index] filteredProducts[index].SKU,
.SKU,
style: TextStyle( style: TextStyle(
color: isAlreadySelected color: isAlreadySelected
? Colors.grey ? Colors.grey
@ -180,9 +152,8 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
? null ? null
: () { : () {
setState(() { setState(() {
provider selectedProducts.add(
.selectedProducts filteredProducts[
.add(filteredProducts[
index]); index]);
}); });
Navigator.pop( Navigator.pop(
@ -196,7 +167,6 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
], ],
); );
}, },
),
); );
}, },
).whenComplete(() { ).whenComplete(() {
@ -210,7 +180,7 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
style: TextStyle(color: Colors.black), style: TextStyle(color: Colors.black),
), ),
), ),
if (provider.selectedProducts.isNotEmpty) ...[ if (selectedProducts.isNotEmpty) ...[
const SizedBox(height: 16.0), const SizedBox(height: 16.0),
CommonElevatedButton( CommonElevatedButton(
borderRadius: 30, borderRadius: 30,
@ -219,12 +189,6 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
text: 'SUBMIT', text: 'SUBMIT',
backgroundColor: const Color(0xff004791), backgroundColor: const Color(0xff004791),
onPressed: () { onPressed: () {
provider
.submitSelectedProducts(
"PrincipalDistributor",
widget.distributor.id!)
.then((value) {
if (value) {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@ -232,8 +196,6 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
const DataSubmitSuccessfull(), const DataSubmitSuccessfull(),
), ),
); );
}
});
}, },
), ),
], ],
@ -251,9 +213,9 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
} }
class ProductBlock extends StatefulWidget { class ProductBlock extends StatefulWidget {
final int index; final Product product;
const ProductBlock({super.key, required this.index}); const ProductBlock({super.key, required this.product});
@override @override
_ProductBlockState createState() => _ProductBlockState(); _ProductBlockState createState() => _ProductBlockState();
@ -263,38 +225,27 @@ class _ProductBlockState extends State<ProductBlock> {
final saleController = TextEditingController(); final saleController = TextEditingController();
final inventoryController = TextEditingController(); final inventoryController = TextEditingController();
String? errorMessage; String? errorMessage;
late ProductProvider provider;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
provider = Provider.of<ProductProvider>(context, listen: false);
} }
bool validateInput() { void validateInput() {
setState(() { setState(() {
if (saleController.text.isNotEmpty && if (saleController.text.isNotEmpty &&
inventoryController.text.isNotEmpty) { inventoryController.text.isNotEmpty) {
// Check if both inputs are valid integers
try {
int sale = int.parse(saleController.text); int sale = int.parse(saleController.text);
int inventory = int.parse(inventoryController.text); int inventory = int.parse(inventoryController.text);
// Validation: inventory should be less than or equal to sales
if (inventory > sale) { if (inventory > sale) {
errorMessage = 'Inventory should be less than or equal to sales'; errorMessage = 'Inventory should be less than or equal to sales';
} else { } else {
errorMessage = null; errorMessage = null;
} }
} catch (e) {
// Handle the case where input is not a valid integer
errorMessage = 'Please enter valid integer values for both fields';
}
} else { } else {
errorMessage = null; errorMessage = null;
} }
}); });
return errorMessage == null;
} }
@override @override
@ -308,9 +259,9 @@ class _ProductBlockState extends State<ProductBlock> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('Product: ${provider.selectedProducts[widget.index].name}', Text('Product: ${widget.product.name}',
style: const TextStyle(fontSize: 16)), style: const TextStyle(fontSize: 16)),
Text('SKU: ${provider.selectedProducts[widget.index].SKU}', Text('SKU: ${widget.product.SKU}',
style: const TextStyle(fontSize: 15)), style: const TextStyle(fontSize: 15)),
const SizedBox(height: 8), const SizedBox(height: 8),
TextField( TextField(
@ -319,10 +270,7 @@ class _ProductBlockState extends State<ProductBlock> {
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
// enabled: widget.product.isPurchased, // enabled: widget.product.isPurchased,
enabled: true, enabled: true,
onChanged: (_) => validateInput() onChanged: (_) => validateInput(),
? provider.selectedProducts[widget.index].sale =
int.parse(saleController.text)
: null,
), ),
TextField( TextField(
controller: inventoryController, controller: inventoryController,
@ -330,10 +278,7 @@ class _ProductBlockState extends State<ProductBlock> {
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
// enabled: widget.product.isPurchased, // enabled: widget.product.isPurchased,
enabled: true, enabled: true,
onChanged: (_) => validateInput() onChanged: (_) => validateInput(),
? provider.selectedProducts[widget.index].inventory =
int.parse(inventoryController.text)
: null,
), ),
if (errorMessage != null) if (errorMessage != null)
Padding( Padding(

View File

@ -1,5 +1,4 @@
import 'package:cheminova/screens/assign_tasks_screen.dart'; import 'package:cheminova/screens/select_sales_coordinator_screen.dart';
import 'package:cheminova/screens/task_management_screen.dart';
import 'package:cheminova/widgets/common_app_bar.dart'; import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_drawer.dart';
@ -56,40 +55,39 @@ class _AssignTaskDashBoardScreenState extends State<AssignTaskDashBoardScreen> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// const Text( const Text(
// 'Assign Tasks', 'Assign Tasks',
// style: TextStyle( style: TextStyle(
// fontSize: 24, fontSize: 24,
// color: Colors.white, color: Colors.white,
// fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
// fontFamily: 'Anek', fontFamily: 'Anek',
// ), ),
// ), ),
// const SizedBox(height: 10), const SizedBox(height: 10),
// Row( Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [ children: [
// SizedBox( SizedBox(
// height: 200, height: 200,
// width: MediaQuery.of(context).size.width / 4.2, width: MediaQuery.of(context).size.width / 4.2,
// child: child:
// _customCard(title: "Total Tasks", subtitle: "100"), _customCard(title: "Total Tasks", subtitle: "100"),
// ), ),
// SizedBox( SizedBox(
// height: 200, height: 200,
// width: MediaQuery.of(context).size.width / 4.2, width: MediaQuery.of(context).size.width / 4.2,
// child: _customCard( child: _customCard(
// title: "Tasks Pending", subtitle: "100"), title: "Tasks Pending", subtitle: "100"),
// ), ),
// SizedBox( SizedBox(
// height: 200, height: 200,
// width: MediaQuery.of(context).size.width / 4.2, width: MediaQuery.of(context).size.width / 4.2,
// child: _customCard( child: _customCard(
// title: "Reports Submitted", subtitle: "100"), title: "Reports Submitted", subtitle: "100"),
// ), ),
// ], ],
// ), ),
const SizedBox(height: 20),
CommonElevatedButton( CommonElevatedButton(
backgroundColor: const Color(0xff004791), backgroundColor: const Color(0xff004791),
borderRadius: 30, borderRadius: 30,
@ -100,7 +98,8 @@ class _AssignTaskDashBoardScreenState extends State<AssignTaskDashBoardScreen> {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => const AssignTasksScreen(), builder: (context) =>
const SelectSalesCoordinatorScreen(),
), ),
); );
}, },
@ -112,12 +111,7 @@ class _AssignTaskDashBoardScreenState extends State<AssignTaskDashBoardScreen> {
width: double.infinity, width: double.infinity,
height: kToolbarHeight - 10, height: kToolbarHeight - 10,
text: 'VIEW TASK STATUS', text: 'VIEW TASK STATUS',
onPressed: () => Navigator.push( onPressed: () {},
context,
MaterialPageRoute(
builder: (context) => const TaskManagementScreen(),
),
),
), ),
const SizedBox(height: 15), const SizedBox(height: 15),
CommonElevatedButton( CommonElevatedButton(

View File

@ -1,14 +1,9 @@
import 'package:cheminova/models/pd_rd_response_model.dart';
import 'package:cheminova/provider/task_provider.dart';
import 'package:cheminova/screens/confirm_task_screen.dart';
import 'package:provider/provider.dart';
import 'package:cheminova/widgets/common_app_bar.dart'; import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_drawer.dart';
import 'package:cheminova/widgets/common_elevated_button.dart'; import 'package:cheminova/widgets/common_elevated_button.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:searchfield/searchfield.dart';
class AssignTasksScreen extends StatefulWidget { class AssignTasksScreen extends StatefulWidget {
const AssignTasksScreen({super.key}); const AssignTasksScreen({super.key});
@ -18,65 +13,11 @@ class AssignTasksScreen extends StatefulWidget {
} }
class _AssignTasksScreenState extends State<AssignTasksScreen> { class _AssignTasksScreenState extends State<AssignTasksScreen> {
bool _isSalesCoordinatorValid = true; final List<bool> _isChecked = List.generate(8, (_) => false);
bool _isTaskValid = true;
bool _isPriorityValid = true;
bool _isNotesValid = true;
bool _isDistributorValid = true;
String? selectedDistributorType;
void _validateAndSubmit() { String _dateSelected = DateFormat('dd/MM/yyyy').format(DateTime.now());
final taskProvider = context.read<TaskProvider>();
setState(() {
// Validate Sales Coordinator
_isSalesCoordinatorValid = taskProvider.selectedSalesCoordinator != null;
// Validate Task
_isTaskValid = taskProvider.selectedTask != null &&
taskProvider.selectedTask!.isNotEmpty;
// Validate Priority
_isPriorityValid = taskProvider.selectedPriority != null &&
taskProvider.selectedPriority!.isNotEmpty;
// Validate Notes
if ((taskProvider.selectedTask == 'Collect KYC' ||
taskProvider.selectedTask == 'Visit RD/PD') &&
taskProvider.noteController.text.isEmpty) {
_isNotesValid = false;
} else {
_isNotesValid = true;
}
// Validate Distributor
if ((taskProvider.selectedTask != 'Collect KYC') &&
(taskProvider.selectedDistributor == null ||
selectedDistributorType == null)) {
_isDistributorValid = false;
} else {
_isDistributorValid = true;
}
});
// If all fields are valid, proceed to the next screen
if (_isSalesCoordinatorValid &&
_isTaskValid &&
_isPriorityValid &&
_isNotesValid &&
_isDistributorValid) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ConfirmTaskScreen(
selectedDistributorType: selectedDistributorType,
),
),
);
}
}
Future<void> _selectDate(BuildContext context) async { Future<void> _selectDate(BuildContext context) async {
final provider = context.read<TaskProvider>();
final dateSelected = await showDatePicker( final dateSelected = await showDatePicker(
context: context, context: context,
initialDate: DateTime.now(), initialDate: DateTime.now(),
@ -84,28 +25,14 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
lastDate: DateTime(2025), lastDate: DateTime(2025),
); );
if (dateSelected != null) { if (dateSelected != null) {
provider.setDate(DateFormat('dd/MM/yyyy').format(dateSelected)); setState(() {
} _dateSelected = DateFormat('dd/MM/yyyy').format(dateSelected);
}
void _updateTaskProvider() {
final provider = context.read<TaskProvider>();
provider.clear();
provider.getSalesCoordinators();
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateTaskProvider();
}); });
} }
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final taskProvider = context.watch<TaskProvider>();
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
appBar: CommonAppBar( appBar: CommonAppBar(
@ -129,15 +56,13 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
), ),
drawer: const CommonDrawer(), drawer: const CommonDrawer(),
body: CommonBackground( body: CommonBackground(
child: Stack( child: SafeArea(
children: [
SafeArea(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Padding( child: Padding(
padding: const EdgeInsets.only(top: 20), padding: const EdgeInsets.only(top: 20),
child: Container( child: Container(
padding: const EdgeInsets.all(20.0) padding:
.copyWith(top: 15, bottom: 30), const EdgeInsets.all(20.0).copyWith(top: 15, bottom: 30),
margin: const EdgeInsets.symmetric(horizontal: 30.0) margin: const EdgeInsets.symmetric(horizontal: 30.0)
.copyWith(bottom: 50), .copyWith(bottom: 50),
decoration: BoxDecoration( decoration: BoxDecoration(
@ -159,69 +84,37 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
), ),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
SearchField( Container(
suggestionsDecoration: SuggestionDecoration( width: double.infinity,
borderRadius: const BorderRadius.only( padding: const EdgeInsets.all(12.0),
bottomLeft: Radius.circular(8.0), margin: const EdgeInsets.only(bottom: 20),
bottomRight: Radius.circular(8), decoration: BoxDecoration(
border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.6),
borderRadius: BorderRadius.circular(16.0),
), ),
border: Border.all( child: const Column(
color: Colors.grey.withOpacity(0.5), crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Sales Coordinator: Name",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
fontFamily: 'Anek',
), ),
), ),
suggestionItemDecoration: BoxDecoration( Text(
borderRadius: BorderRadius.circular(8), "ID: 121",
shape: BoxShape.rectangle, style: TextStyle(
border: Border.all( fontSize: 16,
color: Colors.transparent, fontWeight: FontWeight.bold,
style: BorderStyle.solid, fontFamily: 'Anek',
width: 1.0),
),
searchInputDecoration: InputDecoration(
filled: true,
fillColor: Colors.grey.withOpacity(0.2),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.white,
width: 2.0,
),
borderRadius: BorderRadius.circular(8.0),
),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(16.0),
),
borderSide: BorderSide(
color: Colors.white,
width: 2.0,
), ),
), ),
errorText: !_isSalesCoordinatorValid ],
? 'Please select a Sales Coordinator'
: null,
), ),
hint: 'Select Sales Coordinator',
onSuggestionTap: (selectedItem) {
if (selectedItem.item != null) {
taskProvider.setSelectedSalesCoordinator(
selectedItem.item!);
FocusScope.of(context).unfocus();
}
},
onTapOutside: (event) =>
FocusScope.of(context).unfocus(),
marginColor: Colors.grey.shade300,
suggestions: taskProvider.salesCoordinators
.map(
(e) => SearchFieldListItem(
e.name!,
item: e,
child: Text(e.name!),
), ),
)
.toList(),
),
const SizedBox(height: 20),
Container( Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
@ -244,187 +137,60 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
), ),
SizedBox( SizedBox(
height: 35, height: 35,
child: RadioListTile<String>( child: CheckboxListTile(
contentPadding: EdgeInsets.zero, value: _isChecked[0],
value: 'Visit RD/PD',
groupValue: taskProvider.selectedTask,
onChanged: (value) { onChanged: (value) {
taskProvider.setSelectedTask(value); setState(() {
_isChecked[0] = value!;
});
}, },
title: const Text( title: const Text(
"Visit RD/PD", "Visit Retailers",
), ),
), ),
), ),
SizedBox( SizedBox(
height: 45, height: 45,
child: RadioListTile<String>( child: CheckboxListTile(
contentPadding: EdgeInsets.zero, value: _isChecked[1],
value: 'Update Sales Data',
groupValue: taskProvider.selectedTask,
onChanged: (value) { onChanged: (value) {
taskProvider.setSelectedTask(value); setState(() {
_isChecked[1] = value!;
});
}, },
title: const Text( title: const Text(
"Update Sales Data Data", "Update Sales Data",
), ),
), ),
), ),
SizedBox( SizedBox(
height: 45, height: 45,
child: RadioListTile<String>( child: CheckboxListTile(
contentPadding: EdgeInsets.zero, value: _isChecked[2],
value: 'Update Inventory Data',
groupValue: taskProvider.selectedTask,
onChanged: (value) { onChanged: (value) {
taskProvider.setSelectedTask(value); setState(() {
_isChecked[2] = value!;
});
}, },
title: const Text( title: const Text(
"Update Inventory Data", "Update Liqudation Data",
), ),
), ),
), ),
RadioListTile<String>( CheckboxListTile(
contentPadding: EdgeInsets.zero, value: _isChecked[3],
value: 'Collect KYC',
groupValue: taskProvider.selectedTask,
onChanged: (value) { onChanged: (value) {
taskProvider.setSelectedTask(value); setState(() {
_isChecked[3] = value!;
});
}, },
title: const Text( title: const Text(
"Collect KYC", "Collect KYC",
), ),
), ),
if (!_isTaskValid &&
(taskProvider.selectedTask?.isEmpty ?? true))
const Padding(
padding:
EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Please select a task',
style: TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
),
], ],
), ),
), ),
if (taskProvider.selectedTask == 'Collect KYC' ||
taskProvider.selectedTask == 'Visit RD/PD') ...{
Container(
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.0),
),
child: TextFormField(
controller: taskProvider.noteController,
expands: true,
maxLines: null,
minLines: null,
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(
vertical: 14.0,
horizontal: 16.0,
),
border: InputBorder.none,
labelText: 'Note',
hintText: 'Enter your note',
errorText: !_isNotesValid
? 'Please enter a note'
: null,
),
),
),
const SizedBox(
height: 20,
)
},
if (taskProvider.selectedTask ==
'Update Inventory Data' ||
taskProvider.selectedTask == 'Visit RD/PD' ||
taskProvider.selectedTask == 'Update Sales Data') ...{
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15.0,
vertical: 5,
),
child: DropdownButtonFormField<String>(
decoration: const InputDecoration(
labelText: 'Select Distributor Type',
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(),
),
value: selectedDistributorType,
items: [
'PrincipalDistributor',
'RetailDistributor'
].map((String type) {
return DropdownMenuItem<String>(
value: type,
child: Text(type),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedDistributorType = value;
selectedDistributorType ==
'PrincipalDistributor'
? taskProvider.getPd()
: taskProvider.getRd();
taskProvider.setSelectedDistributor(null);
});
},
),
),
// Dropdown for selecting distributor name based on type
if (selectedDistributorType != null)
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15.0, vertical: 25),
child: DropdownButtonFormField<PdRdResponseModel>(
decoration: const InputDecoration(
labelText: 'Select Distributor Name',
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(),
),
value: taskProvider.selectedDistributor,
items: (selectedDistributorType ==
'PrincipalDistributor'
? taskProvider.pdList
: taskProvider.rdList)
.map((PdRdResponseModel distributor) {
return DropdownMenuItem<PdRdResponseModel>(
value: distributor,
child: Text(distributor.name!),
);
}).toList(),
onChanged: (value) {
taskProvider.setSelectedDistributor(value);
},
isExpanded: true,
isDense: true,
iconSize: 24,
hint: Text(
'Please select a ${selectedDistributorType ?? "Distributor Type"} first'),
),
),
if (!_isDistributorValid)
const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Please select a distributor',
style: TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
),
},
Container( Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
@ -447,43 +213,41 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
), ),
Row( Row(
children: [ children: [
Radio<String>( Checkbox(
value: "Low", value: _isChecked[4],
groupValue: taskProvider.selectedPriority,
onChanged: (value) { onChanged: (value) {
taskProvider.setSelectedPriority(value!); setState(() {
_isChecked[4] = value!;
});
}, },
), ),
const Text("Low"), const Text(
Radio<String>( "Low",
value: "Medium", ),
groupValue: taskProvider.selectedPriority, Checkbox(
value: _isChecked[5],
onChanged: (value) { onChanged: (value) {
taskProvider.setSelectedPriority(value!); setState(() {
_isChecked[5] = value!;
});
}, },
), ),
const Text("Medium"), const Text(
Radio<String>( "Medium",
value: "High", ),
groupValue: taskProvider.selectedPriority, Checkbox(
value: _isChecked[6],
onChanged: (value) { onChanged: (value) {
taskProvider.setSelectedPriority(value!); setState(() {
_isChecked[6] = value!;
});
}, },
), ),
const Text("High"), const Text(
"High",
),
], ],
), ),
if (!_isPriorityValid &&
(taskProvider.selectedPriority?.isEmpty ??
true))
const Padding(
padding:
EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Please select a priority',
style: TextStyle(color: Colors.red),
),
),
], ],
), ),
), ),
@ -510,7 +274,7 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
Row( Row(
children: [ children: [
Text( Text(
taskProvider.selectedDate, _dateSelected,
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
@ -529,7 +293,7 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
width: double.infinity, width: double.infinity,
height: kToolbarHeight - 10, height: kToolbarHeight - 10,
text: 'CONFIRM', text: 'CONFIRM',
onPressed: _validateAndSubmit, onPressed: () {},
), ),
], ],
), ),
@ -537,15 +301,6 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
), ),
), ),
), ),
if (taskProvider.isLoading)
Container(
color: Colors.black.withOpacity(0.1),
child: const Center(
child: CircularProgressIndicator(),
),
),
],
),
), ),
); );
} }

View File

@ -1,239 +0,0 @@
import 'package:cheminova/provider/task_provider.dart';
import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart';
import 'package:cheminova/widgets/common_elevated_button.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ConfirmTaskScreen extends StatefulWidget {
final String? selectedDistributorType;
const ConfirmTaskScreen({
super.key,
this.selectedDistributorType,
});
@override
State<ConfirmTaskScreen> createState() => _ConfirmTaskScreenState();
}
class _ConfirmTaskScreenState extends State<ConfirmTaskScreen> {
@override
Widget build(BuildContext context) {
final taskProvider = context.watch<TaskProvider>();
return Scaffold(
extendBodyBehindAppBar: true,
appBar: CommonAppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Image.asset('assets/Back_attendance.png'),
padding: const EdgeInsets.only(right: 20),
),
],
title: const Center(
child: Text(
'Confirm Task',
style: TextStyle(color: Colors.black87, fontSize: 20),
),
),
),
drawer: const CommonDrawer(),
body: CommonBackground(
child: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Container(
padding:
const EdgeInsets.all(20.0).copyWith(top: 15, bottom: 30),
margin: const EdgeInsets.symmetric(horizontal: 30.0)
.copyWith(bottom: 50),
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.5),
borderRadius: BorderRadius.circular(26.0),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Confirm Task',
style: TextStyle(
fontSize: 24,
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'Anek',
),
),
const SizedBox(height: 20),
_customContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Sales Coordinator:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
fontFamily: 'Anek',
),
),
Text(
taskProvider.selectedSalesCoordinator!.name!,
style: const TextStyle(
fontSize: 16,
fontFamily: 'Anek',
),
),
Text(
'ID: ${taskProvider.selectedSalesCoordinator!.uniqueId!}',
style: const TextStyle(
fontSize: 16,
fontFamily: 'Anek',
),
),
],
),
),
const SizedBox(height: 20),
const Text(
'Tasks:',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
fontFamily: 'Anek',
),
),
const SizedBox(height: 10),
_customContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Task: ${taskProvider.selectedTask!}',
style: const TextStyle(
fontFamily: 'Anek',
),
),
const SizedBox(height: 10),
Text(
'Priority: ${taskProvider.selectedPriority!}',
style: const TextStyle(
fontFamily: 'Anek',
),
),
const SizedBox(height: 10),
Text(
'Deadline: ${taskProvider.selectedDate}',
style: const TextStyle(
fontFamily: 'Anek',
),
),
],
),
),
const SizedBox(height: 20),
if (taskProvider.selectedTask == 'Collect KYC' ||
taskProvider.selectedTask == 'Visit RD/PD')
_customContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Note:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
fontFamily: 'Anek',
),
),
Text(
taskProvider.noteController.text,
style: const TextStyle(
fontSize: 16,
fontFamily: 'Anek',
),
),
],
),
),
const SizedBox(height: 20),
if (taskProvider.selectedTask != 'Collect KYC') ...{
_customContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.selectedDistributorType!,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
fontFamily: 'Anek',
),
),
Text(
taskProvider.selectedDistributor!.name!,
style: const TextStyle(
fontSize: 16,
fontFamily: 'Anek',
),
),
],
)),
},
const SizedBox(height: 20),
CommonElevatedButton(
isLoading: taskProvider.isLoading,
backgroundColor: const Color(0xff004791),
borderRadius: 30,
width: double.infinity,
height: kToolbarHeight - 10,
text: 'CONFIRM',
onPressed: () => taskProvider.assignTask(
context: context,
selectedDistributorType:
widget.selectedDistributorType != null
? widget.selectedDistributorType!
: '',
),
),
const SizedBox(height: 20),
CommonElevatedButton(
backgroundColor: const Color(0xff00784C),
borderRadius: 30,
width: double.infinity,
height: kToolbarHeight - 10,
text: 'EDIT',
onPressed: () => Navigator.pop(context),
),
],
),
),
),
),
),
),
);
}
Widget _customContainer({required Widget child}) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(12.0),
// margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.6),
borderRadius: BorderRadius.circular(16.0),
),
child: child,
);
}
}

View File

@ -14,13 +14,10 @@ class DataSubmitSuccessfullState extends State<DataSubmitSuccessfull> {
void initState() { void initState() {
super.initState(); super.initState();
Future.delayed(const Duration(seconds: 2), () { Future.delayed(const Duration(seconds: 2), () {
Navigator.of(context).pushAndRemoveUntil( Navigator.pushReplacement(
MaterialPageRoute(builder: (context) => const HomePage()), context, MaterialPageRoute(builder: (context) => const HomePage()));
(Route<dynamic> route) => false, // Remove all routes
);
}); });
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -35,11 +32,7 @@ class DataSubmitSuccessfullState extends State<DataSubmitSuccessfull> {
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
fontFamily: 'Anek')), fontFamily: 'Anek')),
const SizedBox( const SizedBox(height: 20), // Add some space between the text and the image
height: 20), // Add some space between the text and the image Image.asset('assets/check_circle.png', )]))));
Image.asset(
'assets/check_circle.png',
)
]))));
} }
} }

View File

@ -1,6 +1,5 @@
import 'package:cheminova/notification_service.dart'; import 'package:cheminova/notification_service.dart';
import 'package:cheminova/provider/user_provider.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/assign_task_dash_board_screen.dart';
import 'package:cheminova/screens/calendar_screen.dart'; import 'package:cheminova/screens/calendar_screen.dart';
import 'package:cheminova/screens/collect_kyc_screen.dart'; import 'package:cheminova/screens/collect_kyc_screen.dart';
@ -8,12 +7,14 @@ import 'package:cheminova/screens/mark_attendence_screen.dart';
import 'package:cheminova/screens/notification_screen.dart'; import 'package:cheminova/screens/notification_screen.dart';
import 'package:cheminova/screens/products_manual_screen.dart'; import 'package:cheminova/screens/products_manual_screen.dart';
import 'package:cheminova/screens/rejected_application_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/product_sales_data.dart';
import 'package:cheminova/screens/update_inventory_screen.dart'; import 'package:cheminova/screens/update_inventory_screen.dart';
import 'package:cheminova/screens/display_sales_screen.dart'; import 'package:cheminova/screens/display_sales_screen.dart';
import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_drawer.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/screens/daily_tasks_screen.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
@ -105,7 +106,17 @@ class _HomePageState extends State<HomePage> {
const SizedBox( const SizedBox(
height: 5, height: 5,
), ),
_buildCustomCard('Assign Tasks', 'Dashboard', onTap: () { _buildCustomCard('Daily Tasks', 'Dashboard', onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DailyTasksScreen(),
));
}),
const SizedBox(
height: 5,
),
_buildCustomCard('Assign Tasks', '', onTap: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@ -119,8 +130,9 @@ class _HomePageState extends State<HomePage> {
Row( Row(
children: [ children: [
Expanded( Expanded(
child: _buildCustomCard('Display\nSales data', child: _buildCustomCard(
'Quickly display Sales\n', onTap: () { 'Display\nSales data', 'Quickly display Sales',
onTap: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@ -151,19 +163,14 @@ class _HomePageState extends State<HomePage> {
Row( Row(
children: [ children: [
Expanded( Expanded(
child: _buildCustomCard( child:
'Visit RD/PD', _buildCustomCard('Summary', '\n\n', onTap: () {
'\n\n',
onTap: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) => const SummaryScreen(),
const VisitDealersScreen(), ));
), }),
);
},
),
), ),
const SizedBox( const SizedBox(
width: 12, width: 12,

View File

@ -29,19 +29,19 @@ class ProductSalesDataState extends State<ProductSalesData> {
final salesController = TextEditingController(); final salesController = TextEditingController();
final commentController = TextEditingController(); final commentController = TextEditingController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CommonBackground( return CommonBackground(
child: Scaffold( child: Scaffold(backgroundColor: Colors.transparent,
backgroundColor: Colors.transparent,
appBar: CommonAppBar( appBar: CommonAppBar(
actions: [ actions: [
IconButton( IconButton(
onPressed: () { onPressed: ()
{
Navigator.pop(context); Navigator.pop(context);
}, },
icon: Image.asset('assets/Back_attendance.png'), icon: Image.asset('assets/Back_attendance.png'), padding: const EdgeInsets.only(right: 20),
padding: const EdgeInsets.only(right: 20),
), ),
], ],
title: const Text('Product Sales Data', title: const Text('Product Sales Data',
@ -49,9 +49,7 @@ class ProductSalesDataState extends State<ProductSalesData> {
fontSize: 20, fontSize: 20,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
fontFamily: 'Anek')), fontFamily: 'Anek')), backgroundColor: Colors.transparent, elevation: 0,
backgroundColor: Colors.transparent,
elevation: 0,
), ),
drawer: const CommonDrawer(), drawer: const CommonDrawer(),
body: Padding( body: Padding(
@ -79,17 +77,20 @@ class ProductSalesDataState extends State<ProductSalesData> {
fillColor: Colors.white, fillColor: Colors.white,
controller: dealercontroller), controller: dealercontroller),
const SizedBox(height: 15), const SizedBox(height: 15),
CommonTextFormField( CommonTextFormField(
title: 'Select Product: Product A', title: 'Select Product: Product A',
fillColor: Colors.white, fillColor: Colors.white,
controller: productController), controller: productController),
const SizedBox(height: 15), const SizedBox(height: 15),
CommonTextFormField( CommonTextFormField(
title: 'Date Range: 10-06 to 20-06', title: 'Date Range: 10-06 to 20-06',
readOnly: true, readOnly: true,
fillColor: Colors.white, fillColor: Colors.white,
controller: dateController), controller: dateController),
const SizedBox(height: 15), const SizedBox(height: 15),
Align( Align(
alignment: Alignment.center, alignment: Alignment.center,
child: CommonElevatedButton( child: CommonElevatedButton(
@ -99,22 +100,19 @@ class ProductSalesDataState extends State<ProductSalesData> {
text: 'VIEW DATA', text: 'VIEW DATA',
backgroundColor: const Color(0xff004791), backgroundColor: const Color(0xff004791),
onPressed: () { onPressed: () {
Navigator.push( Navigator.push(context, MaterialPageRoute(builder: (context) => const DataSubmitSuccessfull(),));
context,
MaterialPageRoute(
builder: (context) =>
const DataSubmitSuccessfull(),
));
}, },
)),
)
),
], ],
), ),
), ),
], ],
), ),
), ),
), ),),
),
); );
} }
} }

View File

@ -1,8 +1,4 @@
import 'package:cheminova/models/product_manual_model.dart';
import 'package:cheminova/provider/product_manual_provider.dart';
import 'package:cheminova/screens/view_pdf_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_drawer.dart';
import 'package:cheminova/widgets/common_app_bar.dart'; import 'package:cheminova/widgets/common_app_bar.dart';
@ -13,13 +9,6 @@ class ProductsManualScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Access the provider
final productManualProvider =
Provider.of<ProductManualProvider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) {
productManualProvider.getProductManualList();
});
return CommonBackground( return CommonBackground(
child: Scaffold( child: Scaffold(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
@ -33,14 +22,12 @@ class ProductsManualScreen extends StatelessWidget {
padding: const EdgeInsets.only(right: 20), padding: const EdgeInsets.only(right: 20),
), ),
], ],
title: const Text( title: const Text('Products Manual',
'Products Manual',
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
fontFamily: 'Anek'), fontFamily: 'Anek')),
),
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
elevation: 0, elevation: 0,
), ),
@ -54,23 +41,8 @@ class ProductsManualScreen extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
const SizedBox(height: 16), const SizedBox(height: 16),
Consumer<ProductManualProvider>( Container(
builder: (context, provider, child) { padding: const EdgeInsets.all(20.0).copyWith(top: 30, bottom: 30),
if (provider.isLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (provider.productManualList.isEmpty) {
return const Center(
child: Text('No products available.'),
);
}
return Container(
padding: const EdgeInsets.all(20.0)
.copyWith(top: 30, bottom: 30),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.white), border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.9), color: const Color(0xffB4D1E5).withOpacity(0.9),
@ -78,15 +50,16 @@ class ProductsManualScreen extends StatelessWidget {
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: provider.productManualList children: <Widget>[
.map( _buildProductButton('Product 1'),
(product) => _buildProductButton('Product 2'),
_buildProductButton(context, product), _buildProductButton('Product 3'),
) _buildProductButton('Product 4'),
.toList(), _buildProductButton('Product 5'),
_buildProductButton('Product 6'),
_buildProductButton('Product 7'),
],
), ),
);
},
), ),
], ],
), ),
@ -96,21 +69,19 @@ class ProductsManualScreen extends StatelessWidget {
); );
} }
Widget _buildProductButton(BuildContext context, ProductManualModel product) { Widget _buildProductButton(String productName) {
return Padding( return Padding(
padding: const EdgeInsets.only(bottom: 15), padding: const EdgeInsets.only(bottom: 15),
child: CommonElevatedButton( child: CommonElevatedButton(
borderRadius: 30, borderRadius: 30,
width: double.infinity, width: double.infinity,
height: kToolbarHeight - 10, height: kToolbarHeight - 10,
text: product.title, text: productName,
backgroundColor: const Color(0xff004791), backgroundColor: const Color(0xff004791),
onPressed: () => Navigator.push( onPressed: () {
context, // Handle product button press
MaterialPageRoute( debugPrint('$productName pressed');
builder: (context) => ViewPdfScreen(productManualModel: product), },
),
),
), ),
); );
} }

View File

@ -1,103 +0,0 @@
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<UserProvider>(
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),
],
),
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:cheminova/screens/assign_tasks_screen.dart';
import 'package:cheminova/widgets/common_app_bar.dart'; import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_drawer.dart';
@ -78,18 +79,10 @@ class _SelectSalesCoordinatorScreenState
child: ListView.builder( child: ListView.builder(
itemCount: salesCoordinators.length, itemCount: salesCoordinators.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return GestureDetector( return _customCard(
onTap: () {
// taskProvider.setSelectedSalesCoordinator(
// salesCoordinators[index],
// );
// Navigator.pop(context);
},
child: _customCard(
name: salesCoordinators[index].name, name: salesCoordinators[index].name,
id: salesCoordinators[index].id, id: salesCoordinators[index].id,
tasks: salesCoordinators[index].tasks, tasks: salesCoordinators[index].tasks,
),
); );
}, },
), ),
@ -105,7 +98,18 @@ class _SelectSalesCoordinatorScreenState
Widget _customCard( Widget _customCard(
{required String name, required String id, required int tasks}) { {required String name, required String id, required int tasks}) {
return Container( return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const AssignTasksScreen();
},
),
);
},
child: Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
margin: const EdgeInsets.all(8), margin: const EdgeInsets.all(8),
@ -143,6 +147,7 @@ class _SelectSalesCoordinatorScreenState
), ),
], ],
), ),
),
); );
} }
} }

View File

@ -1,272 +0,0 @@
import 'package:cheminova/models/task_model.dart';
import 'package:cheminova/provider/task_provider.dart';
import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart';
import 'package:cheminova/widgets/common_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
class TaskManagementScreen extends StatefulWidget {
const TaskManagementScreen({super.key});
@override
State<TaskManagementScreen> createState() => _TaskManagementScreenState();
}
class _TaskManagementScreenState extends State<TaskManagementScreen> {
final TextEditingController _searchController = TextEditingController();
List<TaskModel> _filteredTaskList = [];
String? _selectedChip = 'New'; // State to track the selected chip
void _filterTaskList(String query) {
if (query.isEmpty || query == '' || query == ' ') {
setState(() {
_filteredTaskList = context.read<TaskProvider>().taskModelList;
});
return;
}
setState(() {
_filteredTaskList = _filteredTaskList
.where((task) => task.taskAssignedTo.name
.toLowerCase()
.contains(query.toLowerCase()))
.toList();
});
}
Future<void> _updateTaskProvider() async {
final provider = context.read<TaskProvider>();
provider.clear();
await provider.getNewTasks();
_filteredTaskList.clear();
_filteredTaskList = provider.taskModelList;
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateTaskProvider();
});
}
@override
Widget build(BuildContext context) {
final taskProvider = context.watch<TaskProvider>();
return Scaffold(
extendBodyBehindAppBar: true,
appBar: CommonAppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Image.asset('assets/Back_attendance.png'),
padding: const EdgeInsets.only(right: 20),
),
],
title: const Center(
child: Text(
'Task Management',
style: TextStyle(color: Colors.black87, fontSize: 20),
),
),
),
drawer: const CommonDrawer(),
body: CommonBackground(
child: Stack(
children: [
SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Container(
padding: const EdgeInsets.all(20.0)
.copyWith(top: 15, bottom: 30),
margin: const EdgeInsets.symmetric(horizontal: 30.0)
.copyWith(bottom: 50),
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.5),
borderRadius: BorderRadius.circular(26.0),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CommonTextFormField(
controller: _searchController,
onChanged: (value) => _filterTaskList(value),
title: 'Filter by Sales Coordinator:',
),
const SizedBox(height: 20),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_filterChip(
title: 'New',
icon: const Icon(Icons.new_releases),
onSelected: () async {
setState(() {
_selectedChip = 'New';
});
await taskProvider.getNewTasks();
_filteredTaskList.clear();
_filteredTaskList =
taskProvider.taskModelList;
},
isSelected: _selectedChip == 'New',
),
const SizedBox(width: 5),
_filterChip(
title: 'Pending',
icon: const Icon(Icons.pending),
onSelected: () async {
setState(() {
_selectedChip = 'Pending';
});
await taskProvider.getPendingTasks();
_filteredTaskList.clear();
_filteredTaskList =
taskProvider.taskModelList;
},
isSelected: _selectedChip == 'Pending',
),
const SizedBox(width: 5),
_filterChip(
title: 'Completed',
icon: const Icon(Icons.done),
onSelected: () async {
setState(() {
_selectedChip = 'Completed';
});
await taskProvider.getCompletedTasks();
_filteredTaskList.clear();
_filteredTaskList =
taskProvider.taskModelList;
},
isSelected: _selectedChip == 'Completed',
),
],
),
),
const SizedBox(height: 10),
SizedBox(
height: MediaQuery.of(context).size.height * 0.55,
child: _filteredTaskList.isEmpty
? const Center(child: Text('No tasks found'))
: ListView.builder(
itemCount: _filteredTaskList.length,
itemBuilder: (context, index) => _taskView(
task: _filteredTaskList[
_selectedChip == 'Completed'
? index
: ((_filteredTaskList.length - 1) -
index)],
),
),
),
],
),
),
),
),
),
if (taskProvider.isLoading)
Container(
color: Colors.black.withOpacity(0.1),
child: const Center(
child: CircularProgressIndicator(),
),
),
],
),
),
);
}
Widget _customContainer({required Widget child}) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.6),
borderRadius: BorderRadius.circular(16.0),
),
child: child,
);
}
Widget _taskView({required TaskModel task}) {
final formatedDate = DateFormat('dd/MM/yyyy').format(task.taskDueDate);
return Column(
children: [
_customContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Assigned to: ${task.taskAssignedTo.name}",
style: const TextStyle(
fontFamily: 'Anek',
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text(
"Task: ${task.task}",
style: const TextStyle(
fontFamily: 'Anek',
),
),
const SizedBox(height: 10),
Text(
'Status: ${task.taskStatus}',
style: const TextStyle(
fontFamily: 'Anek',
),
),
const SizedBox(height: 10),
Text(
'Deadline:$formatedDate',
style: const TextStyle(
fontFamily: 'Anek',
),
),
],
),
),
const SizedBox(height: 10),
],
);
}
Widget _filterChip({
required String title,
required Widget icon,
required VoidCallback onSelected,
required bool isSelected,
}) {
return GestureDetector(
onTap: onSelected,
child: Chip(
avatar: icon,
label: Text(
title,
style: const TextStyle(
fontFamily: 'Anek',
),
),
backgroundColor: isSelected ? Colors.blue : Colors.grey[200],
),
);
}
}

View File

@ -1,12 +1,9 @@
import 'package:cheminova/models/pd_rd_response_model.dart'; import 'package:cheminova/screens/Add_products_screen.dart';
import 'package:cheminova/provider/pd_rd_provider.dart'; import 'package:flutter/material.dart';
import 'package:cheminova/screens/add_products_screen.dart';
import 'package:cheminova/widgets/common_background.dart'; import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_app_bar.dart'; import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_drawer.dart';
import 'package:cheminova/widgets/common_elevated_button.dart'; import 'package:cheminova/widgets/common_elevated_button.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class UpdateInventoryScreen extends StatefulWidget { class UpdateInventoryScreen extends StatefulWidget {
const UpdateInventoryScreen({super.key}); const UpdateInventoryScreen({super.key});
@ -16,17 +13,14 @@ class UpdateInventoryScreen extends StatefulWidget {
} }
class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> { class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
final List<String> principalDistributors = ['vaibhav', 'sonu', 'monu'];
final List<String> retailerDistributors = ['shivam', 'vivek'];
String? selectedDistributorType; String? selectedDistributorType;
PdRdResponseModel? selectedDistributor; String? selectedDistributor;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// Fetch the PdRd data when the screen is initialized
// WidgetsBinding.instance.addPostFrameCallback((_) {
// final provider = Provider.of<PdRdProvider>(context, listen: false);
// provider.getPdRd();
// });
} }
@override @override
@ -44,14 +38,12 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
padding: const EdgeInsets.only(right: 20), padding: const EdgeInsets.only(right: 20),
), ),
], ],
title: const Text( title: const Text('Update Inventory Data',
'Update Inventory Data',
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
fontFamily: 'Anek'), fontFamily: 'Anek')),
),
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
elevation: 0, elevation: 0,
), ),
@ -65,30 +57,16 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
text: 'SUBMIT', text: 'SUBMIT',
backgroundColor: const Color(0xff004791), backgroundColor: const Color(0xff004791),
onPressed: () { onPressed: () {
if (selectedDistributor == null ||
selectedDistributorType == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Please select distributor type and distributor')),
);
} else {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => AddProductsScreen( builder: (context) => const AddProductsScreen(),
distributor: selectedDistributor!,
distributorType: selectedDistributorType!,
),
), ),
); );
}
}, },
), ),
), ),
body: Consumer<PdRdProvider>( body: Stack(
builder: (context, provider, child) {
return Stack(
children: [ children: [
Column( Column(
children: [ children: [
@ -114,9 +92,6 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
selectedDistributorType = value; selectedDistributorType = value;
selectedDistributorType == 'Principal Distributor'
? provider.getPd()
: provider.getRd();
selectedDistributor = selectedDistributor =
null; // Reset distributor selection when type changes null; // Reset distributor selection when type changes
}); });
@ -124,11 +99,10 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
), ),
), ),
// Dropdown for selecting distributor name based on type // Dropdown for selecting distributor name based on type
if (selectedDistributorType != null)
Padding( Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 15.0, vertical: 25), horizontal: 15.0, vertical: 25),
child: DropdownButtonFormField<PdRdResponseModel>( child: DropdownButtonFormField<String>(
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'Select Distributor Name', labelText: 'Select Distributor Name',
fillColor: Colors.white, fillColor: Colors.white,
@ -136,14 +110,13 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
border: OutlineInputBorder(), border: OutlineInputBorder(),
), ),
value: selectedDistributor, value: selectedDistributor,
items: (selectedDistributorType == items: (selectedDistributorType == 'Principal Distributor'
'Principal Distributor' ? principalDistributors
? provider.pdList : retailerDistributors)
: provider.rdList) .map((String distributor) {
.map((PdRdResponseModel distributor) { return DropdownMenuItem<String>(
return DropdownMenuItem<PdRdResponseModel>(
value: distributor, value: distributor,
child: Text(distributor.name!), child: Text(distributor),
); );
}).toList(), }).toList(),
onChanged: (value) { onChanged: (value) {
@ -151,6 +124,7 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
selectedDistributor = value; selectedDistributor = value;
}); });
}, },
// Disable the dropdown if no distributor type is selected
isExpanded: true, isExpanded: true,
isDense: true, isDense: true,
iconSize: 24, iconSize: 24,
@ -160,16 +134,7 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
), ),
], ],
), ),
if (provider.isLoading)
Container(
color: Colors.black.withOpacity(0.1),
child: const Center(
child: CircularProgressIndicator(),
),
),
], ],
);
},
), ),
), ),
); );

View File

@ -1,24 +0,0 @@
import 'package:cheminova/models/product_manual_model.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
class ViewPdfScreen extends StatefulWidget {
final ProductManualModel productManualModel;
const ViewPdfScreen({super.key, required this.productManualModel});
@override
State<ViewPdfScreen> createState() => _ViewPdfScreenState();
}
class _ViewPdfScreenState extends State<ViewPdfScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SfPdfViewer.network(
widget.productManualModel.productManualDetail.url,
),
),
);
}
}

View File

@ -12,12 +12,4 @@ class ApiUrls {
static const String notificationUrl = '$baseUrl/get-notification-tm'; static const String notificationUrl = '$baseUrl/get-notification-tm';
static const String fcmUrl = '${baseUrl}kyc/save-fcm-tm'; static const String fcmUrl = '${baseUrl}kyc/save-fcm-tm';
static const String getProducts = '${baseUrl}product/getAll/user/'; static const String getProducts = '${baseUrl}product/getAll/user/';
static const String getRd = 'inventory/distributors-TM/RetailDistributor';
static const String getPd = 'inventory/distributors-TM/PrincipalDistributor';
static const String submitProducts = 'inventory/add-TM';
static const String getSalesCoordinators = 'salescoordinator/getAll-TM';
static const String assignTask = 'task/assign-task';
static const String getProductsManual = 'productmanual/getall';
static const String getAllTasks = 'task/alltasks/';
static const String updateTaskInventoryUrl = '';
} }

View File

@ -2,7 +2,6 @@ import 'package:cheminova/provider/user_provider.dart';
import 'package:cheminova/screens/change_password_screen.dart'; import 'package:cheminova/screens/change_password_screen.dart';
import 'package:cheminova/screens/home_screen.dart'; import 'package:cheminova/screens/home_screen.dart';
import 'package:cheminova/screens/login_screen.dart'; import 'package:cheminova/screens/login_screen.dart';
import 'package:cheminova/screens/profile_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -73,14 +72,7 @@ class CommonDrawer extends StatelessWidget {
leading: const Icon(Icons.account_circle), leading: const Icon(Icons.account_circle),
title: const Text('Profile'), title: const Text('Profile'),
onTap: () { onTap: () {
Navigator.push( Navigator.pop(context);
context,
MaterialPageRoute(
builder: (context) {
return const ProfileScreen();
},
),
);
}, },
), ),
ListTile( ListTile(

View File

@ -13,7 +13,6 @@ class CommonTextFormField extends StatelessWidget {
final List<TextInputFormatter>? inputFormatters; final List<TextInputFormatter>? inputFormatters;
final int? maxLength; final int? maxLength;
final bool obscureText; final bool obscureText;
final void Function(String)? onChanged;
const CommonTextFormField({ const CommonTextFormField({
super.key, super.key,
@ -27,7 +26,6 @@ class CommonTextFormField extends StatelessWidget {
this.keyboardType, this.keyboardType,
this.inputFormatters, this.inputFormatters,
this.maxLength, this.maxLength,
this.onChanged,
this.obscureText = false, this.obscureText = false,
}); });
@ -47,7 +45,6 @@ class CommonTextFormField extends StatelessWidget {
readOnly: readOnly ?? false, readOnly: readOnly ?? false,
maxLines: maxLines, maxLines: maxLines,
maxLength: maxLength, maxLength: maxLength,
onChanged: onChanged,
onTapOutside: (event) => FocusScope.of(context).unfocus(), onTapOutside: (event) => FocusScope.of(context).unfocus(),
validator: validator, validator: validator,
keyboardType: keyboardType, keyboardType: keyboardType,

View File

@ -8,7 +8,6 @@
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h> #include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
@ -17,7 +16,4 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }

View File

@ -5,7 +5,6 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux file_selector_linux
flutter_secure_storage_linux flutter_secure_storage_linux
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@ -5,7 +5,6 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import device_info_plus
import file_selector_macos import file_selector_macos
import firebase_analytics import firebase_analytics
import firebase_core import firebase_core
@ -15,11 +14,8 @@ import flutter_local_notifications
import flutter_secure_storage_macos import flutter_secure_storage_macos
import geolocator_apple import geolocator_apple
import path_provider_foundation import path_provider_foundation
import syncfusion_pdfviewer_macos
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
@ -29,6 +25,4 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }

View File

@ -225,22 +225,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.10" version: "0.7.10"
device_info_plus:
dependency: transitive
description:
name: device_info_plus
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
url: "https://pub.dev"
source: hosted
version: "10.1.2"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
url: "https://pub.dev"
source: hosted
version: "7.0.1"
dio: dio:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1056,14 +1040,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
searchfield:
dependency: "direct main"
description:
name: searchfield
sha256: "913bb61f42d47d82c1adb67047fff3b26dcf6a199f71ecdc9af27c506dda4b48"
url: "https://pub.dev"
source: hosted
version: "1.0.9"
shelf: shelf:
dependency: transitive dependency: transitive
description: description:
@ -1141,70 +1117,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
syncfusion_flutter_core:
dependency: transitive
description:
name: syncfusion_flutter_core
sha256: "85f96b7b06f32a60b19ab0bb8c32bf162a0474f2d94f4844384be1118e6b4954"
url: "https://pub.dev"
source: hosted
version: "26.2.11"
syncfusion_flutter_pdf:
dependency: transitive
description:
name: syncfusion_flutter_pdf
sha256: "0bf5986a8ea7afc54d5712c54f1aba8530be0920872c9dbbe5e0c4369d51eef8"
url: "https://pub.dev"
source: hosted
version: "26.2.11"
syncfusion_flutter_pdfviewer:
dependency: "direct main"
description:
name: syncfusion_flutter_pdfviewer
sha256: "25ca744376c5dafe2e3e5c7718ccb7377a21ddbba00c0d6524801c6ed634c493"
url: "https://pub.dev"
source: hosted
version: "26.2.11"
syncfusion_flutter_signaturepad:
dependency: transitive
description:
name: syncfusion_flutter_signaturepad
sha256: "54545a6611ec8f4b975269f5fd1e7c996172d41398745363542d1307d2976884"
url: "https://pub.dev"
source: hosted
version: "26.2.11"
syncfusion_pdfviewer_macos:
dependency: transitive
description:
name: syncfusion_pdfviewer_macos
sha256: "5731a1ea92455b8322a647387f27c2e7f52b963dff3983b8207233ecc6ef7ba7"
url: "https://pub.dev"
source: hosted
version: "26.2.11"
syncfusion_pdfviewer_platform_interface:
dependency: transitive
description:
name: syncfusion_pdfviewer_platform_interface
sha256: f266aa4657b511201666f394b74c71ecfeaafa2717e4e75e73585a55d99d350d
url: "https://pub.dev"
source: hosted
version: "26.2.11"
syncfusion_pdfviewer_web:
dependency: transitive
description:
name: syncfusion_pdfviewer_web
sha256: "7a3da6586668b851b74ab1bda09d313a54250fb0f74daaadda7133ca3591b235"
url: "https://pub.dev"
source: hosted
version: "26.2.11"
syncfusion_pdfviewer_windows:
dependency: transitive
description:
name: syncfusion_pdfviewer_windows
sha256: "670ac5e4158ba5060fbb26e2a5a04f6d7272eb9f4948d470634a0dbf33e423b2"
url: "https://pub.dev"
source: hosted
version: "26.2.11"
table_calendar: table_calendar:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1269,70 +1181,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
url_launcher:
dependency: transitive
description:
name: url_launcher
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: f0c73347dfcfa5b3db8bc06e1502668265d39c08f310c29bff4e28eea9699f79
url: "https://pub.dev"
source: hosted
version: "6.3.9"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
url: "https://pub.dev"
source: hosted
version: "6.3.1"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
url: "https://pub.dev"
source: hosted
version: "3.2.0"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
@ -1421,14 +1269,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.5.3" version: "5.5.3"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
url: "https://pub.dev"
source: hosted
version: "1.1.4"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View File

@ -50,8 +50,6 @@ dependencies:
flutter_local_notifications: ^17.2.1+2 flutter_local_notifications: ^17.2.1+2
firebase_crashlytics: ^4.0.4 firebase_crashlytics: ^4.0.4
firebase_analytics: ^11.2.1 firebase_analytics: ^11.2.1
searchfield: ^1.0.9
syncfusion_flutter_pdfviewer: ^26.2.11
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -11,8 +11,6 @@
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h> #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <geolocator_windows/geolocator_windows.h> #include <geolocator_windows/geolocator_windows.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar( FileSelectorWindowsRegisterWithRegistrar(
@ -25,8 +23,4 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("GeolocatorWindows")); registry->GetRegistrarForPlugin("GeolocatorWindows"));
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@ -8,8 +8,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_windows flutter_secure_storage_windows
geolocator_windows geolocator_windows
permission_handler_windows permission_handler_windows
syncfusion_pdfviewer_windows
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST