1)getProduct api Integration
2)getCategory wise product api integration 3)Category wise product filter added
This commit is contained in:
parent
7aa59ca145
commit
43413ac168
64
lib/controller/product_controller.dart
Normal file
64
lib/controller/product_controller.dart
Normal file
@ -0,0 +1,64 @@
|
||||
import 'package:cheminova/controller/product_service.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
|
||||
class ProductController extends GetxController {
|
||||
final ProductService productService = ProductService();
|
||||
var products = <Map<String, dynamic>>[].obs;
|
||||
var categories = <String>[].obs; // Holds the list of categories
|
||||
var selectedCategory = Rxn<String>(); // Holds the selected category
|
||||
int _currentPage = 1;
|
||||
bool isLoading = false;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
getCategory();
|
||||
getUser();
|
||||
}
|
||||
|
||||
Future<void> getUser() async {
|
||||
if (isLoading) return;
|
||||
isLoading = true;
|
||||
try {
|
||||
final category = selectedCategory.value; // Get the selected category
|
||||
final fetchedProducts = await productService.getProduct(
|
||||
_currentPage,
|
||||
category: category,
|
||||
);
|
||||
|
||||
if (fetchedProducts != null) {
|
||||
products.addAll(fetchedProducts as Iterable<Map<String, dynamic>>);
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error fetching products: $e");
|
||||
} finally {
|
||||
isLoading = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCategory() async {
|
||||
try {
|
||||
final fetchedCategories = await productService.getCategory();
|
||||
if (fetchedCategories != null) {
|
||||
categories.assignAll(fetchedCategories.map((category) => category['categoryName'] as String));
|
||||
categories.insert(0, 'All'); // Add "All" option
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error fetching categories: $e");
|
||||
}
|
||||
}
|
||||
|
||||
void setCategory(String category) {
|
||||
selectedCategory.value = category == 'All' ? null : category;
|
||||
_currentPage = 1;
|
||||
products.clear();
|
||||
getUser();
|
||||
}
|
||||
|
||||
void loadMoreProducts() {
|
||||
_currentPage++;
|
||||
getUser();
|
||||
}
|
||||
}
|
60
lib/controller/product_service.dart
Normal file
60
lib/controller/product_service.dart
Normal file
@ -0,0 +1,60 @@
|
||||
import '../utils/common_api_service.dart';
|
||||
import '../utils/show_snackbar.dart';
|
||||
|
||||
class ProductService {
|
||||
Future<List<Map<String, dynamic>>?> getProduct(int page, {String? category}) async {
|
||||
try {
|
||||
String url;
|
||||
if (category != null && category.isNotEmpty) {
|
||||
url = "/api/product/getAll/user?page=$page&category=$category";
|
||||
} else {
|
||||
url = "/api/product/getAll/user?page=$page"; // URL without category filter
|
||||
}
|
||||
|
||||
final response = await commonApiService<List<Map<String, dynamic>>>(
|
||||
method: "GET",
|
||||
url: url,
|
||||
fromJson: (json) {
|
||||
if (json['products'] != null) {
|
||||
final List<Map<String, dynamic>> products = (json['products'] as List)
|
||||
.map((productJson) => productJson as Map<String, dynamic>)
|
||||
.toList();
|
||||
return products;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
showSnackbar(e.toString());
|
||||
//print("Error: $e");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Future<List<Map<String, dynamic>>?> getCategory() async {
|
||||
try {
|
||||
final response = await commonApiService<List<Map<String, dynamic>>>(
|
||||
method: "GET",
|
||||
url: "/api/category/getCategories",
|
||||
fromJson: (json) {
|
||||
if (json['categories'] != null) {
|
||||
final List<Map<String, dynamic>> category = (json['categories'] as List)
|
||||
.map((productJson) => productJson as Map<String, dynamic>)
|
||||
.toList();
|
||||
return category;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
showSnackbar(e.toString());
|
||||
print("Error: $e");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -110,7 +110,7 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
|
||||
InputField(
|
||||
hintText: "Email",
|
||||
labelText: "Email",
|
||||
controller: userNameController,
|
||||
controller: authController.emailController,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'package:cheminova/models/product_model.dart';
|
||||
import 'package:cheminova/widgets/my_drawer.dart';
|
||||
import 'package:cheminova/widgets/product_card.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../widgets/my_drawer.dart';
|
||||
import '../../widgets/product_card.dart';
|
||||
import '../../controller/product_service.dart';
|
||||
|
||||
class ProductCatalogScreen extends StatefulWidget {
|
||||
const ProductCatalogScreen({super.key});
|
||||
@ -14,22 +14,101 @@ class ProductCatalogScreen extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
|
||||
final List<ProductModel> _productList = [
|
||||
ProductModel(
|
||||
id: '1',
|
||||
name: 'Product 1',
|
||||
price: 100,
|
||||
description: 'Description 1',
|
||||
category: ProductCategory.food,
|
||||
image: 'assets/images/product.png',
|
||||
)
|
||||
];
|
||||
final ProductService _productService = ProductService();
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
List<Map<String, dynamic>> _products = [];
|
||||
List<Map<String, dynamic>> _categories = [];
|
||||
|
||||
int _currentPage = 1;
|
||||
bool _isLoading = false;
|
||||
bool _hasMoreData = true;
|
||||
|
||||
String? _selectedCategory; // Default to null to handle 'All' explicitly
|
||||
String? _selectedPriceRange;
|
||||
String? _selectedAvailability;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchCategories(); // Fetch categories first to set initial filter
|
||||
_fetchProducts(); // Fetch products after setting initial filters
|
||||
_scrollController.addListener(() {
|
||||
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent &&
|
||||
!_isLoading &&
|
||||
_hasMoreData) {
|
||||
_fetchMoreProducts();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _fetchProducts() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
|
||||
// Adjust the category parameter based on the selected category
|
||||
final category = _selectedCategory == 'All' ? null : _selectedCategory;
|
||||
|
||||
final products = await _productService.getProduct(_currentPage, category: category);
|
||||
setState(() {
|
||||
if (products != null) {
|
||||
_products.addAll(products);
|
||||
_hasMoreData = products.isNotEmpty;
|
||||
}
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _fetchCategories() async {
|
||||
final categories = await _productService.getCategory();
|
||||
if (categories != null) {
|
||||
setState(() {
|
||||
_categories = categories;
|
||||
// Add "All" option
|
||||
_categories.insert(1, {'categoryName': 'All'});
|
||||
_selectedCategory = 'All'; // Set initial selected category to "All"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _onCategoryChanged(String? newCategory) {
|
||||
if (newCategory != null) {
|
||||
setState(() {
|
||||
_selectedCategory = newCategory;
|
||||
_products.clear();
|
||||
_currentPage = 1;
|
||||
});
|
||||
_fetchProducts();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _fetchMoreProducts() async {
|
||||
if (!_isLoading && _hasMoreData) {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_currentPage++;
|
||||
});
|
||||
await _fetchProducts();
|
||||
}
|
||||
}
|
||||
|
||||
void _clearFilters() {
|
||||
setState(() {
|
||||
_selectedCategory = null;
|
||||
_selectedPriceRange = null;
|
||||
_selectedAvailability = null;
|
||||
_products.clear();
|
||||
_currentPage = 1;
|
||||
});
|
||||
_fetchProducts();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
final List<String> _filterList = [
|
||||
"Category",
|
||||
"Price Range",
|
||||
"Availability",
|
||||
];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -74,67 +153,158 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: Get.height * 0.02,
|
||||
),
|
||||
Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 18),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(19),
|
||||
side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: Get.height * 0.02),
|
||||
// Search Bar
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18.0),
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Products",
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.white.withOpacity(0.9),
|
||||
),
|
||||
),
|
||||
),
|
||||
color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: Get.height * 0.05,
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: _filterList.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: Chip(
|
||||
label: Text(
|
||||
_filterList[index],
|
||||
style: GoogleFonts.roboto(
|
||||
SizedBox(height: Get.height * 0.02),
|
||||
Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 18),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(19),
|
||||
side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||
),
|
||||
color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Filters",
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: _clearFilters,
|
||||
child: Text(
|
||||
"Clear Filters",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.red,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: Get.height * 0.6,
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
itemCount: 10,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: ProductCard(
|
||||
product: _productList[0],
|
||||
SizedBox(
|
||||
height: Get.height * 0.05,
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: 3,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: _buildFilterDropdown(index),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
SizedBox(
|
||||
height: Get.height * 0.6,
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: _products.length + (_isLoading ? 1 : 0),
|
||||
itemBuilder: (context, index) {
|
||||
if (index >= _products.length) {
|
||||
print("Product length $_products");
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: ProductCard(
|
||||
productModel: _products[index],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFilterDropdown(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return DropdownButton<String>(
|
||||
value: _selectedCategory,
|
||||
hint: const Text("Category"),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
_onCategoryChanged(value);
|
||||
}
|
||||
},
|
||||
items: _categories.map<DropdownMenuItem<String>>((category) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: category['categoryName'],
|
||||
child: Text(category['categoryName']),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
case 1:
|
||||
return DropdownButton<String>(
|
||||
value: _selectedPriceRange,
|
||||
hint: const Text("Price Range"),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedPriceRange = value;
|
||||
});
|
||||
},
|
||||
items: <String>['\$0-\$50', '\$51-\$100', '\$101-\$150']
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
case 2:
|
||||
return DropdownButton<String>(
|
||||
value: _selectedAvailability,
|
||||
hint: const Text("Availability"),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedAvailability = value;
|
||||
});
|
||||
},
|
||||
items: <String>['In Stock', 'Out of Stock']
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
default:
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
import 'package:cheminova/models/product_model.dart';
|
||||
import 'package:cheminova/screens/product/cart_screen.dart';
|
||||
import 'package:cheminova/screens/order/checkout_screen.dart';
|
||||
import 'package:cheminova/widgets/my_drawer.dart';
|
||||
import 'package:cheminova/widgets/product_card.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'cart_screen.dart';
|
||||
|
||||
class ProductDetailScreen extends StatefulWidget {
|
||||
final ProductModel product;
|
||||
const ProductDetailScreen({super.key, required this.product});
|
||||
final Map<String, dynamic>? productModel;
|
||||
ProductModel? product;
|
||||
|
||||
ProductDetailScreen({super.key, this.product, this.productModel});
|
||||
|
||||
@override
|
||||
State<ProductDetailScreen> createState() => _ProductDetailScreenState();
|
||||
@ -93,17 +98,18 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: Image.asset(
|
||||
widget.product.image,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
child: Image.asset("assets/images/product.png", fit: BoxFit.cover,),
|
||||
// Image.asset(
|
||||
// widget.product.image,
|
||||
// fit: BoxFit.cover,
|
||||
// ),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(
|
||||
widget.product.name,
|
||||
widget.productModel!['name'],
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
@ -114,7 +120,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(
|
||||
"₹ ${widget.product.price.toString()}",
|
||||
"₹ ${widget.productModel!['price'].toString()}",
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w800,
|
||||
@ -125,7 +131,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(
|
||||
widget.product.category.name,
|
||||
widget.productModel!['category']['categoryName'],
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
@ -137,7 +143,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(
|
||||
widget.product.description,
|
||||
widget.productModel!['description'],
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
@ -154,7 +160,12 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
|
||||
width: Get.width * 0.9,
|
||||
height: Get.height * 0.06,
|
||||
child: ElevatedButton(
|
||||
onPressed: () => Get.to(() => const CartScreen()),
|
||||
onPressed: () {
|
||||
// Pass the product data to the CartScreen
|
||||
Get.to(() => CartScreen(
|
||||
// Pass the product in a list
|
||||
));
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: const Color(0xFF00784C),
|
||||
|
@ -5,12 +5,15 @@ import 'package:get/get.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
class ProductCard extends StatelessWidget {
|
||||
final ProductModel product;
|
||||
final Map<String, dynamic>? productModel;
|
||||
ProductModel? product;
|
||||
final bool isInCart;
|
||||
final bool isCheckout;
|
||||
const ProductCard({
|
||||
|
||||
ProductCard({
|
||||
super.key,
|
||||
required this.product,
|
||||
this.product,
|
||||
this.productModel,
|
||||
this.isInCart = false,
|
||||
this.isCheckout = false,
|
||||
});
|
||||
@ -20,7 +23,8 @@ class ProductCard extends StatelessWidget {
|
||||
return GestureDetector(
|
||||
onTap: () => isInCart || isCheckout
|
||||
? null
|
||||
: Get.to(() => ProductDetailScreen(product: product)),
|
||||
: Get.to(() =>
|
||||
ProductDetailScreen(productModel: productModel)),
|
||||
child: Card(
|
||||
child: Row(
|
||||
children: [
|
||||
@ -33,7 +37,8 @@ class ProductCard extends StatelessWidget {
|
||||
width: Get.width * 0.30,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: Image.asset(product.image).image,
|
||||
image: AssetImage("assets/images/product.png"),
|
||||
// Image.asset(productModel!['image']).image,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
@ -47,21 +52,21 @@ class ProductCard extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
product.name,
|
||||
productModel!['name'],
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
product.category.name,
|
||||
productModel!['category']['categoryName'],
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"₹ ${product.price.toString()}0",
|
||||
"₹ ${ productModel!['price'].toString()}0",
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
@ -70,100 +75,102 @@ class ProductCard extends StatelessWidget {
|
||||
isCheckout
|
||||
? const SizedBox()
|
||||
: isInCart
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
width: 100,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF004791),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 24,
|
||||
width: 24,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'+',
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
product.quantity.toString(),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
width: 24,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'-',
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
width: 100,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF004791),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 24,
|
||||
width: 24,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
Icons.delete_outline_rounded,
|
||||
color: Colors.red,
|
||||
child: Text(
|
||||
'+',
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: const Color(0xFF00784C),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 18, vertical: 8),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
"Add To Cart",
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
productModel!['brand']['brandName'],
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
width: 24,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'-',
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
Icons.delete_outline_rounded,
|
||||
color: Colors.red,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
: ElevatedButton(
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: const Color(0xFF00784C),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 18, vertical: 8),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
"Add To Cart",
|
||||
style: GoogleFonts.roboto(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user