/// Cart Item Widget /// /// Displays a single item in the cart with image, details, and quantity controls. library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/core/theme/typography.dart'; import 'package:worker/features/cart/presentation/providers/cart_provider.dart'; import 'package:worker/features/cart/presentation/providers/cart_state.dart'; /// Cart Item Widget /// /// Displays: /// - Product image (80x80, rounded) /// - Product name and SKU /// - Price per unit /// - Quantity controls (-, value, +, unit label) class CartItemWidget extends ConsumerWidget { final CartItemData item; const CartItemWidget({ super.key, required this.item, }); @override Widget build(BuildContext context, WidgetRef ref) { final currencyFormatter = NumberFormat.currency( locale: 'vi_VN', symbol: 'đ', decimalDigits: 0, ); return Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Product Image ClipRRect( borderRadius: BorderRadius.circular(8), child: CachedNetworkImage( imageUrl: item.product.imageUrl, width: 80, height: 80, fit: BoxFit.cover, placeholder: (context, url) => Container( width: 80, height: 80, color: AppColors.grey100, child: const Center( child: CircularProgressIndicator( strokeWidth: 2, ), ), ), errorWidget: (context, url, error) => Container( width: 80, height: 80, color: AppColors.grey100, child: const Icon( Icons.image_not_supported, color: AppColors.grey500, ), ), ), ), const SizedBox(width: 12), // Product Info Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Product Name Text( item.product.name, style: AppTypography.titleMedium.copyWith( fontWeight: FontWeight.w600, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), // SKU Text( 'Mã: ${item.product.erpnextItemCode ?? item.product.productId}', style: AppTypography.bodySmall.copyWith( color: AppColors.grey500, ), ), const SizedBox(height: 8), // Price Text( '${currencyFormatter.format(item.product.basePrice)}/${item.product.unit ?? 'm²'}', style: AppTypography.titleMedium.copyWith( color: AppColors.primaryBlue, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), // Quantity Controls Row( children: [ // Decrease button _QuantityButton( icon: Icons.remove, onPressed: () { ref.read(cartProvider.notifier).decrementQuantity( item.product.productId, ); }, ), const SizedBox(width: 12), // Quantity value Text( item.quantity.toStringAsFixed(0), style: AppTypography.titleMedium.copyWith( fontWeight: FontWeight.w600, ), ), const SizedBox(width: 12), // Increase button _QuantityButton( icon: Icons.add, onPressed: () { ref.read(cartProvider.notifier).incrementQuantity( item.product.productId, ); }, ), const SizedBox(width: 8), // Unit label Text( item.product.unit ?? 'm²', style: AppTypography.bodySmall.copyWith( color: AppColors.grey500, ), ), ], ), ], ), ), ], ), ); } } /// Quantity Button /// /// Small circular button for incrementing/decrementing quantity. class _QuantityButton extends StatelessWidget { final IconData icon; final VoidCallback onPressed; const _QuantityButton({ required this.icon, required this.onPressed, }); @override Widget build(BuildContext context) { return InkWell( onTap: onPressed, borderRadius: BorderRadius.circular(20), child: Container( width: 32, height: 32, decoration: BoxDecoration( color: AppColors.grey100, borderRadius: BorderRadius.circular(20), ), child: Icon( icon, size: 18, color: AppColors.grey900, ), ), ); } }