runable
This commit is contained in:
215
.archive/category_remote_datasource.dart
Normal file
215
.archive/category_remote_datasource.dart
Normal file
@@ -0,0 +1,215 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import '../../../../core/constants/api_constants.dart';
|
||||
import '../../../../core/errors/exceptions.dart';
|
||||
import '../../../../core/network/dio_client.dart';
|
||||
import '../models/category_model.dart';
|
||||
|
||||
/// Remote data source for categories API operations
|
||||
abstract class CategoryRemoteDataSource {
|
||||
/// Fetch all categories from the API
|
||||
Future<List<CategoryModel>> fetchCategories();
|
||||
|
||||
/// Fetch a single category by ID
|
||||
Future<CategoryModel> fetchCategoryById(String id);
|
||||
|
||||
/// Sync categories (bulk update/create)
|
||||
Future<void> syncCategories(List<CategoryModel> categories);
|
||||
}
|
||||
|
||||
/// Implementation of CategoryRemoteDataSource using Dio
|
||||
class CategoryRemoteDataSourceImpl implements CategoryRemoteDataSource {
|
||||
final DioClient _dioClient;
|
||||
|
||||
CategoryRemoteDataSourceImpl(this._dioClient);
|
||||
|
||||
@override
|
||||
Future<List<CategoryModel>> fetchCategories() async {
|
||||
try {
|
||||
final response = await _dioClient.get(ApiConstants.categories);
|
||||
|
||||
if (response.statusCode == ApiConstants.statusOk) {
|
||||
final data = response.data;
|
||||
|
||||
// Handle different response structures
|
||||
List<dynamic> categoriesJson;
|
||||
if (data is Map<String, dynamic>) {
|
||||
// Response wrapped in object: { "categories": [...] }
|
||||
categoriesJson = data['categories'] as List<dynamic>? ??
|
||||
data['data'] as List<dynamic>? ??
|
||||
[];
|
||||
} else if (data is List) {
|
||||
// Direct array response
|
||||
categoriesJson = data;
|
||||
} else {
|
||||
throw DataParsingException('Unexpected response format');
|
||||
}
|
||||
|
||||
return categoriesJson
|
||||
.map((json) => CategoryModel.fromJson(json as Map<String, dynamic>))
|
||||
.toList();
|
||||
} else {
|
||||
throw ServerException(
|
||||
'Failed to fetch categories',
|
||||
response.statusCode ?? 500,
|
||||
);
|
||||
}
|
||||
} on AppException {
|
||||
rethrow;
|
||||
} catch (e, stackTrace) {
|
||||
throw NetworkException(
|
||||
'Failed to fetch categories: ${e.toString()}',
|
||||
null,
|
||||
e,
|
||||
stackTrace,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CategoryModel> fetchCategoryById(String id) async {
|
||||
try {
|
||||
final response = await _dioClient.get(ApiConstants.categoryById(id));
|
||||
|
||||
if (response.statusCode == ApiConstants.statusOk) {
|
||||
final data = response.data;
|
||||
|
||||
// Handle different response structures
|
||||
Map<String, dynamic> categoryJson;
|
||||
if (data is Map<String, dynamic>) {
|
||||
// Check if category is wrapped in a key
|
||||
categoryJson = data['category'] as Map<String, dynamic>? ??
|
||||
data['data'] as Map<String, dynamic>? ??
|
||||
data;
|
||||
} else {
|
||||
throw DataParsingException('Unexpected response format');
|
||||
}
|
||||
|
||||
return CategoryModel.fromJson(categoryJson);
|
||||
} else if (response.statusCode == ApiConstants.statusNotFound) {
|
||||
throw NotFoundException('Category with ID $id not found');
|
||||
} else {
|
||||
throw ServerException(
|
||||
'Failed to fetch category',
|
||||
response.statusCode ?? 500,
|
||||
);
|
||||
}
|
||||
} on AppException {
|
||||
rethrow;
|
||||
} catch (e, stackTrace) {
|
||||
throw NetworkException(
|
||||
'Failed to fetch category: ${e.toString()}',
|
||||
null,
|
||||
e,
|
||||
stackTrace,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> syncCategories(List<CategoryModel> categories) async {
|
||||
try {
|
||||
final categoriesJson = categories.map((c) => c.toJson()).toList();
|
||||
|
||||
final response = await _dioClient.post(
|
||||
ApiConstants.syncCategories,
|
||||
data: {
|
||||
'categories': categoriesJson,
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode != ApiConstants.statusOk &&
|
||||
response.statusCode != ApiConstants.statusCreated) {
|
||||
throw ServerException(
|
||||
'Failed to sync categories',
|
||||
response.statusCode ?? 500,
|
||||
);
|
||||
}
|
||||
} on AppException {
|
||||
rethrow;
|
||||
} catch (e, stackTrace) {
|
||||
throw NetworkException(
|
||||
'Failed to sync categories: ${e.toString()}',
|
||||
null,
|
||||
e,
|
||||
stackTrace,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Mock implementation for testing and development
|
||||
class CategoryRemoteDataSourceMock implements CategoryRemoteDataSource {
|
||||
/// Simulate network delay
|
||||
Future<void> _delay() async {
|
||||
await Future.delayed(
|
||||
Duration(milliseconds: ApiConstants.mockApiDelay),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<CategoryModel>> fetchCategories() async {
|
||||
await _delay();
|
||||
|
||||
// Return mock categories
|
||||
return [
|
||||
CategoryModel(
|
||||
id: '1',
|
||||
name: 'Electronics',
|
||||
description: 'Electronic devices and accessories',
|
||||
iconPath: 'assets/icons/electronics.png',
|
||||
color: '#2196F3',
|
||||
productCount: 25,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 60)),
|
||||
),
|
||||
CategoryModel(
|
||||
id: '2',
|
||||
name: 'Clothing',
|
||||
description: 'Fashion and apparel',
|
||||
iconPath: 'assets/icons/clothing.png',
|
||||
color: '#E91E63',
|
||||
productCount: 50,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 50)),
|
||||
),
|
||||
CategoryModel(
|
||||
id: '3',
|
||||
name: 'Food & Beverages',
|
||||
description: 'Food, drinks, and snacks',
|
||||
iconPath: 'assets/icons/food.png',
|
||||
color: '#FF9800',
|
||||
productCount: 100,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 40)),
|
||||
),
|
||||
CategoryModel(
|
||||
id: '4',
|
||||
name: 'Home & Garden',
|
||||
description: 'Home improvement and garden supplies',
|
||||
iconPath: 'assets/icons/home.png',
|
||||
color: '#4CAF50',
|
||||
productCount: 30,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 30)),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CategoryModel> fetchCategoryById(String id) async {
|
||||
await _delay();
|
||||
|
||||
// Return mock category
|
||||
return CategoryModel(
|
||||
id: id,
|
||||
name: 'Sample Category $id',
|
||||
description: 'This is sample category $id',
|
||||
iconPath: 'assets/icons/category.png',
|
||||
color: '#2196F3',
|
||||
productCount: 10,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 30)),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> syncCategories(List<CategoryModel> categories) async {
|
||||
await _delay();
|
||||
// Mock sync - do nothing
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user