1)Order Place api Integration

2)Confirm Order api Integration
3)get Oder api Integration
This commit is contained in:
saritabirare 2024-09-06 14:39:40 +05:30
parent 43413ac168
commit 215877afc4
34 changed files with 1527 additions and 317 deletions

View File

@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:label="cheminova" android:label="cheminova"
android:name="${applicationName}" android:name="${applicationName}"

View File

@ -0,0 +1,40 @@
import 'package:cheminova/controller/get_place_order_service.dart';
import 'package:cheminova/controller/product_service.dart';
import 'package:cheminova/models/oder_place_model.dart';
import 'package:cheminova/models/product_model1.dart';
import 'package:get/get.dart';
class GetPlacedOrderController extends GetxController {
final GetOrderPlacedServcie _getOrderPlacedServcie = GetOrderPlacedServcie();
var products = <PlacedOrderModel>[].obs;
int _currentPage = 1;
bool isLoading = false;
@override
void onInit() {
super.onInit();
}
Future<void> getOrder(String id) async {
if (isLoading) return;
isLoading = true;
try {
final fetchedProducts = await _getOrderPlacedServcie.getPlacedOrder();
if (fetchedProducts != null) {
products.addAll(fetchedProducts);
}
} catch (e) {
print("Error fetching products: $e");
} finally {
isLoading = false;
update();
}
}
}

View File

@ -0,0 +1,35 @@
import 'package:cheminova/models/oder_place_model.dart';
import '../utils/common_api_service.dart';
import '../utils/show_snackbar.dart';
class GetOrderPlacedServcie{
Future<List<PlacedOrderModel>?> getPlacedOrder() async {
try {
String url;
url = "/api/get-placed-order-pd?id=66cc7869f02b935094127a27";
final response = await commonApiService<List<PlacedOrderModel>>(
method: "GET",
url: url,
fromJson: (json) {
if (json['plcaedOrders'] != null) {
final List<PlacedOrderModel> products = (json['plcaedOrders'] as List)
.map((productJson) => PlacedOrderModel.fromJson(productJson as Map<String, dynamic>))
.toList();
return products;
} else {
return [];
}
},
);
return response;
} catch (e) {
showSnackbar(e.toString());
return null;
}
}
}

View File

@ -1,9 +1,11 @@
import 'package:cheminova/controller/home_service.dart'; import 'package:cheminova/controller/home_service.dart';
import 'package:cheminova/models/user_model.dart'; import 'package:cheminova/models/user_model.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
class HomeController extends GetxController { class HomeController extends GetxController {
final HomeService homeService = HomeService(); final HomeService homeService = HomeService();
var user = Rxn<UserModel>(); var user = Rxn<UserModel>();
@override @override
@ -12,8 +14,10 @@ class HomeController extends GetxController {
super.onInit(); super.onInit();
} }
Future<void> getUser() async { Future<void> getUser() async
user.value = await homeService.getUser(); {
update(); SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token');
user.value = (await homeService.getUser(token: token)) as UserModel? ;
} }
} }

View File

@ -3,12 +3,15 @@ import 'package:cheminova/utils/common_api_service.dart';
import 'package:cheminova/utils/show_snackbar.dart'; import 'package:cheminova/utils/show_snackbar.dart';
class HomeService { class HomeService {
Future<UserModel?> getUser() async { Future<Map<String, dynamic>?> getUser({String? token}) async {
try { try {
final response = await commonApiService<UserModel>( final response = await commonApiService<Map<String,dynamic>>(
method: "GET", method: "GET",
url: "/api/territorymanager/my-profile", url: "api/v1/user/details",
fromJson: (json) => UserModel.fromJson(json), fromJson: (json) => json,
additionalHeaders: { // Pass the token here
'Authorization': 'Bearer $token',
},
); );
return response; return response;
@ -17,4 +20,6 @@ class HomeService {
} }
return null; return null;
} }
} }

View File

@ -0,0 +1,129 @@
import 'dart:convert';
import 'package:cheminova/controller/place_order_service.dart';
import 'package:cheminova/models/product_model.dart';
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/oder_place_model.dart';
class OrderPlacedController extends GetxController {
var placedOrder1 = PlacedOrderModel(
paymentMode: 'cheque',
shipTo: '456, Park Street, Kolkata, West Bengal - 700016',
billTo: '456, Park Street, Kolkata, West Bengal - 700016',
subtotal: 300,
gstTotal: 100,
grandTotal: 400,
orderItems: [
],
).obs;
var isLoading = false.obs;
final OrderPlacedService _orderPlacedService = OrderPlacedService();
Future<void> placeOrder() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token');
isLoading.value = true;
//try {
// Construct order details
PlacedOrderModel orderDetails = placedOrder1.value;
print("Order Details: $orderDetails");
// Call the service to place the order
await _orderPlacedService.placeOrder(orderDetails, token!);
}
// catch (e) {
//
// } finally {
// isLoading.value = false;
// }
}
// import 'package:cheminova/controller/place_order_service.dart';
// import 'package:cheminova/models/category_model.dart';
// import 'package:get/get.dart';
// import 'package:shared_preferences/shared_preferences.dart';
// import '../models/oder_place_model.dart';
// import 'cart_controller.dart';
//
//
// class OrderPlacedController extends GetxController {
// final OrderPlacedService _orderPlacedService = OrderPlacedService();
// final CartController _cartController = Get.find();
// Rx<PlacedOrderModel?> placedOrder1 = Rx<PlacedOrderModel?>(null);
// RxBool isLoading = false.obs;
//
// // Method to place an order with provided details
// Future<void> placeOrder() async {
// SharedPreferences prefs = await SharedPreferences.getInstance();
// String? token = prefs.getString('token');
//
// // Prepare order details
// final order = PlacedOrderModel(
// paymentMode: 'cheque',
// shipTo: '456, Park Street, Kolkata, West Bengal - 700016',
// billTo: '456, Park Street, Kolkata, West Bengal - 700016',
// subtotal: 4000,
// gstTotal: 18,
// grandTotal: 4720,
// orderItems: [
// OrderItem(
// id: "66cc7869f02b935094127a27",
// sku: "BJD",
// name: "Zycor 60m.l",
// price: 4000,
// gst: 18,
// hsnCode: 200,
// description: "",
// productStatus: "Active",
// addedBy: "ChemiNova",
// image: [],
// createdAt: DateTime.parse("2024-08-26T12:43:21.103Z"),
// updatedAt: DateTime.parse("2024-08-26T12:43:21.103Z"),
// count: 1, category:Category(id: "66cc7868f02b935094127a21", categoryName: "Insectiside") ,
// brand: Brand(id: "66cc77fbf02b9350941279f5", brandName: "Old"), v: 0,
// ),
// ],
// );
//
// try {
// isLoading.value = true;
// PlacedOrderModel? result = await _orderPlacedService.placeOrder(order, token);
// if (result != null) {
// placedOrder1.value = result;
// Get.snackbar('Success', 'Order placed successfully.');
// // _cartController.clearCart(); // Clear cart items after order
// } else {
// Get.snackbar('Error', 'Failed to place order.');
// }
// } catch (e) {
// Get.snackbar('Error', e.toString());
// } finally {
// isLoading.value = false;
// }
// }
//
// String getShippingAddress() {
// return placedOrder1.value?.shipTo ?? 'No shipping address';
// }
//
// String getBillingAddress() {
// return placedOrder1.value?.billTo ?? 'No billing address';
// }
//
// String getPaymentMode() {
// return placedOrder1.value?.paymentMode ?? 'No payment mode';
// }
// }

View File

@ -0,0 +1,41 @@
import 'dart:convert';
import 'dart:developer';
import 'package:cheminova/models/product_model.dart';
import 'package:dio/dio.dart';
import '../models/oder_place_model.dart';
import '../utils/log_service.dart';
class OrderPlacedService {
final Dio dio = Dio();
Future<void> placeOrder(PlacedOrderModel orderDetails, String token) async {
//try {
logger.w("orderjson ${jsonEncode(orderDetails.toJson())}");
final response = await dio.post(
'https://cheminova-api-2.onrender.com/api/order-place', // Ensure this is your correct endpoint
data: jsonEncode(orderDetails.toJson()),
options: Options(
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
),
);
logger.w("Status code,${response.statusCode}");
if (response.statusCode != 201) {
throw Exception('Failed to place order');
}
}
// on DioException catch (e) {
// print("DioException: ${e.message}");
// throw Exception('Failed to place order: ${e.message}');
// }
// catch (e) {
// print("General Exception: ${e.toString()}");
// throw Exception('Failed to place order: ${e.toString()}');
// }
}

