Update project
This commit is contained in:
89
lib/features/dashboard/domain/repo/grocery_repository.dart
Normal file
89
lib/features/dashboard/domain/repo/grocery_repository.dart
Normal file
@@ -0,0 +1,89 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
// TODO: point this at wherever your real `Product` model (the one used by
|
||||
// CartController.addToCart) actually lives.
|
||||
import '../../../../modules/product/product.dart';
|
||||
|
||||
/// One subcategory row returned by the API, e.g. "Vegetables & Fruits",
|
||||
/// holding the real `Product` model straight from the API — the same type
|
||||
/// CartController.addToCart expects, so no adapter/mapping is needed to
|
||||
/// add a grocery item to the cart.
|
||||
class GrocerySubcategorySection {
|
||||
final int subcategoryId;
|
||||
final String subcategoryName;
|
||||
final String image;
|
||||
final List<Product> products;
|
||||
|
||||
GrocerySubcategorySection({
|
||||
required this.subcategoryId,
|
||||
required this.subcategoryName,
|
||||
required this.image,
|
||||
required this.products,
|
||||
});
|
||||
}
|
||||
|
||||
class GroceryRepository {
|
||||
static const String _baseUrl =
|
||||
'https://fiesta.nearle.app/live/api/v1/mob/products/getproductsbysubcategory';
|
||||
|
||||
/// Fetches grocery products for the given category/tenant/location and
|
||||
/// returns them grouped by subcategory, in the order the API returns them.
|
||||
///
|
||||
/// Throws an [Exception] with a readable message on failure so the caller
|
||||
/// can show a retry UI.
|
||||
Future<List<GrocerySubcategorySection>> fetchGroceryProducts({
|
||||
required int categoryId,
|
||||
required int tenantId,
|
||||
required int locationId,
|
||||
}) async {
|
||||
final uri = Uri.parse(
|
||||
'$_baseUrl?categoryid=$categoryId&tenantid=$tenantId&locationid=$locationId',
|
||||
);
|
||||
|
||||
late final http.Response response;
|
||||
try {
|
||||
print('Fetching grocery products from API...');
|
||||
print(uri);
|
||||
response = await http.get(uri).timeout(const Duration(seconds: 15));
|
||||
} catch (_) {
|
||||
throw Exception('Could not reach the server. Check your connection.');
|
||||
}
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception(
|
||||
'Failed to load grocery products (HTTP ${response.statusCode})');
|
||||
}
|
||||
|
||||
late final Map<String, dynamic> body;
|
||||
try {
|
||||
body = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
} catch (_) {
|
||||
throw Exception('Received an unexpected response from the server.');
|
||||
}
|
||||
|
||||
if (body['status'] != true) {
|
||||
throw Exception(
|
||||
(body['message'] as String?) ?? 'Failed to load grocery products');
|
||||
}
|
||||
|
||||
final List<dynamic> details =
|
||||
(body['data'] as Map<String, dynamic>?)?['details'] as List<dynamic>? ??
|
||||
[];
|
||||
|
||||
return details.map((rawSection) {
|
||||
final section = rawSection as Map<String, dynamic>;
|
||||
final rawProducts = (section['products'] as List<dynamic>?) ?? [];
|
||||
|
||||
return GrocerySubcategorySection(
|
||||
subcategoryId: (section['subcategoryid'] as num?)?.toInt() ?? 0,
|
||||
subcategoryName: (section['subcategoryname'] as String?) ?? 'Other',
|
||||
image: (section['image'] as String?) ?? 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRNKer1bKTGDnr5Um463cjhRTpKstbPxh5DxA2hrAr1egSWr7VK42aLkiI&s=10',
|
||||
// Uses your existing Product.fromJson, so tenantid/productid/etc.
|
||||
// needed by addToCart are preserved straight from the API.
|
||||
products: Product.fromJsonList(rawProducts),
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user