|
|
@ -4,7 +4,7 @@ import 'package:youmazgestion/Models/produit.dart'; |
|
|
|
|
|
|
|
|
class ProductCard extends StatefulWidget { |
|
|
class ProductCard extends StatefulWidget { |
|
|
final Product product; |
|
|
final Product product; |
|
|
final void Function(Product, int) onAddToCart; |
|
|
final void Function(Product, int) onAddToCart; |
|
|
|
|
|
|
|
|
const ProductCard({ |
|
|
const ProductCard({ |
|
|
Key? key, |
|
|
Key? key, |
|
|
@ -16,7 +16,8 @@ class ProductCard extends StatefulWidget { |
|
|
State<ProductCard> createState() => _ProductCardState(); |
|
|
State<ProductCard> createState() => _ProductCardState(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin { |
|
|
class _ProductCardState extends State<ProductCard> |
|
|
|
|
|
with TickerProviderStateMixin { |
|
|
int selectedQuantity = 1; |
|
|
int selectedQuantity = 1; |
|
|
late AnimationController _scaleController; |
|
|
late AnimationController _scaleController; |
|
|
late AnimationController _fadeController; |
|
|
late AnimationController _fadeController; |
|
|
@ -26,7 +27,7 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
@override |
|
|
@override |
|
|
void initState() { |
|
|
void initState() { |
|
|
super.initState(); |
|
|
super.initState(); |
|
|
|
|
|
|
|
|
// Animations pour les interactions |
|
|
// Animations pour les interactions |
|
|
_scaleController = AnimationController( |
|
|
_scaleController = AnimationController( |
|
|
duration: const Duration(milliseconds: 200), |
|
|
duration: const Duration(milliseconds: 200), |
|
|
@ -36,7 +37,7 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
duration: const Duration(milliseconds: 300), |
|
|
duration: const Duration(milliseconds: 300), |
|
|
vsync: this, |
|
|
vsync: this, |
|
|
)..forward(); |
|
|
)..forward(); |
|
|
|
|
|
|
|
|
_scaleAnimation = Tween<double>( |
|
|
_scaleAnimation = Tween<double>( |
|
|
begin: 1.0, |
|
|
begin: 1.0, |
|
|
end: 0.95, |
|
|
end: 0.95, |
|
|
@ -44,7 +45,7 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
parent: _scaleController, |
|
|
parent: _scaleController, |
|
|
curve: Curves.easeInOut, |
|
|
curve: Curves.easeInOut, |
|
|
)); |
|
|
)); |
|
|
|
|
|
|
|
|
_fadeAnimation = Tween<double>( |
|
|
_fadeAnimation = Tween<double>( |
|
|
begin: 0.0, |
|
|
begin: 0.0, |
|
|
end: 1.0, |
|
|
end: 1.0, |
|
|
@ -122,7 +123,6 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
: _buildPlaceholderImage(), |
|
|
: _buildPlaceholderImage(), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
|
|
|
|
|
|
Positioned.fill( |
|
|
Positioned.fill( |
|
|
child: Container( |
|
|
child: Container( |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
@ -141,7 +141,6 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
|
|
|
|
|
|
if (widget.product.isStockDefined()) |
|
|
if (widget.product.isStockDefined()) |
|
|
Positioned( |
|
|
Positioned( |
|
|
top: 12, |
|
|
top: 12, |
|
|
@ -183,7 +182,6 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
|
|
|
|
|
|
Positioned( |
|
|
Positioned( |
|
|
left: 0, |
|
|
left: 0, |
|
|
right: 0, |
|
|
right: 0, |
|
|
@ -201,7 +199,8 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
vertical: 8, |
|
|
vertical: 8, |
|
|
), |
|
|
), |
|
|
child: Column( |
|
|
child: Column( |
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
crossAxisAlignment: |
|
|
|
|
|
CrossAxisAlignment.start, |
|
|
children: [ |
|
|
children: [ |
|
|
Text( |
|
|
Text( |
|
|
widget.product.name, |
|
|
widget.product.name, |
|
|
@ -222,7 +221,7 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
), |
|
|
), |
|
|
const SizedBox(height: 4), |
|
|
const SizedBox(height: 4), |
|
|
Text( |
|
|
Text( |
|
|
'${widget.product.price.toStringAsFixed(2)} FCFA', |
|
|
'${widget.product.price.toStringAsFixed(2)} MGA', |
|
|
style: const TextStyle( |
|
|
style: const TextStyle( |
|
|
fontWeight: FontWeight.bold, |
|
|
fontWeight: FontWeight.bold, |
|
|
fontSize: 13, |
|
|
fontSize: 13, |
|
|
@ -239,9 +238,7 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
|
|
|
|
|
|
const SizedBox(height: 12), |
|
|
const SizedBox(height: 12), |
|
|
|
|
|
|
|
|
Row( |
|
|
Row( |
|
|
children: [ |
|
|
children: [ |
|
|
Container( |
|
|
Container( |
|
|
@ -250,7 +247,8 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
borderRadius: BorderRadius.circular(20), |
|
|
borderRadius: BorderRadius.circular(20), |
|
|
boxShadow: [ |
|
|
boxShadow: [ |
|
|
BoxShadow( |
|
|
BoxShadow( |
|
|
color: Colors.black.withOpacity(0.1), |
|
|
color: |
|
|
|
|
|
Colors.black.withOpacity(0.1), |
|
|
blurRadius: 4, |
|
|
blurRadius: 4, |
|
|
offset: const Offset(0, 2), |
|
|
offset: const Offset(0, 2), |
|
|
), |
|
|
), |
|
|
@ -295,9 +293,7 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
|
|
|
|
|
|
const SizedBox(width: 8), |
|
|
const SizedBox(width: 8), |
|
|
|
|
|
|
|
|
Expanded( |
|
|
Expanded( |
|
|
child: MouseRegion( |
|
|
child: MouseRegion( |
|
|
cursor: SystemMouseCursors.click, |
|
|
cursor: SystemMouseCursors.click, |
|
|
@ -306,9 +302,11 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
onTapUp: _onTapUp, |
|
|
onTapUp: _onTapUp, |
|
|
onTapCancel: _onTapCancel, |
|
|
onTapCancel: _onTapCancel, |
|
|
onTap: () { |
|
|
onTap: () { |
|
|
widget.onAddToCart(widget.product, selectedQuantity); |
|
|
widget.onAddToCart(widget.product, |
|
|
|
|
|
selectedQuantity); |
|
|
ScaffoldMessenger.of(context).showSnackBar( |
|
|
|
|
|
|
|
|
ScaffoldMessenger.of(context) |
|
|
|
|
|
.showSnackBar( |
|
|
SnackBar( |
|
|
SnackBar( |
|
|
content: Row( |
|
|
content: Row( |
|
|
children: [ |
|
|
children: [ |
|
|
@ -320,16 +318,20 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
Expanded( |
|
|
Expanded( |
|
|
child: Text( |
|
|
child: Text( |
|
|
'${widget.product.name} (x$selectedQuantity) ajouté au panier', |
|
|
'${widget.product.name} (x$selectedQuantity) ajouté au panier', |
|
|
overflow: TextOverflow.ellipsis, |
|
|
overflow: TextOverflow |
|
|
|
|
|
.ellipsis, |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
backgroundColor: Colors.green, |
|
|
backgroundColor: Colors.green, |
|
|
duration: const Duration(seconds: 1), |
|
|
duration: |
|
|
behavior: SnackBarBehavior.floating, |
|
|
const Duration(seconds: 1), |
|
|
|
|
|
behavior: |
|
|
|
|
|
SnackBarBehavior.floating, |
|
|
shape: RoundedRectangleBorder( |
|
|
shape: RoundedRectangleBorder( |
|
|
borderRadius: BorderRadius.circular(10), |
|
|
borderRadius: |
|
|
|
|
|
BorderRadius.circular(10), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
); |
|
|
); |
|
|
@ -342,21 +344,27 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
gradient: const LinearGradient( |
|
|
gradient: const LinearGradient( |
|
|
colors: [ |
|
|
colors: [ |
|
|
Color.fromARGB(255, 4, 54, 95), |
|
|
Color.fromARGB( |
|
|
Color.fromARGB(255, 6, 80, 140), |
|
|
255, 4, 54, 95), |
|
|
|
|
|
Color.fromARGB( |
|
|
|
|
|
255, 6, 80, 140), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
borderRadius: BorderRadius.circular(20), |
|
|
borderRadius: |
|
|
|
|
|
BorderRadius.circular(20), |
|
|
boxShadow: [ |
|
|
boxShadow: [ |
|
|
BoxShadow( |
|
|
BoxShadow( |
|
|
color: const Color.fromARGB(255, 4, 54, 95).withOpacity(0.3), |
|
|
color: const Color.fromARGB( |
|
|
|
|
|
255, 4, 54, 95) |
|
|
|
|
|
.withOpacity(0.3), |
|
|
blurRadius: 6, |
|
|
blurRadius: 6, |
|
|
offset: const Offset(0, 3), |
|
|
offset: const Offset(0, 3), |
|
|
), |
|
|
), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
child: const Row( |
|
|
child: const Row( |
|
|
mainAxisAlignment: MainAxisAlignment.center, |
|
|
mainAxisAlignment: |
|
|
|
|
|
MainAxisAlignment.center, |
|
|
children: [ |
|
|
children: [ |
|
|
const Icon( |
|
|
const Icon( |
|
|
Icons.add_shopping_cart, |
|
|
Icons.add_shopping_cart, |
|
|
@ -369,10 +377,12 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
'Ajouter', |
|
|
'Ajouter', |
|
|
style: TextStyle( |
|
|
style: TextStyle( |
|
|
color: Colors.white, |
|
|
color: Colors.white, |
|
|
fontWeight: FontWeight.bold, |
|
|
fontWeight: |
|
|
|
|
|
FontWeight.bold, |
|
|
fontSize: 12, |
|
|
fontSize: 12, |
|
|
), |
|
|
), |
|
|
overflow: TextOverflow.ellipsis, |
|
|
overflow: |
|
|
|
|
|
TextOverflow.ellipsis, |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
], |
|
|
], |
|
|
@ -442,10 +452,12 @@ class _ProductCardState extends State<ProductCard> with TickerProviderStateMixin |
|
|
child: Icon( |
|
|
child: Icon( |
|
|
icon, |
|
|
icon, |
|
|
size: 16, |
|
|
size: 16, |
|
|
color: onPressed != null ? const Color.fromARGB(255, 4, 54, 95) : Colors.grey, |
|
|
color: onPressed != null |
|
|
|
|
|
? const Color.fromARGB(255, 4, 54, 95) |
|
|
|
|
|
: Colors.grey, |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|