View File

@ -1,10 +1,11 @@
import 'package:cheminova/controller/product_service.dart'; import 'package:cheminova/controller/product_service.dart';
import 'package:cheminova/models/product_model1.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class ProductController extends GetxController { class ProductController extends GetxController {
final ProductService productService = ProductService(); final ProductService productService = ProductService();
var products = <Map<String, dynamic>>[].obs; var products = <Product>[].obs;
var categories = <String>[].obs; // Holds the list of categories var categories = <String>[].obs; // Holds the list of categories
var selectedCategory = Rxn<String>(); // Holds the selected category var selectedCategory = Rxn<String>(); // Holds the selected category
int _currentPage = 1; int _currentPage = 1;
@ -28,7 +29,9 @@ class ProductController extends GetxController {
); );
if (fetchedProducts != null) { if (fetchedProducts != null) {
products.addAll(fetchedProducts as Iterable<Map<String, dynamic>>); // Directly add the fetched products (which are of type List<Product>) to the list
products.addAll(fetchedProducts);
print("fetchedProducts ,$fetchedProducts");
} }
} catch (e) { } catch (e) {
print("Error fetching products: $e"); print("Error fetching products: $e");

View File

@ -1,8 +1,9 @@
import '../models/product_model1.dart';
import '../utils/common_api_service.dart'; import '../utils/common_api_service.dart';
import '../utils/show_snackbar.dart'; import '../utils/show_snackbar.dart';
class ProductService { class ProductService {
Future<List<Map<String, dynamic>>?> getProduct(int page, {String? category}) async { Future<List<Product>?> getProduct(int page, {String? category}) async {
try { try {
String url; String url;
if (category != null && category.isNotEmpty) { if (category != null && category.isNotEmpty) {
@ -11,13 +12,13 @@ class ProductService {
url = "/api/product/getAll/user?page=$page"; // URL without category filter url = "/api/product/getAll/user?page=$page"; // URL without category filter
} }
final response = await commonApiService<List<Map<String, dynamic>>>( final response = await commonApiService<List<Product>>(
method: "GET", method: "GET",
url: url, url: url,
fromJson: (json) { fromJson: (json) {
if (json['products'] != null) { if (json['products'] != null) {
final List<Map<String, dynamic>> products = (json['products'] as List) final List<Product> products = (json['products'] as List)
.map((productJson) => productJson as Map<String, dynamic>) .map((productJson) => Product.fromJson(productJson as Map<String, dynamic>))
.toList(); .toList();
return products; return products;
} else { } else {
@ -27,10 +28,10 @@ class ProductService {
); );
return response; return response;
} catch (e) { } catch (e) {
showSnackbar(e.toString()); // showSnackbar(e.toString());
//print("Error: $e");
return null;
} }
return null;
} }

View File

@ -0,0 +1,23 @@
class AddedBy {
String id;
String name;
AddedBy({
required this.id,
required this.name,
});
factory AddedBy.fromJson(Map<String, dynamic> json) => AddedBy(
id: json["_id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"name": name,
};
@override
String toString() {
return 'AddedBy(id: $id, brandName: $AddedBy,)';
}
}

View File

@ -0,0 +1,27 @@
class Brand {
final String id;
final String brandName;
Brand({
required this.id,
required this.brandName,
});
factory Brand.fromJson(Map<String, dynamic> json) {
return Brand(
id: json['_id'],
brandName: json['brandName'],
);
}
Map<String, dynamic> toJson() {
return {
'_id': id,
'brandName': brandName,
};
}
@override
String toString() {
return 'Brand(id: $id, brandName: $brandName,)';
}
}

View File

@ -0,0 +1,27 @@
// lib/models/cart_item.dart
import 'package:cheminova/models/product_model1.dart';
class CartItem {
final Product product;
int quantity;
CartItem({
required this.product,
this.quantity = 1,
});
// Method to increase quantity
void increaseQuantity() {
quantity++;
}
// Method to decrease quantity
void decreaseQuantity() {
if (quantity > 1) {
quantity--;
}
}
// Method to get total price of this item
int get totalPrice => product.price * quantity;
}

View File

@ -0,0 +1,27 @@
class Category {
final String id;
final String categoryName;
Category({
required this.id,
required this.categoryName,
});
factory Category.fromJson(Map<String, dynamic> json) {
return Category(
id: json['_id'],
categoryName: json['categoryName'],
);
}
Map<String, dynamic> toJson() {
return {
'_id': id,
'categoryName': categoryName,
};
}
@override
String toString() {
return 'Category(id: $id, categoryName: $categoryName,)';
}
}

View File

@ -0,0 +1,183 @@
import 'added_by_model.dart';
import 'brand_model.dart';
import 'category_model.dart';
class PlacedOrderModel {
String paymentMode;
String shipTo;
String billTo;
double subtotal;
double gstTotal;
double grandTotal;
List<OrderItem> orderItems;
PlacedOrderModel({
required this.paymentMode,
required this.shipTo,
required this.billTo,
required this.subtotal,
required this.gstTotal,
required this.grandTotal,
required this.orderItems,
});
Map<String, dynamic> toJson() => {
'paymentMode': paymentMode,
'shipTo': shipTo,
'billTo': billTo,
'subtotal': subtotal,
'gstTotal': gstTotal,
'grandTotal': grandTotal,
'orderItems': orderItems.map((item) => item.toJson()).toList(),
};
factory PlacedOrderModel.fromJson(Map<String, dynamic> json) => PlacedOrderModel(
paymentMode: json['paymentMode'],
shipTo: json['shipTo'],
billTo: json['billTo'],
subtotal: json['subtotal'].toDouble(),
gstTotal: json['gstTotal'].toDouble(),
grandTotal: json['grandTotal'].toDouble(),
orderItems: (json['orderItems'] as List).map((item) => OrderItem.fromJson(item)).toList(),
);
@override
String toString() {
return 'PlacedOrderModel{paymentMode: $paymentMode, '
'shipTo: $shipTo, '
'billTo: $billTo, '
'subtotal: $subtotal, '
'gstTotal: $gstTotal, '
'grandTotal: $grandTotal, '
'orderItems: ${orderItems.map((item) => item.toString()).join(', ')})';
}
}
class OrderItem {
String id;
String sku;
String name;
double price;
double gst;
int hsnCode;
String description;
String productStatus;
final String addedBy;
List<String> image;
DateTime createdAt;
DateTime updatedAt;
int count;
Category category;
Brand brand;
int v;
OrderItem({
required this.id,
required this.sku,
required this.name,
required this.price,
required this.gst,
required this.hsnCode,
required this.description,
required this.productStatus,
required this.addedBy,
required this.image,
required this.createdAt,
required this.updatedAt,
required this.count,
required this.category,
required this.brand,
required this.v,
});
// Adjusted toJson method to match the desired format
Map<String, dynamic> toJson() => {
'_id': id,
'SKU': sku,
'name': name,
'category': category.toJson(), // Ensure Category has a proper toJson method
'brand': brand.toJson(), // Ensure Brand has a proper toJson method
'price': price,
'GST': gst,
'HSN_Code': hsnCode,
'description': description,
'product_Status': productStatus,
'addedBy': {
'_id': id, // Assuming the addedBy is represented by the id
'name': addedBy // If addedBy is just a name, use it directly here
},
'image': image,
'createdAt': createdAt.toIso8601String(),
'updatedAt': updatedAt.toIso8601String(),
'__v': v,
'count': count,
};
factory OrderItem.fromJson(Map<String, dynamic> json) => OrderItem(
id: json['_id'],
sku: json['SKU'],
name: json['name'],
price: json['price'].toDouble(),
gst: json['GST'].toDouble(),
hsnCode: json['HSN_Code'],
description: json['description'],
productStatus: json['product_Status'],
addedBy: json['addedBy']['name'], // Assuming addedBy has a 'name' key
image: List<String>.from(json['image']),
createdAt: DateTime.parse(json['createdAt']),
updatedAt: DateTime.parse(json['updatedAt']),
count: json['count'],
category: Category.fromJson(json['category']),
brand: Brand.fromJson(json['brand']),
v: json['__v'],
);
@override
String toString() {
return 'OrderItem(id: $id, sku: $sku, name: $name, price: $price, gst: $gst, hsnCode: $hsnCode, description: $description, productStatus: $productStatus, addedBy: $addedBy, image: $image, createdAt: $createdAt, updatedAt: $updatedAt, count: $count, category: $category, brand: $brand, v: $v)';
}
}
// class Brand {
// String id;
// String brandName;
//
// Brand({
// required this.id,
// required this.brandName,
// });
//
// factory Brand.fromJson(Map<String, dynamic> json) => Brand(
// id: json["_id"],
// brandName: json["brandName"],
// );
//
// Map<String, dynamic> toJson() => {
// "_id": id,
// "brandName": brandName,
// };
// }
//
// class Category {
// String id;
// String categoryName;
//
// Category({
// required this.id,
// required this.categoryName,
// });
//
// factory Category.fromJson(Map<String, dynamic> json) => Category(
// id: json["_id"],
// categoryName: json["categoryName"],
// );
//
// Map<String, dynamic> toJson() => {
// "_id": id,
// "categoryName": categoryName,
// };
// }

View File

@ -0,0 +1,130 @@
// import 'brand_model.dart';
// import 'category_model.dart';
//
// class OrderItem {
// final String id;
// final String sku;
// final String name;
// final Category category;
// final Brand brand;
// final double price;
// final double gst;
// final int hsnCode;
// final String description;
// final String productStatus;
// final String addedBy;
// final List<String> image;
// final DateTime createdAt;
// final DateTime updatedAt;
// final int count;
//
// OrderItem({
// required this.id,
// required this.sku,
// required this.name,
// required this.category,
// required this.brand,
// required this.price,
// required this.gst,
// required this.hsnCode,
// required this.description,
// required this.productStatus,
// required this.addedBy,
// required this.image,
// required this.createdAt,
// required this.updatedAt,
// required this.count,
// });
//
// factory OrderItem.fromJson(Map<String, dynamic> json) {
// return OrderItem(
// id: json['_id'],
// sku: json['SKU'],
// name: json['name'],
// category: Category.fromJson(json['category']),
// brand: Brand.fromJson(json['brand']),
// price: json['price'].toDouble(),
// gst: json['GST'].toDouble(),
// hsnCode: json['HSN_Code'],
// description: json['description'],
// productStatus: json['product_Status'],
// addedBy: json['addedBy'],
// image: List<String>.from(json['image'] ?? []),
// createdAt: DateTime.parse(json['createdAt']),
// updatedAt: DateTime.parse(json['updatedAt']),
// count: json['count'],
// );
// }
//
// Map<String, dynamic> toJson() {
// return {
// '_id': id,
// 'SKU': sku,
// 'name': name,
// 'category': category,
// 'brand': brand,
// 'price': price,
// 'GST': gst,
// 'HSN_Code': hsnCode,
// 'description': description,
// 'product_Status': productStatus,
// 'addedBy': addedBy,
// 'image': image,
// 'createdAt': createdAt.toIso8601String(),
// 'updatedAt': updatedAt.toIso8601String(),
// 'count': count,
// };
// }
// }
//
// //
// class Category {
// final String id;
// final String categoryName;
//
// Category({
// required this.id,
// required this.categoryName,
// });
//
// factory Category.fromJson(Map<String, dynamic> json) {
// return Category(
// id: json['_id'],
// categoryName: json['categoryName'],
// );
// }
// }
//
// class Brand {
// final String id;
// final String brandName;
//
// Brand({
// required this.id,
// required this.brandName,
// });
//
// factory Brand.fromJson(Map<String, dynamic> json) {
// return Brand(
// id: json['_id'],
// brandName: json['brandName'],
// );
// }
// }
// //
// // class AddedBy {
// // final String id;
// // final String name;
// //
// // AddedBy({
// // required this.id,
// // required this.name,
// // });
// //
// // factory AddedBy.fromJson(Map<String, dynamic> json) {
// // return AddedBy(
// // id: json['_id'],
// // name: json['name'],
// // );
// // }
// // }

View File

@ -5,6 +5,8 @@ class ProductModel {
final String image; final String image;
final String description; final String description;
final double price; final double price;
String? category1;
String? brandname;
final ProductCategory category; final ProductCategory category;
final String id; final String id;
int quantity; int quantity;
@ -15,7 +17,39 @@ class ProductModel {
required this.description, required this.description,
required this.price, required this.price,
required this.category, required this.category,
this.category1,
this.brandname,
required this.id, required this.id,
this.quantity = 1, this.quantity = 1,
}); });
// Factory constructor
factory ProductModel.fromJson(Map<String, dynamic> json) {
return ProductModel(
name: json['name']??"",
image: json['image']??"",
description: json['description']??"",
price: json['price']??"",
category: ProductCategory.values.firstWhere((e) => e.toString().split('.').last == json['category']),
category1: json['category1']??"",
brandname: json['brandname']??"",
id: json['id'],
quantity: json['quantity'] ?? 1,
);
}
// Optional: toJson method if you need to convert the model back to JSON
Map<String, dynamic> toJson() {
return {
'name': name,
'image': image,
'description': description,
'price': price,
'category': category.toString().split('.').last,
'category1': category1,
'brandname': brandname,
'id': id,
'quantity': quantity,
};
}
} }

View File

@ -0,0 +1,116 @@
import 'brand_model.dart';
import 'category_model.dart';
class Product {
final String id;
final String sku;
final String name;
final Category category;
final Brand brand;
final int price;
int quantity;
final int gst;
final int hsnCode;
final String description;
final String productStatus;
final String addedBy;
final DateTime createdAt;
Product({
required this.id,
required this.sku,
required this.name,
required this.category,
required this.brand,
required this.price,
this.quantity =1,
required this.gst,
required this.hsnCode,
required this.description,
required this.productStatus,
required this.addedBy,
required this.createdAt,
});
factory Product.fromJson(Map<String, dynamic> json) {
return Product(
id: json['_id'] as String,
sku: json['SKU'] as String,
name: json['name'] as String,
category:Category.fromJson(json['category'] as Map<String, dynamic>),
brand: Brand.fromJson(json['brand'] as Map<String, dynamic>),
price: json['price'] as int,
gst: json['GST'] as int,
hsnCode: json['HSN_Code'] as int,
description: json['description'] ?? '',
productStatus: json['product_Status'] as String,
addedBy: json['addedBy']['name'] as String,
createdAt: DateTime.parse(json['createdAt'] as String),
);
}
// Method to convert a Product to JSON
Map<String, dynamic> toJson() {
return {
'_id': id,
'SKU': sku,
'name': name,
'category':toJson(),
'brand':toJson(),
'price': price,
'GST': gst,
'HSN_Code': hsnCode,
'description': description,
'product_Status': productStatus,
'addedBy': {
'name': addedBy,
},
'createdAt': createdAt.toIso8601String(),
};
}
// Override toString method for easy printing of Product details
@override
String toString() {
return 'Product(id: $id, sku: $sku, name: $name, category: $category, '
'brand: $brand, price: $price, quantity: $quantity, gst: $gst, '
'hsnCode: $hsnCode, description: $description, productStatus: $productStatus, '
'addedBy: $addedBy, createdAt: $createdAt)';
}
}
// class Category {
// final String id;
// final String categoryName;
//
// Category({
// required this.id,
// required this.categoryName,
// });
//
// factory Category.fromJson(Map<String, dynamic> json) {
// return Category(
// id: json['_id'],
// categoryName: json['categoryName'],
// );
// }
// }
//
// class Brand {
// final String id;
// final String brandName;
//
// Brand({
// required this.id,
// required this.brandName,
// });
//
// factory Brand.fromJson(Map<String, dynamic> json) {
// return Brand(
// id: json['_id'],
// brandName: json['brandName'],
// );
// }
// }

View File

@ -16,11 +16,11 @@ class UserModel {
// Factory constructor to create an instance of UserModel from a JSON map // Factory constructor to create an instance of UserModel from a JSON map
factory UserModel.fromJson(Map<String, dynamic> json) { factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel( return UserModel(
id: json['_id'] as String, id: json['_id'] ??"",
name: json['name'] as String, name: json['name'] ??"Sarita",
uniqueId: json['uniqueId'] as String, uniqueId: json['uniqueId'] ??"1234",
email: json['email'] as String, email: json['email'] ??"",
isVerified: json['isVerified'] as bool, isVerified: json['isVerified'] as bool? ??false,
); );
} }
@ -34,4 +34,10 @@ class UserModel {
'isVerified': isVerified, 'isVerified': isVerified,
}; };
} }
// Override toString() to provide a readable output
@override
String toString() {
return 'UserModel{id: $id, name: $name, uniqueId: $uniqueId, email: $email, isVerified: $isVerified}';
}
} }

View File

@ -132,6 +132,7 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
onPressed: () => authController.forgotpass(), onPressed: () => authController.forgotpass(),
isLoading: authController.isLoading.value, isLoading: authController.isLoading.value,
), ),
], ],
), ),

