This commit is contained in:
Phuoc Nguyen
2025-10-24 16:20:48 +07:00
parent eaaa9921f5
commit b27c5d7742
17 changed files with 3245 additions and 5 deletions

View File

@@ -5,18 +5,20 @@ 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:shimmer/shimmer.dart';
import 'package:worker/core/constants/ui_constants.dart';
import 'package:worker/core/theme/colors.dart';
import 'package:worker/features/favorites/presentation/providers/favorites_provider.dart';
import 'package:worker/features/products/domain/entities/product.dart';
import 'package:worker/generated/l10n/app_localizations.dart';
/// Product Card Widget
///
/// Displays product information in a card format.
/// Includes image, name, price, stock status, and add to cart button.
class ProductCard extends StatelessWidget {
/// Includes image, name, price, stock status, favorite toggle, and add to cart button.
class ProductCard extends ConsumerWidget {
final Product product;
final VoidCallback? onTap;
final VoidCallback? onAddToCart;
@@ -34,8 +36,9 @@ class ProductCard extends StatelessWidget {
}
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context)!;
final isFavorited = ref.watch(isFavoriteProvider(product.productId));
return Card(
elevation: ProductCardSpecs.elevation,
@@ -131,6 +134,56 @@ class ProductCard extends StatelessWidget {
),
),
),
// Favorite Button (bottom-left corner)
Positioned(
bottom: AppSpacing.sm,
left: AppSpacing.sm,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
ref
.read(favoritesProvider.notifier)
.toggleFavorite(product.productId);
// Show feedback
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
isFavorited
? 'Đã xóa khỏi yêu thích'
: 'Đã thêm vào yêu thích',
),
duration: const Duration(seconds: 1),
behavior: SnackBarBehavior.floating,
),
);
},
borderRadius: BorderRadius.circular(20),
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: AppColors.white,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 6,
offset: const Offset(0, 2),
),
],
),
child: Icon(
isFavorited ? Icons.favorite : Icons.favorite_border,
color: isFavorited ? AppColors.danger : AppColors.grey500,
size: 20,
),
),
),
),
),
],
),
),