update review api.
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
/// Providers: Reviews
|
||||
///
|
||||
/// Riverpod providers for review management.
|
||||
library;
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker/core/network/dio_client.dart';
|
||||
import 'package:worker/features/reviews/data/datasources/reviews_remote_datasource.dart';
|
||||
import 'package:worker/features/reviews/data/repositories/reviews_repository_impl.dart';
|
||||
import 'package:worker/features/reviews/domain/entities/review.dart';
|
||||
import 'package:worker/features/reviews/domain/entities/review_statistics.dart';
|
||||
import 'package:worker/features/reviews/domain/repositories/reviews_repository.dart';
|
||||
import 'package:worker/features/reviews/domain/usecases/delete_review.dart';
|
||||
import 'package:worker/features/reviews/domain/usecases/get_product_reviews.dart';
|
||||
import 'package:worker/features/reviews/domain/usecases/submit_review.dart';
|
||||
|
||||
part 'reviews_provider.g.dart';
|
||||
|
||||
// ============================================================================
|
||||
// Data Layer Providers
|
||||
// ============================================================================
|
||||
|
||||
/// Provider for reviews remote data source
|
||||
@riverpod
|
||||
Future<ReviewsRemoteDataSource> reviewsRemoteDataSource(
|
||||
Ref ref,
|
||||
) async {
|
||||
final dioClient = await ref.watch(dioClientProvider.future);
|
||||
return ReviewsRemoteDataSourceImpl(dioClient);
|
||||
}
|
||||
|
||||
/// Provider for reviews repository
|
||||
@riverpod
|
||||
Future<ReviewsRepository> reviewsRepository(Ref ref) async {
|
||||
final remoteDataSource = await ref.watch(reviewsRemoteDataSourceProvider.future);
|
||||
return ReviewsRepositoryImpl(remoteDataSource);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Use Case Providers
|
||||
// ============================================================================
|
||||
|
||||
/// Provider for get product reviews use case
|
||||
@riverpod
|
||||
Future<GetProductReviews> getProductReviews(Ref ref) async {
|
||||
final repository = await ref.watch(reviewsRepositoryProvider.future);
|
||||
return GetProductReviews(repository);
|
||||
}
|
||||
|
||||
/// Provider for submit review use case
|
||||
@riverpod
|
||||
Future<SubmitReview> submitReview(Ref ref) async {
|
||||
final repository = await ref.watch(reviewsRepositoryProvider.future);
|
||||
return SubmitReview(repository);
|
||||
}
|
||||
|
||||
/// Provider for delete review use case
|
||||
@riverpod
|
||||
Future<DeleteReview> deleteReview(Ref ref) async {
|
||||
final repository = await ref.watch(reviewsRepositoryProvider.future);
|
||||
return DeleteReview(repository);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// State Providers
|
||||
// ============================================================================
|
||||
|
||||
/// Provider for fetching reviews for a specific product
|
||||
///
|
||||
/// This is a family provider that takes a product ID and returns
|
||||
/// the list of reviews for that product.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```dart
|
||||
/// final reviewsAsync = ref.watch(productReviewsProvider('PRODUCT_ID'));
|
||||
/// ```
|
||||
@riverpod
|
||||
Future<List<Review>> productReviews(
|
||||
Ref ref,
|
||||
String itemId,
|
||||
) async {
|
||||
final getProductReviewsUseCase = await ref.watch(getProductReviewsProvider.future);
|
||||
|
||||
return await getProductReviewsUseCase(
|
||||
itemId: itemId,
|
||||
limitPageLength: 50, // Fetch more reviews
|
||||
limitStart: 0,
|
||||
);
|
||||
}
|
||||
|
||||
/// Provider for review statistics (from API)
|
||||
///
|
||||
/// Gets statistics directly from API including:
|
||||
/// - Total feedback count
|
||||
/// - Average rating (0-5 scale, already calculated by server)
|
||||
///
|
||||
/// This is more efficient than calculating client-side
|
||||
@riverpod
|
||||
Future<ReviewStatistics> productReviewStatistics(
|
||||
Ref ref,
|
||||
String itemId,
|
||||
) async {
|
||||
final repository = await ref.watch(reviewsRepositoryProvider.future);
|
||||
return await repository.getProductReviewStatistics(itemId: itemId);
|
||||
}
|
||||
|
||||
/// Provider for average rating (convenience wrapper)
|
||||
///
|
||||
/// Gets the average rating from API statistics
|
||||
/// Returns 0.0 if there are no reviews.
|
||||
@riverpod
|
||||
Future<double> productAverageRating(
|
||||
Ref ref,
|
||||
String itemId,
|
||||
) async {
|
||||
final stats = await ref.watch(productReviewStatisticsProvider(itemId).future);
|
||||
return stats.averageRating;
|
||||
}
|
||||
|
||||
/// Provider for counting reviews (convenience wrapper)
|
||||
///
|
||||
/// Gets the total count from API statistics
|
||||
@riverpod
|
||||
Future<int> productReviewCount(
|
||||
Ref ref,
|
||||
String itemId,
|
||||
) async {
|
||||
final stats = await ref.watch(productReviewStatisticsProvider(itemId).future);
|
||||
return stats.totalFeedback;
|
||||
}
|
||||
|
||||
/// Provider for checking if user can submit a review
|
||||
///
|
||||
/// This can be extended to check if user has already reviewed
|
||||
/// the product and enforce one-review-per-user policy.
|
||||
///
|
||||
/// For now, it always returns true.
|
||||
@riverpod
|
||||
Future<bool> canSubmitReview(
|
||||
Ref ref,
|
||||
String itemId,
|
||||
) async {
|
||||
// TODO: Implement logic to check if user already reviewed this product
|
||||
// This would require user email from auth state
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Helper Functions
|
||||
// ============================================================================
|
||||
|
||||
/// Convert star rating (1-5) to API rating (0-1)
|
||||
///
|
||||
/// Example:
|
||||
/// - 1 star = 0.2
|
||||
/// - 2 stars = 0.4
|
||||
/// - 3 stars = 0.6
|
||||
/// - 4 stars = 0.8
|
||||
/// - 5 stars = 1.0
|
||||
double starsToApiRating(int stars) {
|
||||
if (stars < 1 || stars > 5) {
|
||||
throw ArgumentError('Stars must be between 1 and 5. Got: $stars');
|
||||
}
|
||||
return stars / 5.0;
|
||||
}
|
||||
|
||||
/// Convert API rating (0-1) to star rating (1-5)
|
||||
///
|
||||
/// Example:
|
||||
/// - 0.2 = 1 star
|
||||
/// - 0.5 = 2.5 stars (rounded to 3)
|
||||
/// - 1.0 = 5 stars
|
||||
int apiRatingToStars(double rating) {
|
||||
if (rating < 0 || rating > 1) {
|
||||
throw ArgumentError('Rating must be between 0 and 1. Got: $rating');
|
||||
}
|
||||
return (rating * 5).round();
|
||||
}
|
||||
Reference in New Issue
Block a user