View File

@ -85,7 +85,7 @@ class _HomeScreenState extends State<HomeScreen> {
HomeCard( HomeCard(
title: 'Order Management', title: 'Order Management',
onTap: () => Get.to( onTap: () => Get.to(
() => const OrderManagementScreen(), () => OrderManagementScreen(),
), ),
), ),
HomeCard( HomeCard(

View File

@ -1,36 +1,174 @@
import 'package:cheminova/models/product_model.dart'; import 'dart:ffi';
import 'package:cheminova/screens/order/order_confermation_screen.dart'; import 'package:cheminova/controller/get_order_placed_controller.dart';
import 'package:cheminova/widgets/input_field.dart'; import 'package:cheminova/models/added_by_model.dart';
import 'package:cheminova/widgets/my_drawer.dart'; import 'package:cheminova/models/category_model.dart';
import 'package:cheminova/widgets/product_card.dart'; import 'package:cheminova/utils/show_snackbar.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../controller/cart_controller.dart';
import '../../controller/place_order_controller.dart';
import '../../controller/place_order_service.dart';
import '../../controller/product_controller.dart';
import '../../controller/product_service.dart';
import '../../models/brand_model.dart';
import '../../models/oder_place_model.dart';
import '../../models/product_model1.dart';
import '../../widgets/my_drawer.dart';
import '../../widgets/product_card.dart';
import 'order_confermation_screen.dart';
class CheckoutScreen extends StatefulWidget { class CheckoutScreen extends StatefulWidget {
const CheckoutScreen({super.key}); final Product? productModel;
PlacedOrderModel? placeOrder;
CheckoutScreen({super.key, this.productModel, this.placeOrder});
@override @override
State<CheckoutScreen> createState() => _CheckoutScreenState(); State<CheckoutScreen> createState() => _CheckoutScreenState();
} }
class _CheckoutScreenState extends State<CheckoutScreen> { class _CheckoutScreenState extends State<CheckoutScreen> {
final TextEditingController _addressController = TextEditingController(); final CartController _cartController = Get.put(CartController());
final TextEditingController _contactController = TextEditingController(); final ProductService _productService = ProductService();
final ProductController _productController = Get.put(ProductController());
final OrderPlacedController _orderPlacedController =
Get.put(OrderPlacedController());
final GetPlacedOrderController _getPlacedOrderController = Get.put(GetPlacedOrderController());
final List<ProductModel> _checkoutList = [ int currentPage = 1;
ProductModel( String _groupValue = "cheque";
id: "1",
image: 'assets/images/product.png', final List<String> _addressList = [
name: "Product 1", 'Home - 123 Street, City',
category: ProductCategory.food, 'Office - 456 Avenue, City',
description: 'Product 1 description', 'Warehouse - 789 Blvd, City',
price: 100,
),
]; ];
String _groupValue = "Credit Card"; String? _selectedShippingAddress;
String? _selectedBillingAddress;
@override
void initState() {
super.initState();
// _getOrder();
_loadSelectedAddress();
_loadSelectedPaymentMode();
if (_addressList.isNotEmpty) {
_selectedShippingAddress = _addressList.first;
_selectedBillingAddress = _addressList.first;
}
}
void _saveSelectedAddress() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('selectedShippingAddress', _selectedShippingAddress!);
await prefs.setString('selectedBillingAddress', _selectedBillingAddress!);
}
void _onShippingAddressChanged(String? value) {
setState(() {
_selectedShippingAddress = value;
});
_saveSelectedAddress();
}
void _onBillingAddressChanged(String? value) {
setState(() {
_selectedBillingAddress = value;
});
_saveSelectedAddress();
}
void _loadSelectedAddress() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_selectedShippingAddress =
prefs.getString('selectedShippingAddress') ?? _addressList.first;
_selectedBillingAddress =
prefs.getString('selectedBillingAddress') ?? _addressList.first;
});
}
void _onPaymentModeChanged(String? value) {
setState(() {
_groupValue = value!;
});
_saveSelectedPaymentMode();
}
void _saveSelectedPaymentMode() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('selectedPaymentMode', _groupValue);
}
void _loadSelectedPaymentMode() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_groupValue = prefs.getString('selectedPaymentMode') ?? 'cheque';
});
}
// void _getOrder(){
// final details = _getPlacedOrderController.getOrder(widget.productModel!.id);
// print("dffgfg,$details");
// }
void _onPlaceOrder() async {
try {
// Map the cart items (Product) to OrderItem objects
List<OrderItem> orderItems = _cartController.cartList.map<OrderItem>((product) {
return OrderItem(
id: product.id,
name: product.name,
price: product.price.toDouble(),
sku: product.sku,
gst: product.gst.toDouble(),
hsnCode: product.hsnCode,
description: product.description,
productStatus: product.productStatus,
image: [],
createdAt: product.createdAt,
updatedAt: product.createdAt,
count: product.quantity,
//category:product.category,
category:Category(id: product.category.id, categoryName: product.category.categoryName),
// brand:product.brand,
brand:Brand(id: product.brand.id, brandName: product.brand.brandName),
v: 0, addedBy: product.addedBy,
);
}).toList();
// Update the placedOrder1 value
_orderPlacedController.placedOrder1.value= PlacedOrderModel(
paymentMode: _groupValue,
shipTo: _selectedShippingAddress!,
billTo: _selectedBillingAddress!,
orderItems: orderItems,
gstTotal: _cartController.gstTotal.value,
grandTotal: _cartController.grandTotal.value,
subtotal: _cartController.subtotal.value,
);
await _orderPlacedController.placeOrder();
if (_orderPlacedController.isLoading.value) {
showSnackbar("OderPlaced Successfully");
Get.to(() => OrderConfermationScreen(
placedOrder: _orderPlacedController.placedOrder1.value,
));
}
} catch (e) {
print("PlaceOrderScreen error: $e");
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -63,9 +201,7 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
), ),
), ),
], ],
title: const Text( title: const Text("Checkout"),
"Checkout",
),
), ),
drawer: const MyDrawer(), drawer: const MyDrawer(),
body: Stack( body: Stack(
@ -78,9 +214,7 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
SafeArea( SafeArea(
child: Column( child: Column(
children: [ children: [
SizedBox( SizedBox(height: Get.height * 0.02),
height: Get.height * 0.02,
),
Card( Card(
margin: EdgeInsets.symmetric(horizontal: Get.width * 0.05), margin: EdgeInsets.symmetric(horizontal: Get.width * 0.05),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@ -106,15 +240,37 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
), ),
), ),
), ),
InputField( SizedBox(height: 5,),
hintText: 'Address:', DropdownButtonFormField<String>(
labelText: 'Address:', decoration: InputDecoration(
controller: _addressController, labelText: 'Shipping Address:',
hintText: 'Select Shipping Address',
border: OutlineInputBorder(),
),
value: _selectedShippingAddress,
items: _addressList.map((String address) {
return DropdownMenuItem<String>(
value: address,
child: Text(address),
);
}).toList(),
onChanged: _onShippingAddressChanged,
), ),
InputField( SizedBox(height: Get.height * 0.02),
hintText: 'Contact:', DropdownButtonFormField<String>(
labelText: 'Contact:', decoration: InputDecoration(
controller: _contactController, labelText: 'Billing Address:',
hintText: 'Select Billing Address',
border: OutlineInputBorder(),
),
value: _selectedBillingAddress,
items: _addressList.map((String address) {
return DropdownMenuItem<String>(
value: address,
child: Text(address),
);
}).toList(),
onChanged: _onBillingAddressChanged,
), ),
Padding( Padding(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
@ -136,42 +292,30 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
SizedBox( SizedBox(
height: Get.height * 0.035, height: Get.height * 0.035,
child: RadioListTile( child: RadioListTile(
title: const Text("Credit Card"), title: const Text("cheque"),
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
value: "Credit Card", value: "cheque",
groupValue: _groupValue, groupValue: _groupValue,
onChanged: (value) { onChanged: _onPaymentModeChanged,
setState(() {
_groupValue = value.toString();
});
},
), ),
), ),
SizedBox( SizedBox(
height: Get.height * 0.035, height: Get.height * 0.035,
child: RadioListTile( child: RadioListTile(
title: const Text("Net Banking"), title: const Text("online-transfer"),
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
value: "Net Banking", value: "online-transfer",
groupValue: _groupValue, groupValue: _groupValue,
onChanged: (value) { onChanged: _onPaymentModeChanged,
setState(() {
_groupValue = value.toString();
});
},
), ),
), ),
SizedBox( SizedBox(
child: RadioListTile( child: RadioListTile(
title: const Text("Cash on Delivery"), title: const Text("credit"),
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
value: "Cash on Delivery", value: "credit",
groupValue: _groupValue, groupValue: _groupValue,
onChanged: (value) { onChanged: _onPaymentModeChanged,
setState(() {
_groupValue = value.toString();
});
},
), ),
), ),
], ],
@ -198,58 +342,68 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
child: Padding( child: Padding(
padding: EdgeInsets.all(Get.width * 0.02), padding: EdgeInsets.all(Get.width * 0.02),
child: ListView.builder( child: ListView.builder(
padding: EdgeInsets.zero, itemCount: _cartController.cartList.length,
itemCount: 10, itemBuilder: (context, index) {
itemBuilder: (context, index) => final cartItem =
ProductCard( _cartController.cartList[index];
product: _checkoutList[0], return ProductCard(
isCheckout: true, productModel:_cartController.cartList[index] ,
), isCheckout: true,
quantity: _cartController.cartList[0].quantity,
// ListTile(
// title: Text(cartItem.name ?? 'N/A'),
// subtitle: Text(
// 'Quantity: ${cartItem.quantity}'),
// trailing: Text(
// 'Price: \${cartItem.price.toStringAsFixed(2)}'),
// );
);},
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsets.all(Get.width * 0.04), padding: EdgeInsets.all(Get.width * 0.02),
child: Text( child: Column(
'Total Price: ₹ 1000.00', crossAxisAlignment: CrossAxisAlignment.start,
style: GoogleFonts.roboto( children: [
fontSize: Get.width * 0.05, Text(
fontWeight: FontWeight.w700, 'Subtotal: \${_cartController.subtotal.value.toStringAsFixed(2)}'),
color: Colors.black, Text(
), 'GST: \${_cartController.gstTotal.value.toStringAsFixed(2)}'),
Text(
'Grand Total: \${_cartController.grandTotal.value.toStringAsFixed(2)}'),
],
), ),
), ),
], ],
), ),
), ),
], ],
), ),
), ),
), ),
SizedBox( SizedBox(height: 10.0,),
height: Get.height * 0.025, Row(
), mainAxisAlignment: MainAxisAlignment.center,
SizedBox( children: [
width: Get.width * 0.9, ElevatedButton(
height: Get.height * 0.06, onPressed: _onPlaceOrder,
child: ElevatedButton( style: ElevatedButton.styleFrom(
onPressed: () => foregroundColor: Colors.white,
Get.to(() => const OrderConfermationScreen()), backgroundColor: const Color(0xFF00784C),
style: ElevatedButton.styleFrom( padding: EdgeInsets.symmetric(
foregroundColor: Colors.white, horizontal: Get.width * 0.20,
backgroundColor: const Color(0xFF00784C), vertical: Get.height * 0.02),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
),
), ),
child: const Text("Place Order"),
), ),
child: Text( ],
"Place Order",
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.w600,
),
),
),
), ),
], ],
), ),

