349 lines
9.5 KiB
Dart
349 lines
9.5 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import '../models/bean.dart';
|
|
import '../models/machine.dart';
|
|
import '../models/recipe.dart';
|
|
import '../models/drink.dart';
|
|
import '../models/journal_entry.dart';
|
|
import '../services/storage_service.dart';
|
|
import '../services/data_seeding_service.dart';
|
|
|
|
class AppState extends ChangeNotifier {
|
|
final StorageService _storageService = StorageService();
|
|
final DataSeedingService _dataSeedingService = DataSeedingService();
|
|
|
|
List<Bean> _beans = [];
|
|
List<Machine> _machines = [];
|
|
List<Recipe> _recipes = [];
|
|
List<Drink> _drinks = [];
|
|
List<JournalEntry> _journalEntries = [];
|
|
|
|
bool _isLoading = false;
|
|
|
|
// Getters
|
|
List<Bean> get beans => _beans;
|
|
List<Machine> get machines => _machines;
|
|
List<Recipe> get recipes => _recipes;
|
|
List<Drink> get drinks => _drinks;
|
|
List<JournalEntry> get journalEntries => _journalEntries;
|
|
bool get isLoading => _isLoading;
|
|
|
|
// Preferred items
|
|
List<Bean> get preferredBeans =>
|
|
_beans.where((bean) => bean.preferred).toList();
|
|
List<Drink> get preferredDrinks =>
|
|
_drinks.where((drink) => drink.preferred).toList();
|
|
|
|
AppState() {
|
|
_loadData();
|
|
}
|
|
|
|
Future<void> _loadData() async {
|
|
_setLoading(true);
|
|
try {
|
|
// Seed initial data if needed (loads from CSV files)
|
|
await _dataSeedingService.seedInitialData();
|
|
|
|
_beans = await _storageService.getBeans();
|
|
_machines = await _storageService.getMachines();
|
|
_recipes = await _storageService.getRecipes();
|
|
_drinks = await _storageService.getDrinks();
|
|
_journalEntries = await _storageService.getJournalEntries();
|
|
} catch (e) {
|
|
debugPrint('Error loading data: $e');
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
void _setLoading(bool loading) {
|
|
_isLoading = loading;
|
|
notifyListeners();
|
|
}
|
|
|
|
// Bean operations
|
|
Future<void> addBean(Bean bean) async {
|
|
try {
|
|
await _storageService.saveBean(bean);
|
|
// Reload beans from storage to keep data consistent
|
|
_beans = await _storageService.getBeans();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error adding bean: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> updateBean(Bean bean) async {
|
|
try {
|
|
await _storageService.saveBean(bean);
|
|
// Reload beans from storage to keep data consistent
|
|
_beans = await _storageService.getBeans();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error updating bean: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> deleteBean(String id) async {
|
|
try {
|
|
await _storageService.deleteBean(id);
|
|
// Reload beans from storage to keep data consistent
|
|
_beans = await _storageService.getBeans();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error deleting bean: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Machine operations
|
|
Future<void> addMachine(Machine machine) async {
|
|
try {
|
|
await _storageService.saveMachine(machine);
|
|
// Reload machines from storage to keep data consistent
|
|
_machines = await _storageService.getMachines();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error adding machine: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> updateMachine(Machine machine) async {
|
|
try {
|
|
await _storageService.saveMachine(machine);
|
|
// Reload machines from storage to keep data consistent
|
|
_machines = await _storageService.getMachines();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error updating machine: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> deleteMachine(String id) async {
|
|
try {
|
|
await _storageService.deleteMachine(id);
|
|
// Reload machines from storage to keep data consistent
|
|
_machines = await _storageService.getMachines();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error deleting machine: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Recipe operations
|
|
Future<void> addRecipe(Recipe recipe) async {
|
|
try {
|
|
await _storageService.saveRecipe(recipe);
|
|
// Reload recipes from storage to keep data consistent
|
|
_recipes = await _storageService.getRecipes();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error adding recipe: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> updateRecipe(Recipe recipe) async {
|
|
try {
|
|
await _storageService.saveRecipe(recipe);
|
|
// Reload recipes from storage to keep data consistent
|
|
_recipes = await _storageService.getRecipes();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error updating recipe: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> deleteRecipe(String id) async {
|
|
try {
|
|
await _storageService.deleteRecipe(id);
|
|
// Reload recipes from storage to keep data consistent
|
|
_recipes = await _storageService.getRecipes();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error deleting recipe: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Drink operations
|
|
Future<void> addDrink(Drink drink) async {
|
|
try {
|
|
await _storageService.saveDrink(drink);
|
|
// Reload drinks from storage to keep data consistent
|
|
_drinks = await _storageService.getDrinks();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error adding drink: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> updateDrink(Drink drink) async {
|
|
try {
|
|
await _storageService.saveDrink(drink);
|
|
// Reload drinks from storage to keep data consistent
|
|
_drinks = await _storageService.getDrinks();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error updating drink: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> deleteDrink(String id) async {
|
|
try {
|
|
await _storageService.deleteDrink(id);
|
|
// Reload drinks from storage to keep data consistent
|
|
_drinks = await _storageService.getDrinks();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error deleting drink: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Journal operations
|
|
Future<void> addJournalEntry(JournalEntry entry) async {
|
|
try {
|
|
await _storageService.saveJournalEntry(entry);
|
|
// Reload journal entries from storage to keep data consistent
|
|
_journalEntries = await _storageService.getJournalEntries();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error adding journal entry: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> updateJournalEntry(JournalEntry entry) async {
|
|
try {
|
|
await _storageService.saveJournalEntry(entry);
|
|
// Reload journal entries from storage to keep data consistent
|
|
_journalEntries = await _storageService.getJournalEntries();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error updating journal entry: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> deleteJournalEntry(String id) async {
|
|
try {
|
|
await _storageService.deleteJournalEntry(id);
|
|
// Reload journal entries from storage to keep data consistent
|
|
_journalEntries = await _storageService.getJournalEntries();
|
|
notifyListeners();
|
|
} catch (e) {
|
|
debugPrint('Error deleting journal entry: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Search functionality
|
|
List<dynamic> searchAll(String query) {
|
|
final lowerQuery = query.toLowerCase();
|
|
final results = <dynamic>[];
|
|
|
|
// Search beans
|
|
results.addAll(
|
|
_beans.where(
|
|
(bean) =>
|
|
bean.name.toLowerCase().contains(lowerQuery) ||
|
|
bean.varietal.toLowerCase().contains(lowerQuery) ||
|
|
bean.originCountry?.details.toLowerCase().contains(lowerQuery) ==
|
|
true,
|
|
),
|
|
);
|
|
|
|
// Search machines
|
|
results.addAll(
|
|
_machines.where(
|
|
(machine) =>
|
|
machine.manufacturer.toLowerCase().contains(lowerQuery) ||
|
|
machine.model.toLowerCase().contains(lowerQuery) ||
|
|
machine.details.toLowerCase().contains(lowerQuery),
|
|
),
|
|
);
|
|
|
|
// Search recipes
|
|
results.addAll(
|
|
_recipes.where(
|
|
(recipe) =>
|
|
recipe.name.toLowerCase().contains(lowerQuery) ||
|
|
recipe.instructions.toLowerCase().contains(lowerQuery) ||
|
|
recipe.notes?.toLowerCase().contains(lowerQuery) == true,
|
|
),
|
|
);
|
|
|
|
// Search drinks
|
|
results.addAll(
|
|
_drinks.where(
|
|
(drink) =>
|
|
drink.name.toLowerCase().contains(lowerQuery) ||
|
|
drink.details.toLowerCase().contains(lowerQuery) ||
|
|
drink.notes.toLowerCase().contains(lowerQuery),
|
|
),
|
|
);
|
|
|
|
return results;
|
|
}
|
|
|
|
// Clear all data
|
|
Future<void> clearAllData() async {
|
|
await _storageService.clearAllData();
|
|
_beans.clear();
|
|
_machines.clear();
|
|
_recipes.clear();
|
|
_drinks.clear();
|
|
_journalEntries.clear();
|
|
notifyListeners();
|
|
}
|
|
|
|
// Clear and reseed data for testing
|
|
Future<void> clearAndReseedData() async {
|
|
_setLoading(true);
|
|
try {
|
|
await _dataSeedingService.clearAndReseedData();
|
|
await _loadData();
|
|
} catch (e) {
|
|
debugPrint('Error reseeding data: $e');
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
// Catalog browsing operations
|
|
Future<List<Bean>> getAllAvailableBeans() async {
|
|
try {
|
|
return await _storageService.getAllAvailableBeans();
|
|
} catch (e) {
|
|
debugPrint('Error loading available beans: $e');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<List<Machine>> getAllAvailableMachines() async {
|
|
try {
|
|
return await _storageService.getAllAvailableMachines();
|
|
} catch (e) {
|
|
debugPrint('Error loading available machines: $e');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<List<Recipe>> getAllAvailableRecipes() async {
|
|
try {
|
|
return await _storageService.getAllAvailableRecipes();
|
|
} catch (e) {
|
|
debugPrint('Error loading available recipes: $e');
|
|
return [];
|
|
}
|
|
}
|
|
}
|