190 lines
6.0 KiB
Dart
190 lines
6.0 KiB
Dart
/// Data Source: Home Local Data Source
|
|
///
|
|
/// Handles local database operations for home feature using Hive.
|
|
/// This is the single source of truth for cached home data.
|
|
///
|
|
/// Responsibilities:
|
|
/// - Store and retrieve member card from local database
|
|
/// - Store and retrieve promotions from local database
|
|
/// - Handle data expiration and cache invalidation
|
|
library;
|
|
|
|
import 'package:worker/core/errors/exceptions.dart';
|
|
import 'package:worker/features/home/data/models/member_card_model.dart';
|
|
import 'package:worker/features/home/data/models/promotion_model.dart';
|
|
|
|
/// Home Local Data Source
|
|
///
|
|
/// Provides methods to interact with Hive database for home data.
|
|
///
|
|
/// Cache strategy:
|
|
/// - Member card: Single entry, updated on login and refresh
|
|
/// - Promotions: List entry, updated periodically
|
|
abstract class HomeLocalDataSource {
|
|
/// Get cached member card
|
|
///
|
|
/// Returns cached [MemberCardModel] if available.
|
|
/// Throws [CacheException] if no data found or data corrupted.
|
|
Future<MemberCardModel> getMemberCard();
|
|
|
|
/// Cache member card
|
|
///
|
|
/// Stores [MemberCardModel] in local database.
|
|
/// Overwrites existing data.
|
|
Future<void> cacheMemberCard(MemberCardModel memberCard);
|
|
|
|
/// Get cached promotions
|
|
///
|
|
/// Returns list of cached [PromotionModel].
|
|
/// Returns empty list if no cached data.
|
|
/// Throws [CacheException] if data corrupted.
|
|
Future<List<PromotionModel>> getPromotions();
|
|
|
|
/// Cache promotions
|
|
///
|
|
/// Stores list of [PromotionModel] in local database.
|
|
/// Overwrites existing data.
|
|
Future<void> cachePromotions(List<PromotionModel> promotions);
|
|
|
|
/// Clear all cached home data
|
|
///
|
|
/// Used when:
|
|
/// - User logs out
|
|
/// - Cache needs to be invalidated
|
|
Future<void> clearCache();
|
|
|
|
/// Check if member card cache is valid
|
|
///
|
|
/// Returns true if cache exists and not expired.
|
|
/// Cache is considered expired after 24 hours.
|
|
Future<bool> isMemberCardCacheValid();
|
|
|
|
/// Check if promotions cache is valid
|
|
///
|
|
/// Returns true if cache exists and not expired.
|
|
/// Cache is considered expired after 1 hour.
|
|
Future<bool> isPromotionsCacheValid();
|
|
}
|
|
|
|
/// Mock Implementation of Home Local Data Source
|
|
///
|
|
/// **TEMPORARY**: Uses hardcoded mock JSON data
|
|
/// **TODO**: Replace with real Hive implementation when API is available
|
|
///
|
|
/// This mock implementation provides realistic data for development and testing.
|
|
/// Uses the exact same interface as the real implementation will.
|
|
class HomeLocalDataSourceImpl implements HomeLocalDataSource {
|
|
/// Mock JSON data for member card
|
|
static const Map<String, dynamic> _mockMemberCardJson = {
|
|
'memberId': 'M001',
|
|
'name': 'La Nguyen Quynh',
|
|
'memberType': 'architect',
|
|
'tier': 'diamond',
|
|
'points': 9750,
|
|
'validUntil': '2025-12-31T23:59:59.000Z',
|
|
'qrData': '0983441099',
|
|
};
|
|
|
|
/// Mock JSON data for promotions
|
|
static const List<Map<String, dynamic>> _mockPromotionsJson = [
|
|
{
|
|
'id': 'P001',
|
|
'title': 'Mua công nhắc - Khuyến mãi cảng lớn',
|
|
'description': 'Giảm đến 30% cho đơn hàng từ 10 triệu',
|
|
'imageUrl':
|
|
'https://images.unsplash.com/photo-1615971677499-5467cbab01c0?w=280&h=140&fit=crop',
|
|
'startDate': '2025-01-01T00:00:00.000Z',
|
|
'endDate': '2025-12-31T23:59:59.000Z',
|
|
'discountPercentage': 30,
|
|
},
|
|
{
|
|
'id': 'P002',
|
|
'title': 'Keo chà ron tặng kèm',
|
|
'description': 'Mua gạch Eurotile tặng keo chà ron cao cấp',
|
|
'imageUrl':
|
|
'https://images.unsplash.com/photo-1542314831-068cd1dbfeeb?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80',
|
|
'startDate': '2025-01-01T00:00:00.000Z',
|
|
'endDate': '2025-12-31T23:59:59.000Z',
|
|
},
|
|
{
|
|
'id': 'P003',
|
|
'title': 'Ưu đãi đặc biệt thành viên VIP',
|
|
'description': 'Chiết khấu thêm 5% cho thành viên Diamond',
|
|
'imageUrl':
|
|
'https://images.unsplash.com/photo-1565538420870-da08ff96a207?w=280&h=140&fit=crop',
|
|
'startDate': '2025-01-01T00:00:00.000Z',
|
|
'endDate': '2025-12-31T23:59:59.000Z',
|
|
'discountPercentage': 5,
|
|
},
|
|
];
|
|
|
|
/// Constructor
|
|
const HomeLocalDataSourceImpl();
|
|
|
|
@override
|
|
Future<MemberCardModel> getMemberCard() async {
|
|
// Simulate network delay
|
|
await Future.delayed(const Duration(milliseconds: 300));
|
|
|
|
try {
|
|
// Parse mock JSON data
|
|
return MemberCardModel.fromJson(_mockMemberCardJson);
|
|
} catch (e) {
|
|
throw CacheException('Failed to get cached member card: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> cacheMemberCard(MemberCardModel memberCard) async {
|
|
// Simulate write delay
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
// Mock implementation - does nothing
|
|
// TODO: Implement Hive write logic when API is available
|
|
}
|
|
|
|
@override
|
|
Future<List<PromotionModel>> getPromotions() async {
|
|
// Simulate network delay
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
|
|
try {
|
|
// Parse mock JSON data
|
|
return _mockPromotionsJson
|
|
.map((json) => PromotionModel.fromJson(json))
|
|
.toList();
|
|
} catch (e) {
|
|
throw CacheException('Failed to get cached promotions: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> cachePromotions(List<PromotionModel> promotions) async {
|
|
// Simulate write delay
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
// Mock implementation - does nothing
|
|
// TODO: Implement Hive write logic when API is available
|
|
}
|
|
|
|
@override
|
|
Future<void> clearCache() async {
|
|
// Simulate operation delay
|
|
await Future.delayed(const Duration(milliseconds: 50));
|
|
// Mock implementation - does nothing
|
|
// TODO: Implement cache clearing when API is available
|
|
}
|
|
|
|
@override
|
|
Future<bool> isMemberCardCacheValid() async {
|
|
// Mock implementation - always return true for development
|
|
// TODO: Implement real cache validation when API is available
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
Future<bool> isPromotionsCacheValid() async {
|
|
// Mock implementation - always return true for development
|
|
// TODO: Implement real cache validation when API is available
|
|
return true;
|
|
}
|
|
}
|