View File

@ -1,4 +1,6 @@
import 'package:cheminova/controller/get_order_placed_controller.dart';
import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/utils/show_snackbar.dart';
import 'package:cheminova/widgets/my_drawer.dart'; import 'package:cheminova/widgets/my_drawer.dart';
import 'package:cheminova/widgets/product_card.dart'; import 'package:cheminova/widgets/product_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -6,8 +8,15 @@ import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart';
import '../../controller/place_order_controller.dart';
import '../../models/oder_place_model.dart';
import '../../models/product_model1.dart';
class OrderConfermationScreen extends StatefulWidget { class OrderConfermationScreen extends StatefulWidget {
const OrderConfermationScreen({super.key}); Product? productModel;
PlacedOrderModel? placedOrder;
OrderConfermationScreen({super.key,this.productModel,this.placedOrder});
@override @override
State<OrderConfermationScreen> createState() => State<OrderConfermationScreen> createState() =>
@ -15,18 +24,28 @@ class OrderConfermationScreen extends StatefulWidget {
} }
class _OrderConfermationScreenState extends State<OrderConfermationScreen> { class _OrderConfermationScreenState extends State<OrderConfermationScreen> {
final List<ProductModel> _checkoutList = [ final CartController _cartController = Get.put(CartController());
ProductModel( final OrderPlacedController _placedController = Get.put(OrderPlacedController());
id: "1", final GetPlacedOrderController _getPlacedOrderController = Get.put(GetPlacedOrderController());
image: 'assets/images/product.png', // final List<ProductModel> _checkoutList = [
name: "Product 1", // ProductModel(
category: ProductCategory.food, // id: "1",
description: 'Product 1 description', // image: 'assets/images/product.png',
price: 100.00, // name: "Product 1",
), // category: ProductCategory.food,
]; // description: 'Product 1 description',
// price: 100.00,
// ),
// ];
void _getOrder(){
final details = _getPlacedOrderController.getOrder(_cartController.cartList[0].id);
showSnackbar("Get Placed Order Sucessfully");
print("dffgfg,$details");
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final orderItems = _placedController.placedOrder1;
return Scaffold( return Scaffold(
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
appBar: AppBar( appBar: AppBar(
@ -94,7 +113,7 @@ class _OrderConfermationScreenState extends State<OrderConfermationScreen> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Order Number: 123456", "Order Number:1234",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: Get.width * 0.04, fontSize: Get.width * 0.04,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
@ -124,24 +143,27 @@ class _OrderConfermationScreenState extends State<OrderConfermationScreen> {
padding: EdgeInsets.all(Get.width * 0.02), padding: EdgeInsets.all(Get.width * 0.02),
child: ListView.builder( child: ListView.builder(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: 10, itemCount: _cartController.cartList.length,
itemBuilder: (context, index) => itemBuilder: (context, index) =>
ProductCard( ProductCard(
product: _checkoutList[0], productModel:_cartController.cartList[index],
isCheckout: true, isCheckout: true,
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsets.all(Get.width * 0.04), padding: EdgeInsets.all(Get.width * 0.02),
child: Text( child: Column(
'Total Price: ₹ 1000.00', mainAxisAlignment: MainAxisAlignment.end,
style: GoogleFonts.roboto( children: [
fontSize: Get.width * 0.05, Text(
fontWeight: FontWeight.w700, 'Subtotal: \${_cartController.subtotal.value.toStringAsFixed(2)}'),
color: Colors.black, Text(
), 'GST: \${_cartController.gstTotal.value.toStringAsFixed(2)}'),
Text(
'Grand Total: \${_cartController.grandTotal.value.toStringAsFixed(2)}'),
],
), ),
), ),
], ],
@ -161,30 +183,30 @@ class _OrderConfermationScreenState extends State<OrderConfermationScreen> {
Card( Card(
child: SizedBox( child: SizedBox(
width: Get.width, width: Get.width,
height: Get.height * 0.2, height: Get.height * 0.1,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Address: Lorem Ipsum is simply dummy text of the printing and typesetting industry", "Address :${widget.placedOrder!.shipTo}",
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.w400,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Contact: +91 9123456789",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: Get.width * 0.04, fontSize: Get.width * 0.04,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
), ),
), ),
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: Text(
// "Contact: +91 9123456789",
// style: GoogleFonts.roboto(
// fontSize: Get.width * 0.04,
// fontWeight: FontWeight.w400,
// ),
// ),
// ),
], ],
), ),
), ),
@ -196,7 +218,7 @@ class _OrderConfermationScreenState extends State<OrderConfermationScreen> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Estimated Delivery Date: [Date]", "Estimated Delivery Date: 20 Sep 2024",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: Get.width * 0.04, fontSize: Get.width * 0.04,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
@ -205,10 +227,30 @@ class _OrderConfermationScreenState extends State<OrderConfermationScreen> {
), ),
), ),
), ),
], ],
), ),
), ),
), ),
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// ElevatedButton(
// onPressed:_getOrder,
// style: ElevatedButton.styleFrom(
// foregroundColor: Colors.white,
// backgroundColor: const Color(0xFF00784C),
// padding: EdgeInsets.symmetric(
// horizontal: Get.width * 0.20,
// vertical: Get.height * 0.02),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10),
// ),
// ),
// child: const Text("Confirm Order"),
// ),
// ],
// ),
], ],
), ),
), ),

