import 'package:flutter/material.dart'; import '../models/product_model.dart'; import '../services/cart_service.dart'; // Added /// An improved ProductCard widget that works with the enhanced theme system /// - More efficient layout with better organization /// - Uses semantic theme properties for consistent styling /// - Responsive design with flexible sizing class ProductCard extends StatelessWidget { final Product product; // final VoidCallback? onAddToCart; // Removed const ProductCard({ super.key, required this.product, // this.onAddToCart, // Removed }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; return Card( clipBehavior: Clip.antiAlias, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ _buildProductImage(context), Expanded( child: Padding( padding: const EdgeInsets.all(5.0), child: _buildProductDetails(context), ), ), ], ), ); } Widget _buildProductImage(BuildContext context) { return AspectRatio( aspectRatio: 3 / 2, // Adjusted for potentially taller cards. Original 16/10 or 3/2 child: Stack( fit: StackFit.expand, children: [ Image.network( product.imageUrl, fit: BoxFit.cover, loadingBuilder: _imageLoadingBuilder, errorBuilder: _imageErrorBuilder, ), Positioned( top: 8, right: 8, child: _buildCategoryBadge(context), ), ], ), ); } Widget _buildCategoryBadge(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: colorScheme.secondaryContainer.withOpacity(0.85), borderRadius: BorderRadius.circular(4), ), child: Text( product.category, style: theme.textTheme.labelSmall?.copyWith( color: Color(0xFFFFFFFF), fontWeight: FontWeight.w500, ), ), ); } Widget _buildProductDetails(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( product.name, style: Theme.of(context).textTheme.titleMedium, maxLines: 1, // Changed to 1 for consistency, can be 2 if design allows overflow: TextOverflow.ellipsis, ), const SizedBox(height: 10), Text( product.description, style: Theme.of(context).textTheme.bodySmall, maxLines: 2, // Can be adjusted overflow: TextOverflow.ellipsis, ), const Spacer(), const SizedBox(height: 14), _buildPriceAndAction(context), ], ); } Widget _buildPriceAndAction(BuildContext context) { final theme = Theme.of(context); return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, // Ensures spacing children: [ Text( '\$${product.price.toStringAsFixed(2)}', style: theme.textTheme.titleMedium?.copyWith( color: theme.colorScheme.primary, fontWeight: FontWeight.bold, ), ), // const Spacer(), // Removed as MainAxisAlignment.spaceBetween handles it _buildAddToCartButton(context), ], ); } Widget _buildAddToCartButton(BuildContext context) { return IconButton( onPressed: () => _handleAddToCart(context), icon: const Icon(Icons.add_shopping_cart_outlined), style: IconButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary.withOpacity(0.1), foregroundColor: Theme.of(context).colorScheme.primary, ), tooltip: 'Add to cart', ); } void _handleAddToCart(BuildContext context) { final cartService = CartService(); // Get singleton instance cartService.addItem(product); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('${product.name} added to cart'), duration: const Duration(seconds: 2), action: SnackBarAction( label: 'VIEW CART', onPressed: () { Navigator.pushNamed(context, '/cart'); }, ), ), ); } Widget _imageLoadingBuilder( BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { if (loadingProgress == null) return child; return Center( child: CircularProgressIndicator( value: loadingProgress.expectedTotalBytes != null ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes! : null, strokeWidth: 2.0, color: Theme.of(context).colorScheme.primary, ), ); } Widget _imageErrorBuilder( BuildContext context, Object exception, StackTrace? stackTrace) { final theme = Theme.of(context); return Container( color: theme.colorScheme.surfaceVariant, // Or surface.withOpacity(0.1) child: Center( child: Icon( Icons.broken_image_outlined, size: 40, color: theme.colorScheme.onSurfaceVariant.withOpacity(0.6), ), ), ); } }