55 lines
1.7 KiB
Dart
55 lines
1.7 KiB
Dart
/// Provider: Promotions Provider
|
|
///
|
|
/// Manages the state of promotions data using Riverpod.
|
|
/// Uses the same data source as news articles (single API call).
|
|
///
|
|
/// Uses AsyncNotifierProvider for automatic loading, error, and data states.
|
|
library;
|
|
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:worker/features/home/domain/entities/promotion.dart';
|
|
import 'package:worker/features/news/presentation/providers/news_provider.dart';
|
|
|
|
part 'promotions_provider.g.dart';
|
|
|
|
/// Max number of promotions to display on home page
|
|
const int _maxPromotions = 5;
|
|
|
|
/// Promotions Provider
|
|
///
|
|
/// Uses the same data source as news articles to avoid duplicate API calls.
|
|
/// Converts NewsArticle to Promotion entity for display in PromotionSlider.
|
|
/// Limited to 5 items max.
|
|
///
|
|
/// Usage:
|
|
/// ```dart
|
|
/// // In a ConsumerWidget
|
|
/// final promotionsAsync = ref.watch(promotionsProvider);
|
|
///
|
|
/// promotionsAsync.when(
|
|
/// data: (promotions) => PromotionSlider(promotions: promotions),
|
|
/// loading: () => CircularProgressIndicator(),
|
|
/// error: (error, stack) => ErrorWidget(error),
|
|
/// );
|
|
/// ```
|
|
@riverpod
|
|
Future<List<Promotion>> promotions(Ref ref) async {
|
|
// Use newsArticles provider (same API call, no duplicate request)
|
|
final articles = await ref.watch(newsArticlesProvider.future);
|
|
|
|
// Take max 5 articles and convert to Promotion
|
|
final limitedArticles = articles.take(_maxPromotions).toList();
|
|
|
|
return limitedArticles.map((article) {
|
|
final now = DateTime.now();
|
|
return Promotion(
|
|
id: article.id,
|
|
title: article.title,
|
|
description: article.excerpt,
|
|
imageUrl: article.imageUrl,
|
|
startDate: article.publishedDate,
|
|
endDate: now.add(const Duration(days: 365)), // Always active
|
|
);
|
|
}).toList();
|
|
}
|