View File

@ -6,24 +6,19 @@ import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart';
import '../../models/product_model1.dart';
class OrderFullfilmentScreen extends StatefulWidget { class OrderFullfilmentScreen extends StatefulWidget {
const OrderFullfilmentScreen({super.key}); final Product? productModel;
const OrderFullfilmentScreen({super.key,required this.productModel});
@override @override
State<OrderFullfilmentScreen> createState() => _OrderFullfilmentScreenState(); State<OrderFullfilmentScreen> createState() => _OrderFullfilmentScreenState();
} }
class _OrderFullfilmentScreenState extends State<OrderFullfilmentScreen> { class _OrderFullfilmentScreenState extends State<OrderFullfilmentScreen> {
final List<ProductModel> _checkoutList = [ final CartController _cartController = Get.put(CartController());
ProductModel(
id: "1",
image: 'assets/images/image_1.png',
name: "Product 1",
category: ProductCategory.food,
description: 'Product 1 description',
price: 100,
),
];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -153,7 +148,7 @@ class _OrderFullfilmentScreenState extends State<OrderFullfilmentScreen> {
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: 10, itemCount: 10,
itemBuilder: (context, index) => ProductCard( itemBuilder: (context, index) => ProductCard(
product: _checkoutList[0], productModel:widget.productModel,
isCheckout: true, isCheckout: true,
), ),
), ),

View File

@ -1,31 +1,38 @@
import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/screens/order_management/order_fullfilment_screen.dart'; import 'package:cheminova/screens/order_management/order_fullfilment_screen.dart';
import 'package:cheminova/widgets/product_card.dart'; import 'package:cheminova/widgets/product_card.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart';
import '../../models/product_model1.dart';
class OrderManagementDetailScreen extends StatefulWidget { class OrderManagementDetailScreen extends StatefulWidget {
const OrderManagementDetailScreen({super.key}); final Product? productModel;
const OrderManagementDetailScreen({super.key,required this.productModel});
@override @override
State<OrderManagementDetailScreen> createState() => State<OrderManagementDetailScreen> createState() =>
_OrderManagementDetailScreenState(); _OrderManagementDetailScreenState();
} }
class _OrderManagementDetailScreenState class _OrderManagementDetailScreenState
extends State<OrderManagementDetailScreen> { extends State<OrderManagementDetailScreen> {
final List<ProductModel> _checkoutList = [ final CartController _cartController = Get.put(CartController());
ProductModel( // final List<ProductModel> _checkoutList = [
id: "1", // ProductModel(
image: 'assets/images/image_1.png', // id: "1",
name: "Product 1", // image: 'assets/images/image_1.png',
category: ProductCategory.food, // name: "Product 1",
description: 'Product 1 description', // category: ProductCategory.food,
price: 100, // description: 'Product 1 description',
), // price: 100,
]; // ),
// ];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -155,7 +162,7 @@ class _OrderManagementDetailScreenState
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: 10, itemCount: 10,
itemBuilder: (context, index) => ProductCard( itemBuilder: (context, index) => ProductCard(
product: _checkoutList[0], productModel: widget.productModel,
isCheckout: true, isCheckout: true,
), ),
), ),
@ -236,7 +243,9 @@ class _OrderManagementDetailScreenState
height: Get.height * 0.06, height: Get.height * 0.06,
child: ElevatedButton( child: ElevatedButton(
onPressed: () => Get.to( onPressed: () => Get.to(
() => const OrderFullfilmentScreen(), () => OrderFullfilmentScreen(
productModel:widget.productModel ,
),
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, foregroundColor: Colors.white,

View File

@ -6,8 +6,11 @@ import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../models/product_model1.dart';
class OrderManagementScreen extends StatefulWidget { class OrderManagementScreen extends StatefulWidget {
const OrderManagementScreen({super.key}); Product? productModel;
OrderManagementScreen({super.key,this.productModel});
@override @override
State<OrderManagementScreen> createState() => _OrderManagementScreenState(); State<OrderManagementScreen> createState() => _OrderManagementScreenState();
@ -177,7 +180,9 @@ class _OrderManagementScreenState extends State<OrderManagementScreen> {
child: ElevatedButton( child: ElevatedButton(
onPressed: () => Get.to( onPressed: () => Get.to(
() => () =>
const OrderManagementDetailScreen(), OrderManagementDetailScreen(
productModel:widget.productModel,
),
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, foregroundColor: Colors.white,

View File

@ -1,3 +1,4 @@
import 'package:cheminova/models/oder_place_model.dart';
import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/screens/order/checkout_screen.dart'; import 'package:cheminova/screens/order/checkout_screen.dart';
import 'package:cheminova/widgets/my_drawer.dart'; import 'package:cheminova/widgets/my_drawer.dart';
@ -5,27 +6,31 @@ import 'package:cheminova/widgets/product_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get/get_core/get_core.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart';
import '../../models/product_model1.dart';
class CartScreen extends StatefulWidget { class CartScreen extends StatefulWidget {
const CartScreen({super.key}); Product? productModel;
PlacedOrderModel? placedOrder;
CartScreen({super.key, this.productModel,this.placedOrder});
@override @override
State<CartScreen> createState() => _CartScreenState(); State<CartScreen> createState() => _CartScreenState();
} }
class _CartScreenState extends State<CartScreen> { class _CartScreenState extends State<CartScreen> {
final List<ProductModel> _cartList = [ final CartController _cartController = Get.find<CartController>();
ProductModel(
id: "1", // @override
image: 'assets/images/product.png', void initState() {
name: "Product 1", super.initState();
category: ProductCategory.food, if (widget.productModel != null) {
description: 'Product 1 description', _cartController.addToCart(widget.productModel);
price: 100, }
), }
];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -89,29 +94,59 @@ class _CartScreenState extends State<CartScreen> {
children: [ children: [
SizedBox( SizedBox(
height: Get.height * 0.6, height: Get.height * 0.6,
child: ListView.builder( child: Obx(() {
padding: EdgeInsets.zero, return ListView.builder(
itemCount: 10, padding: EdgeInsets.zero,
itemBuilder: (context, index) => ProductCard( itemCount: _cartController.cartList.length,
product: _cartList[0], itemBuilder: (context, index) => ProductCard(
isInCart: true, productModel: _cartController.cartList[index],
), isInCart: true,
), placedOrder:widget.placedOrder,
),
);
}),
), ),
const SizedBox( const SizedBox(
height: 10, height: 10,
), ),
Text( Obx(() {
"Total Price: ₹ Total", return Text(
style: GoogleFonts.roboto( "Subtotal Price: ₹ ${_cartController.subtotal.value}",
fontSize: 20, style: GoogleFonts.roboto(
fontWeight: FontWeight.w700, fontSize: 15,
color: Colors.white, fontWeight: FontWeight.w700,
), color: Colors.white,
), ),
const SizedBox( );
height: 16,
), }),
// const SizedBox(
// height: 16,
// ),
Obx(() {
return Text(
"gstTotal Price: ₹ ${_cartController.gstTotal.value}",
style: GoogleFonts.roboto(
fontSize: 15,
fontWeight: FontWeight.w700,
color: Colors.white,
),
);
}),
Obx(() {
return Text(
"grandTotal Price: ₹ ${_cartController.grandTotal.value}",
style: GoogleFonts.roboto(
fontSize: 15,
fontWeight: FontWeight.w700,
color: Colors.white,
),
);
}),
], ],
), ),
), ),
@ -123,7 +158,10 @@ class _CartScreenState extends State<CartScreen> {
width: Get.width * 0.9, width: Get.width * 0.9,
height: Get.height * 0.06, height: Get.height * 0.06,
child: ElevatedButton( child: ElevatedButton(
onPressed: () => Get.to(() => const CheckoutScreen()), onPressed: () => Get.to(() => CheckoutScreen(
productModel:widget.productModel
)),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, foregroundColor: Colors.white,
backgroundColor: const Color(0xFF00784C), backgroundColor: const Color(0xFF00784C),

View File

@ -1,10 +1,14 @@
import 'package:cheminova/models/product_model1.dart';
import 'package:cheminova/screens/product/cart_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart';
import '../../widgets/my_drawer.dart'; import '../../widgets/my_drawer.dart';
import '../../widgets/product_card.dart'; import '../../widgets/product_card.dart';
import '../../controller/product_service.dart'; import '../../controller/product_service.dart';
import '../../models/product_model.dart'; // Import your ProductModel
class ProductCatalogScreen extends StatefulWidget { class ProductCatalogScreen extends StatefulWidget {
const ProductCatalogScreen({super.key}); const ProductCatalogScreen({super.key});
@ -16,24 +20,27 @@ class ProductCatalogScreen extends StatefulWidget {
class _ProductCatalogScreenState extends State<ProductCatalogScreen> { class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
final ProductService _productService = ProductService(); final ProductService _productService = ProductService();
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
List<Map<String, dynamic>> _products = []; final CartController cartController = Get.put(CartController());
List<Product> _products = []; // Use ProductModel here
List<Map<String, dynamic>> _categories = []; List<Map<String, dynamic>> _categories = [];
int _currentPage = 1; int _currentPage = 1;
bool _isLoading = false; bool _isLoading = false;
bool _hasMoreData = true; bool _hasMoreData = true;
String? _selectedCategory; // Default to null to handle 'All' explicitly String? _selectedCategory;
String? _selectedPriceRange; String? _selectedPriceRange;
String? _selectedAvailability; String? _selectedAvailability;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_fetchCategories(); // Fetch categories first to set initial filter _fetchCategories();
_fetchProducts(); // Fetch products after setting initial filters _fetchProducts();
_scrollController.addListener(() { _scrollController.addListener(() {
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent && if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent &&
!_isLoading && !_isLoading &&
_hasMoreData) { _hasMoreData) {
_fetchMoreProducts(); _fetchMoreProducts();
@ -46,13 +53,13 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
_isLoading = true; _isLoading = true;
}); });
// Adjust the category parameter based on the selected category
final category = _selectedCategory == 'All' ? null : _selectedCategory; final category = _selectedCategory == 'All' ? null : _selectedCategory;
final products = await _productService.getProduct(_currentPage, category: category); final products = await _productService.getProduct(
_currentPage, category: category);
setState(() { setState(() {
if (products != null) { if (products != null) {
_products.addAll(products); _products.addAll(products); // Assuming products is a List<ProductModel>
_hasMoreData = products.isNotEmpty; _hasMoreData = products.isNotEmpty;
} }
_isLoading = false; _isLoading = false;
@ -64,9 +71,8 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
if (categories != null) { if (categories != null) {
setState(() { setState(() {
_categories = categories; _categories = categories;
// Add "All" option
_categories.insert(1, {'categoryName': 'All'}); _categories.insert(1, {'categoryName': 'All'});
_selectedCategory = 'All'; // Set initial selected category to "All" _selectedCategory = 'All';
}); });
} }
} }
@ -131,11 +137,34 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
), ),
actions: [ actions: [
GestureDetector( GestureDetector(
onTap: () => Get.back(), onTap: () => Get.to(CartScreen()),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: SvgPicture.asset( child: Stack(
'assets/svg/back_arrow.svg', children: [
Icon(Icons.shopping_cart, size: 30,),
// Cart count display
Positioned(
right: 0,
child: Obx(() =>
cartController.cartCount.value > 0
? Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text(
'${cartController.cartCount.value}',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
)
: SizedBox.shrink()),
),
],
), ),
), ),
), ),
@ -157,7 +186,6 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
child: Column( child: Column(
children: [ children: [
SizedBox(height: Get.height * 0.02), SizedBox(height: Get.height * 0.02),
// Search Bar
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 18.0), padding: const EdgeInsets.symmetric(horizontal: 18.0),
child: TextField( child: TextField(
@ -212,10 +240,8 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
shrinkWrap: true, shrinkWrap: true,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: 3, itemCount: 3,
itemBuilder: (context, index) => Padding( itemBuilder: (context, index) =>
padding: const EdgeInsets.symmetric(horizontal: 4), _buildFilterDropdown(index),
child: _buildFilterDropdown(index),
),
), ),
), ),
SizedBox( SizedBox(
@ -223,16 +249,20 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
child: ListView.builder( child: ListView.builder(
controller: _scrollController, controller: _scrollController,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: _products.length + (_isLoading ? 1 : 0), itemCount: _products.length +
(_isLoading ? 1 : 0),
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (index >= _products.length) { if (index >= _products.length) {
print("Product length $_products"); print("Product length $_products");
return const Center(child: CircularProgressIndicator()); return const Center(
child: CircularProgressIndicator());
} }
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(
vertical: 8),
child: ProductCard( child: ProductCard(
productModel: _products[index], productModel: _products[index],
// Use ProductModel here
), ),
); );
}, },
@ -254,57 +284,89 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
Widget _buildFilterDropdown(int index) { Widget _buildFilterDropdown(int index) {
switch (index) { switch (index) {
case 0: case 0:
return DropdownButton<String>( return _buildStyledDropdown(
value: _selectedCategory, value: _selectedCategory,
hint: const Text("Category"), onChanged: _onCategoryChanged,
onChanged: (value) { items: _categories.map((category) {
if (value != null) {
_onCategoryChanged(value);
}
},
items: _categories.map<DropdownMenuItem<String>>((category) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
value: category['categoryName'], value: category['categoryName'],
child: Text(category['categoryName']), child: Text(category['categoryName']),
); );
}).toList(), }).toList(),
hint: "Category",
); );
case 1: // case 1:
return DropdownButton<String>( // return _buildStyledDropdown(
value: _selectedPriceRange, // value: _selectedPriceRange,
hint: const Text("Price Range"), // onChanged: (value) {
onChanged: (value) { // setState(() {
setState(() { // _selectedPriceRange = value;
_selectedPriceRange = value; // });
}); // },
}, // items: [
items: <String>['\$0-\$50', '\$51-\$100', '\$101-\$150'] // const DropdownMenuItem<String>(
.map<DropdownMenuItem<String>>((String value) { // value: "Under ₹50",
return DropdownMenuItem<String>( // child: Text("Under ₹50"),
value: value, // ),
child: Text(value), // const DropdownMenuItem<String>(
); // value: "₹50 - ₹100",
}).toList(), // child: Text("₹50 - ₹100"),
); // ),
case 2: // const DropdownMenuItem<String>(
return DropdownButton<String>( // value: "Above ₹100",
value: _selectedAvailability, // child: Text("Above ₹100"),
hint: const Text("Availability"), // ),
onChanged: (value) { // ],
setState(() { // hint: "Price Range",
_selectedAvailability = value; // );
}); // case 2:
}, // return _buildStyledDropdown(
items: <String>['In Stock', 'Out of Stock'] // value: _selectedAvailability,
.map<DropdownMenuItem<String>>((String value) { // onChanged: (value) {
return DropdownMenuItem<String>( // setState(() {
value: value, // _selectedAvailability = value;
child: Text(value), // });
); // },
}).toList(), // items: [
); // const DropdownMenuItem<String>(
// value: "In Stock",
// child: Text("In Stock"),
// ),
// const DropdownMenuItem<String>(
// value: "Out of Stock",
// child: Text("Out of Stock"),
// ),
// ],
// hint: "Availability",
// );
default: default:
return Container(); return const SizedBox();
} }
} }
Widget _buildStyledDropdown({
required String? value,
required ValueChanged<String?> onChanged,
required List<DropdownMenuItem<String>> items,
required String hint,
}) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
border: Border.all(color: Colors.grey.shade300),
color: Colors.white,
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: value,
onChanged: onChanged,
items: items,
hint: Text(hint),
icon: const Icon(Icons.arrow_drop_down),
),
),
);
}
} }

View File

@ -1,5 +1,7 @@
import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/models/product_model1.dart';
import 'package:cheminova/screens/order/checkout_screen.dart'; import 'package:cheminova/screens/order/checkout_screen.dart';
import 'package:cheminova/utils/show_snackbar.dart';
import 'package:cheminova/widgets/my_drawer.dart'; import 'package:cheminova/widgets/my_drawer.dart';
import 'package:cheminova/widgets/product_card.dart'; import 'package:cheminova/widgets/product_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -7,10 +9,11 @@ import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart';
import 'cart_screen.dart'; import 'cart_screen.dart';
class ProductDetailScreen extends StatefulWidget { class ProductDetailScreen extends StatefulWidget {
final Map<String, dynamic>? productModel; Product? productModel;
ProductModel? product; ProductModel? product;
ProductDetailScreen({super.key, this.product, this.productModel}); ProductDetailScreen({super.key, this.product, this.productModel});
@ -20,6 +23,7 @@ class ProductDetailScreen extends StatefulWidget {
} }
class _ProductDetailScreenState extends State<ProductDetailScreen> { class _ProductDetailScreenState extends State<ProductDetailScreen> {
final CartController _cartController = Get.put(CartController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -109,7 +113,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text( child: Text(
widget.productModel!['name'], widget.productModel!.name,
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -120,7 +124,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text( child: Text(
"${widget.productModel!['price'].toString()}", "${widget.productModel!.price.toString()}",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 24, fontSize: 24,
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
@ -131,7 +135,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text( child: Text(
widget.productModel!['category']['categoryName'], widget.productModel!.category!.categoryName,
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
@ -143,7 +147,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text( child: Text(
widget.productModel!['description'], widget.productModel!.description,
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
@ -162,9 +166,8 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
// Pass the product data to the CartScreen // Pass the product data to the CartScreen
Get.to(() => CartScreen( _cartController.addToCart(widget.productModel!);
// Pass the product in a list showSnackbar("Product Added to cart");
));
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, foregroundColor: Colors.white,

View File

@ -85,7 +85,7 @@ Future<BodyType?> commonApiService<BodyType>({
errorMessage = e.response?.data; errorMessage = e.response?.data;
} }
showSnackbar(errorMessage); //showSnackbar(errorMessage);
} catch (e) { } catch (e) {
print("exception $url $e"); print("exception $url $e");
} }

View File

@ -0,0 +1,7 @@
import 'package:logger/logger.dart';
final logger = Logger(
printer: PrettyPrinter(
lineLength: 500
)
);

View File

@ -23,31 +23,33 @@ class _MyDrawerState extends State<MyDrawer> {
SizedBox( SizedBox(
height: 150, height: 150,
child: Obx( child: Obx(
() => DrawerHeader( (){
decoration: const BoxDecoration( return DrawerHeader(
color: Colors.black87, decoration: const BoxDecoration(
), color: Colors.black87,
child: Column( ),
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ mainAxisAlignment: MainAxisAlignment.start,
Text( children: [
homeController.user.value?.name ?? "username", Text(
style: const TextStyle( homeController.user.value?.name?? "username",
color: Colors.white, style: const TextStyle(
fontSize: 18, color: Colors.white,
fontSize: 18,
),
), ),
), Text(
Text( homeController.user.value?.uniqueId?? 'Employee ID',
homeController.user.value?.uniqueId ?? 'Employee ID', style: const TextStyle(
style: const TextStyle( color: Colors.white,
color: Colors.white, fontSize: 20,
fontSize: 20, ),
), ),
), ],
], ),
), );
), },
), ),
), ),
ListTile( ListTile(

View File

@ -1,30 +1,52 @@
import 'package:cheminova/controller/cart_controller.dart';
import 'package:cheminova/models/oder_place_model.dart';
import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/screens/product/product_detail_screen.dart'; import 'package:cheminova/screens/product/product_detail_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
class ProductCard extends StatelessWidget { import '../models/product_model1.dart';
final Map<String, dynamic>? productModel; import '../screens/product/cart_screen.dart';
import '../utils/show_snackbar.dart';
class ProductCard extends StatefulWidget {
final Product? productModel;
PlacedOrderModel? placedOrder;
ProductModel? product; ProductModel? product;
final bool isInCart; final bool isInCart;
final bool isCheckout; final bool isCheckout;
final bool isConfirmation;
int? quantity;
ProductCard({ ProductCard({
super.key, super.key,
this.product, this.product,
this.quantity=1,
this.productModel, this.productModel,
this.placedOrder,
this.isInCart = false, this.isInCart = false,
this.isCheckout = false, this.isCheckout = false,
this.isConfirmation = false,
}); });
@override
State<ProductCard> createState() => _ProductCardState();
}
class _ProductCardState extends State<ProductCard> {
@override
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final CartController _cartController = Get.put(CartController());
bool showQuantity = widget.isInCart || widget.isCheckout || widget.isConfirmation;
bool isProductInCart = _cartController.cartList.contains(widget.productModel);
return GestureDetector( return GestureDetector(
onTap: () => isInCart || isCheckout onTap: () => widget.isInCart || widget.isCheckout
? null ? null
: Get.to(() => : Get.to(() =>
ProductDetailScreen(productModel: productModel)), ProductDetailScreen(productModel: widget.productModel)),
child: Card( child: Card(
child: Row( child: Row(
children: [ children: [
@ -52,29 +74,38 @@ class ProductCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
productModel!['name'], widget.productModel!.name,
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
Text( Text(
productModel!['category']['categoryName'], widget.productModel!.category!.categoryName,
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
), ),
Text( Text(
"${ productModel!['price'].toString()}0", "${ widget.productModel!.price.toString()}",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 22, fontSize: 22,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
), ),
isCheckout showQuantity
? Text(
"Quantity: ${widget.productModel!.quantity.toString()}",
style: GoogleFonts.roboto(
fontSize: 15,
fontWeight: FontWeight.w700,
),
)
: const SizedBox(),
widget.isCheckout
? const SizedBox() ? const SizedBox()
: isInCart : widget.isInCart
? Row( ? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -93,7 +124,13 @@ class ProductCard extends StatelessWidget {
height: 24, height: 24,
width: 24, width: 24,
child: ElevatedButton( child: ElevatedButton(
onPressed: () {}, onPressed: () {
_cartController.increaseQuantity(widget.productModel!);
setState(() {
widget.quantity = widget.productModel!.quantity;
});
},
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@ -111,7 +148,7 @@ class ProductCard extends StatelessWidget {
), ),
), ),
Text( Text(
productModel!['brand']['brandName'], "${widget.quantity}",
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 16, fontSize: 16,
@ -121,7 +158,13 @@ class ProductCard extends StatelessWidget {
height: 24, height: 24,
width: 24, width: 24,
child: ElevatedButton( child: ElevatedButton(
onPressed: () {}, onPressed: () {
_cartController.decreaseQuantity(widget.productModel!);
setState(() {
widget.quantity = widget.productModel!.quantity;
});
},
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@ -141,8 +184,11 @@ class ProductCard extends StatelessWidget {
], ],
), ),
), ),
SizedBox(width: 20.0,),
IconButton( IconButton(
onPressed: () {}, onPressed: () {
_cartController.removeFromCart(widget.productModel);
},
icon: const Icon( icon: const Icon(
Icons.delete_outline_rounded, Icons.delete_outline_rounded,
color: Colors.red, color: Colors.red,
@ -152,7 +198,12 @@ class ProductCard extends StatelessWidget {
) )
: ElevatedButton( : ElevatedButton(
onPressed: () { onPressed: () {
if (isProductInCart) {
showSnackbar("Product already added to cart");
} else {
_cartController.addToCart(widget.productModel!);
showSnackbar("Product added to cart successfully");
}
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, foregroundColor: Colors.white,

View File

@ -200,6 +200,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.0" version: "3.0.0"
logger:
dependency: "direct main"
description:
name: logger
sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:

View File

@ -41,6 +41,7 @@ dependencies:
dio: ^5.5.0+1 dio: ^5.5.0+1
http: ^1.2.2 http: ^1.2.2
shared_preferences: ^2.2.3 shared_preferences: ^2.2.3
logger: ^2.4.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: