orderlistcomplete

This commit is contained in:
2025-02-08 18:55:38 +05:30
parent 1c9c112a2f
commit c6a6ded51d
28 changed files with 2040 additions and 826 deletions

View File

@@ -7,6 +7,7 @@ import 'package:grocery_app/src/logic/provider/address_provider.dart';
import 'package:grocery_app/src/logic/provider/auth_provider.dart';
import 'package:grocery_app/src/logic/provider/bottom_navbar_provider.dart';
import 'package:grocery_app/src/logic/provider/home_provider.dart';
import 'package:grocery_app/src/logic/provider/order_provider.dart';
import 'package:grocery_app/src/logic/provider/profile_provider.dart';
import 'package:grocery_app/src/ui/splash/splash_screen.dart';
import 'package:grocery_app/utils/constants/color_constant.dart';
@@ -43,6 +44,8 @@ class MyApplication extends StatelessWidget {
ChangeNotifierProvider(create: (_) => BottomNavProvider()),
ChangeNotifierProvider(create: (_) => AddressProvider()),
ChangeNotifierProvider(create: (_) => ProfileProvider()),
ChangeNotifierProvider(create: (_) => OrderProvider()),
],
child: MaterialApp.router(
routerConfig: MyRoutes.router,

View File

@@ -25,15 +25,10 @@ class APIURL {
static const String refresh_token = "${BASE_URL}auth/refresh-token";
static const String uploadImage = "${BASE_URL}images/upload";
static const String updateProfile = "${BASE_URL}user/profile";
static const String paymentOrder = "${BASE_URL}payment/order";
static const String paymentOrder = "${BASE_URL}payment/initiate";
static const String paymentCODOrder = "${BASE_URL}orders";
static const String myOrder = "${BASE_URL}orders/my-orders";
static const String forgetPassword = "${BASE_URL}auth/forgot-password/vendor";
static const String verifyForgetPassword =
"${BASE_URL}auth/forgot-password-verify-otp/vendor";
@@ -45,7 +40,6 @@ class APIURL {
static const String createProduct = "${BASE_URL}products";
static const String deleteProduct = "${BASE_URL}products/";
static const String updateProduct = "${BASE_URL}products/";
}

View File

@@ -1,37 +1,29 @@
import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:grocery_app/src/core/network_services/dio_client.dart';
import 'package:grocery_app/src/logic/repo/auth_repo.dart';
import 'package:grocery_app/src/logic/repo/order_repo.dart';
import 'package:grocery_app/src/logic/repo/product_repo.dart';
import 'package:grocery_app/src/logic/services/auth_service_locator.dart';
import 'package:grocery_app/src/logic/services/home_locator.dart';
import 'package:grocery_app/src/logic/services/orderSirvice.dart';
GetIt getIt = GetIt.instance;
class ServiceLocator
{
class ServiceLocator {
static void setup() {
// dio client
getIt.registerSingleton(Dio());
getIt.registerSingleton(DioClient(getIt<Dio>()));
getIt.registerSingleton(AuthServices());
getIt.registerSingleton(ProductService());
// getIt.registerSingleton(StoreService());
getIt.registerSingleton(ProductService());
getIt.registerSingleton(OrderService());
// getIt.registerSingleton(HomeService());
// Repos
getIt.registerSingleton(AuthRepo(getIt<AuthServices>()));
getIt.registerSingleton(ProductRepo(getIt<ProductService>()));
// getIt.registerSingleton(StoreRepo(getIt<StoreService>()));
getIt.registerSingleton(AuthRepo(getIt<AuthServices>()));
getIt.registerSingleton(ProductRepo(getIt<ProductService>()));
getIt.registerSingleton(OrderRepo(getIt<OrderService>()));
// getIt.registerSingleton(HomeRepo(getIt<HomeService>()));
}
}

View File

@@ -2,7 +2,9 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:grocery_app/src/data/allProduct_model.dart';
import 'package:grocery_app/src/data/myOrder.dart';
import 'package:grocery_app/src/ui/bottomnavigation/bottom_bar_widget.dart';
import 'package:grocery_app/src/ui/card_checkout/card_checkout_screen.dart';
import 'package:grocery_app/src/ui/coupons/coupons_screen.dart';
@@ -11,6 +13,8 @@ import 'package:grocery_app/src/ui/fruitvegidetail/fruit_veggie_detail.dart';
import 'package:grocery_app/src/ui/login/login_screen.dart';
import 'package:grocery_app/src/ui/login/signup_screen.dart';
import 'package:grocery_app/src/ui/map/add_locations.dart';
import 'package:grocery_app/src/ui/myOrder/OrderDetailsScreen.dart';
import 'package:grocery_app/src/ui/myOrder/my_order.dart';
import 'package:grocery_app/src/ui/onboarding/on_boarding_screen.dart';
import 'package:grocery_app/src/ui/otp/login_otp.dart';
import 'package:grocery_app/src/ui/otp/otp_screen.dart';
@@ -114,6 +118,20 @@ class MyRoutes {
pageBuilder: (context, state) => PaymentFailureScreen(),
),
animatedGoRoute(
path: MYORDER,
name: MYORDER,
pageBuilder: (context, state) => MyOrderScreen(),
),
animatedGoRoute(
path: ORDERDETAILS,
name: ORDERDETAILS,
pageBuilder: (context, state) {
final order = state.extra as Datum; // Cast extra as Datum
return OrderDetailsScreen(order: order);
},
),
// animatedGoRoute(
// path: UPDATESTORE,
// name: UPDATESTORE,
@@ -233,6 +251,9 @@ class MyRoutes {
static const SELECTPAYMENTSCREEN = "/paymnetscreen";
static const SUCCESSPAYMENT = "/paymentSuccessScreen";
static const PAYMENTFAILD = "/paymentfailed";
static const MYORDER = "/myorder";
static const ORDERDETAILS = "/OrderDetailsScreen";
// static const TERMANDCONDITIONS = "/termsandcondition";
// static const SETUPBUSSINESS = "/setupbussiness";

684
lib/src/data/myOrder.dart Normal file
View File

@@ -0,0 +1,684 @@
// To parse this JSON data, do
//
// final myOrder = myOrderFromJson(jsondynamic);
import 'dart:convert';
MyOrder myOrderFromJson(dynamic str) => MyOrder.fromJson(json.decode(str));
dynamic myOrderToJson(MyOrder data) => json.encode(data.toJson());
class MyOrder {
List<Datum>? data;
Meta? meta;
MyOrder({
this.data,
this.meta,
});
factory MyOrder.fromJson(Map<dynamic, dynamic> json) => MyOrder(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
meta: Meta.fromJson(json["meta"]),
);
Map<dynamic, dynamic> toJson() => {
"data": List<dynamic>.from(data!.map((x) => x.toJson())),
"meta": meta!.toJson(),
};
}
class Datum {
dynamic id;
dynamic orderNumber;
dynamic userId;
int? totalItems;
dynamic subtotal;
dynamic deliveryCharge;
dynamic discount;
dynamic grandTotal;
dynamic paymentMethod;
dynamic paymentStatus;
dynamic transactionId;
dynamic orderStatus;
dynamic deliveryAddressId;
dynamic couponId;
dynamic cancelReason;
dynamic cancelledBy;
dynamic cancelledAt;
DateTime? createdAt;
DateTime? updatedAt;
User? user;
List<OrderItem>? orderItems;
DeliveryAddress? deliveryAddress;
List<StatusHistory>? statusHistory;
List<Store>? stores;
Datum({
this.id,
this.orderNumber,
this.userId,
this.totalItems,
this.subtotal,
this.deliveryCharge,
this.discount,
this.grandTotal,
this.paymentMethod,
this.paymentStatus,
this.transactionId,
this.orderStatus,
this.deliveryAddressId,
this.couponId,
this.cancelReason,
this.cancelledBy,
this.cancelledAt,
this.createdAt,
this.updatedAt,
this.user,
this.orderItems,
this.deliveryAddress,
this.statusHistory,
this.stores,
});
factory Datum.fromJson(Map<dynamic, dynamic> json) => Datum(
id: json["id"],
orderNumber: json["orderNumber"],
userId: json["userId"],
totalItems: json["totalItems"],
subtotal: json["subtotal"],
deliveryCharge: json["deliveryCharge"],
discount: json["discount"],
grandTotal: json["grandTotal"],
paymentMethod: json["paymentMethod"],
paymentStatus: json["paymentStatus"],
transactionId: json["transactionId"],
orderStatus: json["orderStatus"],
deliveryAddressId: json["deliveryAddressId"],
couponId: json["couponId"],
cancelReason: json["cancelReason"],
cancelledBy: json["cancelledBy"],
cancelledAt: json["cancelledAt"],
createdAt: DateTime?.parse(json["createdAt"]),
updatedAt: DateTime?.parse(json["updatedAt"]),
user: User.fromJson(json["user"]),
orderItems: List<OrderItem>.from(
json["orderItems"].map((x) => OrderItem.fromJson(x))),
deliveryAddress: DeliveryAddress.fromJson(json["deliveryAddress"]),
statusHistory: List<StatusHistory>.from(
json["statusHistory"].map((x) => StatusHistory.fromJson(x))),
stores: List<Store>.from(json["stores"].map((x) => Store.fromJson(x))),
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"orderNumber": orderNumber,
"userId": userId,
"totalItems": totalItems,
"subtotal": subtotal,
"deliveryCharge": deliveryCharge,
"discount": discount,
"grandTotal": grandTotal,
"paymentMethod": paymentMethod,
"paymentStatus": paymentStatus,
"transactionId": transactionId,
"orderStatus": orderStatus,
"deliveryAddressId": deliveryAddressId,
"couponId": couponId,
"cancelReason": cancelReason,
"cancelledBy": cancelledBy,
"cancelledAt": cancelledAt,
"createdAt": createdAt,
"updatedAt": updatedAt,
"user": user!.toJson(),
"orderItems": List<dynamic>.from(orderItems!.map((x) => x.toJson())),
"deliveryAddress": deliveryAddress!.toJson(),
"statusHistory":
List<dynamic>.from(statusHistory!.map((x) => x.toJson())),
"stores": List<dynamic>.from(stores!.map((x) => x.toJson())),
};
}
class DeliveryAddress {
dynamic id;
dynamic pincode;
dynamic phoneNumber;
dynamic alternatePhoneNumber;
dynamic addressLine;
dynamic landmark;
dynamic addressType;
dynamic city;
dynamic district;
dynamic name;
dynamic state;
dynamic country;
bool? isDeliverable;
bool? isDefault;
dynamic additionalInstructions;
DateTime? createdAt;
DateTime? updatedAt;
dynamic userId;
DeliveryAddress({
this.id,
this.pincode,
this.phoneNumber,
this.alternatePhoneNumber,
this.addressLine,
this.landmark,
this.addressType,
this.city,
this.district,
this.name,
this.state,
this.country,
this.isDeliverable,
this.isDefault,
this.additionalInstructions,
this.createdAt,
this.updatedAt,
this.userId,
});
factory DeliveryAddress.fromJson(Map<dynamic, dynamic> json) =>
DeliveryAddress(
id: json["id"],
pincode: json["pincode"],
phoneNumber: json["phoneNumber"],
alternatePhoneNumber: json["alternatePhoneNumber"],
addressLine: json["addressLine"],
landmark: json["landmark"],
addressType: json["addressType"],
city: json["city"],
district: json["district"],
name: json["name"],
state: json["state"],
country: json["country"],
isDeliverable: json["isDeliverable"],
isDefault: json["isDefault"],
additionalInstructions: json["additionalInstructions"],
createdAt: DateTime?.parse(json["createdAt"]),
updatedAt: DateTime?.parse(json["updatedAt"]),
userId: json["userId"],
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"pincode": pincode,
"phoneNumber": phoneNumber,
"alternatePhoneNumber": alternatePhoneNumber,
"addressLine": addressLine,
"landmark": landmark,
"addressType": addressType,
"city": city,
"district": district,
"name": name,
"state": state,
"country": country,
"isDeliverable": isDeliverable,
"isDefault": isDefault,
"additionalInstructions": additionalInstructions,
"createdAt": createdAt,
"updatedAt": updatedAt,
"userId": userId,
};
}
class OrderItem {
dynamic id;
dynamic orderId;
dynamic productId;
dynamic storeId;
dynamic productName;
dynamic productImage;
dynamic productVariant;
int? quantity;
dynamic price;
dynamic originalPrice;
dynamic discountAmount;
DateTime? createdAt;
DateTime? updatedAt;
Product? product;
// Store? store;
OrderItem({
this.id,
this.orderId,
this.productId,
this.storeId,
this.productName,
this.productImage,
this.productVariant,
this.quantity,
this.price,
this.originalPrice,
this.discountAmount,
this.createdAt,
this.updatedAt,
this.product,
// this.store,
});
factory OrderItem.fromJson(Map<dynamic, dynamic> json) => OrderItem(
id: json["id"],
orderId: json["orderId"],
productId: json["productId"],
storeId: json["storeId"],
productName: json["productName"],
productImage: json["productImage"],
productVariant: json["productVariant"],
quantity: json["quantity"],
price: json["price"],
originalPrice: json["originalPrice"],
discountAmount: json["discountAmount"],
createdAt: DateTime?.parse(json["createdAt"]),
updatedAt: DateTime?.parse(json["updatedAt"]),
product: Product.fromJson(json["product"]),
// store: Store.fromJson(json["store"]),
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"orderId": orderId,
"productId": productId,
"storeId": storeId,
"productName": productName,
"productImage": productImage,
"productVariant": productVariant,
"quantity": quantity,
"price": price,
"originalPrice": originalPrice,
"discountAmount": discountAmount,
"createdAt": createdAt,
"updatedAt": updatedAt,
"product": product!.toJson(),
// "store": store!.toJson(),
};
}
class Product {
dynamic id;
dynamic name;
dynamic description;
dynamic additionalInfo;
dynamic brand;
dynamic basePrice;
dynamic discountPrice;
int? stock;
int? quantity;
dynamic unit;
dynamic slug;
dynamic averageRating;
bool? isInStock;
bool? isActive;
DateTime? createdAt;
DateTime? updatedAt;
dynamic storeId;
dynamic categoryId;
dynamic productTypeId;
dynamic timeSlotId;
List<ProductImage>? productImages;
Category? category;
dynamic? productType;
Product({
this.id,
this.name,
this.description,
this.additionalInfo,
this.brand,
this.basePrice,
this.discountPrice,
this.stock,
this.quantity,
this.unit,
this.slug,
this.averageRating,
this.isInStock,
this.isActive,
this.createdAt,
this.updatedAt,
this.storeId,
this.categoryId,
this.productTypeId,
this.timeSlotId,
this.productImages,
this.category,
this.productType,
});
factory Product.fromJson(Map<dynamic, dynamic> json) => Product(
id: json["id"],
name: json["name"],
description: json["description"],
additionalInfo: json["additionalInfo"],
brand: json["brand"],
basePrice: json["basePrice"],
discountPrice: json["discountPrice"],
stock: json["stock"],
quantity: json["quantity"],
unit: json["unit"],
slug: json["slug"],
averageRating: json["averageRating"],
isInStock: json["isInStock"],
isActive: json["isActive"],
createdAt: DateTime?.parse(json["createdAt"]),
updatedAt: DateTime?.parse(json["updatedAt"]),
storeId: json["storeId"],
categoryId: json["categoryId"],
productTypeId: json["productTypeId"],
timeSlotId: json["timeSlotId"],
productImages: List<ProductImage>.from(
json["productImages"].map((x) => ProductImage.fromJson(x))),
category: Category.fromJson(json["category"]),
productType: json["productType"],
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"name": name,
"description": description,
"additionalInfo": additionalInfo,
"brand": brand,
"basePrice": basePrice,
"discountPrice": discountPrice,
"stock": stock,
"quantity": quantity,
"unit": unit,
"slug": slug,
"averageRating": averageRating,
"isInStock": isInStock,
"isActive": isActive,
"createdAt": createdAt,
"updatedAt": updatedAt,
"storeId": storeId,
"categoryId": categoryId,
"productTypeId": productTypeId,
"timeSlotId": timeSlotId,
"productImages":
List<dynamic>.from(productImages!.map((x) => x.toJson())),
"category": category!.toJson(),
"productType": productType,
};
}
class Category {
dynamic id;
dynamic name;
dynamic path;
Category({
this.id,
this.name,
this.path,
});
factory Category.fromJson(Map<dynamic, dynamic> json) => Category(
id: json["id"],
name: json["name"],
path: json["path"],
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"name": name,
"path": path,
};
}
class ProductImage {
dynamic id;
dynamic url;
bool? isDefault;
dynamic productId;
ProductImage({
this.id,
this.url,
this.isDefault,
this.productId,
});
factory ProductImage.fromJson(Map<dynamic, dynamic> json) => ProductImage(
id: json["id"],
url: json["url"],
isDefault: json["isDefault"],
productId: json["productId"],
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"url": url,
"isDefault": isDefault,
"productId": productId,
};
}
class Store {
dynamic id;
dynamic storeName;
dynamic storePicture;
dynamic storeAddress;
dynamic officialPhoneNumber;
User? vendor;
OperateDates? operateDates;
OperateTimes? operateTimes;
Store({
this.id,
this.storeName,
this.storePicture,
this.storeAddress,
this.officialPhoneNumber,
this.vendor,
this.operateDates,
this.operateTimes,
});
factory Store.fromJson(Map<dynamic, dynamic> json) => Store(
id: json["id"],
storeName: json["storeName"],
storePicture: json["storePicture"],
storeAddress: json["storeAddress"],
officialPhoneNumber: json["officialPhoneNumber"],
vendor: User.fromJson(json["vendor"]),
operateDates: OperateDates.fromJson(json["operateDates"]),
operateTimes: OperateTimes.fromJson(json["operateTimes"]),
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"storeName": storeName,
"storePicture": storePicture,
"storeAddress": storeAddress,
"officialPhoneNumber": officialPhoneNumber,
"vendor": vendor!.toJson(),
"operateDates": operateDates!.toJson(),
"operateTimes": operateTimes!.toJson(),
};
}
class OperateDates {
dynamic id;
bool? monday;
bool? tuesday;
bool? wednesday;
bool? thursday;
bool? friday;
bool? saturday;
bool? sunday;
dynamic storeId;
OperateDates({
this.id,
this.monday,
this.tuesday,
this.wednesday,
this.thursday,
this.friday,
this.saturday,
this.sunday,
this.storeId,
});
factory OperateDates.fromJson(Map<dynamic, dynamic> json) => OperateDates(
id: json["id"],
monday: json["monday"],
tuesday: json["tuesday"],
wednesday: json["wednesday"],
thursday: json["thursday"],
friday: json["friday"],
saturday: json["saturday"],
sunday: json["sunday"],
storeId: json["storeId"],
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"monday": monday,
"tuesday": tuesday,
"wednesday": wednesday,
"thursday": thursday,
"friday": friday,
"saturday": saturday,
"sunday": sunday,
"storeId": storeId,
};
}
class OperateTimes {
dynamic id;
dynamic startTime;
dynamic endTime;
dynamic storeId;
OperateTimes({
this.id,
this.startTime,
this.endTime,
this.storeId,
});
factory OperateTimes.fromJson(Map<dynamic, dynamic> json) => OperateTimes(
id: json["id"],
startTime: json["startTime"],
endTime: json["endTime"],
storeId: json["storeId"],
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"startTime": startTime,
"endTime": endTime,
"storeId": storeId,
};
}
class User {
dynamic id;
dynamic email;
dynamic firstName;
dynamic lastName;
dynamic phone;
dynamic role;
User({
this.id,
this.email,
this.firstName,
this.lastName,
this.phone,
this.role,
});
factory User.fromJson(Map<dynamic, dynamic> json) => User(
id: json["id"],
email: json["email"],
firstName: json["firstName"],
lastName: json["lastName"],
phone: json["phone"],
role: json["role"],
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"email": email,
"firstName": firstName,
"lastName": lastName,
"phone": phone,
"role": role,
};
}
class StatusHistory {
dynamic id;
dynamic orderId;
dynamic status;
dynamic comment;
dynamic updatedBy;
DateTime? createdAt;
StatusHistory({
this.id,
this.orderId,
this.status,
this.comment,
this.updatedBy,
this.createdAt,
});
factory StatusHistory.fromJson(Map<dynamic, dynamic> json) => StatusHistory(
id: json["id"],
orderId: json["orderId"],
status: json["status"],
comment: json["comment"],
updatedBy: json["updatedBy"],
createdAt: DateTime?.parse(json["createdAt"]),
);
Map<dynamic, dynamic> toJson() => {
"id": id,
"orderId": orderId,
"status": status,
"comment": comment,
"updatedBy": updatedBy,
"createdAt": createdAt,
};
}
class Meta {
int? total;
int? page;
int? limit;
int? lastPage;
bool? hasNextPage;
bool? hasPreviousPage;
Meta({
this.total,
this.page,
this.limit,
this.lastPage,
this.hasNextPage,
this.hasPreviousPage,
});
factory Meta.fromJson(Map<dynamic, dynamic> json) => Meta(
total: json["total"],
page: json["page"],
limit: json["limit"],
lastPage: json["lastPage"],
hasNextPage: json["hasNextPage"],
hasPreviousPage: json["hasPreviousPage"],
);
Map<dynamic, dynamic> toJson() => {
"total": total,
"page": page,
"limit": limit,
"lastPage": lastPage,
"hasNextPage": hasNextPage,
"hasPreviousPage": hasPreviousPage,
};
}

View File

@@ -185,8 +185,6 @@ class AddtocartProvider extends ChangeNotifier {
"remarks": remarks
};
try {
var result = await _homeRepo.paymentOrder(data);
return result.fold(
@@ -211,7 +209,81 @@ class AddtocartProvider extends ChangeNotifier {
},
);
} catch (e) {
ispaymentLoader = false;
ispaymentLoader = false;
notifyListeners();
}
}
////////////////////////////COD ////////////
Future<void> paymentCODOrder(
BuildContext context,
double subtotal,
String deliverCharge,
double discountPrice,
String grandTotal,
String couponId,
String addressId,
) async {
ispaymentLoader = true;
notifyListeners();
var data;
if (couponId.isNotEmpty)
{
data = {
{
"addressId": addressId,
"paymentMethod": "COD",
"paymentStatus": "PENDING",
"orderStatus": "PENDING",
"subtotal": subtotal,
"deliveryCharge": deliverCharge,
"discount": discountPrice,
"grandTotal": grandTotal,
"couponId": couponId
}
};
}
else {
data = {
{
"addressId": addressId,
"paymentMethod": "COD",
"paymentStatus": "PENDING",
"orderStatus": "PENDING",
"subtotal": subtotal,
"deliveryCharge": deliverCharge,
"discount": discountPrice,
"grandTotal": grandTotal,
}
};
}
try {
var result = await _homeRepo.paymentCODOrder(data);
return result.fold(
(error) {
ispaymentLoader = false;
notifyListeners();
},
(response) {
if (response.data!.instrumentResponse!.redirectInfo != null &&
response.data!.instrumentResponse!.redirectInfo != '') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PaymentWebView(
paymentUrl:
response.data!.instrumentResponse!.redirectInfo!.url),
),
);
}
ispaymentLoader = false;
notifyListeners();
},
);
} catch (e) {
ispaymentLoader = false;
notifyListeners();
}
}

