assign task of KYC
This commit is contained in:
parent
7cce7db73c
commit
1436aa0131
@ -3,6 +3,7 @@ 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/pd_rd_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';
|
||||||
@ -100,6 +101,7 @@ Future<void> main() async {
|
|||||||
ChangeNotifierProvider(create: (_) => UserProvider()),
|
ChangeNotifierProvider(create: (_) => UserProvider()),
|
||||||
ChangeNotifierProvider(create: (_) => ProductProvider()),
|
ChangeNotifierProvider(create: (_) => ProductProvider()),
|
||||||
ChangeNotifierProvider(create: (_) => PdRdProvider()),
|
ChangeNotifierProvider(create: (_) => PdRdProvider()),
|
||||||
|
ChangeNotifierProvider(create: (_) => TaskProvider()),
|
||||||
],
|
],
|
||||||
child: const MyApp(),
|
child: const MyApp(),
|
||||||
),
|
),
|
||||||
@ -121,8 +123,12 @@ class _MyAppState extends State<MyApp> {
|
|||||||
// scaffoldMessengerKey: SnackBarService().scaffoldMessengerKey,
|
// scaffoldMessengerKey: SnackBarService().scaffoldMessengerKey,
|
||||||
title: 'cheminova',
|
title: 'cheminova',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
colorScheme: ColorScheme.fromSeed(
|
||||||
useMaterial3: true),
|
seedColor: const Color(0xff004791),
|
||||||
home: const SplashScreen());
|
),
|
||||||
|
useMaterial3: true,
|
||||||
|
),
|
||||||
|
home: const SplashScreen(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,123 +1,127 @@
|
|||||||
class PdRdResponseModel {
|
class PdRdResponseModel {
|
||||||
String id;
|
String? id;
|
||||||
String name;
|
String? uniqueId;
|
||||||
String tradeName;
|
String? name;
|
||||||
String address;
|
String? tradeName;
|
||||||
String state;
|
String? address;
|
||||||
String city;
|
String? state;
|
||||||
String district;
|
String? city;
|
||||||
String pincode;
|
String? district;
|
||||||
String mobileNumber;
|
String? pincode;
|
||||||
String principalDistributer;
|
String? mobileNumber;
|
||||||
String panNumber;
|
String? principalDistributer;
|
||||||
ImageModel panImg;
|
String? panNumber;
|
||||||
String aadharNumber;
|
ImageModel? panImg;
|
||||||
ImageModel aadharImg;
|
String? aadharNumber;
|
||||||
String gstNumber;
|
ImageModel? aadharImg;
|
||||||
ImageModel gstImg;
|
String? gstNumber;
|
||||||
ImageModel pesticideLicenseImg;
|
ImageModel? gstImg;
|
||||||
ImageModel selfieEntranceImg;
|
ImageModel? pesticideLicenseImg;
|
||||||
String status;
|
ImageModel? selfieEntranceImg;
|
||||||
String addedBy;
|
String? status;
|
||||||
|
String? addedBy;
|
||||||
String? userType;
|
String? userType;
|
||||||
List<Note> notes;
|
List<Note>? notes;
|
||||||
DateTime createdAt;
|
DateTime? createdAt;
|
||||||
DateTime updatedAt;
|
DateTime? updatedAt;
|
||||||
int v;
|
int? v;
|
||||||
|
|
||||||
PdRdResponseModel({
|
PdRdResponseModel({
|
||||||
required this.id,
|
this.id,
|
||||||
required this.name,
|
this.uniqueId,
|
||||||
required this.tradeName,
|
this.name,
|
||||||
required this.address,
|
this.tradeName,
|
||||||
required this.state,
|
this.address,
|
||||||
required this.city,
|
this.state,
|
||||||
required this.district,
|
this.city,
|
||||||
required this.pincode,
|
this.district,
|
||||||
required this.mobileNumber,
|
this.pincode,
|
||||||
required this.principalDistributer,
|
this.mobileNumber,
|
||||||
required this.panNumber,
|
this.principalDistributer,
|
||||||
required this.panImg,
|
this.panNumber,
|
||||||
required this.aadharNumber,
|
this.panImg,
|
||||||
required this.aadharImg,
|
this.aadharNumber,
|
||||||
required this.gstNumber,
|
this.aadharImg,
|
||||||
required this.gstImg,
|
this.gstNumber,
|
||||||
required this.pesticideLicenseImg,
|
this.gstImg,
|
||||||
required this.selfieEntranceImg,
|
this.pesticideLicenseImg,
|
||||||
required this.status,
|
this.selfieEntranceImg,
|
||||||
required this.addedBy,
|
this.status,
|
||||||
|
this.addedBy,
|
||||||
this.userType,
|
this.userType,
|
||||||
required this.notes,
|
this.notes,
|
||||||
required this.createdAt,
|
this.createdAt,
|
||||||
required this.updatedAt,
|
this.updatedAt,
|
||||||
required this.v,
|
this.v,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory PdRdResponseModel.fromJson(Map<String, dynamic> json) =>
|
factory PdRdResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||||
PdRdResponseModel(
|
PdRdResponseModel(
|
||||||
id: json["_id"],
|
id: json["_id"],
|
||||||
name: json["name"],
|
name: json["name"],
|
||||||
tradeName: json["trade_name"],
|
uniqueId: json["uniqueId"],
|
||||||
address: json["address"],
|
// tradeName: json["trade_name"],
|
||||||
state: json["state"],
|
// address: json["address"],
|
||||||
city: json["city"],
|
// state: json["state"],
|
||||||
district: json["district"],
|
// city: json["city"],
|
||||||
pincode: json["pincode"],
|
// district: json["district"],
|
||||||
mobileNumber: json["mobile_number"],
|
// pincode: json["pincode"],
|
||||||
principalDistributer: json["principal_distributer"],
|
// mobileNumber: json["mobile_number"],
|
||||||
panNumber: json["pan_number"],
|
// principalDistributer: json["principal_distributer"],
|
||||||
panImg: ImageModel.fromJson(json["pan_img"]),
|
// panNumber: json["pan_number"],
|
||||||
aadharNumber: json["aadhar_number"],
|
// panImg: ImageModel.fromJson(json["pan_img"]),
|
||||||
aadharImg: ImageModel.fromJson(json["aadhar_img"]),
|
// aadharNumber: json["aadhar_number"],
|
||||||
gstNumber: json["gst_number"],
|
// aadharImg: ImageModel.fromJson(json["aadhar_img"]),
|
||||||
gstImg: ImageModel.fromJson(json["gst_img"]),
|
// gstNumber: json["gst_number"],
|
||||||
pesticideLicenseImg: ImageModel.fromJson(json["pesticide_license_img"]),
|
// gstImg: ImageModel.fromJson(json["gst_img"]),
|
||||||
selfieEntranceImg: ImageModel.fromJson(json["selfie_entrance_img"]),
|
// pesticideLicenseImg: ImageModel.fromJson(json["pesticide_license_img"]),
|
||||||
status: json["status"],
|
// selfieEntranceImg: ImageModel.fromJson(json["selfie_entrance_img"]),
|
||||||
addedBy: json["addedBy"],
|
// status: json["status"],
|
||||||
userType: json["userType"],
|
// addedBy: json["addedBy"],
|
||||||
notes: List<Note>.from(json["notes"].map((x) => Note.fromJson(x))),
|
// userType: json["userType"],
|
||||||
createdAt: DateTime.parse(json["createdAt"]),
|
// notes: List<Note>.from(json["notes"].map((x) => Note.fromJson(x))),
|
||||||
updatedAt: DateTime.parse(json["updatedAt"]),
|
// createdAt: DateTime.parse(json["createdAt"]),
|
||||||
v: json["__v"],
|
// updatedAt: DateTime.parse(json["updatedAt"]),
|
||||||
|
// v: json["__v"],
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
"_id": id,
|
"_id": id,
|
||||||
"name": name,
|
"name": name,
|
||||||
"trade_name": tradeName,
|
"uniqueId": uniqueId,
|
||||||
"address": address,
|
// "trade_name": tradeName,
|
||||||
"state": state,
|
// "address": address,
|
||||||
"city": city,
|
// "state": state,
|
||||||
"district": district,
|
// "city": city,
|
||||||
"pincode": pincode,
|
// "district": district,
|
||||||
"mobile_number": mobileNumber,
|
// "pincode": pincode,
|
||||||
"principal_distributer": principalDistributer,
|
// "mobile_number": mobileNumber,
|
||||||
"pan_number": panNumber,
|
// "principal_distributer": principalDistributer,
|
||||||
"pan_img": panImg.toJson(),
|
// "pan_number": panNumber,
|
||||||
"aadhar_number": aadharNumber,
|
// "pan_img": panImg.toJson(),
|
||||||
"aadhar_img": aadharImg.toJson(),
|
// "aadhar_number": aadharNumber,
|
||||||
"gst_number": gstNumber,
|
// "aadhar_img": aadharImg.toJson(),
|
||||||
"gst_img": gstImg.toJson(),
|
// "gst_number": gstNumber,
|
||||||
"pesticide_license_img": pesticideLicenseImg.toJson(),
|
// "gst_img": gstImg.toJson(),
|
||||||
"selfie_entrance_img": selfieEntranceImg.toJson(),
|
// "pesticide_license_img": pesticideLicenseImg.toJson(),
|
||||||
"status": status,
|
// "selfie_entrance_img": selfieEntranceImg.toJson(),
|
||||||
"addedBy": addedBy,
|
// "status": status,
|
||||||
"userType": userType,
|
// "addedBy": addedBy,
|
||||||
"notes": List<dynamic>.from(notes.map((x) => x.toJson())),
|
// "userType": userType,
|
||||||
"createdAt": createdAt.toIso8601String(),
|
// "notes": List<dynamic>.from(notes.map((x) => x.toJson())),
|
||||||
"updatedAt": updatedAt.toIso8601String(),
|
// "createdAt": createdAt.toIso8601String(),
|
||||||
"__v": v,
|
// "updatedAt": updatedAt.toIso8601String(),
|
||||||
|
// "__v": v,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class ImageModel {
|
class ImageModel {
|
||||||
String publicId;
|
String? publicId;
|
||||||
String url;
|
String? url;
|
||||||
|
|
||||||
ImageModel({
|
ImageModel({
|
||||||
required this.publicId,
|
this.publicId,
|
||||||
required this.url,
|
this.url,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory ImageModel.fromJson(Map<String, dynamic> json) => ImageModel(
|
factory ImageModel.fromJson(Map<String, dynamic> json) => ImageModel(
|
||||||
@ -132,14 +136,14 @@ class ImageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Note {
|
class Note {
|
||||||
String message;
|
String? message;
|
||||||
DateTime replyDate;
|
DateTime? replyDate;
|
||||||
String id;
|
String? id;
|
||||||
|
|
||||||
Note({
|
Note({
|
||||||
required this.message,
|
this.message,
|
||||||
required this.replyDate,
|
this.replyDate,
|
||||||
required this.id,
|
this.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Note.fromJson(Map<String, dynamic> json) => Note(
|
factory Note.fromJson(Map<String, dynamic> json) => Note(
|
||||||
@ -150,7 +154,7 @@ class Note {
|
|||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
"message": message,
|
"message": message,
|
||||||
"replyDate": replyDate.toIso8601String(),
|
// "replyDate": replyDate.toIso8601String(),
|
||||||
"_id": id,
|
"_id": id,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ class PdRdProvider extends ChangeNotifier {
|
|||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
bool get isLoading => _isLoading;
|
bool get isLoading => _isLoading;
|
||||||
|
|
||||||
List<PdRdResponseModel> _pdRdList = [];
|
List<PdRdResponseModel> _pdList = [];
|
||||||
List<PdRdResponseModel> get pdRdList => _pdRdList;
|
List<PdRdResponseModel> get pdList => _pdList;
|
||||||
|
List<PdRdResponseModel> _rdList = [];
|
||||||
|
List<PdRdResponseModel> get rdList => _rdList;
|
||||||
|
|
||||||
final _apiClient = ApiClient();
|
final _apiClient = ApiClient();
|
||||||
|
|
||||||
@ -18,16 +20,42 @@ class PdRdProvider extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getPdRd() async {
|
void clearLists() {
|
||||||
|
_pdList.clear();
|
||||||
|
_rdList.clear();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getPd() async {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
clearLists(); // Clear the list before fetching new data
|
||||||
try {
|
try {
|
||||||
Response response = await _apiClient.get(ApiUrls.getPdRdUrl);
|
Response response = await _apiClient.get(ApiUrls.getPd);
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
// Assuming the response data is a list of PdRdResponseModel objects
|
|
||||||
List<PdRdResponseModel> data = (response.data as List)
|
List<PdRdResponseModel> data = (response.data as List)
|
||||||
.map((json) => PdRdResponseModel.fromJson(json))
|
.map((json) => PdRdResponseModel.fromJson(json))
|
||||||
.toList();
|
.toList();
|
||||||
_pdRdList = data;
|
_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 {
|
} else {
|
||||||
print("Failed to load data: ${response.statusCode}");
|
print("Failed to load data: ${response.statusCode}");
|
||||||
}
|
}
|
||||||
|
111
lib/provider/task_provider.dart
Normal file
111
lib/provider/task_provider.dart
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import 'package:cheminova/models/pd_rd_response_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 = [];
|
||||||
|
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;
|
||||||
|
|
||||||
|
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();
|
||||||
|
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(BuildContext context) async {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
Response response = await _apiClient.post(
|
||||||
|
ApiUrls.assignTask,
|
||||||
|
data: {
|
||||||
|
'taskAssignedTo': _selectedSalesCoordinator!.id,
|
||||||
|
'task': _selectedTask,
|
||||||
|
'taskPriority': _selectedPriority,
|
||||||
|
'taskDueDate': _selectedDate,
|
||||||
|
'note': _noteController.text,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -72,7 +72,7 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.distributor.name,
|
widget.distributor.name!,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
@ -222,7 +222,7 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
|
|||||||
provider
|
provider
|
||||||
.submitSelectedProducts(
|
.submitSelectedProducts(
|
||||||
"PrincipalDistributor",
|
"PrincipalDistributor",
|
||||||
widget.distributor.id)
|
widget.distributor.id!)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -275,27 +275,25 @@ class _ProductBlockState extends State<ProductBlock> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
if (saleController.text.isNotEmpty &&
|
if (saleController.text.isNotEmpty &&
|
||||||
inventoryController.text.isNotEmpty) {
|
inventoryController.text.isNotEmpty) {
|
||||||
// Check if the input can be parsed as an integer
|
// Check if both inputs are valid integers
|
||||||
if (int.tryParse(saleController.text) == null ||
|
try {
|
||||||
int.tryParse(inventoryController.text) == null) {
|
|
||||||
errorMessage = 'Please enter valid integer value';
|
|
||||||
} else {
|
|
||||||
// Parse the input as integers
|
|
||||||
int sale = int.parse(saleController.text);
|
int sale = int.parse(saleController.text);
|
||||||
int inventory = int.parse(inventoryController.text);
|
int inventory = int.parse(inventoryController.text);
|
||||||
|
|
||||||
// Validate if inventory is less than or equal to sales
|
// 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 = 'Please fill in both fields';
|
errorMessage = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return errorMessage == null;
|
return errorMessage == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:cheminova/screens/select_sales_coordinator_screen.dart';
|
import 'package:cheminova/screens/assign_tasks_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';
|
||||||
@ -55,39 +56,40 @@ 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,
|
||||||
@ -98,8 +100,7 @@ class _AssignTaskDashBoardScreenState extends State<AssignTaskDashBoardScreen> {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) => const AssignTasksScreen(),
|
||||||
const SelectSalesCoordinatorScreen(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -111,7 +112,12 @@ 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: () {},
|
onPressed: () => Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const TaskManagementScreen(),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
CommonElevatedButton(
|
CommonElevatedButton(
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
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});
|
||||||
@ -13,11 +17,45 @@ class AssignTasksScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
||||||
final List<bool> _isChecked = List.generate(8, (_) => false);
|
bool _isSalesCoordinatorValid = true;
|
||||||
|
bool _isTaskValid = true;
|
||||||
|
bool _isPriorityValid = true;
|
||||||
|
bool _isNotesValid = true;
|
||||||
|
|
||||||
String _dateSelected = DateFormat('dd/MM/yyyy').format(DateTime.now());
|
void _validateAndSubmit() {
|
||||||
|
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.noteController.text.isEmpty) {
|
||||||
|
_isNotesValid = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If all fields are valid, proceed to the next screen
|
||||||
|
if (_isSalesCoordinatorValid && _isTaskValid && _isPriorityValid) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const ConfirmTaskScreen(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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(),
|
||||||
@ -25,14 +63,28 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
lastDate: DateTime(2025),
|
lastDate: DateTime(2025),
|
||||||
);
|
);
|
||||||
if (dateSelected != null) {
|
if (dateSelected != null) {
|
||||||
setState(() {
|
provider.setDate(DateFormat('dd/MM/yyyy').format(dateSelected));
|
||||||
_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(
|
||||||
@ -56,13 +108,15 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
),
|
),
|
||||||
drawer: const CommonDrawer(),
|
drawer: const CommonDrawer(),
|
||||||
body: CommonBackground(
|
body: CommonBackground(
|
||||||
child: SafeArea(
|
child: Stack(
|
||||||
|
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:
|
padding: const EdgeInsets.all(20.0)
|
||||||
const EdgeInsets.all(20.0).copyWith(top: 15, bottom: 30),
|
.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(
|
||||||
@ -84,37 +138,69 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Container(
|
SearchField(
|
||||||
width: double.infinity,
|
suggestionsDecoration: SuggestionDecoration(
|
||||||
padding: const EdgeInsets.all(12.0),
|
borderRadius: const BorderRadius.only(
|
||||||
margin: const EdgeInsets.only(bottom: 20),
|
bottomLeft: Radius.circular(8.0),
|
||||||
decoration: BoxDecoration(
|
bottomRight: Radius.circular(8),
|
||||||
border: Border.all(color: Colors.white),
|
|
||||||
color: const Color(0xffB4D1E5).withOpacity(0.6),
|
|
||||||
borderRadius: BorderRadius.circular(16.0),
|
|
||||||
),
|
),
|
||||||
child: const Column(
|
border: Border.all(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
color: Colors.grey.withOpacity(0.5),
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Sales Coordinator: Name",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontFamily: 'Anek',
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
suggestionItemDecoration: BoxDecoration(
|
||||||
"ID: 121",
|
borderRadius: BorderRadius.circular(8),
|
||||||
style: TextStyle(
|
shape: BoxShape.rectangle,
|
||||||
fontSize: 16,
|
border: Border.all(
|
||||||
fontWeight: FontWeight.bold,
|
color: Colors.transparent,
|
||||||
fontFamily: 'Anek',
|
style: BorderStyle.solid,
|
||||||
|
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),
|
||||||
@ -137,12 +223,12 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 35,
|
height: 35,
|
||||||
child: CheckboxListTile(
|
child: RadioListTile<String>(
|
||||||
value: _isChecked[0],
|
contentPadding: EdgeInsets.zero,
|
||||||
|
value: 'Visit Retailers',
|
||||||
|
groupValue: taskProvider.selectedTask,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
taskProvider.setSelectedTask(value);
|
||||||
_isChecked[0] = value!;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
title: const Text(
|
title: const Text(
|
||||||
"Visit Retailers",
|
"Visit Retailers",
|
||||||
@ -151,12 +237,12 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 45,
|
height: 45,
|
||||||
child: CheckboxListTile(
|
child: RadioListTile<String>(
|
||||||
value: _isChecked[1],
|
contentPadding: EdgeInsets.zero,
|
||||||
|
value: 'Update Sales Data',
|
||||||
|
groupValue: taskProvider.selectedTask,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
taskProvider.setSelectedTask(value);
|
||||||
_isChecked[1] = value!;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
title: const Text(
|
title: const Text(
|
||||||
"Update Sales Data",
|
"Update Sales Data",
|
||||||
@ -165,32 +251,75 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 45,
|
height: 45,
|
||||||
child: CheckboxListTile(
|
child: RadioListTile<String>(
|
||||||
value: _isChecked[2],
|
contentPadding: EdgeInsets.zero,
|
||||||
|
value: 'Update Liqudation Data',
|
||||||
|
groupValue: taskProvider.selectedTask,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
taskProvider.setSelectedTask(value);
|
||||||
_isChecked[2] = value!;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
title: const Text(
|
title: const Text(
|
||||||
"Update Liqudation Data",
|
"Update Liqudation Data",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CheckboxListTile(
|
RadioListTile<String>(
|
||||||
value: _isChecked[3],
|
contentPadding: EdgeInsets.zero,
|
||||||
|
value: 'Collect KYC',
|
||||||
|
groupValue: taskProvider.selectedTask,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
taskProvider.setSelectedTask(value);
|
||||||
_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') ...{
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
},
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
@ -213,41 +342,43 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Checkbox(
|
Radio<String>(
|
||||||
value: _isChecked[4],
|
value: "Low",
|
||||||
|
groupValue: taskProvider.selectedPriority,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
taskProvider.setSelectedPriority(value!);
|
||||||
_isChecked[4] = value!;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Text(
|
const Text("Low"),
|
||||||
"Low",
|
Radio<String>(
|
||||||
),
|
value: "Medium",
|
||||||
Checkbox(
|
groupValue: taskProvider.selectedPriority,
|
||||||
value: _isChecked[5],
|
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
taskProvider.setSelectedPriority(value!);
|
||||||
_isChecked[5] = value!;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Text(
|
const Text("Medium"),
|
||||||
"Medium",
|
Radio<String>(
|
||||||
),
|
value: "High",
|
||||||
Checkbox(
|
groupValue: taskProvider.selectedPriority,
|
||||||
value: _isChecked[6],
|
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
taskProvider.setSelectedPriority(value!);
|
||||||
_isChecked[6] = value!;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Text(
|
const Text("High"),
|
||||||
"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),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -274,7 +405,7 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
_dateSelected,
|
taskProvider.selectedDate,
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -293,7 +424,7 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: kToolbarHeight - 10,
|
height: kToolbarHeight - 10,
|
||||||
text: 'CONFIRM',
|
text: 'CONFIRM',
|
||||||
onPressed: () {},
|
onPressed: _validateAndSubmit,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -301,6 +432,15 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (taskProvider.isLoading)
|
||||||
|
Container(
|
||||||
|
color: Colors.black.withOpacity(0.1),
|
||||||
|
child: const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
204
lib/screens/confirm_task_screen.dart
Normal file
204
lib/screens/confirm_task_screen.dart
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
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 {
|
||||||
|
const ConfirmTaskScreen({super.key});
|
||||||
|
|
||||||
|
@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')
|
||||||
|
_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),
|
||||||
|
CommonElevatedButton(
|
||||||
|
isLoading: taskProvider.isLoading,
|
||||||
|
backgroundColor: const Color(0xff004791),
|
||||||
|
borderRadius: 30,
|
||||||
|
width: double.infinity,
|
||||||
|
height: kToolbarHeight - 10,
|
||||||
|
text: 'CONFIRM',
|
||||||
|
onPressed: () => taskProvider.assignTask(context),
|
||||||
|
),
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -14,10 +14,13 @@ 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.pushReplacement(
|
Navigator.of(context).pushAndRemoveUntil(
|
||||||
context, MaterialPageRoute(builder: (context) => const HomePage()));
|
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(
|
||||||
@ -32,7 +35,11 @@ class DataSubmitSuccessfullState extends State<DataSubmitSuccessfull> {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
fontFamily: 'Anek')),
|
fontFamily: 'Anek')),
|
||||||
const SizedBox(height: 20), // Add some space between the text and the image
|
const SizedBox(
|
||||||
Image.asset('assets/check_circle.png', )]))));
|
height: 20), // Add some space between the text and the image
|
||||||
|
Image.asset(
|
||||||
|
'assets/check_circle.png',
|
||||||
|
)
|
||||||
|
]))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
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';
|
||||||
@ -79,10 +78,18 @@ class _SelectSalesCoordinatorScreenState
|
|||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: salesCoordinators.length,
|
itemCount: salesCoordinators.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return _customCard(
|
return GestureDetector(
|
||||||
|
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,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -98,18 +105,7 @@ 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 GestureDetector(
|
return Container(
|
||||||
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),
|
||||||
@ -147,7 +143,6 @@ class _SelectSalesCoordinatorScreenState
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
254
lib/screens/task_management_screen.dart
Normal file
254
lib/screens/task_management_screen.dart
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
class TaskManagementScreen extends StatefulWidget {
|
||||||
|
const TaskManagementScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<TaskManagementScreen> createState() => _TaskManagementScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TaskManagementScreenState extends State<TaskManagementScreen> {
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
final List<String> _taskList = [
|
||||||
|
'Task 1',
|
||||||
|
'Task 2',
|
||||||
|
'Task 3',
|
||||||
|
'Task 4',
|
||||||
|
'Task 5',
|
||||||
|
'Task 6',
|
||||||
|
'Task 7',
|
||||||
|
'Task 8',
|
||||||
|
'Task 9',
|
||||||
|
'Task 10',
|
||||||
|
];
|
||||||
|
|
||||||
|
final List<String> _filters = [
|
||||||
|
'All',
|
||||||
|
'Pending',
|
||||||
|
'Completed',
|
||||||
|
];
|
||||||
|
|
||||||
|
List<String> _filteredTaskList = [];
|
||||||
|
|
||||||
|
void _filterTaskList(String query) {
|
||||||
|
setState(() {
|
||||||
|
_filteredTaskList = _taskList
|
||||||
|
.where((task) => task.toLowerCase().contains(query.toLowerCase()))
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_filteredTaskList = _taskList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
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: 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: 'All',
|
||||||
|
icon: const Icon(Icons.all_inclusive),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
_filterChip(
|
||||||
|
title: 'Pending',
|
||||||
|
icon: const Icon(Icons.pending),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
_filterChip(
|
||||||
|
title: 'Completed',
|
||||||
|
icon: const Icon(Icons.done),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Tasks:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Anek',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.55,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: _filteredTaskList.length,
|
||||||
|
itemBuilder: (context, index) => _taskView(
|
||||||
|
title: _filteredTaskList[index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// CommonElevatedButton(
|
||||||
|
// backgroundColor: const Color(0xff004791),
|
||||||
|
// borderRadius: 30,
|
||||||
|
// width: double.infinity,
|
||||||
|
// height: kToolbarHeight - 10,
|
||||||
|
// text: 'EDIT',
|
||||||
|
// onPressed: () => Navigator.push(
|
||||||
|
// context,
|
||||||
|
// MaterialPageRoute(
|
||||||
|
// builder: (context) => const AssignTasksScreen(),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 20),
|
||||||
|
// CommonElevatedButton(
|
||||||
|
// backgroundColor: const Color(0xff00784C),
|
||||||
|
// borderRadius: 30,
|
||||||
|
// width: double.infinity,
|
||||||
|
// height: kToolbarHeight - 10,
|
||||||
|
// text: 'REASSIGN',
|
||||||
|
// onPressed: () => Navigator.push(
|
||||||
|
// context,
|
||||||
|
// MaterialPageRoute(
|
||||||
|
// builder: (context) =>
|
||||||
|
// const SelectSalesCoordinatorScreen(),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 20),
|
||||||
|
// CommonElevatedButton(
|
||||||
|
// backgroundColor: const Color(0xff00784C),
|
||||||
|
// borderRadius: 30,
|
||||||
|
// width: double.infinity,
|
||||||
|
// height: kToolbarHeight - 10,
|
||||||
|
// text: 'MARK AS COMPLETED',
|
||||||
|
// onPressed: () {},
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _taskView({required String title}) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
_customContainer(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Sales Coordinator: 1',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Anek',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontFamily: 'Anek',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
const Text(
|
||||||
|
'Status: Pending',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Anek',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
const Text(
|
||||||
|
'Deadline: 12/12/2024',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Anek',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _filterChip({required String title, required Widget icon}) {
|
||||||
|
return Chip(
|
||||||
|
avatar: icon,
|
||||||
|
label: Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontFamily: 'Anek',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -23,10 +23,10 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
// Fetch the PdRd data when the screen is initialized
|
// Fetch the PdRd data when the screen is initialized
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
final provider = Provider.of<PdRdProvider>(context, listen: false);
|
// final provider = Provider.of<PdRdProvider>(context, listen: false);
|
||||||
provider.getPdRd();
|
// provider.getPdRd();
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -65,9 +65,12 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
|
|||||||
text: 'SUBMIT',
|
text: 'SUBMIT',
|
||||||
backgroundColor: const Color(0xff004791),
|
backgroundColor: const Color(0xff004791),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if(selectedDistributor == null || selectedDistributorType == null){
|
if (selectedDistributor == null ||
|
||||||
|
selectedDistributorType == null) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Please select distributor type and distributor')),
|
const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Please select distributor type and distributor')),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -85,22 +88,6 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
|
|||||||
),
|
),
|
||||||
body: Consumer<PdRdProvider>(
|
body: Consumer<PdRdProvider>(
|
||||||
builder: (context, provider, child) {
|
builder: (context, provider, child) {
|
||||||
if (provider.isLoading) {
|
|
||||||
return const Center(child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (provider.pdRdList.isEmpty) {
|
|
||||||
return const Center(child: Text('No distributors available.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PdRdResponseModel> principalDistributors = provider.pdRdList
|
|
||||||
.where((item) => item.userType == 'SalesCoOrdinator')
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
List<PdRdResponseModel> retailerDistributors = provider.pdRdList
|
|
||||||
.where((item) => item.userType != 'SalesCoOrdinator')
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
@ -127,6 +114,9 @@ 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
|
||||||
});
|
});
|
||||||
@ -148,12 +138,12 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
|
|||||||
value: selectedDistributor,
|
value: selectedDistributor,
|
||||||
items: (selectedDistributorType ==
|
items: (selectedDistributorType ==
|
||||||
'Principal Distributor'
|
'Principal Distributor'
|
||||||
? principalDistributors
|
? provider.pdList
|
||||||
: retailerDistributors)
|
: provider.rdList)
|
||||||
.map((PdRdResponseModel distributor) {
|
.map((PdRdResponseModel distributor) {
|
||||||
return DropdownMenuItem<PdRdResponseModel>(
|
return DropdownMenuItem<PdRdResponseModel>(
|
||||||
value: distributor,
|
value: distributor,
|
||||||
child: Text(distributor.name),
|
child: Text(distributor.name!),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -170,6 +160,13 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (provider.isLoading)
|
||||||
|
Container(
|
||||||
|
color: Colors.black.withOpacity(0.1),
|
||||||
|
child: const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,9 @@ 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 getPdRdUrl =
|
static const String getPd = 'inventory/distributors-TM/RetailDistributor';
|
||||||
'inventory/distributors-TM/RetailDistributor';
|
static const String getRd = 'inventory/distributors-TM/PrincipalDistributor';
|
||||||
static const String submitProducts = 'inventory/add-TM';
|
static const String submitProducts = 'inventory/add-TM';
|
||||||
|
static const String getSalesCoordinators = 'salescoordinator/getAll-TM';
|
||||||
|
static const String assignTask = 'task/assign-task';
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ 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,
|
||||||
@ -26,6 +27,7 @@ class CommonTextFormField extends StatelessWidget {
|
|||||||
this.keyboardType,
|
this.keyboardType,
|
||||||
this.inputFormatters,
|
this.inputFormatters,
|
||||||
this.maxLength,
|
this.maxLength,
|
||||||
|
this.onChanged,
|
||||||
this.obscureText = false,
|
this.obscureText = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -45,6 +47,7 @@ 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,
|
||||||
|
@ -1040,6 +1040,14 @@ 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:
|
||||||
|
@ -50,6 +50,7 @@ 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
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user