91 lines
2.7 KiB
Dart
91 lines
2.7 KiB
Dart
import 'dart:async';
|
||
import 'package:get/get.dart';
|
||
import 'package:marco/model/dynamicMenu/dynamic_menu_model.dart';
|
||
import 'package:marco/helpers/services/api_service.dart';
|
||
import 'package:marco/helpers/services/app_logger.dart';
|
||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
||
|
||
class DynamicMenuController extends GetxController {
|
||
// UI reactive states
|
||
final RxBool isLoading = false.obs;
|
||
final RxBool hasError = false.obs;
|
||
final RxString errorMessage = ''.obs;
|
||
final RxList<MenuItem> menuItems = <MenuItem>[].obs;
|
||
|
||
Timer? _autoRefreshTimer;
|
||
|
||
@override
|
||
void onInit() {
|
||
super.onInit();
|
||
|
||
// ✅ Load cached menus immediately (so user doesn’t see empty state)
|
||
final cachedMenus = LocalStorage.getMenus();
|
||
if (cachedMenus.isNotEmpty) {
|
||
menuItems.assignAll(cachedMenus);
|
||
logSafe("Loaded ${cachedMenus.length} menus from cache at startup");
|
||
}
|
||
|
||
// ✅ Fetch from API in background
|
||
fetchMenu();
|
||
|
||
// Auto refresh every 15 minutes
|
||
_autoRefreshTimer = Timer.periodic(
|
||
const Duration(minutes: 15),
|
||
(_) => fetchMenu(),
|
||
);
|
||
}
|
||
|
||
/// Fetch dynamic menu from API with cache fallback
|
||
Future<void> fetchMenu() async {
|
||
isLoading.value = true;
|
||
hasError.value = false;
|
||
errorMessage.value = '';
|
||
|
||
try {
|
||
final responseData = await ApiService.getMenuApi();
|
||
if (responseData != null) {
|
||
// Parse JSON into MenuResponse
|
||
final menuResponse = MenuResponse.fromJson(responseData);
|
||
menuItems.assignAll(menuResponse.data);
|
||
|
||
// Save for offline use
|
||
await LocalStorage.setMenus(menuItems);
|
||
|
||
logSafe("✅ Menu loaded from API with ${menuItems.length} items");
|
||
} else {
|
||
_handleApiFailure("Menu API returned null response");
|
||
}
|
||
} catch (e) {
|
||
_handleApiFailure("Menu fetch exception: $e");
|
||
} finally {
|
||
isLoading.value = false;
|
||
}
|
||
}
|
||
|
||
void _handleApiFailure(String logMessage) {
|
||
logSafe(logMessage, level: LogLevel.error);
|
||
|
||
final cachedMenus = LocalStorage.getMenus();
|
||
if (cachedMenus.isNotEmpty) {
|
||
menuItems.assignAll(cachedMenus);
|
||
errorMessage.value = "⚠️ Using offline menus (latest sync failed)";
|
||
logSafe("Loaded ${menuItems.length} menus from cache after failure");
|
||
} else {
|
||
hasError.value = true;
|
||
errorMessage.value = "❌ Unable to load menus. Please try again later.";
|
||
menuItems.clear();
|
||
}
|
||
}
|
||
|
||
bool isMenuAllowed(String menuName) {
|
||
final menu = menuItems.firstWhereOrNull((m) => m.name == menuName);
|
||
return menu?.available ?? false; // default false if not found
|
||
}
|
||
|
||
@override
|
||
void onClose() {
|
||
_autoRefreshTimer?.cancel();
|
||
super.onClose();
|
||
}
|
||
}
|