View File

@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:grocery_app/src/core/network_services/service_locator.dart';
import 'package:grocery_app/src/data/myOrder.dart';
import 'package:grocery_app/src/logic/repo/order_repo.dart';
class OrderProvider extends ChangeNotifier {
final _orderRepo = getIt<OrderRepo>();
List<Datum> orderList = [];
bool isloading = true;
Future<void> getMyOrder(BuildContext context) async {
var data = {};
try {
var result = await _orderRepo.myOrder(data);
return result.fold(
(error) {
isloading = false;
notifyListeners();
},
(response) {
orderList = response.data!;
isloading = false;
notifyListeners();
},
);
} catch (e) {
print("sfddsfdfff $e");
isloading = false;
notifyListeners();
}
}
}

View File

@@ -0,0 +1,26 @@
import 'package:dio/dio.dart';
import 'package:fpdart/fpdart.dart';
import 'package:grocery_app/src/core/utils/custom_dio_exception.dart';
import 'package:grocery_app/src/core/utils/response_type_def.dart';
import 'package:grocery_app/src/data/myOrder.dart';
import 'package:grocery_app/src/data/order_paymnet.dart';
import 'package:grocery_app/src/logic/services/orderSirvice.dart';
class OrderRepo {
final OrderService _orderService;
OrderRepo(this._orderService);
FutureResult<MyOrder> myOrder(data) async {
try {
var response = await _orderService.myOrder(data);
MyOrder productCategory = myOrderFromJson(response.toString());
print("ldkjglfdhglkj ${productCategory}");
return right(productCategory);
} on DioException catch (e) {
var error = CustomDioExceptions.handleError(e);
return left(error);
}
}
}

