Files
grocery_user_app-frontend/lib/src/ui/bestdeal/bestdeal_screen.dart
2025-03-24 18:09:54 +05:30

568 lines
23 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_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/data/all_cart_items.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/ui/data_notfound.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/shared_pref_utils.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';
import 'package:shimmer/shimmer.dart';
class BestDealScreen extends StatefulWidget {
const BestDealScreen({super.key});
@override
State<BestDealScreen> createState() => _BestDealScreenState();
}
class _BestDealScreenState extends State<BestDealScreen> {
bool _isSearching = false;
TextEditingController _searchController = TextEditingController();
@override
void initState() {
Provider.of<ProductProvider>(context, listen: false)
.getBestDealProduct(context, '');
super.initState();
}
int calculateDiscountPercentage(double basePrice, double discountPrice) {
print(
"Base Price (Before Discount): $basePrice, Discount Price (After Discount): $discountPrice");
if (basePrice <= 0 || discountPrice <= 0 || discountPrice > basePrice) {
print("Error: Invalid price values.");
return 0;
}
double discountAmount = basePrice - discountPrice;
double discountPercentage = (discountAmount / basePrice) * 100;
return discountPercentage.round();
}
@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: _isSearching
? TextField(
controller: _searchController,
autofocus: true, // Focus on search field when opened
decoration: InputDecoration(
hintText: "Search...",
border: InputBorder.none,
),
style: TextStyle(fontSize: 18),
onChanged: (query) {
// You can call a search function here
},
)
: const Text(
"Best Deal",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w700,
),
),
actions: [
if (_isSearching) // Show search icon only when searching
InkWell(
onTap: () {
Provider.of<ProductProvider>(context, listen: false)
.getBestDealProduct(context, _searchController.text);
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Icon(
MdiIcons.magnify,
size: 35,
),
),
),
InkWell(
onTap: () {
setState(() {
_isSearching = !_isSearching;
if (!_isSearching) {
_searchController.clear(); // Clear search when closed
}
});
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Icon(
_isSearching ? Icons.close : MdiIcons.magnify,
size: 35,
),
),
),
],
),
floatingActionButton: floatingAction(),
body: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: itemBestdeal(),
));
}
Widget floatingAction() {
return Consumer<ProductProvider>(builder: (context, provider, child) {
if (provider.countList.isEmpty) {
return Center();
} else {
return Padding(
padding: const EdgeInsets.only(left: 30),
child: Container(
height: 80,
width: MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
color: APPCOLOR.lightGreen,
borderRadius: BorderRadius.circular(15)),
child: Padding(
padding: const EdgeInsets.all(10),
child: Row(
children: [
SizedBox(
width: 80,
child: Stack(
children: [
Container(
height: 70,
width: 70,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.5),
borderRadius: BorderRadius.circular(10)),
),
Positioned(
left: 20,
bottom: 0,
top: 0,
right: 0,
child: AppNetworkImage(
height: 70,
width: 70,
radius: 10,
imageUrl: provider.lastImageurl ??
"https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg",
backGroundColor: Colors.white,
),
),
],
),
),
const SizedBox(
width: 10,
),
Text(
provider.countList.length.toString(),
style: context.customRegular(
Colors.white,
29,
),
),
const Spacer(),
InkWell(
onTap: () {
context.read<BottomNavProvider>().setIndex(2);
Navigator.pop(context);
},
child: Row(
children: [
Text(
'View Cart',
style: context.customMedium(Colors.white, 24),
),
const SizedBox(
width: 10,
),
const Icon(
Icons.arrow_forward,
color: Colors.white,
size: 35,
),
],
),
)
],
),
),
),
);
}
});
}
Widget itemBestdeal() {
return Consumer<ProductProvider>(builder: (context, provider, child) {
if (provider.isBestdealingloading) {
return Padding(
padding: const EdgeInsets.all(15),
child: GridView.builder(
itemCount: 6, // Number of shimmer items
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.5),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemBuilder: (context, index) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.all(5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.15,
width: MediaQuery.of(context).size.width * 0.4,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(15),
),
),
SizedBox(height: 8),
Container(
height: 10,
width: MediaQuery.of(context).size.width * 0.35,
color: Colors.grey[300],
),
SizedBox(height: 5),
Container(
height: 10,
width: MediaQuery.of(context).size.width * 0.25,
color: Colors.grey[300],
),
SizedBox(height: 10),
Container(
height: 15,
width: MediaQuery.of(context).size.width * 0.3,
color: Colors.grey[300],
),
],
),
),
),
);
},
),
);
} else if (provider.bestdeal.isEmpty) {
return Center(
child: DataNotFound(
imagePath: 'assets/images/cart.jpg',
message: "Sorry! Don't have a product",
width: 300.w,
height: 300.h,
));
} else {
return Padding(
padding: const EdgeInsets.all(15),
child: GridView.builder(
itemCount: provider.bestdeal.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.5),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemBuilder: (context, index) {
var bestdealproduct = provider.bestdeal[index];
return InkWell(
onTap: () {
context.push(
MyRoutes.PRODUCTDETAILS,
extra: {
"id": bestdealproduct.id,
"quantity": 1,
"price": bestdealproduct.discountPrice,
},
);
},
child: Container(
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: MediaQuery.of(context).size.height *
0.15, // Dynamic height
width: MediaQuery.of(context).size.width *
0.4, // Dynamic width
decoration: BoxDecoration(
color: APPCOLOR.bgGrey,
borderRadius: BorderRadius.circular(15),
),
child: Stack(
alignment: Alignment.center,
children: [
Center(
child: AppNetworkImage(
height:
MediaQuery.of(context).size.height * 0.13,
width:
MediaQuery.of(context).size.width * 0.35,
imageUrl: bestdealproduct
.productImages?.first.url ??
"",
backGroundColor: Colors.transparent,
radius: 10,
),
),
Positioned(
right: 1,
bottom: 0,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(5),
),
child: Center(
child: Text(
"${calculateDiscountPercentage(double.parse(bestdealproduct.basePrice), double.parse(bestdealproduct.discountPrice))}% OFF",
style: TextStyle(
color: Colors.white, fontSize: 15)),
),
),
)
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.005),
Text(
bestdealproduct.name ?? "",
textAlign: TextAlign.left,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: context.customMedium(APPCOLOR.balck1A1A1A, 16),
),
Text(
bestdealproduct.unit ?? "",
textAlign: TextAlign.left,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.customMedium(
Colors.grey.withOpacity(0.8),
12,
),
),
if (bestdealproduct!.quantity > 0)
Text("In Stock ",
style:
TextStyle(color: Colors.green, fontSize: 14)),
Spacer(),
Row(
children: [
Column(
children: [
Text(
"${bestdealproduct.discountPrice ?? ""} ",
textAlign: TextAlign.left,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style:
context.customSemiBold(Colors.black, 15),
),
Text(
"${bestdealproduct.basePrice ?? ""}",
textAlign: TextAlign.left,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context
.customMedium(
Colors.grey.withOpacity(0.8),
15,
)
.copyWith(
decoration: TextDecoration.lineThrough,
),
),
],
),
Spacer(),
Align(
alignment: Alignment.centerRight,
child: GestureDetector(
onTap: () async {
if (await SharedPrefUtils.getToken() !=
null) {
await provider.addToWithCart(
context,
bestdealproduct.id!,
bestdealproduct,
bestdealproduct
.productImages?.first.url);
} else {
context.push(MyRoutes.SIGNUP);
}
},
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[
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),
),
),
),
),
),
],
),
],
),
),
),
);
},
),
);
// Padding(
// padding: const EdgeInsets.all(15),
// child: GridView.builder(
// itemCount: provider.bestdeal.length,
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 2,
// childAspectRatio: MediaQuery.of(context).size.width /
// (MediaQuery.of(context).size.height / 1.5),
// crossAxisSpacing: 10,
// mainAxisSpacing: 10,
// ),
// itemBuilder: (context, index) {
// var bestdealproduct = provider.bestdeal[index];
// return InkWell(
// onTap: () {
// context.push(MyRoutes.PRODUCTDETAILS,
// extra: bestdealproduct.id);
// },
// child: Container(
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(15),
// ),
// child: Padding(
// padding: const EdgeInsets.all(5),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Container(
// height: MediaQuery.of(context).size.height * 0.15,
// width: MediaQuery.of(context).size.width * 0.4,
// decoration: BoxDecoration(
// color: APPCOLOR.bgGrey,
// borderRadius: BorderRadius.circular(15),
// ),
// child: AppNetworkImage(
// height: MediaQuery.of(context).size.height * 0.13,
// width: MediaQuery.of(context).size.width * 0.35,
// imageUrl:
// bestdealproduct.productImages?.first.url ?? "",
// backGroundColor: Colors.transparent,
// ),
// ),
// SizedBox(height: 8),
// Text(bestdealproduct.name ?? ""),
// Text(bestdealproduct.unit ?? ""),
// Text(bestdealproduct.quantity > 0
// ? "In Stock"
// : "Out of Stock"),
// Row(
// children: [
// Text("₹${bestdealproduct.discountPrice ?? ""}"),
// Text(
// "₹${bestdealproduct.basePrice ?? ""}",
// style: TextStyle(
// decoration: TextDecoration.lineThrough,
// ),
// ),
// ],
// ),
// ],
// ),
// ),
// ),
// );
// },
// ),
// );
}
});
}
}