import 'dart:io'; import 'package:flutter/material.dart'; import '../../models/product.dart'; class ProductTile extends StatelessWidget { final Product product; final bool enabled; final VoidCallback onTap; final VoidCallback? onLongPress; static const _tileImageSize = 280.0; const ProductTile({ super.key, required this.product, required this.enabled, required this.onTap, this.onLongPress, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final scheme = theme.colorScheme; final outOfStock = product.isOutOfStock; final lowStock = !outOfStock && product.isLowStock; final hasImage = product.imagePath != null && product.imagePath!.isNotEmpty; final borderColor = outOfStock ? scheme.error.withValues(alpha: 0.7) : lowStock ? Colors.amber.withValues(alpha: 0.9) : scheme.onSurface.withValues(alpha: 0.08); return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), border: Border.all( color: borderColor, width: outOfStock || lowStock ? 2 : 1, ), ), child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Material( color: theme.cardTheme.color ?? scheme.surface, child: InkWell( // Never blocked by stock: the count may simply be off onTap: enabled ? onTap : null, onLongPress: onLongPress, child: Stack( fit: StackFit.expand, children: [ Opacity( opacity: enabled ? 1 : 0.4, child: hasImage ? Image.file( File(product.imagePath!), fit: BoxFit.scaleDown, cacheWidth: _tileImageSize.toInt(), errorBuilder: (context, error, stackTrace) => _noImage(scheme), ) : _noImage(scheme), ), if (hasImage) Positioned.fill( child: DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.transparent, Colors.black.withValues(alpha: 0.35), ], stops: const [0.6, 1.0], ), ), ), ), Positioned( top: 10, right: 10, child: _StockBadge(product: product), ), ], ), ), ), ), ); } Widget _noImage(ColorScheme scheme) { return Center( child: Icon( Icons.image_not_supported_outlined, size: 34, color: scheme.onSurface.withValues(alpha: 0.3), ), ); } } class _StockBadge extends StatelessWidget { final Product product; const _StockBadge({required this.product}); @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; final out = product.isOutOfStock; final low = !out && product.isLowStock; return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: out ? scheme.error.withValues(alpha: 0.9) : low ? Colors.amber.withValues(alpha: 0.9) : scheme.primary.withValues(alpha: 0.85), borderRadius: BorderRadius.circular(999), ), child: Text( product.infiniteStock ? '∞' : '${product.stockQuantity}', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w800, color: out ? scheme.onError : low ? Colors.black : scheme.onPrimary, ), ), ); } }