addtocart
This commit is contained in:
@@ -15,6 +15,10 @@ class APIURL {
|
||||
static const String addToCart = "${BASE_URL}carts/items";
|
||||
static const String gettAllWishList = "${BASE_URL}carts/wishlist";
|
||||
static const String similarProduct = "${BASE_URL}products/";
|
||||
static const String getItemCards = "${BASE_URL}carts/current";
|
||||
static const String checkPin = "${BASE_URL}pin-codes/check/";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
248
lib/src/data/all_cart_items.dart
Normal file
248
lib/src/data/all_cart_items.dart
Normal file
@@ -0,0 +1,248 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final allCartItems = allCartItemsFromJson(jsondynamic);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:grocery_app/src/data/allProduct_model.dart';
|
||||
|
||||
AllCartItems allCartItemsFromJson(dynamic str) =>
|
||||
AllCartItems.fromJson(json.decode(str));
|
||||
|
||||
dynamic allCartItemsToJson(AllCartItems data) => json.encode(data.toJson());
|
||||
|
||||
class AllCartItems {
|
||||
dynamic id;
|
||||
dynamic userId;
|
||||
dynamic subtotal;
|
||||
DateTime? createdAt;
|
||||
DateTime? updatedAt;
|
||||
List<Item>? items;
|
||||
|
||||
AllCartItems({
|
||||
this.id,
|
||||
this.userId,
|
||||
this.subtotal,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.items,
|
||||
});
|
||||
|
||||
factory AllCartItems.fromJson(Map<dynamic, dynamic> json) => AllCartItems(
|
||||
id: json["id"],
|
||||
userId: json["userId"],
|
||||
subtotal: json["subtotal"],
|
||||
createdAt: DateTime.parse(json["createdAt"]),
|
||||
updatedAt: DateTime.parse(json["updatedAt"]),
|
||||
items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<dynamic, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"userId": userId,
|
||||
"subtotal": subtotal,
|
||||
"createdAt": createdAt,
|
||||
"updatedAt": updatedAt,
|
||||
"items": List<dynamic>.from(items!.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
|
||||
class Item {
|
||||
dynamic id;
|
||||
dynamic quantity;
|
||||
dynamic priceSnapshot;
|
||||
dynamic cartId;
|
||||
dynamic productId;
|
||||
dynamic storeId;
|
||||
DateTime? createdAt;
|
||||
DateTime? updatedAt;
|
||||
Product? product;
|
||||
Store? store;
|
||||
|
||||
Item({
|
||||
this.id,
|
||||
this.quantity,
|
||||
this.priceSnapshot,
|
||||
this.cartId,
|
||||
this.productId,
|
||||
this.storeId,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.product,
|
||||
this.store,
|
||||
});
|
||||
|
||||
factory Item.fromJson(Map<dynamic, dynamic> json) => Item(
|
||||
id: json["id"],
|
||||
quantity: json["quantity"],
|
||||
priceSnapshot: json["priceSnapshot"],
|
||||
cartId: json["cartId"],
|
||||
productId: json["productId"],
|
||||
storeId: json["storeId"],
|
||||
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,
|
||||
"quantity": quantity,
|
||||
"priceSnapshot": priceSnapshot,
|
||||
"cartId": cartId,
|
||||
"productId": productId,
|
||||
"storeId": storeId,
|
||||
"createdAt": createdAt,
|
||||
"updatedAt": updatedAt,
|
||||
"product": product!.toJson(),
|
||||
"store": store!.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class Category {
|
||||
dynamic id;
|
||||
dynamic name;
|
||||
dynamic description;
|
||||
dynamic image;
|
||||
dynamic slug;
|
||||
dynamic level;
|
||||
bool? isActive;
|
||||
DateTime? createdAt;
|
||||
DateTime? updatedAt;
|
||||
dynamic parentCategoryId;
|
||||
dynamic path;
|
||||
|
||||
Category({
|
||||
this.id,
|
||||
this.name,
|
||||
this.description,
|
||||
this.image,
|
||||
this.slug,
|
||||
this.level,
|
||||
this.isActive,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.parentCategoryId,
|
||||
this.path,
|
||||
});
|
||||
|
||||
factory Category.fromJson(Map<dynamic, dynamic> json) => Category(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
image: json["image"],
|
||||
slug: json["slug"],
|
||||
level: json["level"],
|
||||
isActive: json["isActive"],
|
||||
createdAt: DateTime.parse(json["createdAt"]),
|
||||
updatedAt: DateTime.parse(json["updatedAt"]),
|
||||
parentCategoryId: json["parentCategoryId"],
|
||||
path: json["path"],
|
||||
);
|
||||
|
||||
Map<dynamic, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"image": image,
|
||||
"slug": slug,
|
||||
"level": level,
|
||||
"isActive": isActive,
|
||||
"createdAt": createdAt,
|
||||
"updatedAt": updatedAt,
|
||||
"parentCategoryId": parentCategoryId,
|
||||
"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 storeDescription;
|
||||
dynamic officialPhoneNumber;
|
||||
dynamic storeAddress;
|
||||
dynamic gstNumber;
|
||||
dynamic gumastaNumber;
|
||||
dynamic storePicture;
|
||||
DateTime? createdAt;
|
||||
DateTime? updatedAt;
|
||||
dynamic vendorId;
|
||||
bool? isActive;
|
||||
dynamic couponId;
|
||||
|
||||
Store({
|
||||
this.id,
|
||||
this.storeName,
|
||||
this.storeDescription,
|
||||
this.officialPhoneNumber,
|
||||
this.storeAddress,
|
||||
this.gstNumber,
|
||||
this.gumastaNumber,
|
||||
this.storePicture,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.vendorId,
|
||||
this.isActive,
|
||||
this.couponId,
|
||||
});
|
||||
|
||||
factory Store.fromJson(Map<dynamic, dynamic> json) => Store(
|
||||
id: json["id"],
|
||||
storeName: json["storeName"],
|
||||
storeDescription: json["storeDescription"],
|
||||
officialPhoneNumber: json["officialPhoneNumber"],
|
||||
storeAddress: json["storeAddress"],
|
||||
gstNumber: json["gstNumber"],
|
||||
gumastaNumber: json["gumastaNumber"],
|
||||
storePicture: json["storePicture"],
|
||||
createdAt: DateTime.parse(json["createdAt"]),
|
||||
updatedAt: DateTime.parse(json["updatedAt"]),
|
||||
vendorId: json["vendorId"],
|
||||
isActive: json["isActive"],
|
||||
couponId: json["couponId"],
|
||||
);
|
||||
|
||||
Map<dynamic, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"storeName": storeName,
|
||||
"storeDescription": storeDescription,
|
||||
"officialPhoneNumber": officialPhoneNumber,
|
||||
"storeAddress": storeAddress,
|
||||
"gstNumber": gstNumber,
|
||||
"gumastaNumber": gumastaNumber,
|
||||
"storePicture": storePicture,
|
||||
"createdAt": createdAt,
|
||||
"updatedAt": updatedAt,
|
||||
"vendorId": vendorId,
|
||||
"isActive": isActive,
|
||||
"couponId": couponId,
|
||||
};
|
||||
}
|
||||
56
lib/src/data/check_pin_response.dart
Normal file
56
lib/src/data/check_pin_response.dart
Normal file
@@ -0,0 +1,56 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final checkPinResponse = checkPinResponseFromJson(jsondynamic);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
CheckPinResponse checkPinResponseFromJson(dynamic str) =>
|
||||
CheckPinResponse.fromJson(json.decode(str));
|
||||
|
||||
dynamic checkPinResponseToJson(CheckPinResponse data) =>
|
||||
json.encode(data.toJson());
|
||||
|
||||
class CheckPinResponse {
|
||||
dynamic id;
|
||||
dynamic code;
|
||||
bool? isActive;
|
||||
bool? isManual;
|
||||
DateTime? createdAt;
|
||||
DateTime? updatedAt;
|
||||
bool? isDeliverable;
|
||||
|
||||
|
||||
CheckPinResponse({
|
||||
this.id,
|
||||
this.code,
|
||||
this.isActive,
|
||||
this.isManual,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.isDeliverable,
|
||||
|
||||
});
|
||||
|
||||
factory CheckPinResponse.fromJson(Map<dynamic, dynamic> json) =>
|
||||
CheckPinResponse(
|
||||
id: json["id"],
|
||||
code: json["code"],
|
||||
isActive: json["isActive"],
|
||||
isManual: json["isManual"],
|
||||
createdAt: DateTime.parse(json["createdAt"]),
|
||||
updatedAt: DateTime.parse(json["updatedAt"]),
|
||||
isDeliverable: json["isDeliverable"],
|
||||
|
||||
);
|
||||
|
||||
Map<dynamic, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"code": code,
|
||||
"isActive": isActive,
|
||||
"isManual": isManual,
|
||||
"createdAt": createdAt,
|
||||
"updatedAt": updatedAt,
|
||||
"isDeliverable": isDeliverable,
|
||||
|
||||
};
|
||||
}
|
||||
126
lib/src/logic/provider/addTocart_provider.dart
Normal file
126
lib/src/logic/provider/addTocart_provider.dart
Normal file
@@ -0,0 +1,126 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geocoding/geocoding.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:grocery_app/src/core/network_services/service_locator.dart';
|
||||
import 'package:grocery_app/src/data/all_cart_items.dart';
|
||||
import 'package:grocery_app/src/logic/repo/product_repo.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class AddtocartProvider extends ChangeNotifier {
|
||||
String _pinCode = "Fetching...";
|
||||
bool _isLoading = false;
|
||||
bool _isDeliverable = false;
|
||||
|
||||
String get pinCode => _pinCode;
|
||||
bool get isLoading => _isLoading;
|
||||
bool get isDeliverable => _isDeliverable;
|
||||
|
||||
Future<void> getCurrentLocation(BuildContext context) async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!serviceEnabled) {
|
||||
_pinCode = "Location services disabled.";
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LocationPermission permission = await Geolocator.requestPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
_pinCode = "Permission denied.";
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Position position = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.high,
|
||||
);
|
||||
|
||||
print("Location fetched: ${position.latitude}, ${position.longitude}");
|
||||
|
||||
List<Placemark> placemarks = await placemarkFromCoordinates(
|
||||
position.latitude,
|
||||
position.longitude,
|
||||
);
|
||||
|
||||
if (placemarks.isNotEmpty) {
|
||||
_pinCode = placemarks.first.postalCode ?? "Unknown";
|
||||
print("Pincode found: $_pinCode");
|
||||
|
||||
// Now check if this pin code is deliverable
|
||||
await checkPin(context, _pinCode);
|
||||
} else {
|
||||
_pinCode = "Could not fetch pin code.";
|
||||
print("Error: No placemarks found.");
|
||||
}
|
||||
} catch (e) {
|
||||
_pinCode = "Error: ${e.toString()}";
|
||||
print("Error: ${e.toString()}");
|
||||
}
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> checkPin(BuildContext context, pin) async {
|
||||
var data = {};
|
||||
try {
|
||||
var result = await _homeRepo.checkPin(data, pin);
|
||||
|
||||
return result.fold(
|
||||
(error) {
|
||||
_isDeliverable = false;
|
||||
isLoaddcartItem = false;
|
||||
notifyListeners();
|
||||
},
|
||||
(response) {
|
||||
print("kdhfgkjfkghkfghkj ${response.isDeliverable!}");
|
||||
if (response.isDeliverable!) {
|
||||
_isDeliverable = true;
|
||||
}
|
||||
|
||||
isLoaddcartItem = false;
|
||||
notifyListeners();
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_isDeliverable = false;
|
||||
isLoaddcartItem = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
final _homeRepo = getIt<ProductRepo>();
|
||||
|
||||
AllCartItems allitem = AllCartItems();
|
||||
|
||||
bool isLoaddcartItem = true;
|
||||
Future<void> getItemCards(BuildContext context) async {
|
||||
var data = {};
|
||||
try {
|
||||
var result = await _homeRepo.getItemCards(data);
|
||||
|
||||
return result.fold(
|
||||
(error) {
|
||||
isLoaddcartItem = false;
|
||||
notifyListeners();
|
||||
},
|
||||
(response) {
|
||||
allitem = response!;
|
||||
isLoaddcartItem = false;
|
||||
notifyListeners();
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
isLoaddcartItem = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:grocery_app/src/core/network_services/service_locator.dart';
|
||||
import 'package:grocery_app/src/core/routes/routes.dart';
|
||||
import 'package:grocery_app/src/data/allProduct_model.dart';
|
||||
import 'package:grocery_app/src/data/all_cart_items.dart';
|
||||
import 'package:grocery_app/src/data/banners.dart';
|
||||
import 'package:grocery_app/src/data/best_dealProduct.dart';
|
||||
import 'package:grocery_app/src/data/product_category.dart';
|
||||
@@ -273,7 +274,7 @@ class ProductProvider extends ChangeNotifier {
|
||||
Map<String, bool> isLoading = {};
|
||||
|
||||
Future<void> addToCart(BuildContext context, String productId) async {
|
||||
if (cartItems.contains(productId)) return; // Prevent duplicate additions
|
||||
//if (cartItems.contains(productId)) return; // Prevent duplicate additions
|
||||
|
||||
isLoading[productId] = true;
|
||||
notifyListeners(); // Notify UI to show loading indicator
|
||||
@@ -402,4 +403,8 @@ class ProductProvider extends ChangeNotifier {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////// all carts////////////////////////
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ 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/allProduct_model.dart';
|
||||
import 'package:grocery_app/src/data/all_cart_items.dart';
|
||||
import 'package:grocery_app/src/data/banners.dart';
|
||||
import 'package:grocery_app/src/data/best_dealProduct.dart';
|
||||
import 'package:grocery_app/src/data/check_pin_response.dart';
|
||||
import 'package:grocery_app/src/data/product_category.dart';
|
||||
import 'package:grocery_app/src/data/wish_list_model.dart';
|
||||
import 'package:grocery_app/src/logic/services/home_locator.dart';
|
||||
@@ -85,6 +87,33 @@ class ProductRepo {
|
||||
}
|
||||
}
|
||||
|
||||
FutureResult<AllCartItems> getItemCards(data) async {
|
||||
try {
|
||||
var response = await _productService.getItemCards(data);
|
||||
|
||||
AllCartItems allCartItems = allCartItemsFromJson(response.toString());
|
||||
|
||||
return right(allCartItems);
|
||||
} on DioException catch (e) {
|
||||
print("sdkjfkjdkfjgjfdjg");
|
||||
var error = CustomDioExceptions.handleError(e);
|
||||
return left(error);
|
||||
}
|
||||
}
|
||||
|
||||
FutureResult<CheckPinResponse> checkPin(data,pin) async {
|
||||
try {
|
||||
var response = await _productService.checkPin(data,pin);
|
||||
CheckPinResponse allCartItems = checkPinResponseFromJson(response.toString());
|
||||
|
||||
return right(allCartItems);
|
||||
} on DioException catch (e) {
|
||||
|
||||
var error = CustomDioExceptions.handleError(e);
|
||||
return left(error);
|
||||
}
|
||||
}
|
||||
|
||||
FutureResult<String> addToWish(data) async {
|
||||
try {
|
||||
var response = await _productService.addToWish(data);
|
||||
@@ -134,6 +163,8 @@ class ProductRepo {
|
||||
|
||||
BannerModel bannerresponse = bannerFromJson(response.toString());
|
||||
|
||||
print("skjdgkjdsf ${bannerresponse}");
|
||||
|
||||
final String model = response.toString();
|
||||
|
||||
return right(bannerresponse);
|
||||
|
||||
@@ -50,6 +50,22 @@ class ProductService extends ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future getItemCards(data) async {
|
||||
var response = await api.get(APIURL.getItemCards, data: jsonEncode(data));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Future checkPin(data,pin) async {
|
||||
var response = await api.get(APIURL.checkPin+pin, data: jsonEncode(data));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Future addToWish(data) async {
|
||||
|
||||
@@ -20,11 +20,10 @@ class BestDealScreen extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _BestDealScreenState extends State<BestDealScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
centerTitle: true,
|
||||
leading: Center(
|
||||
@@ -59,7 +58,7 @@ class _BestDealScreenState extends State<BestDealScreen> {
|
||||
)
|
||||
],
|
||||
),
|
||||
floatingActionButton: Padding(
|
||||
floatingActionButton: Padding(
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
child: Container(
|
||||
height: 80,
|
||||
@@ -278,12 +277,19 @@ class _BestDealScreenState extends State<BestDealScreen> {
|
||||
alignment: Alignment.centerRight,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
print(
|
||||
"Add to Cart Pressed for ${bestdealproduct.id}");
|
||||
|
||||
if (await SharedPrefUtils.getToken() != null) {
|
||||
provider.isLoading[bestdealproduct.id] ??
|
||||
false
|
||||
? null
|
||||
: () => provider.addToCart(
|
||||
context, bestdealproduct.id!);
|
||||
// if (!(provider
|
||||
// .isLoading[bestdealproduct.id] ??
|
||||
// false))
|
||||
// {
|
||||
|
||||
await provider.addToCart(
|
||||
context, bestdealproduct.id!);
|
||||
|
||||
// }
|
||||
} else {
|
||||
context.push(MyRoutes.LOGIN);
|
||||
}
|
||||
@@ -291,18 +297,34 @@ class _BestDealScreenState extends State<BestDealScreen> {
|
||||
child: Container(
|
||||
height:
|
||||
MediaQuery.of(context).size.height * 0.035,
|
||||
width: MediaQuery.of(context).size.width *
|
||||
0.12, // Adjusted dynamic width
|
||||
width: MediaQuery.of(context).size.width * 0.1,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Add',
|
||||
style:
|
||||
context.customRegular(Colors.white, 12),
|
||||
),
|
||||
child: provider
|
||||
.isLoading[bestdealproduct.id] ??
|
||||
false
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
height: 10,
|
||||
width: 10,
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
strokeWidth: 2),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
// provider.cartItems
|
||||
// .contains(bestdealproduct.id)
|
||||
// ? 'Added'
|
||||
// :
|
||||
'Add',
|
||||
style: context.customRegular(
|
||||
Colors.white, 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:grocery_app/src/ui/cart/cartview_screen.dart';
|
||||
import 'package:grocery_app/src/ui/favourite/favourite_screen.dart';
|
||||
import 'package:grocery_app/src/ui/header.dart';
|
||||
@@ -40,20 +41,40 @@ class _BottomBarState extends State<BottomBarWidget> {
|
||||
initialPage: 0,
|
||||
keepPage: true,
|
||||
);
|
||||
|
||||
determinePosition();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future<void> determinePosition() async {
|
||||
bool serviceEnabled;
|
||||
LocationPermission permission;
|
||||
serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!serviceEnabled) {
|
||||
return Future.error('Location services are disabled.');
|
||||
}
|
||||
permission = await Geolocator.checkPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
permission = await Geolocator.requestPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
return Future.error('Location permissions are denied');
|
||||
}
|
||||
}
|
||||
if (permission == LocationPermission.deniedForever) {
|
||||
return Future.error(
|
||||
'Location permissions are permanently denied, we cannot request permissions.');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SizeConfig().init(context);
|
||||
|
||||
return Scaffold(
|
||||
|
||||
body: PageView(
|
||||
controller: bottomWidgetPageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: <Widget>[
|
||||
|
||||
HomeScreen(),
|
||||
FavouriteScreen(),
|
||||
Mycart(),
|
||||
|
||||
@@ -15,9 +15,12 @@ class CartItem extends StatelessWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// final theme = context.theme;
|
||||
return Padding(
|
||||
Widget build(BuildContext context)
|
||||
{
|
||||
|
||||
return
|
||||
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -90,5 +93,7 @@ class CartItem extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_animate/flutter_animate.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.dart';
|
||||
import 'package:grocery_app/src/common_widget/textfield_widget.dart';
|
||||
import 'package:grocery_app/src/logic/provider/addTocart_provider.dart';
|
||||
import 'package:grocery_app/src/logic/provider/home_provider.dart';
|
||||
import 'package:grocery_app/src/ui/bestdeal/bestdeal_screen.dart';
|
||||
import 'package:grocery_app/src/ui/cart/cart_item.dart';
|
||||
import 'package:grocery_app/src/ui/widgets/custom_icon_button.dart';
|
||||
import 'package:grocery_app/src/ui/widgets/elevated_button.dart';
|
||||
import 'package:grocery_app/utils/constants/assets_constant.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/constants/string_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/extensions.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Mycart extends StatefulWidget {
|
||||
const Mycart({super.key});
|
||||
@@ -19,27 +28,22 @@ class Mycart extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MycartState extends State<Mycart> {
|
||||
@override
|
||||
void initState() {
|
||||
Provider.of<AddtocartProvider>(context, listen: false)
|
||||
.getItemCards(context);
|
||||
Provider.of<AddtocartProvider>(context, listen: false)
|
||||
.getCurrentLocation(context);
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
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: Center(
|
||||
child: const Text(
|
||||
'Cart 🛒',
|
||||
@@ -49,194 +53,457 @@ class _MycartState extends State<Mycart> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// actions: [
|
||||
// InkWell(
|
||||
// onTap: () {},
|
||||
// child: Icon(
|
||||
// MdiIcons.magnify,
|
||||
// size: 35,
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
separatorBuilder: (_, index) => Padding(
|
||||
padding: EdgeInsets.only(top: 12.h, bottom: 24.h),
|
||||
child: const Divider(thickness: 1),
|
||||
),
|
||||
itemCount: 10,
|
||||
itemBuilder: (context, index) => CartItem(
|
||||
//product: controller.products[index],
|
||||
)
|
||||
.animate(delay: (100 * index).ms)
|
||||
.fade()
|
||||
.slideX(
|
||||
duration: 300.ms,
|
||||
begin: -1,
|
||||
curve: Curves.easeInSine,
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
cartItems(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"Best Deal",
|
||||
"Before you checkout",
|
||||
style: context.customExtraBold(Colors.black, 18),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const BestDealScreen();
|
||||
},
|
||||
));
|
||||
},
|
||||
child: Text(
|
||||
"See All",
|
||||
style: context.customMedium(APPCOLOR.lightGreen, 16),
|
||||
),
|
||||
relatedProduct(),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Divider(),
|
||||
cartPlace(),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
SizedBox(
|
||||
height: 222,
|
||||
child: ListView.builder(
|
||||
itemCount: 5,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 10, bottom: 5, top: 5),
|
||||
child: Container(
|
||||
height: 215,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.1),
|
||||
blurRadius: 1,
|
||||
offset: const Offset(5, 5),
|
||||
),
|
||||
]),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget relatedProduct() {
|
||||
return SizedBox(
|
||||
height: 222,
|
||||
child: ListView.builder(
|
||||
itemCount: 5,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 10, bottom: 5, top: 5),
|
||||
child: Container(
|
||||
height: 215,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.1),
|
||||
blurRadius: 1,
|
||||
offset: const Offset(5, 5),
|
||||
),
|
||||
]),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 100,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.bgGrey,
|
||||
borderRadius: BorderRadius.circular(15)),
|
||||
child: const Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 100,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.bgGrey,
|
||||
borderRadius: BorderRadius.circular(15)),
|
||||
child: const Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
AppNetworkImage(
|
||||
height: 70,
|
||||
width: 70,
|
||||
imageUrl:
|
||||
"https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
|
||||
backGroundColor: Colors.transparent),
|
||||
Positioned(
|
||||
right: 5,
|
||||
top: 5,
|
||||
child: Icon(Icons.favorite_border))
|
||||
],
|
||||
AppNetworkImage(
|
||||
height: 70,
|
||||
width: 70,
|
||||
imageUrl:
|
||||
"https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
|
||||
backGroundColor: Colors.transparent),
|
||||
Positioned(
|
||||
right: 5,
|
||||
top: 5,
|
||||
child: Icon(Icons.favorite_border))
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Fortune Arhar Dal (Toor Dal)",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"500 ML",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(
|
||||
Colors.grey.withOpacity(0.8), 12),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"\$12",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customSemiBold(Colors.black, 12),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Text(
|
||||
"\$14",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context
|
||||
.customMedium(
|
||||
Colors.grey.withOpacity(0.8), 12)
|
||||
.copyWith(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
height: 30,
|
||||
width: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Add',
|
||||
style: context.customRegular(Colors.white, 12),
|
||||
)),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Fortune Arhar Dal (Toor Dal)",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style:
|
||||
context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"500 ML",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(
|
||||
Colors.grey.withOpacity(0.8), 12),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"\$12",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customSemiBold(
|
||||
Colors.black, 12),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Text(
|
||||
"\$14",
|
||||
textAlign: TextAlign.left,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context
|
||||
.customMedium(
|
||||
Colors.grey.withOpacity(0.8), 12)
|
||||
.copyWith(
|
||||
decoration:
|
||||
TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
height: 30,
|
||||
width: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Add',
|
||||
style: context.customRegular(
|
||||
Colors.white, 12),
|
||||
)),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cartItems() {
|
||||
return Consumer<AddtocartProvider>(builder: (context, provider, child) {
|
||||
if (provider.isLoaddcartItem) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 120),
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
} else if (provider.allitem != null) {
|
||||
return Center(child: Text('🛒 Your Front Shop Cart is empty'));
|
||||
} else {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true, // Prevents internal scrolling
|
||||
physics: NeverScrollableScrollPhysics(), // Disables inner scroll
|
||||
separatorBuilder: (_, index) => Padding(
|
||||
padding: EdgeInsets.only(top: 12.h, bottom: 24.h),
|
||||
child: const Divider(thickness: 1),
|
||||
),
|
||||
itemCount: provider.allitem.items!.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: AppNetworkImage(
|
||||
width: 50.w,
|
||||
height: 40.h,
|
||||
imageUrl:
|
||||
'https://i.pinimg.com/originals/a5/f3/5f/a5f35fb23e942809da3df91b23718e8d.png',
|
||||
backGroundColor: APPCOLOR.bgGrey,
|
||||
radius: 10,
|
||||
),
|
||||
),
|
||||
// Image.asset(product.image, width: 50.w, height: 40.h),
|
||||
|
||||
16.horizontalSpace,
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Vegitables and Fruits",
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
),
|
||||
5.verticalSpace,
|
||||
Text(
|
||||
'1kg, 10\$',
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
CustomIconButton(
|
||||
width: 20.w,
|
||||
height: 20.h,
|
||||
onPressed: () {},
|
||||
icon: SvgPicture.asset(
|
||||
APPASSETS.removeIcon,
|
||||
fit: BoxFit.none,
|
||||
),
|
||||
backgroundColor: APPCOLOR.appGreen,
|
||||
),
|
||||
16.horizontalSpace,
|
||||
Text(
|
||||
"10",
|
||||
style: context.customMedium(APPCOLOR.balck1A1A1A, 14),
|
||||
),
|
||||
16.horizontalSpace,
|
||||
CustomIconButton(
|
||||
width: 20.w,
|
||||
height: 20.h,
|
||||
onPressed: () {},
|
||||
icon: SvgPicture.asset(
|
||||
APPASSETS.addIcon,
|
||||
fit: BoxFit.none,
|
||||
),
|
||||
backgroundColor: APPCOLOR.appGreen,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
).animate(delay: (100 * index).ms).fade().slideX(
|
||||
duration: 300.ms,
|
||||
begin: -1,
|
||||
curve: Curves.easeInSine,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget cartPlace() {
|
||||
return Consumer<AddtocartProvider>(builder: (context, provider, child) {
|
||||
print("jdhfgkdfkjg ${provider.allitem.createdAt}");
|
||||
if (provider.isLoaddcartItem) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 120),
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
} else if (provider.allitem == null) {
|
||||
return Center(child: Text('🛒 Your Front Shop Cart is empty'));
|
||||
} else if (provider.allitem.items != null) {
|
||||
return Center(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
|
||||
onPressed: () {},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('Continue Shopping',
|
||||
style: TextStyle(fontSize: 16, color: Colors.white))
|
||||
],
|
||||
),
|
||||
));
|
||||
} else {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ListTile(
|
||||
leading: Icon(Icons.local_offer, color: Colors.green),
|
||||
title: Text('APPLY COUPON',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
trailing: Icon(Icons.arrow_forward_ios),
|
||||
onTap: () {},
|
||||
),
|
||||
SummaryRow(label: 'Item Total', value: '\$24'),
|
||||
SummaryRow(label: 'Discount', value: '\$2'),
|
||||
SummaryRow(label: 'Delivery Free', value: 'Free', isGreen: true),
|
||||
Divider(),
|
||||
SummaryRow(label: 'Grand Total', value: '\$22', isBold: true),
|
||||
ListTile(
|
||||
leading: Icon(Icons.home, color: Colors.green),
|
||||
title: provider.isDeliverable
|
||||
? Text('Delivering to : ${provider.pinCode}')
|
||||
: Text(
|
||||
'Out Of Stock : ${provider.pinCode}',
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
trailing: Text('Change', style: TextStyle(color: Colors.blue)),
|
||||
onTap: () {
|
||||
_showBottomSheet(context);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
|
||||
onPressed: () {},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('\$22 Place Order', style: TextStyle(fontSize: 16))
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _showBottomSheet(BuildContext context) {
|
||||
TextEditingController checkPinCode = TextEditingController();
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return Consumer<AddtocartProvider>(
|
||||
builder: (context, pinProvider, child) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(20.w),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Form(
|
||||
child: Container(
|
||||
width: 200.h,
|
||||
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(
|
||||
8), // Border radius for container
|
||||
border: Border.all(color: Colors.grey, width: 1),
|
||||
), // Border for the container
|
||||
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Container(
|
||||
height: 20.h,
|
||||
child: TextFormField(
|
||||
controller: checkPinCode,
|
||||
keyboardType: TextInputType.phone,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Enter PIN',
|
||||
border: InputBorder
|
||||
.none, // Remove the inner border
|
||||
),
|
||||
)
|
||||
],
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Cannot be empty';
|
||||
} else if (!RegExp(r'^[0-9]{4,6}$')
|
||||
.hasMatch(value)) {
|
||||
return 'Enter a valid PIN (4-6 digits)';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
pinProvider.checkPin(context, checkPinCode.text);
|
||||
},
|
||||
child: Expanded(
|
||||
flex: 1,
|
||||
child: Text(
|
||||
"Check PIN",
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black),
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
Gap(10.h),
|
||||
// if (!pinProvider.isMatch)
|
||||
Text(
|
||||
'pin code invoild',
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
Gap(10.h),
|
||||
Center(
|
||||
child: SizedBox(
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: ButtonElevated(
|
||||
text: 'Submit',
|
||||
onPressed: () {},
|
||||
backgroundColor: APPCOLOR.appGreen),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SummaryRow extends StatelessWidget {
|
||||
final String label, value;
|
||||
final bool isGreen, isBold;
|
||||
|
||||
SummaryRow(
|
||||
{required this.label,
|
||||
required this.value,
|
||||
this.isGreen = false,
|
||||
this.isBold = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: isBold ? FontWeight.bold : FontWeight.normal)),
|
||||
Text(value,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
|
||||
color: isGreen ? Colors.green : Colors.black)),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -109,11 +109,7 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
|
||||
itemBuilder: (context, index) {
|
||||
var product = provider.products[index];
|
||||
|
||||
print("jndsfkgkdfg ${product.isInWishlist}");
|
||||
|
||||
if (product.isInWishlist) {
|
||||
provider.wishlist.add(product.id);
|
||||
}
|
||||
|
||||
return Container(
|
||||
height: itemHeight,
|
||||
decoration: BoxDecoration(
|
||||
@@ -151,41 +147,61 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
|
||||
"https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
|
||||
backGroundColor: Colors.transparent,
|
||||
),
|
||||
// Positioned(
|
||||
// right: 5,
|
||||
// top: 5,
|
||||
// child: InkWell(
|
||||
// onTap: () async {
|
||||
// if (await SharedPrefUtils.getToken() !=
|
||||
// null) {
|
||||
// if (product.isInWishlist) {
|
||||
// Fluttertoast.showToast(
|
||||
// msg: "Item already added!",
|
||||
// toastLength: Toast.LENGTH_SHORT,
|
||||
// gravity: ToastGravity.BOTTOM,
|
||||
// backgroundColor: Colors.green,
|
||||
// textColor: Colors.white,
|
||||
// fontSize: 14.0,
|
||||
// );
|
||||
// } else {
|
||||
// //product.isInWishlist=ture;
|
||||
// provider
|
||||
// .toggleWishlist1(product.id!);
|
||||
// }
|
||||
// } else {
|
||||
// context.push(MyRoutes.LOGIN);
|
||||
// }
|
||||
// },
|
||||
// child: Icon(
|
||||
// product.isInWishlist
|
||||
// ? Icons.favorite
|
||||
// : Icons.favorite_border,
|
||||
// color: product.isInWishlist
|
||||
// ? Colors.red
|
||||
// : Colors.grey,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
Positioned(
|
||||
right: 5,
|
||||
top: 5,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
if (await SharedPrefUtils.getToken() !=
|
||||
null)
|
||||
{
|
||||
if (product.isInWishlist)
|
||||
{
|
||||
Fluttertoast.showToast(
|
||||
msg: "Item already added!",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0,
|
||||
);
|
||||
} else
|
||||
{
|
||||
|
||||
|
||||
//product.isInWishlist=ture;
|
||||
provider.toggleWishlist1( product.id!);
|
||||
|
||||
}
|
||||
null) {
|
||||
provider.toggleWishlist(
|
||||
context, product.id!);
|
||||
} else {
|
||||
context.push(MyRoutes.LOGIN);
|
||||
}
|
||||
},
|
||||
child: Icon(
|
||||
product.isInWishlist
|
||||
provider.wishlist.contains(product.id)
|
||||
? Icons.favorite
|
||||
: Icons.favorite_border,
|
||||
color: product.isInWishlist
|
||||
color: provider.wishlist
|
||||
.contains(product.id)
|
||||
? Colors.red
|
||||
: Colors.grey,
|
||||
),
|
||||
@@ -246,37 +262,56 @@ class _FruitVeggieDetailState extends State<FruitVeggieDetail> {
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
if (await SharedPrefUtils.getToken() !=
|
||||
null) {
|
||||
provider.isLoading[product.id] ??
|
||||
false
|
||||
? null
|
||||
: () => provider.addToCart(
|
||||
context, product.id!);
|
||||
} else {
|
||||
context.push(MyRoutes.LOGIN);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height: 40,
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Add',
|
||||
style: context.customRegular(
|
||||
Colors.white, 12),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
print(
|
||||
"Add to Cart Pressed for ${product.id}");
|
||||
|
||||
if (await SharedPrefUtils.getToken() !=
|
||||
null) {
|
||||
await provider.addToCart(
|
||||
context, product.id!);
|
||||
} else {
|
||||
context.push(MyRoutes.LOGIN);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height:
|
||||
MediaQuery.of(context).size.height *
|
||||
0.035,
|
||||
width: MediaQuery.of(context).size.width *
|
||||
0.1,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: provider.isLoading[product.id] ??
|
||||
false
|
||||
? Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
height: 10,
|
||||
width: 10,
|
||||
child:
|
||||
CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
strokeWidth: 2),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
// provider.cartItems
|
||||
// .contains(bestdealproduct.id)
|
||||
// ? 'Added'
|
||||
// :
|
||||
'Add',
|
||||
style: context.customRegular(
|
||||
Colors.white, 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -314,8 +314,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// const Spacer(),
|
||||
const Spacer(),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: GestureDetector(
|
||||
@@ -325,27 +324,18 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
if (await SharedPrefUtils.getToken() !=
|
||||
null) {
|
||||
if (!(provider
|
||||
.isLoading[bestdealproduct.id] ??
|
||||
false)) {
|
||||
await provider.addToCart(
|
||||
context, bestdealproduct.id!);
|
||||
}
|
||||
// if (!(provider
|
||||
// .isLoading[bestdealproduct.id] ??
|
||||
// false))
|
||||
// {
|
||||
|
||||
await provider.addToCart(
|
||||
context, bestdealproduct.id!);
|
||||
|
||||
// }
|
||||
} else {
|
||||
context.push(MyRoutes.LOGIN);
|
||||
}
|
||||
|
||||
// if (await SharedPrefUtils.getToken() != null)
|
||||
// {
|
||||
|
||||
// provider.isLoading[bestdealproduct.id] ?? false
|
||||
// ? null
|
||||
// : () => provider.addToCart(
|
||||
// context, bestdealproduct.id!);
|
||||
// } else
|
||||
// {
|
||||
// context.push(MyRoutes.LOGIN);
|
||||
// }
|
||||
},
|
||||
child: Container(
|
||||
height: MediaQuery.of(context).size.height *
|
||||
@@ -353,23 +343,29 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
width:
|
||||
MediaQuery.of(context).size.width * 0.1,
|
||||
decoration: BoxDecoration(
|
||||
color: provider.cartItems
|
||||
.contains(bestdealproduct.id)
|
||||
? Colors.grey
|
||||
: APPCOLOR.lightGreen,
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Center(
|
||||
child: provider.isLoading[
|
||||
bestdealproduct.id] ??
|
||||
false
|
||||
? CircularProgressIndicator(
|
||||
color: Colors.white, strokeWidth: 2)
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
height: 10,
|
||||
width: 10,
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
strokeWidth: 2),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
provider.cartItems.contains(
|
||||
bestdealproduct.id)
|
||||
? 'Added'
|
||||
: 'Add',
|
||||
// provider.cartItems
|
||||
// .contains(bestdealproduct.id)
|
||||
// ? 'Added'
|
||||
// :
|
||||
'Add',
|
||||
style: context.customRegular(
|
||||
Colors.white, 12),
|
||||
),
|
||||
|
||||
87
lib/src/ui/widgets/elevated_button.dart
Normal file
87
lib/src/ui/widgets/elevated_button.dart
Normal file
@@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/extensions.dart';
|
||||
|
||||
class ButtonElevated extends StatelessWidget {
|
||||
final String text;
|
||||
final VoidCallback? onPressed;
|
||||
final double? height;
|
||||
final double? elevation;
|
||||
final double? width;
|
||||
final Color? backgroundColor;
|
||||
final bool enabled;
|
||||
final OutlinedBorder? shape;
|
||||
final Color? textColor;
|
||||
final double? borderRadius;
|
||||
final double? fontSize;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final Color? borderColor;
|
||||
final Icon? leadingIcon;
|
||||
final Icon? suffixIcon;
|
||||
|
||||
//final Color? disabledBackgroundColor;
|
||||
|
||||
const ButtonElevated({
|
||||
Key? key,
|
||||
required this.text,
|
||||
required this.onPressed,
|
||||
this.height,
|
||||
this.width,
|
||||
this.elevation,
|
||||
this.backgroundColor,
|
||||
//this.disabledBackgroundColor,
|
||||
this.textColor,
|
||||
this.enabled = true,
|
||||
this.borderColor,
|
||||
this.shape,
|
||||
this.borderRadius,
|
||||
this.fontSize,
|
||||
this.padding,
|
||||
this.suffixIcon,
|
||||
this.leadingIcon,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return ElevatedButton(
|
||||
onPressed: enabled ? onPressed : null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
side: BorderSide(color: borderColor ?? APPCOLOR.whiteFBFEFB),
|
||||
elevation: elevation ?? 2,
|
||||
padding: padding ?? EdgeInsets.symmetric(horizontal: 5.w),
|
||||
backgroundColor: enabled
|
||||
? (backgroundColor ?? APPCOLOR.appGreen)
|
||||
: APPCOLOR.bgGrey,
|
||||
//disabledBackgroundColor??
|
||||
minimumSize: Size(width ?? constraints.minWidth, height ?? 40.h),
|
||||
shape: shape ??
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4.r),
|
||||
),
|
||||
),
|
||||
child: FittedBox(
|
||||
child: Row(
|
||||
children: [
|
||||
if (leadingIcon != null) leadingIcon!,
|
||||
if (leadingIcon != null) Gap(5.w),
|
||||
Text(
|
||||
text,
|
||||
style: context.titleTextStyle.copyWith(
|
||||
color: textColor ?? context.appColor.whiteColor,
|
||||
fontSize: fontSize ?? 16.sp,
|
||||
),
|
||||
),
|
||||
if (suffixIcon != null) Gap(5.w),
|
||||
if (suffixIcon != null) suffixIcon!,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user