rluv_client/lib/global/store.dart
2023-07-22 21:29:32 -06:00

186 lines
5.7 KiB
Dart

import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:helpers/helpers/print.dart';
import 'package:rluv/global/api.dart';
import 'package:rluv/models/budget.dart';
import 'package:rluv/models/budget_category_model.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/family_model.dart';
import '../models/shared_note.dart';
import '../models/transaction_model.dart';
import '../models/user.dart';
class Store {
static final Store _instance = Store._internal();
bool _initDone = false;
SharedPreferences? prefs;
factory Store() {
if (_instance._initDone) {
return _instance;
}
_instance._initDone = true;
SharedPreferences.getInstance().then(
(value) => _instance.prefs = value,
);
_instance.dashboardProvider =
StateNotifierProvider<DashBoardStateNotifier, Map<String, dynamic>?>(
(ref) {
final family = ref.watch(_instance.familyProvider).valueOrNull;
return DashBoardStateNotifier(family);
},
);
// _instance.dashboardProvider = FutureProvider<Map<String, dynamic>?>(
// (ref) async {
// final family = await ref.watch(_instance.familyProvider.future);
// return Api().get("dashboard/${family.id}");
// },
// );
_instance.budgetProvider = Provider<Budget?>(
(ref) {
final dash = ref.watch(_instance.dashboardProvider);
if (dash == null) return null;
final budgetData = dash['budget'] as Map<String, dynamic>?;
if (budgetData == null) return null;
return Budget.fromJson(budgetData);
},
);
_instance.budgetCategoriesProvider = Provider<List<BudgetCategory>>((ref) {
final dash = ref.watch(_instance.dashboardProvider);
if (dash == null) return [];
final categoriesData = dash['budget_categories'] as List<dynamic>;
final categories = categoriesData
.map(
(e) => BudgetCategory.fromJson(e as Map<String, dynamic>),
)
.toList();
if (_instance.prefs != null) {
final budgetJson = jsonEncode({'budget_categories': categoriesData});
printBlue('updated prefs stored categories');
_instance.prefs!.setString('budget_categories', budgetJson);
}
return categories;
});
_instance.transactionsProvider = Provider<List<Transaction>>((ref) {
final dash = ref.watch(_instance.dashboardProvider);
if (dash == null) return [];
final transactions = dash['transactions'] as List<dynamic>;
return transactions
.map(
(e) => Transaction.fromJson(e as Map<String, dynamic>),
)
.toList();
});
return _instance;
}
Store._internal();
final FutureProvider<User> userProvider = FutureProvider<User>(
(ref) {
return User(
id: 0,
budgetId: 1,
createdAt: DateTime.now(),
familyId: 1,
lastActivityAt: DateTime.now(),
name: 'TEMP',
updatedAt: DateTime.now(),
);
},
);
final FutureProvider<FamilyModel> familyProvider =
FutureProvider<FamilyModel>((ref) => FamilyModel(
id: 1,
budgetId: 1,
createdAt: DateTime.now(),
updatedAt: DateTime.now()));
late final Provider<List<BudgetCategory>> budgetCategoriesProvider;
late final Provider<Budget?> budgetProvider;
late final Provider<List<Transaction>> transactionsProvider;
late final Provider<List<SharedNote>> sharedNotesProvider;
// late final FutureProvider<Map<String, dynamic>?> dashboardProvider;
late final StateNotifierProvider<DashBoardStateNotifier,
Map<String, dynamic>?> dashboardProvider;
void fetchDashboard() {}
}
class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
DashBoardStateNotifier(FamilyModel? family) : super(null) {
fetchDashboard(family);
}
Future fetchDashboard(FamilyModel? family) async {
if (family == null) {
printPink('Unable to get dashboard');
return;
}
printAmber('Fetching dashboard');
state = await Api().get("dashboard/${family.id}");
}
void update(Map<String, dynamic> data) {
if (state == null) {
printPink('Cant update data, state is null');
return;
}
if (data.keys.length != 1 || data.values.length != 1) {
throw Exception('Only one key/val used in update');
}
final key = data.keys.first;
switch (key) {
case 'transactions':
case 'budget_categories':
final subStateList = state![key] as List<dynamic>;
final subStateListObj = subStateList
.map(
(e) => e as Map<String, dynamic>,
)
.toList();
subStateListObj.removeWhere(
(element) =>
element['id'] ==
(data.values.first as Map<String, dynamic>)['id'],
);
subStateListObj.add(data.values.first);
final newState = state;
newState![key] = subStateListObj;
state = {...newState};
// printBlue(state);
break;
default:
break;
}
}
void add(Map<String, dynamic> data) {
if (state == null) {
printPink('Cant add data, state is null');
return;
}
if (data.keys.length != 1 || data.values.length != 1) {
throw Exception('Only one key/val used in add');
}
final key = data.keys.first;
switch (key) {
case 'transactions':
case 'budget_categories':
final subStateList = state![key] as List<dynamic>;
final newState = state;
subStateList.add(data.values.first);
newState![key] = subStateList;
state = {...newState};
// printBlue(state);
break;
default:
break;
}
}
}