View File

@@ -114,6 +114,28 @@ class ProductRepo {
}
}
FutureResult<OrderPaymnet> paymentCODOrder(data) async {
try {
var response = await _productService.paymentCODOrder(data);
print("kjdfglkjfdgjklfgkldj${data} ${response} ");
OrderPaymnet productCategory = orderPaymnetFromJson(response.toString());
print("lkjdflkjfhgdkhfgkd ");
// final String model = response.toString();
return right(productCategory);
} on DioException catch (e) {
var error = CustomDioExceptions.handleError(e);
return left(error);
}
}
FutureResult<List<Product>> similarProduct(
data, BuildContext context, id) async {
try {

View File

@@ -61,6 +61,15 @@ class ProductService extends ApiService {
return response;
}
Future paymentCODOrder(data) async {
print("kdjfgkjjkdfgkjdkfgjkdfgj ${data}");
var response =
await api.post(APIURL.paymentCODOrder, data: jsonEncode(data));
return response;
}
Future similarProduct(data, id) async {
var response = await api.get(APIURL.similarProduct + id + "/similar",
data: jsonEncode(data));

View File

@@ -0,0 +1,16 @@
import 'dart:convert';
import 'package:grocery_app/src/core/constant/api.dart';
import 'package:grocery_app/src/core/network_services/api_services.dart';
class OrderService extends ApiService
{
Future myOrder(data) async {
var response = await api.get(APIURL.myOrder, data: jsonEncode(data));
return response;
}
}

View File

@@ -1,58 +0,0 @@
// import 'dart:convert';
// import 'dart:io';
// import 'package:dio/dio.dart';
// import 'package:vendor_app/src/core/constant/api.dart';
// import 'package:vendor_app/src/core/network_services/api_services.dart';
// class ProductService extends ApiService {
// // Future createStore(data) async
// // {
// // var response = await api.get(APIURL.createStore, data: jsonEncode(data));
// // return response;
// // }
// Future getProduct(data) async {
// var response = await api.get(APIURL.getProduct, data: jsonEncode(data));
// return response;
// }
// Future createProduct(data) async {
// var response = await api.post(APIURL.getProduct, data: jsonEncode(data));
// return response;
// }
// Future deleteProduct(data, id) async {
// var response =
// await api.delete(APIURL.deleteProduct + id, data: jsonEncode(data));
// return response;
// }
// Future updateProduct(data, id) async {
// var response =
// await api.patch(APIURL.updateProduct + id, data: jsonEncode(data));
// return response;
// }
// Future getCategoryByLevel(data) async {
// var response =
// await api.get(APIURL.getCategoryByLevel, data: jsonEncode(data));
// return response;
// }
// // Future uploadImage(data) async
// // {
// // var response = await api.post(APIURL.uploadImage, data: jsonEncode(data));
// // return response;
// // }
// Future<Response> uploadImage(File imageFile,
// {Map<String, dynamic>? additionalFields}) async {
// const String url = APIURL.uploadImage;
// return await api.uploadImage(
// url,
// imageFile,
// additionalFields: additionalFields,
// );
// }
// }

View File

@@ -80,20 +80,33 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
Expanded(
child: InkWell(
onTap: () {
print("kjdhfkhjghjkdf");
if (paymentProvider.selectedPaymentMethod == "Online") {
paymentProvider.orderPaymnet(
context,
widget.amount,
widget.currency,
widget.originalAmount,
widget.name,
widget.phone,
widget.email,
widget.userId,
widget.cartId,
widget.addressId,
widget.remarks);
} else {
// paymentProvider.paymentCODOrder(
// context,
// subtotal,
// deliverCharge,
// discountPrice,
// grandTotal,
// couponId,
// widget.addressId,
// );
}
paymentProvider.orderPaymnet(
context,
widget.amount,
widget.currency,
widget.originalAmount,
widget.name,
widget.phone,
widget.email,
widget.userId,
widget.cartId,
widget.addressId,
widget.remarks);
},
child: Container(
height: 50,

View File

@@ -713,7 +713,7 @@ class _MycartState extends State<Mycart> {
);
} else if (provider.allitem == null) {
return Center(child: Text('🛒 Your Front Shop Cart is empty'));
} else if (provider.allitem.items == null) {
} else if (provider.allitem.items!.isEmpty) {
return Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
@@ -729,6 +729,7 @@ class _MycartState extends State<Mycart> {
),
));
} else {
print("kldjhgjkhfgjkh ${provider.allitem.items}");
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -976,7 +977,8 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
onPressed: () {
Navigator.pop(context);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
builder: (context)
{
return CardCheckoutScreen(
amount: double.parse(
paymentProvider.allitem.subtotal.toString()),
@@ -992,9 +994,6 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
remarks: paymentProvider.selecteUserName);
},
));
// showPaymentMethodBottomSheet(context);
// context.push(MyRoutes.SELECTPAYMENTSCREEN);
},
label: Text(
"Continue",

View File

@@ -0,0 +1,205 @@
import 'package:flutter/material.dart';
import 'package:grocery_app/src/common_widget/network_image.dart';
import 'package:grocery_app/src/data/myOrder.dart';
class OrderDetailsScreen extends StatefulWidget {
final Datum order;
const OrderDetailsScreen({Key? key, required this.order}) : super(key: key);
@override
_OrderDetailsScreenState createState() => _OrderDetailsScreenState();
}
class _OrderDetailsScreenState extends State<OrderDetailsScreen> {
int currentStep = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Order Details')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_orderInfo(),
SizedBox(height: 20),
_animatedShippingTimeline(),
SizedBox(height: 20),
_itemsList(),
SizedBox(height: 20),
_cancelButton(),
],
),
),
);
}
/// Order Information
Widget _orderInfo() {
return Card(
elevation: 4,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: Container(
width: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.order.orderNumber,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(height: 5),
Text(widget.order.createdAt.toString()),
SizedBox(height: 5),
Text(
"Status: ${_getStatusText(widget.order.orderStatus)}",
style:
TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
),
],
),
),
),
);
}
/// Animated Shipping Timeline
Widget _animatedShippingTimeline() {
return Column(
children: [
for (int i = 0; i < 3; i++) _timelineStep(i),
],
);
}
/// Each Step in the Timeline
Widget _timelineStep(int step) {
bool isCompleted = step <= currentStep;
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
AnimatedContainer(
duration: Duration(milliseconds: 500),
width: 20,
height: 20,
decoration: BoxDecoration(
color: isCompleted ? Colors.green : Colors.grey,
shape: BoxShape.circle,
),
child: Icon(Icons.check, size: 14, color: Colors.white),
),
if (step < 2)
AnimatedContainer(
duration: Duration(milliseconds: 500),
width: 5,
height: 50,
color: isCompleted ? Colors.green : Colors.grey,
),
],
),
SizedBox(width: 10),
Text(
_getStatusTextForStep(widget.order.orderStatus),
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
],
);
}
/// Status Texts
String _getStatusTextForStep(orderStatus) {
switch (orderStatus) {
case 'PENDING':
return "PENDING";
case 'SHIPPED':
return "SHIPPED";
case 'DELIVERD':
return "DELIVERD";
default:
return "";
}
}
String _getStatusText(orderStatus) {
switch (orderStatus) {
case 'PENDING':
return "PENDING";
case 'SHIPPED':
return "SHIPPED";
case 'DELIVERD':
return "DELIVERD";
default:
return "";
}
}
/// List of Ordered Items
Widget _itemsList() {
// final List<Map<String, dynamic>> items = [
// {
// "name": "Coffee",
// "quantity": 2,
// "price": 10.00,
// "image": "https://via.placeholder.com/50"
// },
// {
// "name": "Rice",
// "quantity": 1,
// "price": 10.50,
// "image": "https://via.placeholder.com/50"
// }
// ];
return Expanded(
child: ListView.builder(
itemCount: widget.order.orderItems!.length,
itemBuilder: (context, index) {
// final item = items[index];
var orderitem = widget.order.orderItems![index];
return Card(
margin: EdgeInsets.symmetric(vertical: 8),
child: ListTile(
leading: Container(
width: 50,
height: 50,
child: AppNetworkImage(
height: MediaQuery.of(context).size.height * 0.08,
width: 48,
imageUrl: orderitem.productImage ?? "",
backGroundColor: Colors.transparent,
),
),
title: Text(orderitem.productName ?? ""),
subtitle: Text("Qty: ${orderitem.quantity.toString()}"),
trailing: Text("\$${orderitem.price ?? ""}",
style: TextStyle(fontWeight: FontWeight.bold)),
),
);
},
),
);
}
/// Cancel Order Button (Only if not delivered)
Widget _cancelButton() {
return ElevatedButton(
onPressed: currentStep < 2
? () {
setState(() {
currentStep = 2; // Simulate cancellation
});
}
: null, // Disable if already delivered
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
disabledBackgroundColor: Colors.grey,
),
child: Text("Cancel Order", style: TextStyle(color: Colors.white)),
);
}
}

