favorite
This commit is contained in:
284
lib/features/favorites/README.md
Normal file
284
lib/features/favorites/README.md
Normal file
@@ -0,0 +1,284 @@
|
||||
# Favorites Feature
|
||||
|
||||
A complete favorites state management system for the Worker app using **Riverpod 3.0** with code generation and **Hive** for local persistence.
|
||||
|
||||
---
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
```
|
||||
lib/features/favorites/
|
||||
├── data/
|
||||
│ ├── datasources/
|
||||
│ │ └── favorites_local_datasource.dart # Hive operations
|
||||
│ └── models/
|
||||
│ ├── favorite_model.dart # Hive model (TypeId: 28)
|
||||
│ └── favorite_model.g.dart # Generated adapter
|
||||
├── domain/
|
||||
│ └── entities/
|
||||
│ └── favorite.dart # Business entity
|
||||
├── presentation/
|
||||
│ └── providers/
|
||||
│ ├── favorites_provider.dart # Riverpod providers
|
||||
│ └── favorites_provider.g.dart # Generated providers
|
||||
├── INTEGRATION_SUMMARY.md # Complete documentation
|
||||
├── USAGE_EXAMPLES.md # Code examples
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 1. Import Provider
|
||||
```dart
|
||||
import 'package:worker/features/favorites/presentation/providers/favorites_provider.dart';
|
||||
```
|
||||
|
||||
### 2. Check if Product is Favorited
|
||||
```dart
|
||||
final isFavorited = ref.watch(isFavoriteProvider(productId));
|
||||
```
|
||||
|
||||
### 3. Toggle Favorite
|
||||
```dart
|
||||
ref.read(favoritesProvider.notifier).toggleFavorite(productId);
|
||||
```
|
||||
|
||||
### 4. Get Favorites Count
|
||||
```dart
|
||||
final count = ref.watch(favoriteCountProvider);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Available Providers
|
||||
|
||||
| Provider | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `favoritesProvider` | `AsyncNotifier<Set<String>>` | Main favorites state |
|
||||
| `isFavoriteProvider(productId)` | `Provider<bool>` | Check if product is favorited |
|
||||
| `favoriteCountProvider` | `Provider<int>` | Total count of favorites |
|
||||
| `favoriteProductIdsProvider` | `Provider<List<String>>` | All favorite product IDs |
|
||||
| `favoritesLocalDataSourceProvider` | `Provider<DataSource>` | Database access |
|
||||
| `currentUserIdProvider` | `Provider<String>` | Current user ID (TODO: auth) |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Common Use Cases
|
||||
|
||||
### Favorite Button in Product Card
|
||||
```dart
|
||||
class ProductCard extends ConsumerWidget {
|
||||
final String productId;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isFavorited = ref.watch(isFavoriteProvider(productId));
|
||||
|
||||
return IconButton(
|
||||
icon: Icon(
|
||||
isFavorited ? Icons.favorite : Icons.favorite_border,
|
||||
color: isFavorited ? Colors.red : Colors.grey,
|
||||
),
|
||||
onPressed: () {
|
||||
ref.read(favoritesProvider.notifier).toggleFavorite(productId);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Favorites Count Badge
|
||||
```dart
|
||||
class FavoriteBadge extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final count = ref.watch(favoriteCountProvider);
|
||||
|
||||
return Badge(
|
||||
label: Text('$count'),
|
||||
child: Icon(Icons.favorite),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Display All Favorites
|
||||
```dart
|
||||
class FavoritesPage extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final favoritesAsync = ref.watch(favoritesProvider);
|
||||
|
||||
return favoritesAsync.when(
|
||||
data: (favorites) => ListView.builder(
|
||||
itemCount: favorites.length,
|
||||
itemBuilder: (context, index) {
|
||||
final productId = favorites.elementAt(index);
|
||||
return ProductTile(productId: productId);
|
||||
},
|
||||
),
|
||||
loading: () => CircularProgressIndicator(),
|
||||
error: (error, stack) => ErrorWidget(error),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Provider Methods
|
||||
|
||||
### Main Provider (`favoritesProvider.notifier`)
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `addFavorite(productId)` | Add product to favorites |
|
||||
| `removeFavorite(productId)` | Remove product from favorites |
|
||||
| `toggleFavorite(productId)` | Toggle favorite status |
|
||||
| `refresh()` | Reload favorites from database |
|
||||
| `clearAll()` | Remove all favorites |
|
||||
|
||||
---
|
||||
|
||||
## 💾 Data Persistence
|
||||
|
||||
- **Storage**: Hive local database
|
||||
- **Box**: `favorite_box` (HiveBoxNames.favoriteBox)
|
||||
- **Model**: `FavoriteModel` (TypeId: 28)
|
||||
- **Fields**:
|
||||
- `favoriteId`: Unique ID (userId_productId_timestamp)
|
||||
- `productId`: Product reference
|
||||
- `userId`: User reference
|
||||
- `createdAt`: Timestamp
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Important Notes
|
||||
|
||||
### TODO: Auth Integration
|
||||
Currently using hardcoded userId (`'user_001'`). Replace when auth is ready:
|
||||
|
||||
```dart
|
||||
// In favorites_provider.dart
|
||||
@riverpod
|
||||
String currentUserId(Ref ref) {
|
||||
// TODO: Replace with actual auth provider
|
||||
final user = ref.watch(authProvider).user;
|
||||
return user?.id ?? 'guest';
|
||||
}
|
||||
```
|
||||
|
||||
### Hive Box Initialization
|
||||
Ensure the favorites box is opened in `main.dart`:
|
||||
|
||||
```dart
|
||||
await Hive.openBox<FavoriteModel>(HiveBoxNames.favoriteBox);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- **[INTEGRATION_SUMMARY.md](./INTEGRATION_SUMMARY.md)** - Complete technical documentation
|
||||
- **[USAGE_EXAMPLES.md](./USAGE_EXAMPLES.md)** - Comprehensive code examples
|
||||
|
||||
---
|
||||
|
||||
## ✅ Features
|
||||
|
||||
- ✅ Add/remove favorites
|
||||
- ✅ Toggle favorite status
|
||||
- ✅ Persistent storage (Hive)
|
||||
- ✅ Multi-user support
|
||||
- ✅ Optimistic updates
|
||||
- ✅ Error handling
|
||||
- ✅ Loading states
|
||||
- ✅ Debug logging
|
||||
- ✅ Auto-dispose providers
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
```dart
|
||||
test('should add favorite', () async {
|
||||
final container = ProviderContainer();
|
||||
addTearDown(container.dispose);
|
||||
|
||||
await container.read(favoritesProvider.notifier)
|
||||
.addFavorite('product_1');
|
||||
|
||||
final favorites = await container.read(favoritesProvider.future);
|
||||
expect(favorites, contains('product_1'));
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 UI Integration Examples
|
||||
|
||||
See **[USAGE_EXAMPLES.md](./USAGE_EXAMPLES.md)** for:
|
||||
- Favorite buttons with loading states
|
||||
- Favorites page with pull-to-refresh
|
||||
- Empty state handling
|
||||
- Error state handling
|
||||
- App lifecycle management
|
||||
- Performance optimization
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Debugging
|
||||
|
||||
All operations log to console:
|
||||
```
|
||||
[FavoritesProvider] Added favorite: product_123
|
||||
[FavoritesLocalDataSource] Loaded 5 favorites for user: user_001
|
||||
[FavoritesProvider] Error adding favorite: ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Performance
|
||||
|
||||
- **O(1)** favorite lookup using `Set<String>`
|
||||
- **Auto-dispose** providers when not in use
|
||||
- **Selective rebuilds** with `isFavoriteProvider`
|
||||
- **Database compaction** available
|
||||
|
||||
---
|
||||
|
||||
## 🔮 Future Enhancements
|
||||
|
||||
- [ ] Remote API sync
|
||||
- [ ] Offline queue
|
||||
- [ ] Cross-device sync
|
||||
- [ ] Batch operations
|
||||
- [ ] Favorites collections
|
||||
- [ ] Share favorites
|
||||
- [ ] Analytics tracking
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Troubleshooting
|
||||
|
||||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| Favorites not persisting | Check Hive box initialization in `main.dart` |
|
||||
| State not updating | Use `ref.read()` for mutations, `ref.watch()` for listening |
|
||||
| Performance issues | Use `isFavoriteProvider` instead of watching full `favoritesProvider` |
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support
|
||||
|
||||
For detailed examples and advanced use cases, see:
|
||||
- **[USAGE_EXAMPLES.md](./USAGE_EXAMPLES.md)**
|
||||
- **[INTEGRATION_SUMMARY.md](./INTEGRATION_SUMMARY.md)**
|
||||
|
||||
---
|
||||
|
||||
**Status**: ✅ Ready for integration
|
||||
**Version**: 1.0.0
|
||||
**Last Updated**: 2024-10-24
|
||||
Reference in New Issue
Block a user