Files
worker/docs/md/REVIEWS_QUICK_REFERENCE.md
Phuoc Nguyen 19d9a3dc2d update loaing
2025-12-02 18:09:20 +07:00

266 lines
5.7 KiB
Markdown

# Reviews API - Quick Reference Guide
## Rating Scale Conversion
### Convert UI Stars to API Rating
```dart
// UI: 5 stars → API: 1.0
final apiRating = stars / 5.0;
```
### Convert API Rating to UI Stars
```dart
// API: 0.8 → UI: 4 stars
final stars = (rating * 5).round();
```
### Helper Functions (in reviews_provider.dart)
```dart
double apiRating = starsToApiRating(5); // Returns 1.0
int stars = apiRatingToStars(0.8); // Returns 4
```
---
## Provider Usage
### Get Reviews for Product
```dart
final reviewsAsync = ref.watch(productReviewsProvider(itemId));
reviewsAsync.when(
data: (reviews) => /* show reviews */,
loading: () => const CustomLoadingIndicator(),
error: (error, stack) => /* show error */,
);
```
### Get Average Rating
```dart
final avgRatingAsync = ref.watch(productAverageRatingProvider(itemId));
```
### Get Review Count
```dart
final countAsync = ref.watch(productReviewCountProvider(itemId));
```
### Submit Review
```dart
try {
final submitUseCase = ref.read(submitReviewProvider);
await submitUseCase(
itemId: productId,
rating: stars / 5.0, // Convert stars to 0-1
comment: comment,
);
// Refresh reviews
ref.invalidate(productReviewsProvider(productId));
} catch (e) {
// Handle error
}
```
### Delete Review
```dart
try {
final deleteUseCase = ref.read(deleteReviewProvider);
await deleteUseCase(name: reviewId);
// Refresh reviews
ref.invalidate(productReviewsProvider(productId));
} catch (e) {
// Handle error
}
```
---
## API Endpoints
### Get Reviews
```dart
POST /api/method/building_material.building_material.api.item_feedback.get_list
Body: {
"limit_page_length": 10,
"limit_start": 0,
"item_id": "PRODUCT_ID"
}
```
### Submit Review
```dart
POST /api/method/building_material.building_material.api.item_feedback.update
Body: {
"item_id": "PRODUCT_ID",
"rating": 0.8, // 0-1 scale
"comment": "Great!",
"name": "REVIEW_ID" // Optional, for updates
}
```
### Delete Review
```dart
POST /api/method/building_material.building_material.api.item_feedback.delete
Body: {
"name": "ITEM-PRODUCT_ID-user@email.com"
}
```
---
## Review Entity
```dart
class Review {
final String id; // Review ID
final String itemId; // Product code
final double rating; // API rating (0-1)
final String comment; // Review text
final String? reviewerName; // Reviewer name
final String? reviewerEmail; // Reviewer email
final DateTime? reviewDate; // Review date
// Convert to stars (0-5)
int get starsRating => (rating * 5).round();
double get starsRatingDecimal => rating * 5;
}
```
---
## Error Handling
### Common Exceptions
```dart
try {
// API call
} on NoInternetException {
// No internet connection
} on TimeoutException {
// Request timeout
} on UnauthorizedException {
// Session expired
} on ValidationException catch (e) {
// Invalid data: e.message
} on NotFoundException {
// Review not found
} on ServerException {
// Server error (5xx)
} catch (e) {
// Unknown error
}
```
### Status Codes
- **400**: Bad Request - Invalid data
- **401**: Unauthorized - Session expired
- **403**: Forbidden - No permission
- **404**: Not Found - Review doesn't exist
- **409**: Conflict - Review already exists
- **429**: Too Many Requests - Rate limited
- **500+**: Server Error
---
## Validation Rules
### Rating
- Must be 0-1 for API
- Must be 1-5 for UI
- Cannot be empty
### Comment
- Minimum: 20 characters
- Maximum: 1000 characters
- Cannot be empty or whitespace only
---
## Date Formatting
```dart
String _formatDate(DateTime date) {
final now = DateTime.now();
final diff = now.difference(date);
if (diff.inDays == 0) return 'Hôm nay';
if (diff.inDays == 1) return 'Hôm qua';
if (diff.inDays < 7) return '${diff.inDays} ngày trước';
if (diff.inDays < 30) return '${(diff.inDays / 7).floor()} tuần trước';
if (diff.inDays < 365) return '${(diff.inDays / 30).floor()} tháng trước';
return '${(diff.inDays / 365).floor()} năm trước';
}
```
---
## Review ID Format
```
ITEM-{item_id}-{user_email}
```
**Examples**:
- `ITEM-GIB20 G04-john@example.com`
- `ITEM-Product123-user@company.com`
---
## Testing Checklist
- [ ] Reviews load correctly
- [ ] Rating conversion works (0-1 ↔ 1-5)
- [ ] Submit review refreshes list
- [ ] Average rating calculates correctly
- [ ] Empty state shows when no reviews
- [ ] Loading state shows during API calls
- [ ] Error messages display correctly
- [ ] Date formatting works
- [ ] Star ratings display correctly
- [ ] Form validation works
---
## Common Issues
### Issue: Reviews not loading
**Solution**: Check auth tokens (sid, csrf_token) are set
### Issue: Rating conversion wrong
**Solution**: Always use `stars / 5.0` for API, `(rating * 5).round()` for UI
### Issue: Reviews not refreshing after submit
**Solution**: Use `ref.invalidate(productReviewsProvider(itemId))`
### Issue: Provider not found error
**Solution**: Run `dart run build_runner build` to generate .g.dart files
---
## File Locations
**Domain**:
- `lib/features/reviews/domain/entities/review.dart`
- `lib/features/reviews/domain/repositories/reviews_repository.dart`
- `lib/features/reviews/domain/usecases/*.dart`
**Data**:
- `lib/features/reviews/data/models/review_model.dart`
- `lib/features/reviews/data/datasources/reviews_remote_datasource.dart`
- `lib/features/reviews/data/repositories/reviews_repository_impl.dart`
**Presentation**:
- `lib/features/reviews/presentation/providers/reviews_provider.dart`
**Updated**:
- `lib/features/products/presentation/widgets/product_detail/product_tabs_section.dart`
- `lib/features/products/presentation/pages/write_review_page.dart`
- `lib/core/constants/api_constants.dart`