View File

@@ -0,0 +1,235 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:grocery_app/src/common_widget/network_image.dart';
import 'package:grocery_app/src/core/routes/routes.dart';
import 'package:grocery_app/src/logic/provider/order_provider.dart';
import 'package:grocery_app/utils/constants/assets_constant.dart';
import 'package:grocery_app/utils/constants/color_constant.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
class MyOrderScreen extends StatefulWidget {
@override
State<MyOrderScreen> createState() => _MyOrderScreenState();
}
class _MyOrderScreenState extends State<MyOrderScreen> {
@override
void initState() {
Provider.of<OrderProvider>(context, listen: false).getMyOrder(context);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
leading: Center(
child: SizedBox(
height: 20,
width: 20,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: SvgPicture.asset(
APPASSETS.back,
height: 20,
width: 20,
)),
),
),
title: const Text(
"My Order",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w700,
),
),
),
body: Consumer<OrderProvider>(builder: (context, orderProvider, child) {
if (orderProvider.isloading) {
return Center(child: CircularProgressIndicator());
}
if (orderProvider.orderList.isEmpty) {
return Center(child: Text('No orders found!'));
}
return Column(
children: [
Expanded(
child: ListView.builder(
itemCount: orderProvider.orderList.length,
itemBuilder: (context, index) {
final order = orderProvider.orderList[index];
return InkWell(
onTap: () {
context.pushNamed(MyRoutes.ORDERDETAILS, extra: order);
//context.push(MyRoutes.ORDERDETAILS);
},
child: Card(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Center(
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: APPCOLOR.bgGrey,
borderRadius: BorderRadius.circular(15),
),
child: Stack(
alignment: Alignment.center,
children: [
AppNetworkImage(
height: MediaQuery.of(context)
.size
.height *
0.08,
width: 48,
imageUrl: order
.orderItems!.first.productImage,
backGroundColor: Colors.transparent,
),
],
),
),
),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(order.orderNumber,
style: TextStyle(
fontWeight: FontWeight.bold)),
Text(order.paymentMethod,
style: TextStyle(color: Colors.grey)),
Text(order.totalItems.toString() + " items",
style: TextStyle(color: Colors.grey)),
],
),
Spacer(),
if (order.totalItems == 1) ...{
Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.green.shade100,
borderRadius: BorderRadius.circular(10),
),
child: Text(order.orderStatus,
style: TextStyle(color: Colors.green)),
),
} else ...{
Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.green.shade100,
borderRadius: BorderRadius.circular(10),
),
child: Text("View All",
style: TextStyle(color: Colors.green)),
),
}
],
),
SizedBox(height: 10),
Text(order.createdAt.toString(),
style: TextStyle(color: Colors.grey)),
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("\$" + order.grandTotal,
style:
TextStyle(fontWeight: FontWeight.bold)),
Row(
children: [
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.green),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10),
),
),
child: Row(
children: [
Icon(Icons.message,
color: Colors.green),
SizedBox(width: 5),
Text('Message',
style: TextStyle(
color: Colors.green)),
],
),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: () {
print("lkdhgkjdfgj");
_makePhoneCall(
order.stores!.first.vendor!.phone);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10),
),
),
child: Row(
children: [
Icon(Icons.call, color: Colors.white),
SizedBox(width: 5),
Text('Call',
style: TextStyle(
color: Colors.white)),
],
),
),
],
),
],
),
],
),
),
),
);
},
),
),
],
);
}),
);
}
Future<void> _makePhoneCall(String number) async {
try {
final Uri phoneUri = Uri(scheme: 'tel', path: number);
if (await canLaunchUrl(phoneUri)) {
await launchUrl(phoneUri);
} else {
throw 'Could not launch $phoneUri';
}
} catch (e) {
print("Error launching phone call: $e");
}
}
}

View File

@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:grocery_app/src/common_widget/network_image.dart';
import 'package:grocery_app/src/core/routes/routes.dart';
import 'package:grocery_app/src/logic/provider/home_provider.dart';
import 'package:grocery_app/src/ui/card_checkout/card_checkout_screen.dart';
import 'package:grocery_app/src/ui/edit_profile/edit_profile_screen.dart';
@@ -28,8 +30,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
var top = 0.0;
@override
Widget build(BuildContext context)
{
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
@@ -171,8 +172,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
trailing: Icon(MdiIcons.chevronRight),
),
ListTile(
onTap: ()
{
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) {
// return const CardCheckoutScreen();
@@ -184,7 +184,9 @@ class _ProfileScreenState extends State<ProfileScreen> {
trailing: Icon(MdiIcons.chevronRight),
),
ListTile(
onTap: () {},
onTap: () {
context.push(MyRoutes.MYORDER);
},
leading: Icon(MdiIcons.cubeOutline),
title: const Text('My Order'),
trailing: Icon(MdiIcons.chevronRight),